From 3a372d61d0799ea82124887262d18ca21e385f22 Mon Sep 17 00:00:00 2001 From: Tom Lane <tgl@sss.pgh.pa.us> Date: Mon, 8 Nov 2004 04:02:20 +0000 Subject: [PATCH] Kris Jurka pointed out that the qualified_name production wasn't working as intended --- for some reason, FROM a.b.c was getting parsed as if it were a function name and not a qualified name. I think there must be a bug in bison, because it should have complained that the grammar was ambiguous. Anyway, fix it along the same lines previously used for func_name vs columnref, and get rid of the right-recursion in attrs that seems to have confused bison. --- src/backend/parser/gram.y | 40 +++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 12c1acac4d8..f4d99486d3d 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.479 2004/11/05 19:16:02 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.480 2004/11/08 04:02:20 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -82,6 +82,7 @@ static Node *makeRowNullTest(NullTestType test, RowExpr *row); static DefElem *makeDefElem(char *name, Node *arg); static A_Const *makeBoolAConst(bool state); static FuncCall *makeOverlaps(List *largs, List *rargs); +static void check_qualified_name(List *names); static List *check_func_name(List *names); static List *extractArgTypes(List *parameters); static SelectStmt *findLeftmostSelect(SelectStmt *node); @@ -2670,14 +2671,10 @@ any_name: ColId { $$ = list_make1(makeString($1)); } | ColId attrs { $$ = lcons(makeString($1), $2); } ; -/* - * The slightly convoluted way of writing this production avoids reduce/reduce - * errors against indirection_el. - */ attrs: '.' attr_name { $$ = list_make1(makeString($2)); } - | '.' attr_name attrs - { $$ = lcons(makeString($2), $3); } + | attrs '.' attr_name + { $$ = lappend($1, makeString($3)); } ; @@ -7391,6 +7388,13 @@ qualified_name_list: | qualified_name_list ',' qualified_name { $$ = lappend($1, $3); } ; +/* + * The production for a qualified relation name has to exactly match the + * production for a qualified func_name, because in a FROM clause we cannot + * tell which we are parsing until we see what comes after it ('(' for a + * func_name, something else for a relation). Therefore we allow 'indirection' + * which may contain subscripts, and reject that case in the C code. + */ qualified_name: relation_name { @@ -7399,8 +7403,9 @@ qualified_name: $$->schemaname = NULL; $$->relname = $1; } - | relation_name attrs + | relation_name indirection { + check_qualified_name($2); $$ = makeNode(RangeVar); switch (list_length($2)) { @@ -8200,6 +8205,25 @@ makeOverlaps(List *largs, List *rargs) return n; } +/* check_qualified_name --- check the result of qualified_name production + * + * It's easiest to let the grammar production for qualified_name allow + * subscripts and '*', which we then must reject here. + */ +static void +check_qualified_name(List *names) +{ + ListCell *i; + + foreach(i, names) + { + if (!IsA(lfirst(i), String)) + yyerror("syntax error"); + else if (strcmp(strVal(lfirst(i)), "*") == 0) + yyerror("syntax error"); + } +} + /* check_func_name --- check the result of func_name production * * It's easiest to let the grammar production for func_name allow subscripts -- GitLab