Commit 86c43f4e authored by Robert Haas's avatar Robert Haas

pgbench: Support double constants and functions.

The new functions are pi(), random(), random_exponential(),
random_gaussian(), and sqrt().  I was worried that this would be
slower than before, but, if anything, it actually turns out to be
slightly faster, because we now express the built-in pgbench scripts
using fewer lines; each \setrandom can be merged into a subsequent
\set.

Fabien Coelho
parent 9bd61311
This diff is collapsed.
...@@ -20,6 +20,7 @@ PgBenchExpr *expr_parse_result; ...@@ -20,6 +20,7 @@ PgBenchExpr *expr_parse_result;
static PgBenchExprList *make_elist(PgBenchExpr *exp, PgBenchExprList *list); static PgBenchExprList *make_elist(PgBenchExpr *exp, PgBenchExprList *list);
static PgBenchExpr *make_integer_constant(int64 ival); static PgBenchExpr *make_integer_constant(int64 ival);
static PgBenchExpr *make_double_constant(double dval);
static PgBenchExpr *make_variable(char *varname); static PgBenchExpr *make_variable(char *varname);
static PgBenchExpr *make_op(yyscan_t yyscanner, const char *operator, static PgBenchExpr *make_op(yyscan_t yyscanner, const char *operator,
PgBenchExpr *lexpr, PgBenchExpr *rexpr); PgBenchExpr *lexpr, PgBenchExpr *rexpr);
...@@ -38,6 +39,7 @@ static PgBenchExpr *make_func(yyscan_t yyscanner, int fnumber, PgBenchExprList * ...@@ -38,6 +39,7 @@ static PgBenchExpr *make_func(yyscan_t yyscanner, int fnumber, PgBenchExprList *
%union %union
{ {
int64 ival; int64 ival;
double dval;
char *str; char *str;
PgBenchExpr *expr; PgBenchExpr *expr;
PgBenchExprList *elist; PgBenchExprList *elist;
...@@ -46,9 +48,10 @@ static PgBenchExpr *make_func(yyscan_t yyscanner, int fnumber, PgBenchExprList * ...@@ -46,9 +48,10 @@ static PgBenchExpr *make_func(yyscan_t yyscanner, int fnumber, PgBenchExprList *
%type <elist> elist %type <elist> elist
%type <expr> expr %type <expr> expr
%type <ival> INTEGER function %type <ival> INTEGER function
%type <dval> DOUBLE
%type <str> VARIABLE FUNCTION %type <str> VARIABLE FUNCTION
%token INTEGER VARIABLE FUNCTION %token INTEGER DOUBLE VARIABLE FUNCTION
/* Precedence: lowest to highest */ /* Precedence: lowest to highest */
%left '+' '-' %left '+' '-'
...@@ -74,6 +77,7 @@ expr: '(' expr ')' { $$ = $2; } ...@@ -74,6 +77,7 @@ expr: '(' expr ')' { $$ = $2; }
| expr '/' expr { $$ = make_op(yyscanner, "/", $1, $3); } | expr '/' expr { $$ = make_op(yyscanner, "/", $1, $3); }
| expr '%' expr { $$ = make_op(yyscanner, "%", $1, $3); } | expr '%' expr { $$ = make_op(yyscanner, "%", $1, $3); }
| INTEGER { $$ = make_integer_constant($1); } | INTEGER { $$ = make_integer_constant($1); }
| DOUBLE { $$ = make_double_constant($1); }
| VARIABLE { $$ = make_variable($1); } | VARIABLE { $$ = make_variable($1); }
| function '(' elist ')' { $$ = make_func(yyscanner, $1, $3); } | function '(' elist ')' { $$ = make_func(yyscanner, $1, $3); }
; ;
...@@ -88,8 +92,20 @@ make_integer_constant(int64 ival) ...@@ -88,8 +92,20 @@ make_integer_constant(int64 ival)
{ {
PgBenchExpr *expr = pg_malloc(sizeof(PgBenchExpr)); PgBenchExpr *expr = pg_malloc(sizeof(PgBenchExpr));
expr->etype = ENODE_INTEGER_CONSTANT; expr->etype = ENODE_CONSTANT;
expr->u.integer_constant.ival = ival; expr->u.constant.type = PGBT_INT;
expr->u.constant.u.ival = ival;
return expr;
}
static PgBenchExpr *
make_double_constant(double dval)
{
PgBenchExpr *expr = pg_malloc(sizeof(PgBenchExpr));
expr->etype = ENODE_CONSTANT;
expr->u.constant.type = PGBT_DOUBLE;
expr->u.constant.u.dval = dval;
return expr; return expr;
} }
...@@ -154,6 +170,27 @@ static const struct ...@@ -154,6 +170,27 @@ static const struct
{ {
"debug", 1, PGBENCH_DEBUG "debug", 1, PGBENCH_DEBUG
}, },
{
"pi", 0, PGBENCH_PI
},
{
"sqrt", 1, PGBENCH_SQRT
},
{
"int", 1, PGBENCH_INT
},
{
"double", 1, PGBENCH_DOUBLE
},
{
"random", 2, PGBENCH_RANDOM
},
{
"random_gaussian", 3, PGBENCH_RANDOM_GAUSSIAN
},
{
"random_exponential", 3, PGBENCH_RANDOM_EXPONENTIAL
},
/* keep as last array element */ /* keep as last array element */
{ {
NULL, 0, 0 NULL, 0, 0
......
...@@ -125,6 +125,11 @@ newline [\n] ...@@ -125,6 +125,11 @@ newline [\n]
yylval->ival = strtoint64(yytext); yylval->ival = strtoint64(yytext);
return INTEGER; return INTEGER;
} }
{digit}+(\.{digit}*)?([eE][-+]?{digit}+)? {
yycolumn += yyleng;
yylval->dval = atof(yytext);
return DOUBLE;
}
{alpha}{alnum}* { {alpha}{alnum}* {
yylval->str = pg_strdup(yytext); yylval->str = pg_strdup(yytext);
return FUNCTION; return FUNCTION;
......
This diff is collapsed.
...@@ -28,10 +28,31 @@ ...@@ -28,10 +28,31 @@
*/ */
union YYSTYPE; union YYSTYPE;
/*
* Variable types used in parser.
*/
typedef enum
{
PGBT_INT,
PGBT_DOUBLE
/* add other types here */
} PgBenchValueType;
typedef struct
{
PgBenchValueType type;
union
{
int64 ival;
double dval;
/* add other types here */
} u;
} PgBenchValue;
/* Types of expression nodes */ /* Types of expression nodes */
typedef enum PgBenchExprType typedef enum PgBenchExprType
{ {
ENODE_INTEGER_CONSTANT, ENODE_CONSTANT,
ENODE_VARIABLE, ENODE_VARIABLE,
ENODE_FUNCTION ENODE_FUNCTION
} PgBenchExprType; } PgBenchExprType;
...@@ -48,6 +69,13 @@ typedef enum PgBenchFunction ...@@ -48,6 +69,13 @@ typedef enum PgBenchFunction
PGBENCH_ABS, PGBENCH_ABS,
PGBENCH_MIN, PGBENCH_MIN,
PGBENCH_MAX, PGBENCH_MAX,
PGBENCH_INT,
PGBENCH_DOUBLE,
PGBENCH_PI,
PGBENCH_SQRT,
PGBENCH_RANDOM,
PGBENCH_RANDOM_GAUSSIAN,
PGBENCH_RANDOM_EXPONENTIAL
} PgBenchFunction; } PgBenchFunction;
typedef struct PgBenchExpr PgBenchExpr; typedef struct PgBenchExpr PgBenchExpr;
...@@ -59,10 +87,7 @@ struct PgBenchExpr ...@@ -59,10 +87,7 @@ struct PgBenchExpr
PgBenchExprType etype; PgBenchExprType etype;
union union
{ {
struct PgBenchValue constant;
{
int64 ival;
} integer_constant;
struct struct
{ {
char *varname; char *varname;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment