Skip to content

Commit 3a372d6

Browse files
committed
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.
1 parent 0d1ca2a commit 3a372d6

File tree

1 file changed

+32
-8
lines changed

1 file changed

+32
-8
lines changed

src/backend/parser/gram.y

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.479 2004/11/05 19:16:02 tgl Exp $
14+
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.480 2004/11/08 04:02:20 tgl Exp $
1515
*
1616
* HISTORY
1717
* AUTHOR DATE MAJOR EVENT
@@ -82,6 +82,7 @@ static Node *makeRowNullTest(NullTestType test, RowExpr *row);
8282
static DefElem *makeDefElem(char *name, Node *arg);
8383
static A_Const *makeBoolAConst(bool state);
8484
static FuncCall *makeOverlaps(List *largs, List *rargs);
85+
static void check_qualified_name(List *names);
8586
static List *check_func_name(List *names);
8687
static List *extractArgTypes(List *parameters);
8788
static SelectStmt *findLeftmostSelect(SelectStmt *node);
@@ -2670,14 +2671,10 @@ any_name: ColId { $$ = list_make1(makeString($1)); }
26702671
| ColId attrs { $$ = lcons(makeString($1), $2); }
26712672
;
26722673

2673-
/*
2674-
* The slightly convoluted way of writing this production avoids reduce/reduce
2675-
* errors against indirection_el.
2676-
*/
26772674
attrs: '.' attr_name
26782675
{ $$ = list_make1(makeString($2)); }
2679-
| '.' attr_name attrs
2680-
{ $$ = lcons(makeString($2), $3); }
2676+
| attrs '.' attr_name
2677+
{ $$ = lappend($1, makeString($3)); }
26812678
;
26822679

26832680

@@ -7391,6 +7388,13 @@ qualified_name_list:
73917388
| qualified_name_list ',' qualified_name { $$ = lappend($1, $3); }
73927389
;
73937390

7391+
/*
7392+
* The production for a qualified relation name has to exactly match the
7393+
* production for a qualified func_name, because in a FROM clause we cannot
7394+
* tell which we are parsing until we see what comes after it ('(' for a
7395+
* func_name, something else for a relation). Therefore we allow 'indirection'
7396+
* which may contain subscripts, and reject that case in the C code.
7397+
*/
73947398
qualified_name:
73957399
relation_name
73967400
{
@@ -7399,8 +7403,9 @@ qualified_name:
73997403
$$->schemaname = NULL;
74007404
$$->relname = $1;
74017405
}
7402-
| relation_name attrs
7406+
| relation_name indirection
74037407
{
7408+
check_qualified_name($2);
74047409
$$ = makeNode(RangeVar);
74057410
switch (list_length($2))
74067411
{
@@ -8200,6 +8205,25 @@ makeOverlaps(List *largs, List *rargs)
82008205
return n;
82018206
}
82028207

8208+
/* check_qualified_name --- check the result of qualified_name production
8209+
*
8210+
* It's easiest to let the grammar production for qualified_name allow
8211+
* subscripts and '*', which we then must reject here.
8212+
*/
8213+
static void
8214+
check_qualified_name(List *names)
8215+
{
8216+
ListCell *i;
8217+
8218+
foreach(i, names)
8219+
{
8220+
if (!IsA(lfirst(i), String))
8221+
yyerror("syntax error");
8222+
else if (strcmp(strVal(lfirst(i)), "*") == 0)
8223+
yyerror("syntax error");
8224+
}
8225+
}
8226+
82038227
/* check_func_name --- check the result of func_name production
82048228
*
82058229
* It's easiest to let the grammar production for func_name allow subscripts

0 commit comments

Comments
 (0)