mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-04 17:17:25 +02:00
Allow IMPORT FOREIGN SCHEMA within pl/pgsql.
Since IMPORT FOREIGN SCHEMA has an INTO clause, pl/pgsql needs to be aware of that and avoid capturing the INTO as an INTO-variables clause. This isn't hard, though it's annoying to have to make IMPORT a plpgsql keyword just for this. (Fortunately, we have the infrastructure now to make it an unreserved keyword, so at least this shouldn't break any existing pl/pgsql code.) Per report from Merlin Moncure. Back-patch to 9.5 where IMPORT FOREIGN SCHEMA was introduced. Report: <CAHyXU0wpHf2bbtKGL1gtUEFATCY86r=VKxfcACVcTMQ70mCyig@mail.gmail.com>
This commit is contained in:
parent
2d22c3b701
commit
a0943dbbea
@ -286,6 +286,7 @@ static void check_raise_parameters(PLpgSQL_stmt_raise *stmt);
|
|||||||
%token <keyword> K_GET
|
%token <keyword> K_GET
|
||||||
%token <keyword> K_HINT
|
%token <keyword> K_HINT
|
||||||
%token <keyword> K_IF
|
%token <keyword> K_IF
|
||||||
|
%token <keyword> K_IMPORT
|
||||||
%token <keyword> K_IN
|
%token <keyword> K_IN
|
||||||
%token <keyword> K_INFO
|
%token <keyword> K_INFO
|
||||||
%token <keyword> K_INSERT
|
%token <keyword> K_INSERT
|
||||||
@ -1891,7 +1892,11 @@ loop_body : proc_sect K_END K_LOOP opt_label ';'
|
|||||||
* assignment. Give an appropriate complaint for that, instead of letting
|
* assignment. Give an appropriate complaint for that, instead of letting
|
||||||
* the core parser throw an unhelpful "syntax error".
|
* the core parser throw an unhelpful "syntax error".
|
||||||
*/
|
*/
|
||||||
stmt_execsql : K_INSERT
|
stmt_execsql : K_IMPORT
|
||||||
|
{
|
||||||
|
$$ = make_execsql_stmt(K_IMPORT, @1);
|
||||||
|
}
|
||||||
|
| K_INSERT
|
||||||
{
|
{
|
||||||
$$ = make_execsql_stmt(K_INSERT, @1);
|
$$ = make_execsql_stmt(K_INSERT, @1);
|
||||||
}
|
}
|
||||||
@ -2369,6 +2374,7 @@ unreserved_keyword :
|
|||||||
| K_FORWARD
|
| K_FORWARD
|
||||||
| K_GET
|
| K_GET
|
||||||
| K_HINT
|
| K_HINT
|
||||||
|
| K_IMPORT
|
||||||
| K_INFO
|
| K_INFO
|
||||||
| K_INSERT
|
| K_INSERT
|
||||||
| K_IS
|
| K_IS
|
||||||
@ -2794,12 +2800,32 @@ make_execsql_stmt(int firsttoken, int location)
|
|||||||
plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR;
|
plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We have to special-case the sequence INSERT INTO, because we don't want
|
* Scan to the end of the SQL command. Identify any INTO-variables
|
||||||
* that to be taken as an INTO-variables clause. Fortunately, this is the
|
* clause lurking within it, and parse that via read_into_target().
|
||||||
* only valid use of INTO in a pl/pgsql SQL command, and INTO is already a
|
*
|
||||||
* fully reserved word in the main grammar. We have to treat it that way
|
* Because INTO is sometimes used in the main SQL grammar, we have to be
|
||||||
* anywhere in the string, not only at the start; consider CREATE RULE
|
* careful not to take any such usage of INTO as a pl/pgsql INTO clause.
|
||||||
* containing an INSERT statement.
|
* There are currently three such cases:
|
||||||
|
*
|
||||||
|
* 1. SELECT ... INTO. We don't care, we just override that with the
|
||||||
|
* pl/pgsql definition.
|
||||||
|
*
|
||||||
|
* 2. INSERT INTO. This is relatively easy to recognize since the words
|
||||||
|
* must appear adjacently; but we can't assume INSERT starts the command,
|
||||||
|
* because it can appear in CREATE RULE or WITH. Unfortunately, INSERT is
|
||||||
|
* *not* fully reserved, so that means there is a chance of a false match;
|
||||||
|
* but it's not very likely.
|
||||||
|
*
|
||||||
|
* 3. IMPORT FOREIGN SCHEMA ... INTO. This is not allowed in CREATE RULE
|
||||||
|
* or WITH, so we just check for IMPORT as the command's first token.
|
||||||
|
* (If IMPORT FOREIGN SCHEMA returned data someone might wish to capture
|
||||||
|
* with an INTO-variables clause, we'd have to work much harder here.)
|
||||||
|
*
|
||||||
|
* Fortunately, INTO is a fully reserved word in the main grammar, so
|
||||||
|
* at least we need not worry about it appearing as an identifier.
|
||||||
|
*
|
||||||
|
* Any future additional uses of INTO in the main grammar will doubtless
|
||||||
|
* break this logic again ... beware!
|
||||||
*/
|
*/
|
||||||
tok = firsttoken;
|
tok = firsttoken;
|
||||||
for (;;)
|
for (;;)
|
||||||
@ -2812,9 +2838,12 @@ make_execsql_stmt(int firsttoken, int location)
|
|||||||
break;
|
break;
|
||||||
if (tok == 0)
|
if (tok == 0)
|
||||||
yyerror("unexpected end of function definition");
|
yyerror("unexpected end of function definition");
|
||||||
|
if (tok == K_INTO)
|
||||||
if (tok == K_INTO && prev_tok != K_INSERT)
|
|
||||||
{
|
{
|
||||||
|
if (prev_tok == K_INSERT)
|
||||||
|
continue; /* INSERT INTO is not an INTO-target */
|
||||||
|
if (firsttoken == K_IMPORT)
|
||||||
|
continue; /* IMPORT ... INTO is not an INTO-target */
|
||||||
if (have_into)
|
if (have_into)
|
||||||
yyerror("INTO specified more than once");
|
yyerror("INTO specified more than once");
|
||||||
have_into = true;
|
have_into = true;
|
||||||
|
@ -127,6 +127,7 @@ static const ScanKeyword unreserved_keywords[] = {
|
|||||||
PG_KEYWORD("forward", K_FORWARD, UNRESERVED_KEYWORD)
|
PG_KEYWORD("forward", K_FORWARD, UNRESERVED_KEYWORD)
|
||||||
PG_KEYWORD("get", K_GET, UNRESERVED_KEYWORD)
|
PG_KEYWORD("get", K_GET, UNRESERVED_KEYWORD)
|
||||||
PG_KEYWORD("hint", K_HINT, UNRESERVED_KEYWORD)
|
PG_KEYWORD("hint", K_HINT, UNRESERVED_KEYWORD)
|
||||||
|
PG_KEYWORD("import", K_IMPORT, UNRESERVED_KEYWORD)
|
||||||
PG_KEYWORD("info", K_INFO, UNRESERVED_KEYWORD)
|
PG_KEYWORD("info", K_INFO, UNRESERVED_KEYWORD)
|
||||||
PG_KEYWORD("insert", K_INSERT, UNRESERVED_KEYWORD)
|
PG_KEYWORD("insert", K_INSERT, UNRESERVED_KEYWORD)
|
||||||
PG_KEYWORD("is", K_IS, UNRESERVED_KEYWORD)
|
PG_KEYWORD("is", K_IS, UNRESERVED_KEYWORD)
|
||||||
|
Loading…
Reference in New Issue
Block a user