Skip to content

Commit 9682e80

Browse files
committed
Allow a_expr not just AexprConst in the right-hand list of
IN and NOT IN operators. Rewrite grotty implementation of IN-list parsing ... look Ma, no global variable ...
1 parent bb68f6e commit 9682e80

File tree

1 file changed

+49
-46
lines changed

1 file changed

+49
-46
lines changed

src/backend/parser/gram.y

Lines changed: 49 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.95 1999/07/27 03:51:06 tgl Exp $
13+
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.96 1999/07/28 17:39:38 tgl Exp $
1414
*
1515
* HISTORY
1616
* AUTHOR DATE MAJOR EVENT
@@ -55,7 +55,6 @@
5555

5656
static char saved_relname[NAMEDATALEN]; /* need this for complex attributes */
5757
static bool QueryIsRule = FALSE;
58-
static List *saved_In_Expr = NIL;
5958
static Oid *param_type_info;
6059
static int pfunc_num_args;
6160
extern List *parsetree;
@@ -213,9 +212,8 @@ Oid param_type(int t); /* used in parse_expr.c */
213212
%type <defelt> def_elem
214213
%type <node> def_arg, columnElem, where_clause,
215214
a_expr, a_expr_or_null, b_expr, AexprConst,
216-
in_expr, in_expr_nodes, not_in_expr, not_in_expr_nodes,
217-
having_clause
218-
%type <list> row_descriptor, row_list, c_list, c_expr
215+
in_expr, having_clause
216+
%type <list> row_descriptor, row_list, c_list, c_expr, in_expr_nodes
219217
%type <node> row_expr
220218
%type <str> row_op
221219
%type <node> case_expr, case_arg, when_clause, case_default
@@ -3986,33 +3984,59 @@ a_expr: attr
39863984
makeA_Expr(OP, "<", $1, $4),
39873985
makeA_Expr(OP, ">", $1, $6));
39883986
}
3989-
| a_expr IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' in_expr ')'
3987+
| a_expr IN '(' in_expr ')'
39903988
{
3991-
saved_In_Expr = lnext(saved_In_Expr);
3992-
if (nodeTag($5) == T_SubLink)
3989+
/* in_expr returns a SubLink or a list of a_exprs */
3990+
if (IsA($4, SubLink))
39933991
{
3994-
SubLink *n = (SubLink *)$5;
3992+
SubLink *n = (SubLink *)$4;
39953993
n->lefthand = lcons($1, NIL);
39963994
n->oper = lcons("=",NIL);
39973995
n->useor = false;
39983996
n->subLinkType = ANY_SUBLINK;
39993997
$$ = (Node *)n;
40003998
}
4001-
else $$ = $5;
3999+
else
4000+
{
4001+
Node *n = NULL;
4002+
List *l;
4003+
foreach(l, (List *) $4)
4004+
{
4005+
Node *cmp = makeA_Expr(OP, "=", $1, lfirst(l));
4006+
if (n == NULL)
4007+
n = cmp;
4008+
else
4009+
n = makeA_Expr(OR, NULL, n, cmp);
4010+
}
4011+
$$ = n;
4012+
}
40024013
}
4003-
| a_expr NOT IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' not_in_expr ')'
4014+
| a_expr NOT IN '(' in_expr ')'
40044015
{
4005-
saved_In_Expr = lnext(saved_In_Expr);
4006-
if (nodeTag($6) == T_SubLink)
4016+
/* in_expr returns a SubLink or a list of a_exprs */
4017+
if (IsA($5, SubLink))
40074018
{
4008-
SubLink *n = (SubLink *)$6;
4009-
n->lefthand = lcons($1, NIL);
4010-
n->oper = lcons("<>",NIL);
4011-
n->useor = false;
4012-
n->subLinkType = ALL_SUBLINK;
4013-
$$ = (Node *)n;
4019+
SubLink *n = (SubLink *)$5;
4020+
n->lefthand = lcons($1, NIL);
4021+
n->oper = lcons("<>",NIL);
4022+
n->useor = false;
4023+
n->subLinkType = ALL_SUBLINK;
4024+
$$ = (Node *)n;
4025+
}
4026+
else
4027+
{
4028+
Node *n = NULL;
4029+
List *l;
4030+
foreach(l, (List *) $5)
4031+
{
4032+
Node *cmp = makeA_Expr(OP, "<>", $1, lfirst(l));
4033+
if (n == NULL)
4034+
n = cmp;
4035+
else
4036+
n = makeA_Expr(AND, NULL, n, cmp);
4037+
}
4038+
$$ = n;
40144039
}
4015-
else $$ = $6;
40164040
}
40174041
| a_expr Op '(' SubSelect ')'
40184042
{
@@ -4632,33 +4656,13 @@ in_expr: SubSelect
46324656
$$ = (Node *)n;
46334657
}
46344658
| in_expr_nodes
4635-
{ $$ = $1; }
4636-
;
4637-
4638-
in_expr_nodes: AexprConst
4639-
{ $$ = makeA_Expr(OP, "=", lfirst(saved_In_Expr), $1); }
4640-
| in_expr_nodes ',' AexprConst
4641-
{ $$ = makeA_Expr(OR, NULL, $1,
4642-
makeA_Expr(OP, "=", lfirst(saved_In_Expr), $3));
4643-
}
4659+
{ $$ = (Node *)$1; }
46444660
;
46454661

4646-
not_in_expr: SubSelect
4647-
{
4648-
SubLink *n = makeNode(SubLink);
4649-
n->subselect = $1;
4650-
$$ = (Node *)n;
4651-
}
4652-
| not_in_expr_nodes
4653-
{ $$ = $1; }
4654-
;
4655-
4656-
not_in_expr_nodes: AexprConst
4657-
{ $$ = makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $1); }
4658-
| not_in_expr_nodes ',' AexprConst
4659-
{ $$ = makeA_Expr(AND, NULL, $1,
4660-
makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $3));
4661-
}
4662+
in_expr_nodes: a_expr
4663+
{ $$ = lcons($1, NIL); }
4664+
| in_expr_nodes ',' a_expr
4665+
{ $$ = lappend($1, $3); }
46624666
;
46634667

46644668
/* Case clause
@@ -5239,7 +5243,6 @@ void parser_init(Oid *typev, int nargs)
52395243
{
52405244
QueryIsRule = FALSE;
52415245
saved_relname[0]= '\0';
5242-
saved_In_Expr = NULL;
52435246

52445247
param_type_init(typev, nargs);
52455248
}

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