Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit c21ea4d

Browse files
committed
Disallow a digit as the first character of a variable name in pgbench.
The point of this restriction is to avoid trying to substitute variables into timestamp literal values, which may contain strings like '12:34'. There is a good deal more that should be done to reduce pgbench's tendency to substitute where it shouldn't. But this is sufficient to solve the case complained of by Jaime Soler, and it's simple enough to back-patch. Back-patch to v11; before commit 9d36a38, pgbench had a slightly different definition of what a variable name is, and anyway it seems unwise to change long-stable branches for this. Fabien Coelho Discussion: https://postgr.es/m/alpine.DEB.2.22.394.2006291740420.805678@pseudo
1 parent 5abca4b commit c21ea4d

File tree

2 files changed

+24
-10
lines changed

2 files changed

+24
-10
lines changed

doc/src/sgml/ref/pgbench.sgml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1008,7 +1008,7 @@ pgbench <optional> <replaceable>options</replaceable> </optional> <replaceable>d
10081008
<para>
10091009
There is a simple variable-substitution facility for script files.
10101010
Variable names must consist of letters (including non-Latin letters),
1011-
digits, and underscores.
1011+
digits, and underscores, with the first character not being a digit.
10121012
Variables can be set by the command-line <option>-D</option> option,
10131013
explained above, or by the meta commands explained below.
10141014
In addition to any variables preset by <option>-D</option> command-line options,

src/bin/pgbench/pgbench.c

+23-9
Original file line numberDiff line numberDiff line change
@@ -1375,6 +1375,7 @@ makeVariableValue(Variable *var)
13751375
* "src/bin/pgbench/exprscan.l". Also see parseVariable(), below.
13761376
*
13771377
* Note: this static function is copied from "src/bin/psql/variables.c"
1378+
* but changed to disallow variable names starting with a digit.
13781379
*/
13791380
static bool
13801381
valid_variable_name(const char *name)
@@ -1385,6 +1386,15 @@ valid_variable_name(const char *name)
13851386
if (*ptr == '\0')
13861387
return false;
13871388

1389+
/* must not start with [0-9] */
1390+
if (IS_HIGHBIT_SET(*ptr) ||
1391+
strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
1392+
"_", *ptr) != NULL)
1393+
ptr++;
1394+
else
1395+
return false;
1396+
1397+
/* remaining characters can include [0-9] */
13881398
while (*ptr)
13891399
{
13901400
if (IS_HIGHBIT_SET(*ptr) ||
@@ -1505,23 +1515,27 @@ putVariableInt(CState *st, const char *context, char *name, int64 value)
15051515
*
15061516
* "sql" points at a colon. If what follows it looks like a valid
15071517
* variable name, return a malloc'd string containing the variable name,
1508-
* and set *eaten to the number of characters consumed.
1518+
* and set *eaten to the number of characters consumed (including the colon).
15091519
* Otherwise, return NULL.
15101520
*/
15111521
static char *
15121522
parseVariable(const char *sql, int *eaten)
15131523
{
1514-
int i = 0;
1524+
int i = 1; /* starting at 1 skips the colon */
15151525
char *name;
15161526

1517-
do
1518-
{
1527+
/* keep this logic in sync with valid_variable_name() */
1528+
if (IS_HIGHBIT_SET(sql[i]) ||
1529+
strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
1530+
"_", sql[i]) != NULL)
1531+
i++;
1532+
else
1533+
return NULL;
1534+
1535+
while (IS_HIGHBIT_SET(sql[i]) ||
1536+
strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
1537+
"_0123456789", sql[i]) != NULL)
15191538
i++;
1520-
} while (IS_HIGHBIT_SET(sql[i]) ||
1521-
strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
1522-
"_0123456789", sql[i]) != NULL);
1523-
if (i == 1)
1524-
return NULL; /* no valid variable name chars */
15251539

15261540
name = pg_malloc(i);
15271541
memcpy(name, &sql[1], i - 1);

0 commit comments

Comments
 (0)