Skip to content

Commit 449a00f

Browse files
committed
Fix the raw-parsetree representation of star (as in SELECT * FROM or
SELECT foo.*) so that it cannot be confused with a quoted identifier "*". Instead create a separate node type A_Star to represent this notation. Per pgsql-hackers discussion of 2007-Sep-27.
1 parent 6253f9d commit 449a00f

File tree

13 files changed

+223
-106
lines changed

13 files changed

+223
-106
lines changed

src/backend/catalog/namespace.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* Portions Copyright (c) 1994, Regents of the University of California
1414
*
1515
* IDENTIFICATION
16-
* $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.109 2008/07/16 16:55:23 tgl Exp $
16+
* $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.110 2008/08/30 01:39:13 tgl Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -2189,6 +2189,9 @@ makeRangeVarFromNameList(List *names)
21892189
*
21902190
* This is used primarily to form error messages, and so we do not quote
21912191
* the list elements, for the sake of legibility.
2192+
*
2193+
* In most scenarios the list elements should always be Value strings,
2194+
* but we also allow A_Star for the convenience of ColumnRef processing.
21922195
*/
21932196
char *
21942197
NameListToString(List *names)
@@ -2200,9 +2203,18 @@ NameListToString(List *names)
22002203

22012204
foreach(l, names)
22022205
{
2206+
Node *name = (Node *) lfirst(l);
2207+
22032208
if (l != list_head(names))
22042209
appendStringInfoChar(&string, '.');
2205-
appendStringInfoString(&string, strVal(lfirst(l)));
2210+
2211+
if (IsA(name, String))
2212+
appendStringInfoString(&string, strVal(name));
2213+
else if (IsA(name, A_Star))
2214+
appendStringInfoString(&string, "*");
2215+
else
2216+
elog(ERROR, "unexpected node type in name list: %d",
2217+
(int) nodeTag(name));
22062218
}
22072219

22082220
return string.data;

src/backend/commands/async.c

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.140 2008/03/26 21:10:37 alvherre Exp $
10+
* $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.141 2008/08/30 01:39:13 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -274,24 +274,16 @@ Async_Listen(const char *relname)
274274
void
275275
Async_Unlisten(const char *relname)
276276
{
277-
/* Handle specially the `unlisten "*"' command */
278-
if ((!relname) || (*relname == '\0') || (strcmp(relname, "*") == 0))
279-
{
280-
Async_UnlistenAll();
281-
}
282-
else
283-
{
284-
if (Trace_notify)
285-
elog(DEBUG1, "Async_Unlisten(%s,%d)", relname, MyProcPid);
277+
if (Trace_notify)
278+
elog(DEBUG1, "Async_Unlisten(%s,%d)", relname, MyProcPid);
286279

287-
queue_listen(LISTEN_UNLISTEN, relname);
288-
}
280+
queue_listen(LISTEN_UNLISTEN, relname);
289281
}
290282

291283
/*
292284
* Async_UnlistenAll
293285
*
294-
* This is invoked by UNLISTEN "*" command, and also at backend exit.
286+
* This is invoked by UNLISTEN * command, and also at backend exit.
295287
*/
296288
void
297289
Async_UnlistenAll(void)

src/backend/nodes/copyfuncs.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1994, Regents of the University of California
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.402 2008/08/28 23:09:45 tgl Exp $
18+
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.403 2008/08/30 01:39:13 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -1697,6 +1697,14 @@ _copyFuncCall(FuncCall *from)
16971697
return newnode;
16981698
}
16991699

1700+
static A_Star *
1701+
_copyAStar(A_Star *from)
1702+
{
1703+
A_Star *newnode = makeNode(A_Star);
1704+
1705+
return newnode;
1706+
}
1707+
17001708
static A_Indices *
17011709
_copyAIndices(A_Indices *from)
17021710
{
@@ -3589,6 +3597,9 @@ copyObject(void *from)
35893597
case T_FuncCall:
35903598
retval = _copyFuncCall(from);
35913599
break;
3600+
case T_A_Star:
3601+
retval = _copyAStar(from);
3602+
break;
35923603
case T_A_Indices:
35933604
retval = _copyAIndices(from);
35943605
break;

src/backend/nodes/equalfuncs.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* Portions Copyright (c) 1994, Regents of the University of California
2323
*
2424
* IDENTIFICATION
25-
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.329 2008/08/28 23:09:46 tgl Exp $
25+
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.330 2008/08/30 01:39:13 tgl Exp $
2626
*
2727
*-------------------------------------------------------------------------
2828
*/
@@ -1765,6 +1765,12 @@ _equalFuncCall(FuncCall *a, FuncCall *b)
17651765
return true;
17661766
}
17671767

1768+
static bool
1769+
_equalAStar(A_Star *a, A_Star *b)
1770+
{
1771+
return true;
1772+
}
1773+
17681774
static bool
17691775
_equalAIndices(A_Indices *a, A_Indices *b)
17701776
{
@@ -2531,6 +2537,9 @@ equal(void *a, void *b)
25312537
case T_FuncCall:
25322538
retval = _equalFuncCall(a, b);
25332539
break;
2540+
case T_A_Star:
2541+
retval = _equalAStar(a, b);
2542+
break;
25342543
case T_A_Indices:
25352544
retval = _equalAIndices(a, b);
25362545
break;

src/backend/nodes/outfuncs.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.336 2008/08/28 23:09:46 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.337 2008/08/30 01:39:14 tgl Exp $
1212
*
1313
* NOTES
1414
* Every node type that can appear in stored rules' parsetrees *must*
@@ -1989,6 +1989,12 @@ _outAConst(StringInfo str, A_Const *node)
19891989
WRITE_LOCATION_FIELD(location);
19901990
}
19911991

1992+
static void
1993+
_outA_Star(StringInfo str, A_Star *node)
1994+
{
1995+
WRITE_NODE_TYPE("A_STAR");
1996+
}
1997+
19921998
static void
19931999
_outA_Indices(StringInfo str, A_Indices *node)
19942000
{
@@ -2467,6 +2473,9 @@ _outNode(StringInfo str, void *obj)
24672473
case T_A_Const:
24682474
_outAConst(str, obj);
24692475
break;
2476+
case T_A_Star:
2477+
_outA_Star(str, obj);
2478+
break;
24702479
case T_A_Indices:
24712480
_outA_Indices(str, obj);
24722481
break;

src/backend/parser/gram.y

Lines changed: 46 additions & 23 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.619 2008/08/28 23:09:47 tgl Exp $
14+
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.620 2008/08/30 01:39:14 tgl Exp $
1515
*
1616
* HISTORY
1717
* AUTHOR DATE MAJOR EVENT
@@ -89,7 +89,7 @@ static bool QueryIsRule = FALSE;
8989
*/
9090
/*#define __YYSCLASS*/
9191

92-
static Node *makeColumnRef(char *relname, List *indirection, int location);
92+
static Node *makeColumnRef(char *colname, List *indirection, int location);
9393
static Node *makeTypeCast(Node *arg, TypeName *typename, int location);
9494
static Node *makeStringConst(char *str, int location);
9595
static Node *makeStringConstCast(char *str, int location, TypeName *typename);
@@ -102,6 +102,7 @@ static Node *makeBoolAConst(bool state, int location);
102102
static FuncCall *makeOverlaps(List *largs, List *rargs, int location);
103103
static void check_qualified_name(List *names);
104104
static List *check_func_name(List *names);
105+
static List *check_indirection(List *indirection);
105106
static List *extractArgTypes(List *parameters);
106107
static SelectStmt *findLeftmostSelect(SelectStmt *node);
107108
static void insertSelectOptions(SelectStmt *stmt,
@@ -5144,9 +5145,7 @@ UnlistenStmt:
51445145
| UNLISTEN '*'
51455146
{
51465147
UnlistenStmt *n = makeNode(UnlistenStmt);
5147-
n->relation = makeNode(RangeVar);
5148-
n->relation->relname = "*";
5149-
n->relation->schemaname = NULL;
5148+
n->relation = NULL;
51505149
$$ = (Node *)n;
51515150
}
51525151
;
@@ -5999,7 +5998,7 @@ insert_column_item:
59995998
{
60005999
$$ = makeNode(ResTarget);
60016000
$$->name = $1;
6002-
$$->indirection = $2;
6001+
$$->indirection = check_indirection($2);
60036002
$$->val = NULL;
60046003
$$->location = @1;
60056004
}
@@ -6138,7 +6137,7 @@ set_target:
61386137
{
61396138
$$ = makeNode(ResTarget);
61406139
$$->name = $1;
6141-
$$->indirection = $2;
6140+
$$->indirection = check_indirection($2);
61426141
$$->val = NULL; /* upper production sets this */
61436142
$$->location = @1;
61446143
}
@@ -7842,7 +7841,7 @@ c_expr: columnref { $$ = $1; }
78427841
{
78437842
A_Indirection *n = makeNode(A_Indirection);
78447843
n->arg = (Node *) p;
7845-
n->indirection = $2;
7844+
n->indirection = check_indirection($2);
78467845
$$ = (Node *) n;
78477846
}
78487847
else
@@ -7854,7 +7853,7 @@ c_expr: columnref { $$ = $1; }
78547853
{
78557854
A_Indirection *n = makeNode(A_Indirection);
78567855
n->arg = $2;
7857-
n->indirection = $4;
7856+
n->indirection = check_indirection($4);
78587857
$$ = (Node *)n;
78597858
}
78607859
else
@@ -8409,15 +8408,15 @@ xml_attribute_el: a_expr AS ColLabel
84098408
{
84108409
$$ = makeNode(ResTarget);
84118410
$$->name = $3;
8412-
$$->indirection = NULL;
8411+
$$->indirection = NIL;
84138412
$$->val = (Node *) $1;
84148413
$$->location = @1;
84158414
}
84168415
| a_expr
84178416
{
84188417
$$ = makeNode(ResTarget);
84198418
$$->name = NULL;
8420-
$$->indirection = NULL;
8419+
$$->indirection = NIL;
84218420
$$->val = (Node *) $1;
84228421
$$->location = @1;
84238422
}
@@ -8724,7 +8723,7 @@ indirection_el:
87248723
}
87258724
| '.' '*'
87268725
{
8727-
$$ = (Node *) makeString("*");
8726+
$$ = (Node *) makeNode(A_Star);
87288727
}
87298728
| '[' a_expr ']'
87308729
{
@@ -8833,7 +8832,7 @@ target_el: a_expr AS ColLabel
88338832
| '*'
88348833
{
88358834
ColumnRef *n = makeNode(ColumnRef);
8836-
n->fields = list_make1(makeString("*"));
8835+
n->fields = list_make1(makeNode(A_Star));
88378836
n->location = @1;
88388837

88398838
$$ = makeNode(ResTarget);
@@ -9511,7 +9510,7 @@ SpecialRuleRelation:
95119510
%%
95129511

95139512
static Node *
9514-
makeColumnRef(char *relname, List *indirection, int location)
9513+
makeColumnRef(char *colname, List *indirection, int location)
95159514
{
95169515
/*
95179516
* Generate a ColumnRef node, with an A_Indirection node added if there
@@ -9533,23 +9532,30 @@ makeColumnRef(char *relname, List *indirection, int location)
95339532
if (nfields == 0)
95349533
{
95359534
/* easy case - all indirection goes to A_Indirection */
9536-
c->fields = list_make1(makeString(relname));
9537-
i->indirection = indirection;
9535+
c->fields = list_make1(makeString(colname));
9536+
i->indirection = check_indirection(indirection);
95389537
}
95399538
else
95409539
{
95419540
/* got to split the list in two */
9542-
i->indirection = list_copy_tail(indirection, nfields);
9541+
i->indirection = check_indirection(list_copy_tail(indirection,
9542+
nfields));
95439543
indirection = list_truncate(indirection, nfields);
9544-
c->fields = lcons(makeString(relname), indirection);
9544+
c->fields = lcons(makeString(colname), indirection);
95459545
}
95469546
i->arg = (Node *) c;
95479547
return (Node *) i;
95489548
}
9549+
else if (IsA(lfirst(l), A_Star))
9550+
{
9551+
/* We only allow '*' at the end of a ColumnRef */
9552+
if (lnext(l) != NULL)
9553+
yyerror("improper use of \"*\"");
9554+
}
95499555
nfields++;
95509556
}
95519557
/* No subscripting, so all indirection gets added to field list */
9552-
c->fields = lcons(makeString(relname), indirection);
9558+
c->fields = lcons(makeString(colname), indirection);
95539559
return (Node *) c;
95549560
}
95559561

@@ -9712,8 +9718,6 @@ check_qualified_name(List *names)
97129718
{
97139719
if (!IsA(lfirst(i), String))
97149720
yyerror("syntax error");
9715-
else if (strcmp(strVal(lfirst(i)), "*") == 0)
9716-
yyerror("syntax error");
97179721
}
97189722
}
97199723

@@ -9731,12 +9735,31 @@ check_func_name(List *names)
97319735
{
97329736
if (!IsA(lfirst(i), String))
97339737
yyerror("syntax error");
9734-
else if (strcmp(strVal(lfirst(i)), "*") == 0)
9735-
yyerror("syntax error");
97369738
}
97379739
return names;
97389740
}
97399741

9742+
/* check_indirection --- check the result of indirection production
9743+
*
9744+
* We only allow '*' at the end of the list, but it's hard to enforce that
9745+
* in the grammar, so do it here.
9746+
*/
9747+
static List *
9748+
check_indirection(List *indirection)
9749+
{
9750+
ListCell *l;
9751+
9752+
foreach(l, indirection)
9753+
{
9754+
if (IsA(lfirst(l), A_Star))
9755+
{
9756+
if (lnext(l) != NULL)
9757+
yyerror("improper use of \"*\"");
9758+
}
9759+
}
9760+
return indirection;
9761+
}
9762+
97409763
/* extractArgTypes()
97419764
* Given a list of FunctionParameter nodes, extract a list of just the
97429765
* argument types (TypeNames) for input parameters only. This is what

src/backend/parser/parse_clause.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.177 2008/08/28 23:09:47 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.178 2008/08/30 01:39:14 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1181,7 +1181,8 @@ findTargetlistEntry(ParseState *pstate, Node *node, List **tlist, int clause)
11811181
*----------
11821182
*/
11831183
if (IsA(node, ColumnRef) &&
1184-
list_length(((ColumnRef *) node)->fields) == 1)
1184+
list_length(((ColumnRef *) node)->fields) == 1 &&
1185+
IsA(linitial(((ColumnRef *) node)->fields), String))
11851186
{
11861187
char *name = strVal(linitial(((ColumnRef *) node)->fields));
11871188
int location = ((ColumnRef *) node)->location;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy