mirror of
https://github.com/postgres/postgres.git
synced 2025-06-26 12:21:12 +03:00
Rename pgbench min/max to least/greatest, and fix handling of double args.
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.
This commit is contained in:
@ -935,14 +935,15 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
|
|||||||
<row>
|
<row>
|
||||||
<entry><literal><function>abs(<replaceable>a</>)</></></>
|
<entry><literal><function>abs(<replaceable>a</>)</></></>
|
||||||
<entry>same as <replaceable>a</></>
|
<entry>same as <replaceable>a</></>
|
||||||
<entry>integer or double absolute value</>
|
<entry>absolute value</>
|
||||||
<entry><literal>abs(-17)</></>
|
<entry><literal>abs(-17)</></>
|
||||||
<entry><literal>17</></>
|
<entry><literal>17</></>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal><function>debug(<replaceable>a</>)</></></>
|
<entry><literal><function>debug(<replaceable>a</>)</></></>
|
||||||
<entry>same as <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>debug(5432.1)</></>
|
||||||
<entry><literal>5432.1</></>
|
<entry><literal>5432.1</></>
|
||||||
</row>
|
</row>
|
||||||
@ -961,23 +962,23 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
|
|||||||
<entry><literal>9</></>
|
<entry><literal>9</></>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal><function>max(<replaceable>i</> [, <replaceable>...</> ] )</></></>
|
<entry><literal><function>greatest(<replaceable>a</> [, <replaceable>...</> ] )</></></>
|
||||||
<entry>integer</>
|
<entry>double if any <replaceable>a</> is double, else integer</>
|
||||||
<entry>maximum value</>
|
<entry>largest value among arguments</>
|
||||||
<entry><literal>max(5, 4, 3, 2)</></>
|
<entry><literal>greatest(5, 4, 3, 2)</></>
|
||||||
<entry><literal>5</></>
|
<entry><literal>5</></>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal><function>min(<replaceable>i</> [, <replaceable>...</> ] )</></></>
|
<entry><literal><function>least(<replaceable>a</> [, <replaceable>...</> ] )</></></>
|
||||||
<entry>integer</>
|
<entry>double if any <replaceable>a</> is double, else integer</>
|
||||||
<entry>minimum value</>
|
<entry>smallest value among arguments</>
|
||||||
<entry><literal>min(5, 4, 3, 2)</></>
|
<entry><literal>least(5, 4, 3, 2.1)</></>
|
||||||
<entry><literal>2</></>
|
<entry><literal>2.1</></>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry><literal><function>pi()</></></>
|
<entry><literal><function>pi()</></></>
|
||||||
<entry>double</>
|
<entry>double</>
|
||||||
<entry>value of the PI constant</>
|
<entry>value of the constant PI</>
|
||||||
<entry><literal>pi()</></>
|
<entry><literal>pi()</></>
|
||||||
<entry><literal>3.14159265358979323846</></>
|
<entry><literal>3.14159265358979323846</></>
|
||||||
</row>
|
</row>
|
||||||
|
@ -131,7 +131,7 @@ make_op(yyscan_t yyscanner, const char *operator,
|
|||||||
* List of available functions:
|
* List of available functions:
|
||||||
* - fname: function name
|
* - fname: function name
|
||||||
* - nargs: number of arguments
|
* - 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
|
* - tag: function identifier from PgBenchFunction enum
|
||||||
*/
|
*/
|
||||||
static const struct
|
static const struct
|
||||||
@ -162,10 +162,10 @@ static const struct
|
|||||||
"abs", 1, PGBENCH_ABS
|
"abs", 1, PGBENCH_ABS
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"min", -1, PGBENCH_MIN
|
"least", -1, PGBENCH_LEAST
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"max", -1, PGBENCH_MAX
|
"greatest", -1, PGBENCH_GREATEST
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"debug", 1, PGBENCH_DEBUG
|
"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",
|
expr_yyerror_more(yyscanner, "unexpected number of arguments",
|
||||||
PGBENCH_FUNCTIONS[fnumber].fname);
|
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 &&
|
if (PGBENCH_FUNCTIONS[fnumber].nargs == -1 &&
|
||||||
elist_length(args) == 0)
|
elist_length(args) == 0)
|
||||||
expr_yyerror_more(yyscanner, "at least one argument expected",
|
expr_yyerror_more(yyscanner, "at least one argument expected",
|
||||||
|
@ -1298,31 +1298,63 @@ evalFunc(TState *thread, CState *st,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* variable number of int arguments */
|
/* variable number of arguments */
|
||||||
case PGBENCH_MIN:
|
case PGBENCH_LEAST:
|
||||||
case PGBENCH_MAX:
|
case PGBENCH_GREATEST:
|
||||||
{
|
{
|
||||||
int64 extremum;
|
bool havedouble;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
Assert(nargs >= 1);
|
Assert(nargs >= 1);
|
||||||
|
|
||||||
if (!coerceToInt(&vargs[0], &extremum))
|
/* need double result if any input is double */
|
||||||
return false;
|
havedouble = false;
|
||||||
|
for (i = 0; i < nargs; i++)
|
||||||
for (i = 1; i < nargs; i++)
|
|
||||||
{
|
{
|
||||||
int64 ival;
|
if (vargs[i].type == PGBT_DOUBLE)
|
||||||
|
{
|
||||||
if (!coerceToInt(&vargs[i], &ival))
|
havedouble = true;
|
||||||
return false;
|
break;
|
||||||
|
}
|
||||||
if (func == PGBENCH_MIN)
|
|
||||||
extremum = extremum < ival ? extremum : ival;
|
|
||||||
else if (func == PGBENCH_MAX)
|
|
||||||
extremum = extremum > ival ? extremum : ival;
|
|
||||||
}
|
}
|
||||||
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,8 +67,8 @@ typedef enum PgBenchFunction
|
|||||||
PGBENCH_MOD,
|
PGBENCH_MOD,
|
||||||
PGBENCH_DEBUG,
|
PGBENCH_DEBUG,
|
||||||
PGBENCH_ABS,
|
PGBENCH_ABS,
|
||||||
PGBENCH_MIN,
|
PGBENCH_LEAST,
|
||||||
PGBENCH_MAX,
|
PGBENCH_GREATEST,
|
||||||
PGBENCH_INT,
|
PGBENCH_INT,
|
||||||
PGBENCH_DOUBLE,
|
PGBENCH_DOUBLE,
|
||||||
PGBENCH_PI,
|
PGBENCH_PI,
|
||||||
|
Reference in New Issue
Block a user