Rename pgbench min/max to least/greatest, and fix handling of double args.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 5 May 2016 18:51:00 +0000 (14:51 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 5 May 2016 18:51:00 +0000 (14:51 -0400)
These functions behave like the backend's least/greatest functions,
not like min/max, so the originally-chosen names invite confusion.
Per discussion, rename to least/greatest.

I also took it upon myself to make them return double if any input is
double.  The previous behavior of silently coercing all inputs to int
surely does not meet the principle of least astonishment.

Copy-edit some of the other new functions' documentation, too.

doc/src/sgml/ref/pgbench.sgml
src/bin/pgbench/exprparse.y
src/bin/pgbench/pgbench.c
src/bin/pgbench/pgbench.h

index a6c69ff344d57cb0a58914f1cb1fefeea1938a41..e6c7c94fe2517d25e039e3416372ce6e5fc7ed89 100644 (file)
@@ -935,14 +935,15 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
       <row>
        <entry><literal><function>abs(<replaceable>a</>)</></></>
        <entry>same as <replaceable>a</></>
-       <entry>integer or double absolute value</>
+       <entry>absolute value</>
        <entry><literal>abs(-17)</></>
        <entry><literal>17</></>
       </row>
       <row>
        <entry><literal><function>debug(<replaceable>a</>)</></></>
        <entry>same as <replaceable>a</> </>
-       <entry>print to <systemitem>stderr</systemitem> the given argument</>
+       <entry>print <replaceable>a</> to <systemitem>stderr</systemitem>,
+        and return <replaceable>a</></>
        <entry><literal>debug(5432.1)</></>
        <entry><literal>5432.1</></>
       </row>
@@ -961,23 +962,23 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
        <entry><literal>9</></>
       </row>
       <row>
-       <entry><literal><function>max(<replaceable>i</> [, <replaceable>...</> ] )</></></>
-       <entry>integer</>
-       <entry>maximum value</>
-       <entry><literal>max(5, 4, 3, 2)</></>
+       <entry><literal><function>greatest(<replaceable>a</> [, <replaceable>...</> ] )</></></>
+       <entry>double if any <replaceable>a</> is double, else integer</>
+       <entry>largest value among arguments</>
+       <entry><literal>greatest(5, 4, 3, 2)</></>
        <entry><literal>5</></>
       </row>
       <row>
-       <entry><literal><function>min(<replaceable>i</> [, <replaceable>...</> ] )</></></>
-       <entry>integer</>
-       <entry>minimum value</>
-       <entry><literal>min(5, 4, 3, 2)</></>
-       <entry><literal>2</></>
+       <entry><literal><function>least(<replaceable>a</> [, <replaceable>...</> ] )</></></>
+       <entry>double if any <replaceable>a</> is double, else integer</>
+       <entry>smallest value among arguments</>
+       <entry><literal>least(5, 4, 3, 2.1)</></>
+       <entry><literal>2.1</></>
       </row>
       <row>
        <entry><literal><function>pi()</></></>
        <entry>double</>
-       <entry>value of the PI constant</>
+       <entry>value of the constant PI</>
        <entry><literal>pi()</></>
        <entry><literal>3.14159265358979323846</></>
       </row>
index 64c29dcfa7b80966a9711bd47adfd9e8d934db7b..0cc665b75b4bed6929faef62a8d70394d57b18da 100644 (file)
@@ -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",
index 076fbd38afe2faac3cb0a7da9558e09f8ef5e4b9..2a9063a3453828e413043118fe0fce775a814371 100644 (file)
@@ -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;
+                               Assert(nargs >= 1);
 
-                               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 (vargs[i].type == PGBT_DOUBLE)
+                                       {
+                                               havedouble = true;
+                                               break;
+                                       }
+                               }
+                               if (havedouble)
+                               {
+                                       double          extremum;
 
-                                       if (!coerceToInt(&vargs[i], &ival))
+                                       if (!coerceToDouble(&vargs[0], &extremum))
                                                return false;
-
-                                       if (func == PGBENCH_MIN)
-                                               extremum = extremum < ival ? extremum : ival;
-                                       else if (func == PGBENCH_MAX)
-                                               extremum = extremum > ival ? extremum : ival;
+                                       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;
 
-                               setIntValue(retval, 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;
                        }
 
index 7dcb67f52035cfc7b89f9d15522f1e546bb3afcb..58baad8ee67078e1c9acdc9c1b76a94df0014557 100644 (file)
@@ -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,