LCOV - differential code coverage report
Current view: top level - src/bin/pgbench - exprparse.y (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 99.3 % 151 150 1 150
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 12 12 12
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (180,240] days: 100.0 % 1 1 1
Legend: Lines: hit not hit (240..) days: 99.3 % 150 149 1 149
Function coverage date bins:
(240..) days: 100.0 % 12 12 12

 Age         Owner                  TLA  Line data    Source code
                                  1                 : %{
                                  2                 : /*-------------------------------------------------------------------------
                                  3                 :  *
                                  4                 :  * exprparse.y
                                  5                 :  *    bison grammar for a simple expression syntax
                                  6                 :  *
                                  7                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                  8                 :  * Portions Copyright (c) 1994, Regents of the University of California
                                  9                 :  *
                                 10                 :  * src/bin/pgbench/exprparse.y
                                 11                 :  *
                                 12                 :  *-------------------------------------------------------------------------
                                 13                 :  */
                                 14                 : 
                                 15                 : #include "postgres_fe.h"
                                 16                 : 
                                 17                 : #include "pgbench.h"
                                 18                 : 
                                 19                 : #define PGBENCH_NARGS_VARIABLE  (-1)
                                 20                 : #define PGBENCH_NARGS_CASE      (-2)
                                 21                 : #define PGBENCH_NARGS_HASH      (-3)
                                 22                 : #define PGBENCH_NARGS_PERMUTE   (-4)
                                 23                 : 
                                 24                 : PgBenchExpr *expr_parse_result;
                                 25                 : 
                                 26                 : static PgBenchExprList *make_elist(PgBenchExpr *expr, PgBenchExprList *list);
                                 27                 : static PgBenchExpr *make_null_constant(void);
                                 28                 : static PgBenchExpr *make_boolean_constant(bool bval);
                                 29                 : static PgBenchExpr *make_integer_constant(int64 ival);
                                 30                 : static PgBenchExpr *make_double_constant(double dval);
                                 31                 : static PgBenchExpr *make_variable(char *varname);
                                 32                 : static PgBenchExpr *make_op(yyscan_t yyscanner, const char *operator,
                                 33                 :                             PgBenchExpr *lexpr, PgBenchExpr *rexpr);
                                 34                 : static PgBenchExpr *make_uop(yyscan_t yyscanner, const char *operator, PgBenchExpr *expr);
                                 35                 : static int  find_func(yyscan_t yyscanner, const char *fname);
                                 36                 : static PgBenchExpr *make_func(yyscan_t yyscanner, int fnumber, PgBenchExprList *args);
                                 37                 : static PgBenchExpr *make_case(yyscan_t yyscanner, PgBenchExprList *when_then_list, PgBenchExpr *else_part);
                                 38                 : 
                                 39                 : %}
                                 40                 : 
                                 41                 : %pure-parser
                                 42                 : %expect 0
                                 43                 : %name-prefix="expr_yy"
                                 44                 : 
                                 45                 : %parse-param {yyscan_t yyscanner}
                                 46                 : %lex-param   {yyscan_t yyscanner}
                                 47                 : 
                                 48                 : %union
                                 49                 : {
                                 50                 :     int64       ival;
                                 51                 :     double      dval;
                                 52                 :     bool        bval;
                                 53                 :     char       *str;
                                 54                 :     PgBenchExpr *expr;
                                 55                 :     PgBenchExprList *elist;
                                 56                 : }
                                 57                 : 
                                 58                 : %type <elist> elist when_then_list
                                 59                 : %type <expr> expr case_control
                                 60                 : %type <ival> INTEGER_CONST function
                                 61                 : %type <dval> DOUBLE_CONST
                                 62                 : %type <bval> BOOLEAN_CONST
                                 63                 : %type <str> VARIABLE FUNCTION
                                 64                 : 
                                 65                 : %token NULL_CONST INTEGER_CONST MAXINT_PLUS_ONE_CONST DOUBLE_CONST
                                 66                 : %token BOOLEAN_CONST VARIABLE FUNCTION
                                 67                 : %token AND_OP OR_OP NOT_OP NE_OP LE_OP GE_OP LS_OP RS_OP IS_OP
                                 68                 : %token CASE_KW WHEN_KW THEN_KW ELSE_KW END_KW
                                 69                 : 
                                 70                 : /* Precedence: lowest to highest, taken from postgres SQL parser */
                                 71                 : %left   OR_OP
                                 72                 : %left   AND_OP
                                 73                 : %right  NOT_OP
                                 74                 : %nonassoc IS_OP ISNULL_OP NOTNULL_OP
                                 75                 : %nonassoc '<' '>' '=' LE_OP GE_OP NE_OP
                                 76                 : %left   '|' '#' '&' LS_OP RS_OP '~'
                                 77                 : %left   '+' '-'
                                 78                 : %left   '*' '/' '%'
                                 79                 : %right  UNARY
                                 80                 : 
                                 81                 : %%
                                 82                 : 
                                 83                 : result: expr                {
  201 tgl                        84 CBC         365 :                                 expr_parse_result = $1;
                                 85                 :                                 (void) yynerrs; /* suppress compiler warning */
                                 86                 :                             }
                                 87                 : 
 1916 teodor                     88               5 : elist:                      { $$ = NULL; }
                                 89             393 :     | expr                  { $$ = make_elist($1, NULL); }
 2595 rhaas                      90             343 :     | elist ',' expr        { $$ = make_elist($3, $1); }
                                 91                 :     ;
                                 92                 : 
 2960                            93              52 : expr: '(' expr ')'          { $$ = $2; }
 1916 teodor                     94               2 :     | '+' expr %prec UNARY  { $$ = $2; }
                                 95                 :     /* unary minus "-x" implemented as "0 - x" */
                                 96              46 :     | '-' expr %prec UNARY  { $$ = make_op(yyscanner, "-",
                                 97                 :                                            make_integer_constant(0), $2); }
                                 98                 :     /* special PG_INT64_MIN handling, only after a unary minus */
                                 99                 :     | '-' MAXINT_PLUS_ONE_CONST %prec UNARY
 1655 andres                    100               1 :                             { $$ = make_integer_constant(PG_INT64_MIN); }
                                101                 :     /* binary ones complement "~x" implemented as 0xffff... xor x" */
 1916 teodor                    102               2 :     | '~' expr              { $$ = make_op(yyscanner, "#",
                                103                 :                                            make_integer_constant(~INT64CONST(0)), $2); }
                                104              12 :     | NOT_OP expr           { $$ = make_uop(yyscanner, "!not", $2); }
 2577 tgl                       105              48 :     | expr '+' expr         { $$ = make_op(yyscanner, "+", $1, $3); }
                                106              18 :     | expr '-' expr         { $$ = make_op(yyscanner, "-", $1, $3); }
                                107             204 :     | expr '*' expr         { $$ = make_op(yyscanner, "*", $1, $3); }
                                108              12 :     | expr '/' expr         { $$ = make_op(yyscanner, "/", $1, $3); }
 1916 teodor                    109               2 :     | expr '%' expr         { $$ = make_op(yyscanner, "mod", $1, $3); }
                                110              10 :     | expr '<' expr          { $$ = make_op(yyscanner, "<", $1, $3); }
                                111               4 :     | expr LE_OP expr       { $$ = make_op(yyscanner, "<=", $1, $3); }
                                112               6 :     | expr '>' expr          { $$ = make_op(yyscanner, "<", $3, $1); }
                                113               3 :     | expr GE_OP expr       { $$ = make_op(yyscanner, "<=", $3, $1); }
                                114              31 :     | expr '=' expr         { $$ = make_op(yyscanner, "=", $1, $3); }
                                115               8 :     | expr NE_OP expr       { $$ = make_op(yyscanner, "<>", $1, $3); }
                                116               1 :     | expr '&' expr         { $$ = make_op(yyscanner, "&", $1, $3); }
                                117               2 :     | expr '|' expr         { $$ = make_op(yyscanner, "|", $1, $3); }
                                118               1 :     | expr '#' expr         { $$ = make_op(yyscanner, "#", $1, $3); }
                                119               7 :     | expr LS_OP expr       { $$ = make_op(yyscanner, "<<", $1, $3); }
                                120               1 :     | expr RS_OP expr       { $$ = make_op(yyscanner, ">>", $1, $3); }
                                121              44 :     | expr AND_OP expr      { $$ = make_op(yyscanner, "!and", $1, $3); }
                                122               5 :     | expr OR_OP expr       { $$ = make_op(yyscanner, "!or", $1, $3); }
                                123                 :     /* IS variants */
                                124               1 :     | expr ISNULL_OP        { $$ = make_op(yyscanner, "!is", $1, make_null_constant()); }
                                125                 :     | expr NOTNULL_OP       {
                                126               2 :                                 $$ = make_uop(yyscanner, "!not",
                                127               1 :                                               make_op(yyscanner, "!is", $1, make_null_constant()));
                                128                 :                             }
                                129               4 :     | expr IS_OP NULL_CONST { $$ = make_op(yyscanner, "!is", $1, make_null_constant()); }
                                130                 :     | expr IS_OP NOT_OP NULL_CONST
                                131                 :                             {
                                132               4 :                                 $$ = make_uop(yyscanner, "!not",
                                133               2 :                                               make_op(yyscanner, "!is", $1, make_null_constant()));
                                134                 :                             }
                                135                 :     | expr IS_OP BOOLEAN_CONST
                                136                 :                             {
                                137               1 :                                 $$ = make_op(yyscanner, "!is", $1, make_boolean_constant($3));
                                138                 :                             }
                                139                 :     | expr IS_OP NOT_OP BOOLEAN_CONST
                                140                 :                             {
                                141               1 :                                 $$ = make_uop(yyscanner, "!not",
                                142               1 :                                               make_op(yyscanner, "!is", $1, make_boolean_constant($4)));
                                143                 :                             }
                                144                 :     /* constants */
                                145               6 :     | NULL_CONST            { $$ = make_null_constant(); }
                                146              20 :     | BOOLEAN_CONST         { $$ = make_boolean_constant($1); }
 2567 tgl                       147             791 :     | INTEGER_CONST         { $$ = make_integer_constant($1); }
                                148              61 :     | DOUBLE_CONST          { $$ = make_double_constant($1); }
                                149                 :     /* misc */
 1916 teodor                    150             269 :     | VARIABLE              { $$ = make_variable($1); }
 2577 tgl                       151             398 :     | function '(' elist ')' { $$ = make_func(yyscanner, $1, $3); }
 1916 teodor                    152              14 :     | case_control          { $$ = $1; }
                                153                 :     ;
                                154                 : 
                                155                 : when_then_list:
                                156               2 :       when_then_list WHEN_KW expr THEN_KW expr { $$ = make_elist($5, make_elist($3, $1)); }
                                157              14 :     | WHEN_KW expr THEN_KW expr { $$ = make_elist($4, make_elist($2, NULL)); }
                                158                 : 
                                159                 : case_control:
                                160               4 :       CASE_KW when_then_list END_KW { $$ = make_case(yyscanner, $2, make_null_constant()); }
                                161              10 :     | CASE_KW when_then_list ELSE_KW expr END_KW { $$ = make_case(yyscanner, $2, $4); }
                                162                 : 
 2577 tgl                       163             399 : function: FUNCTION          { $$ = find_func(yyscanner, $1); pg_free($1); }
                                164                 :     ;
                                165                 : 
                                166                 : %%
                                167                 : 
                                168                 : static PgBenchExpr *
 1916 teodor                    169              18 : make_null_constant(void)
                                170                 : {
                                171              18 :     PgBenchExpr *expr = pg_malloc(sizeof(PgBenchExpr));
                                172                 : 
                                173              18 :     expr->etype = ENODE_CONSTANT;
                                174              18 :     expr->u.constant.type = PGBT_NULL;
                                175              18 :     expr->u.constant.u.ival = 0;
                                176              18 :     return expr;
                                177                 : }
                                178                 : 
                                179                 : static PgBenchExpr *
 2960 rhaas                     180             840 : make_integer_constant(int64 ival)
                                181                 : {
                                182             840 :     PgBenchExpr *expr = pg_malloc(sizeof(PgBenchExpr));
                                183                 : 
 2568                           184             840 :     expr->etype = ENODE_CONSTANT;
                                185             840 :     expr->u.constant.type = PGBT_INT;
                                186             840 :     expr->u.constant.u.ival = ival;
                                187             840 :     return expr;
                                188                 : }
                                189                 : 
                                190                 : static PgBenchExpr *
                                191              61 : make_double_constant(double dval)
                                192                 : {
                                193              61 :     PgBenchExpr *expr = pg_malloc(sizeof(PgBenchExpr));
                                194                 : 
                                195              61 :     expr->etype = ENODE_CONSTANT;
                                196              61 :     expr->u.constant.type = PGBT_DOUBLE;
                                197              61 :     expr->u.constant.u.dval = dval;
 2960                           198              61 :     return expr;
                                199                 : }
                                200                 : 
                                201                 : static PgBenchExpr *
 1916 teodor                    202              22 : make_boolean_constant(bool bval)
                                203                 : {
                                204              22 :     PgBenchExpr *expr = pg_malloc(sizeof(PgBenchExpr));
                                205                 : 
                                206              22 :     expr->etype = ENODE_CONSTANT;
                                207              22 :     expr->u.constant.type = PGBT_BOOLEAN;
                                208              22 :     expr->u.constant.u.bval = bval;
                                209              22 :     return expr;
                                210                 : }
                                211                 : 
                                212                 : static PgBenchExpr *
 2960 rhaas                     213             306 : make_variable(char *varname)
                                214                 : {
                                215             306 :     PgBenchExpr *expr = pg_malloc(sizeof(PgBenchExpr));
                                216                 : 
                                217             306 :     expr->etype = ENODE_VARIABLE;
                                218             306 :     expr->u.variable.varname = varname;
                                219             306 :     return expr;
                                220                 : }
                                221                 : 
                                222                 : /* binary operators */
                                223                 : static PgBenchExpr *
 2577 tgl                       224             465 : make_op(yyscan_t yyscanner, const char *operator,
                                225                 :         PgBenchExpr *lexpr, PgBenchExpr *rexpr)
                                226                 : {
                                227             465 :     return make_func(yyscanner, find_func(yyscanner, operator),
                                228                 :                      make_elist(rexpr, make_elist(lexpr, NULL)));
                                229                 : }
                                230                 : 
                                231                 : /* unary operator */
                                232                 : static PgBenchExpr *
 1916 teodor                    233              16 : make_uop(yyscan_t yyscanner, const char *operator, PgBenchExpr *expr)
                                234                 : {
                                235              16 :     return make_func(yyscanner, find_func(yyscanner, operator), make_elist(expr, NULL));
                                236                 : }
                                237                 : 
                                238                 : /*
                                239                 :  * List of available functions:
                                240                 :  * - fname: function name, "!..." for special internal functions
                                241                 :  * - nargs: number of arguments. Special cases:
                                242                 :  *          - PGBENCH_NARGS_VARIABLE is a special value for least & greatest
                                243                 :  *            meaning #args >= 1;
                                244                 :  *          - PGBENCH_NARGS_CASE is for the "CASE WHEN ..." function, which
                                245                 :  *            has #args >= 3 and odd;
                                246                 :  *          - PGBENCH_NARGS_HASH is for hash functions, which have one required
                                247                 :  *            and one optional argument;
                                248                 :  * - tag: function identifier from PgBenchFunction enum
                                249                 :  */
                                250                 : static const struct
                                251                 : {
                                252                 :     const char *fname;
                                253                 :     int         nargs;
                                254                 :     PgBenchFunction tag;
                                255                 : }   PGBENCH_FUNCTIONS[] =
                                256                 : {
                                257                 :     /* parsed as operators, executed as functions */
                                258                 :     {
                                259                 :         "+", 2, PGBENCH_ADD
                                260                 :     },
                                261                 :     {
                                262                 :         "-", 2, PGBENCH_SUB
                                263                 :     },
                                264                 :     {
                                265                 :         "*", 2, PGBENCH_MUL
                                266                 :     },
                                267                 :     {
                                268                 :         "/", 2, PGBENCH_DIV
                                269                 :     },
                                270                 :     {
                                271                 :         "mod", 2, PGBENCH_MOD
                                272                 :     },
                                273                 :     /* actual functions */
                                274                 :     {
                                275                 :         "abs", 1, PGBENCH_ABS
                                276                 :     },
                                277                 :     {
                                278                 :         "least", PGBENCH_NARGS_VARIABLE, PGBENCH_LEAST
                                279                 :     },
                                280                 :     {
                                281                 :         "greatest", PGBENCH_NARGS_VARIABLE, PGBENCH_GREATEST
                                282                 :     },
                                283                 :     {
                                284                 :         "debug", 1, PGBENCH_DEBUG
                                285                 :     },
                                286                 :     {
                                287                 :         "pi", 0, PGBENCH_PI
                                288                 :     },
                                289                 :     {
                                290                 :         "sqrt", 1, PGBENCH_SQRT
                                291                 :     },
                                292                 :     {
                                293                 :         "ln", 1, PGBENCH_LN
                                294                 :     },
                                295                 :     {
                                296                 :         "exp", 1, PGBENCH_EXP
                                297                 :     },
                                298                 :     {
                                299                 :         "int", 1, PGBENCH_INT
                                300                 :     },
                                301                 :     {
                                302                 :         "double", 1, PGBENCH_DOUBLE
                                303                 :     },
                                304                 :     {
                                305                 :         "random", 2, PGBENCH_RANDOM
                                306                 :     },
                                307                 :     {
                                308                 :         "random_gaussian", 3, PGBENCH_RANDOM_GAUSSIAN
                                309                 :     },
                                310                 :     {
                                311                 :         "random_exponential", 3, PGBENCH_RANDOM_EXPONENTIAL
                                312                 :     },
                                313                 :     {
                                314                 :         "random_zipfian", 3, PGBENCH_RANDOM_ZIPFIAN
                                315                 :     },
                                316                 :     {
                                317                 :         "pow", 2, PGBENCH_POW
                                318                 :     },
                                319                 :     {
                                320                 :         "power", 2, PGBENCH_POW
                                321                 :     },
                                322                 :     /* logical operators */
                                323                 :     {
                                324                 :         "!and", 2, PGBENCH_AND
                                325                 :     },
                                326                 :     {
                                327                 :         "!or", 2, PGBENCH_OR
                                328                 :     },
                                329                 :     {
                                330                 :         "!not", 1, PGBENCH_NOT
                                331                 :     },
                                332                 :     /* bitwise integer operators */
                                333                 :     {
                                334                 :         "&", 2, PGBENCH_BITAND
                                335                 :     },
                                336                 :     {
                                337                 :         "|", 2, PGBENCH_BITOR
                                338                 :     },
                                339                 :     {
                                340                 :         "#", 2, PGBENCH_BITXOR
                                341                 :     },
                                342                 :     {
                                343                 :         "<<", 2, PGBENCH_LSHIFT
                                344                 :     },
                                345                 :     {
                                346                 :         ">>", 2, PGBENCH_RSHIFT
                                347                 :     },
                                348                 :     /* comparison operators */
                                349                 :     {
                                350                 :         "=", 2, PGBENCH_EQ
                                351                 :     },
                                352                 :     {
                                353                 :         "<>", 2, PGBENCH_NE
                                354                 :     },
                                355                 :     {
                                356                 :         "<=", 2, PGBENCH_LE
                                357                 :     },
                                358                 :     {
                                359                 :         "<", 2, PGBENCH_LT
                                360                 :     },
                                361                 :     {
                                362                 :         "!is", 2, PGBENCH_IS
                                363                 :     },
                                364                 :     /* "case when ... then ... else ... end" construction */
                                365                 :     {
                                366                 :         "!case_end", PGBENCH_NARGS_CASE, PGBENCH_CASE
                                367                 :     },
                                368                 :     {
                                369                 :         "hash", PGBENCH_NARGS_HASH, PGBENCH_HASH_MURMUR2
                                370                 :     },
                                371                 :     {
                                372                 :         "hash_murmur2", PGBENCH_NARGS_HASH, PGBENCH_HASH_MURMUR2
                                373                 :     },
                                374                 :     {
                                375                 :         "hash_fnv1a", PGBENCH_NARGS_HASH, PGBENCH_HASH_FNV1A
                                376                 :     },
                                377                 :     {
                                378                 :         "permute", PGBENCH_NARGS_PERMUTE, PGBENCH_PERMUTE
                                379                 :     },
                                380                 :     /* keep as last array element */
                                381                 :     {
                                382                 :         NULL, 0, 0
                                383                 :     }
                                384                 : };
                                385                 : 
                                386                 : /*
                                387                 :  * Find a function from its name
                                388                 :  *
                                389                 :  * return the index of the function from the PGBENCH_FUNCTIONS array
                                390                 :  * or fail if the function is unknown.
                                391                 :  */
                                392                 : static int
 2577 tgl                       393             894 : find_func(yyscan_t yyscanner, const char *fname)
                                394                 : {
 2576                           395             894 :     int         i = 0;
                                396                 : 
 2595 rhaas                     397           12456 :     while (PGBENCH_FUNCTIONS[i].fname)
                                398                 :     {
                                399           12455 :         if (pg_strcasecmp(fname, PGBENCH_FUNCTIONS[i].fname) == 0)
                                400             893 :             return i;
                                401           11562 :         i++;
                                402                 :     }
                                403                 : 
 2577 tgl                       404               1 :     expr_yyerror_more(yyscanner, "unexpected function name", fname);
                                405                 : 
                                406                 :     /* not reached */
                                407                 :     return -1;
                                408                 : }
                                409                 : 
                                410                 : /* Expression linked list builder */
                                411                 : static PgBenchExprList *
 2595 rhaas                     412            1765 : make_elist(PgBenchExpr *expr, PgBenchExprList *list)
                                413                 : {
                                414                 :     PgBenchExprLink *cons;
                                415                 : 
                                416            1765 :     if (list == NULL)
                                417                 :     {
                                418             888 :         list = pg_malloc(sizeof(PgBenchExprList));
                                419             888 :         list->head = NULL;
                                420             888 :         list->tail = NULL;
                                421                 :     }
                                422                 : 
                                423            1765 :     cons = pg_malloc(sizeof(PgBenchExprLink));
                                424            1765 :     cons->expr = expr;
                                425            1765 :     cons->next = NULL;
                                426                 : 
                                427            1765 :     if (list->head == NULL)
                                428             888 :         list->head = cons;
                                429                 :     else
                                430             877 :         list->tail->next = cons;
                                431                 : 
                                432            1765 :     list->tail = cons;
                                433                 : 
                                434            1765 :     return list;
                                435                 : }
                                436                 : 
                                437                 : /* Return the length of an expression list */
                                438                 : static int
                                439             893 : elist_length(PgBenchExprList *list)
                                440                 : {
 2576 tgl                       441             893 :     PgBenchExprLink *link = list != NULL ? list->head : NULL;
                                442             893 :     int         len = 0;
                                443                 : 
 2595 rhaas                     444            2621 :     for (; link != NULL; link = link->next)
                                445            1728 :         len++;
                                446                 : 
                                447             893 :     return len;
                                448                 : }
                                449                 : 
                                450                 : /* Build function call expression */
                                451                 : static PgBenchExpr *
 2577 tgl                       452             893 : make_func(yyscan_t yyscanner, int fnumber, PgBenchExprList *args)
                                453                 : {
 1845 teodor                    454             893 :     int len = elist_length(args);
                                455                 : 
 2960 rhaas                     456             893 :     PgBenchExpr *expr = pg_malloc(sizeof(PgBenchExpr));
                                457                 : 
 2595                           458             893 :     Assert(fnumber >= 0);
                                459                 : 
                                460                 :     /* validate arguments number including few special cases */
 1845 teodor                    461             893 :     switch (PGBENCH_FUNCTIONS[fnumber].nargs)
                                462                 :     {
                                463                 :         /* check at least one arg for least & greatest */
                                464               8 :         case PGBENCH_NARGS_VARIABLE:
                                465               8 :             if (len == 0)
                                466               3 :                 expr_yyerror_more(yyscanner, "at least one argument expected",
                                467               3 :                                   PGBENCH_FUNCTIONS[fnumber].fname);
                                468               5 :             break;
                                469                 : 
                                470                 :         /* case (when ... then ...)+ (else ...)? end */
                                471              14 :         case PGBENCH_NARGS_CASE:
                                472                 :             /* 'else' branch is always present, but could be a NULL-constant */
                                473              14 :             if (len < 3 || len % 2 != 1)
 1845 teodor                    474 UBC           0 :                 expr_yyerror_more(yyscanner,
                                475                 :                                   "odd and >= 3 number of arguments expected",
                                476                 :                                   "case control structure");
 1845 teodor                    477 CBC          14 :             break;
                                478                 : 
                                479                 :         /* hash functions with optional seed argument */
                                480               8 :         case PGBENCH_NARGS_HASH:
 1717 michael                   481               8 :             if (len < 1 || len > 2)
 1845 teodor                    482               2 :                 expr_yyerror_more(yyscanner, "unexpected number of arguments",
                                483               2 :                                   PGBENCH_FUNCTIONS[fnumber].fname);
                                484                 : 
                                485               6 :             if (len == 1)
                                486                 :             {
                                487               2 :                 PgBenchExpr *var = make_variable("default_seed");
                                488               2 :                 args = make_elist(var, args);
                                489                 :             }
                                490               6 :             break;
                                491                 : 
                                492                 :         /* pseudorandom permutation function with optional seed argument */
  733 dean.a.rasheed            493              48 :         case PGBENCH_NARGS_PERMUTE:
                                494              48 :             if (len < 2 || len > 3)
                                495               2 :                 expr_yyerror_more(yyscanner, "unexpected number of arguments",
                                496               2 :                                   PGBENCH_FUNCTIONS[fnumber].fname);
                                497                 : 
                                498              46 :             if (len == 2)
                                499                 :             {
                                500              35 :                 PgBenchExpr *var = make_variable("default_seed");
                                501              35 :                 args = make_elist(var, args);
                                502                 :             }
                                503              46 :             break;
                                504                 : 
                                505                 :         /* common case: positive arguments number */
 1845 teodor                    506             815 :         default:
                                507             815 :             Assert(PGBENCH_FUNCTIONS[fnumber].nargs >= 0);
                                508                 : 
                                509             815 :             if (PGBENCH_FUNCTIONS[fnumber].nargs != len)
                                510               1 :                 expr_yyerror_more(yyscanner, "unexpected number of arguments",
                                511               1 :                                   PGBENCH_FUNCTIONS[fnumber].fname);
                                512                 :     }
                                513                 : 
 2595 rhaas                     514             885 :     expr->etype = ENODE_FUNCTION;
                                515             885 :     expr->u.function.function = PGBENCH_FUNCTIONS[fnumber].tag;
                                516                 : 
                                517                 :     /* only the link is used, the head/tail is not useful anymore */
 2576 tgl                       518             885 :     expr->u.function.args = args != NULL ? args->head : NULL;
 2595 rhaas                     519             885 :     if (args)
                                520             884 :         pg_free(args);
                                521                 : 
 2960                           522             885 :     return expr;
                                523                 : }
                                524                 : 
                                525                 : static PgBenchExpr *
 1916 teodor                    526              14 : make_case(yyscan_t yyscanner, PgBenchExprList *when_then_list, PgBenchExpr *else_part)
                                527                 : {
                                528              14 :     return make_func(yyscanner,
                                529                 :                      find_func(yyscanner, "!case_end"),
                                530                 :                      make_elist(else_part, when_then_list));
                                531                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a