mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-15 08:20:16 +08:00
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:
parent
0d1ca2a474
commit
3a372d61d0
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user