Skip to content

Commit 9d36a38

Browse files
committed
Adjust pgbench to allow non-ASCII characters in variable names.
This puts it in sync with psql's notion of what is a valid variable name. Like psql, we document that "non-Latin letters" are allowed, but actually any non-ASCII character is accepted. Fabien Coelho Discussion: https://postgr.es/m/20170405.094548.1184280384967203518.t-ishii@sraoss.co.jp
1 parent 863d754 commit 9d36a38

File tree

3 files changed

+42
-11
lines changed

3 files changed

+42
-11
lines changed

doc/src/sgml/ref/pgbench.sgml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,8 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
771771

772772
<para>
773773
There is a simple variable-substitution facility for script files.
774+
Variable names must consist of letters (including non-Latin letters),
775+
digits, and underscores.
774776
Variables can be set by the command-line <option>-D</> option,
775777
explained above, or by the meta commands explained below.
776778
In addition to any variables preset by <option>-D</> command-line options,

src/bin/pgbench/exprscan.l

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ extern void expr_yyset_column(int column_no, yyscan_t yyscanner);
5858
%option prefix="expr_yy"
5959

6060
/* Character classes */
61-
alpha [a-zA-Z_]
61+
alpha [a-zA-Z\200-\377_]
6262
digit [0-9]
63-
alnum [a-zA-Z0-9_]
63+
alnum [A-Za-z\200-\377_0-9]
6464
/* {space} + {nonspace} + {newline} should cover all characters */
6565
space [ \t\r\f\v]
6666
nonspace [^ \t\r\f\v\n]

src/bin/pgbench/pgbench.c

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,19 +1020,38 @@ makeVariableNumeric(Variable *var)
10201020
return true;
10211021
}
10221022

1023-
/* check whether the name consists of alphabets, numerals and underscores. */
1023+
/*
1024+
* Check whether a variable's name is allowed.
1025+
*
1026+
* We allow any non-ASCII character, as well as ASCII letters, digits, and
1027+
* underscore.
1028+
*
1029+
* Keep this in sync with the definitions of variable name characters in
1030+
* "src/fe_utils/psqlscan.l", "src/bin/psql/psqlscanslash.l" and
1031+
* "src/bin/pgbench/exprscan.l". Also see parseVariable(), below.
1032+
*
1033+
* Note: this static function is copied from "src/bin/psql/variables.c"
1034+
*/
10241035
static bool
1025-
isLegalVariableName(const char *name)
1036+
valid_variable_name(const char *name)
10261037
{
1027-
int i;
1038+
const unsigned char *ptr = (const unsigned char *) name;
1039+
1040+
/* Mustn't be zero-length */
1041+
if (*ptr == '\0')
1042+
return false;
10281043

1029-
for (i = 0; name[i] != '\0'; i++)
1044+
while (*ptr)
10301045
{
1031-
if (!isalnum((unsigned char) name[i]) && name[i] != '_')
1046+
if (IS_HIGHBIT_SET(*ptr) ||
1047+
strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
1048+
"_0123456789", *ptr) != NULL)
1049+
ptr++;
1050+
else
10321051
return false;
10331052
}
10341053

1035-
return (i > 0); /* must be non-empty */
1054+
return true;
10361055
}
10371056

10381057
/*
@@ -1054,7 +1073,7 @@ lookupCreateVariable(CState *st, const char *context, char *name)
10541073
* Check for the name only when declaring a new variable to avoid
10551074
* overhead.
10561075
*/
1057-
if (!isLegalVariableName(name))
1076+
if (!valid_variable_name(name))
10581077
{
10591078
fprintf(stderr, "%s: invalid variable name: \"%s\"\n",
10601079
context, name);
@@ -1139,6 +1158,14 @@ putVariableInt(CState *st, const char *context, char *name, int64 value)
11391158
return putVariableNumber(st, context, name, &val);
11401159
}
11411160

1161+
/*
1162+
* Parse a possible variable reference (:varname).
1163+
*
1164+
* "sql" points at a colon. If what follows it looks like a valid
1165+
* variable name, return a malloc'd string containing the variable name,
1166+
* and set *eaten to the number of characters consumed.
1167+
* Otherwise, return NULL.
1168+
*/
11421169
static char *
11431170
parseVariable(const char *sql, int *eaten)
11441171
{
@@ -1148,9 +1175,11 @@ parseVariable(const char *sql, int *eaten)
11481175
do
11491176
{
11501177
i++;
1151-
} while (isalnum((unsigned char) sql[i]) || sql[i] == '_');
1178+
} while (IS_HIGHBIT_SET(sql[i]) ||
1179+
strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
1180+
"_0123456789", sql[i]) != NULL);
11521181
if (i == 1)
1153-
return NULL;
1182+
return NULL; /* no valid variable name chars */
11541183

11551184
name = pg_malloc(i);
11561185
memcpy(name, &sql[1], i - 1);

0 commit comments

Comments
 (0)