mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
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
This commit is contained in:
@ -771,6 +771,8 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
There is a simple variable-substitution facility for script files.
|
There is a simple variable-substitution facility for script files.
|
||||||
|
Variable names must consist of letters (including non-Latin letters),
|
||||||
|
digits, and underscores.
|
||||||
Variables can be set by the command-line <option>-D</> option,
|
Variables can be set by the command-line <option>-D</> option,
|
||||||
explained above, or by the meta commands explained below.
|
explained above, or by the meta commands explained below.
|
||||||
In addition to any variables preset by <option>-D</> command-line options,
|
In addition to any variables preset by <option>-D</> command-line options,
|
||||||
|
@ -58,9 +58,9 @@ extern void expr_yyset_column(int column_no, yyscan_t yyscanner);
|
|||||||
%option prefix="expr_yy"
|
%option prefix="expr_yy"
|
||||||
|
|
||||||
/* Character classes */
|
/* Character classes */
|
||||||
alpha [a-zA-Z_]
|
alpha [a-zA-Z\200-\377_]
|
||||||
digit [0-9]
|
digit [0-9]
|
||||||
alnum [a-zA-Z0-9_]
|
alnum [A-Za-z\200-\377_0-9]
|
||||||
/* {space} + {nonspace} + {newline} should cover all characters */
|
/* {space} + {nonspace} + {newline} should cover all characters */
|
||||||
space [ \t\r\f\v]
|
space [ \t\r\f\v]
|
||||||
nonspace [^ \t\r\f\v\n]
|
nonspace [^ \t\r\f\v\n]
|
||||||
|
@ -1020,19 +1020,38 @@ makeVariableNumeric(Variable *var)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check whether the name consists of alphabets, numerals and underscores. */
|
/*
|
||||||
|
* Check whether a variable's name is allowed.
|
||||||
|
*
|
||||||
|
* We allow any non-ASCII character, as well as ASCII letters, digits, and
|
||||||
|
* underscore.
|
||||||
|
*
|
||||||
|
* Keep this in sync with the definitions of variable name characters in
|
||||||
|
* "src/fe_utils/psqlscan.l", "src/bin/psql/psqlscanslash.l" and
|
||||||
|
* "src/bin/pgbench/exprscan.l". Also see parseVariable(), below.
|
||||||
|
*
|
||||||
|
* Note: this static function is copied from "src/bin/psql/variables.c"
|
||||||
|
*/
|
||||||
static bool
|
static bool
|
||||||
isLegalVariableName(const char *name)
|
valid_variable_name(const char *name)
|
||||||
{
|
{
|
||||||
int i;
|
const unsigned char *ptr = (const unsigned char *) name;
|
||||||
|
|
||||||
for (i = 0; name[i] != '\0'; i++)
|
/* Mustn't be zero-length */
|
||||||
|
if (*ptr == '\0')
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while (*ptr)
|
||||||
{
|
{
|
||||||
if (!isalnum((unsigned char) name[i]) && name[i] != '_')
|
if (IS_HIGHBIT_SET(*ptr) ||
|
||||||
|
strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
|
||||||
|
"_0123456789", *ptr) != NULL)
|
||||||
|
ptr++;
|
||||||
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (i > 0); /* must be non-empty */
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1054,7 +1073,7 @@ lookupCreateVariable(CState *st, const char *context, char *name)
|
|||||||
* Check for the name only when declaring a new variable to avoid
|
* Check for the name only when declaring a new variable to avoid
|
||||||
* overhead.
|
* overhead.
|
||||||
*/
|
*/
|
||||||
if (!isLegalVariableName(name))
|
if (!valid_variable_name(name))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: invalid variable name: \"%s\"\n",
|
fprintf(stderr, "%s: invalid variable name: \"%s\"\n",
|
||||||
context, name);
|
context, name);
|
||||||
@ -1139,6 +1158,14 @@ putVariableInt(CState *st, const char *context, char *name, int64 value)
|
|||||||
return putVariableNumber(st, context, name, &val);
|
return putVariableNumber(st, context, name, &val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse a possible variable reference (:varname).
|
||||||
|
*
|
||||||
|
* "sql" points at a colon. If what follows it looks like a valid
|
||||||
|
* variable name, return a malloc'd string containing the variable name,
|
||||||
|
* and set *eaten to the number of characters consumed.
|
||||||
|
* Otherwise, return NULL.
|
||||||
|
*/
|
||||||
static char *
|
static char *
|
||||||
parseVariable(const char *sql, int *eaten)
|
parseVariable(const char *sql, int *eaten)
|
||||||
{
|
{
|
||||||
@ -1148,9 +1175,11 @@ parseVariable(const char *sql, int *eaten)
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
} while (isalnum((unsigned char) sql[i]) || sql[i] == '_');
|
} while (IS_HIGHBIT_SET(sql[i]) ||
|
||||||
|
strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
|
||||||
|
"_0123456789", sql[i]) != NULL);
|
||||||
if (i == 1)
|
if (i == 1)
|
||||||
return NULL;
|
return NULL; /* no valid variable name chars */
|
||||||
|
|
||||||
name = pg_malloc(i);
|
name = pg_malloc(i);
|
||||||
memcpy(name, &sql[1], i - 1);
|
memcpy(name, &sql[1], i - 1);
|
||||||
|
Reference in New Issue
Block a user