11
11
*
12
12
*
13
13
* 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 $
15
15
*
16
16
* HISTORY
17
17
* AUTHOR DATE MAJOR EVENT
@@ -82,6 +82,7 @@ static Node *makeRowNullTest(NullTestType test, RowExpr *row);
82
82
static DefElem *makeDefElem (char *name, Node *arg);
83
83
static A_Const *makeBoolAConst (bool state);
84
84
static FuncCall *makeOverlaps (List *largs, List *rargs);
85
+ static void check_qualified_name (List *names);
85
86
static List *check_func_name (List *names);
86
87
static List *extractArgTypes (List *parameters);
87
88
static SelectStmt *findLeftmostSelect (SelectStmt *node);
@@ -2670,14 +2671,10 @@ any_name: ColId { $$ = list_make1(makeString($1)); }
2670
2671
| ColId attrs { $$ = lcons(makeString($1 ), $2 ); }
2671
2672
;
2672
2673
2673
- /*
2674
- * The slightly convoluted way of writing this production avoids reduce/reduce
2675
- * errors against indirection_el.
2676
- */
2677
2674
attrs: ' .' attr_name
2678
2675
{ $$ = list_make1(makeString($2 )); }
2679
- | ' .' attr_name attrs
2680
- { $$ = lcons(makeString( $2 ), $3 ); }
2676
+ | attrs ' .' attr_name
2677
+ { $$ = lappend( $1 , makeString( $3 ) ); }
2681
2678
;
2682
2679
2683
2680
@@ -7391,6 +7388,13 @@ qualified_name_list:
7391
7388
| qualified_name_list ' ,' qualified_name { $$ = lappend($1 , $3 ); }
7392
7389
;
7393
7390
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
+ */
7394
7398
qualified_name:
7395
7399
relation_name
7396
7400
{
@@ -7399,8 +7403,9 @@ qualified_name:
7399
7403
$$ ->schemaname = NULL ;
7400
7404
$$ ->relname = $1 ;
7401
7405
}
7402
- | relation_name attrs
7406
+ | relation_name indirection
7403
7407
{
7408
+ check_qualified_name ($2 );
7404
7409
$$ = makeNode(RangeVar);
7405
7410
switch (list_length($2 ))
7406
7411
{
@@ -8200,6 +8205,25 @@ makeOverlaps(List *largs, List *rargs)
8200
8205
return n;
8201
8206
}
8202
8207
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
+
8203
8227
/* check_func_name --- check the result of func_name production
8204
8228
*
8205
8229
* It's easiest to let the grammar production for func_name allow subscripts
0 commit comments