diff --git a/doc/src/sgml/ref/pgbench.sgml b/doc/src/sgml/ref/pgbench.sgml index a6c69ff344d..e6c7c94fe25 100644 --- a/doc/src/sgml/ref/pgbench.sgml +++ b/doc/src/sgml/ref/pgbench.sgml @@ -935,14 +935,15 @@ pgbench options dbname abs(a) same as a - integer or double absolute value + absolute value abs(-17) 17 debug(a) same as a - print to stderr the given argument + print a to stderr, + and return a debug(5432.1) 5432.1 @@ -961,23 +962,23 @@ pgbench options dbname 9 - max(i [, ... ] ) - integer - maximum value - max(5, 4, 3, 2) + greatest(a [, ... ] ) + double if any a is double, else integer + largest value among arguments + greatest(5, 4, 3, 2) 5 - min(i [, ... ] ) - integer - minimum value - min(5, 4, 3, 2) - 2 + least(a [, ... ] ) + double if any a is double, else integer + smallest value among arguments + least(5, 4, 3, 2.1) + 2.1 pi() double - value of the PI constant + value of the constant PI pi() 3.14159265358979323846 diff --git a/src/bin/pgbench/exprparse.y b/src/bin/pgbench/exprparse.y index 64c29dcfa7b..0cc665b75b4 100644 --- a/src/bin/pgbench/exprparse.y +++ b/src/bin/pgbench/exprparse.y @@ -131,7 +131,7 @@ make_op(yyscan_t yyscanner, const char *operator, * List of available functions: * - fname: function name * - nargs: number of arguments - * -1 is a special value for min & max meaning #args >= 1 + * -1 is a special value for least & greatest meaning #args >= 1 * - tag: function identifier from PgBenchFunction enum */ static const struct @@ -162,10 +162,10 @@ static const struct "abs", 1, PGBENCH_ABS }, { - "min", -1, PGBENCH_MIN + "least", -1, PGBENCH_LEAST }, { - "max", -1, PGBENCH_MAX + "greatest", -1, PGBENCH_GREATEST }, { "debug", 1, PGBENCH_DEBUG @@ -274,7 +274,7 @@ make_func(yyscan_t yyscanner, int fnumber, PgBenchExprList *args) expr_yyerror_more(yyscanner, "unexpected number of arguments", PGBENCH_FUNCTIONS[fnumber].fname); - /* check at least one arg for min & max */ + /* check at least one arg for least & greatest */ if (PGBENCH_FUNCTIONS[fnumber].nargs == -1 && elist_length(args) == 0) expr_yyerror_more(yyscanner, "at least one argument expected", diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c index 076fbd38afe..2a9063a3453 100644 --- a/src/bin/pgbench/pgbench.c +++ b/src/bin/pgbench/pgbench.c @@ -1298,31 +1298,63 @@ evalFunc(TState *thread, CState *st, return true; } - /* variable number of int arguments */ - case PGBENCH_MIN: - case PGBENCH_MAX: + /* variable number of arguments */ + case PGBENCH_LEAST: + case PGBENCH_GREATEST: { - int64 extremum; + bool havedouble; int i; + Assert(nargs >= 1); - if (!coerceToInt(&vargs[0], &extremum)) - return false; - - for (i = 1; i < nargs; i++) + /* need double result if any input is double */ + havedouble = false; + for (i = 0; i < nargs; i++) { - int64 ival; - - if (!coerceToInt(&vargs[i], &ival)) - return false; - - if (func == PGBENCH_MIN) - extremum = extremum < ival ? extremum : ival; - else if (func == PGBENCH_MAX) - extremum = extremum > ival ? extremum : ival; + if (vargs[i].type == PGBT_DOUBLE) + { + havedouble = true; + break; + } } + if (havedouble) + { + double extremum; - setIntValue(retval, extremum); + if (!coerceToDouble(&vargs[0], &extremum)) + return false; + for (i = 1; i < nargs; i++) + { + double dval; + + if (!coerceToDouble(&vargs[i], &dval)) + return false; + if (func == PGBENCH_LEAST) + extremum = Min(extremum, dval); + else + extremum = Max(extremum, dval); + } + setDoubleValue(retval, extremum); + } + else + { + int64 extremum; + + if (!coerceToInt(&vargs[0], &extremum)) + return false; + for (i = 1; i < nargs; i++) + { + int64 ival; + + if (!coerceToInt(&vargs[i], &ival)) + return false; + if (func == PGBENCH_LEAST) + extremum = Min(extremum, ival); + else + extremum = Max(extremum, ival); + } + setIntValue(retval, extremum); + } return true; } diff --git a/src/bin/pgbench/pgbench.h b/src/bin/pgbench/pgbench.h index 7dcb67f5203..58baad8ee67 100644 --- a/src/bin/pgbench/pgbench.h +++ b/src/bin/pgbench/pgbench.h @@ -67,8 +67,8 @@ typedef enum PgBenchFunction PGBENCH_MOD, PGBENCH_DEBUG, PGBENCH_ABS, - PGBENCH_MIN, - PGBENCH_MAX, + PGBENCH_LEAST, + PGBENCH_GREATEST, PGBENCH_INT, PGBENCH_DOUBLE, PGBENCH_PI,