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.
This commit is contained in:
Tom Lane 2004-11-08 04:02:20 +00:00
parent 0d1ca2a474
commit 3a372d61d0
1 changed files with 32 additions and 8 deletions

View File

@ -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