|
10 | 10 | * |
11 | 11 | * |
12 | 12 | * 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 $ |
14 | 14 | * |
15 | 15 | * HISTORY |
16 | 16 | * AUTHORDATEMAJOR EVENT |
|
55 | 55 |
|
56 | 56 | static char saved_relname[NAMEDATALEN]; /* need this for complex attributes */ |
57 | 57 | static bool QueryIsRule = FALSE; |
58 | | -static List *saved_In_Expr = NIL; |
59 | 58 | static Oid*param_type_info; |
60 | 59 | static intpfunc_num_args; |
61 | 60 | extern List *parsetree; |
@@ -213,9 +212,8 @@ Oidparam_type(int t); /* used in parse_expr.c */ |
213 | 212 | %type <defelt>def_elem |
214 | 213 | %type <node>def_arg, columnElem, where_clause, |
215 | 214 | 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 |
219 | 217 | %type <node>row_expr |
220 | 218 | %type <str>row_op |
221 | 219 | %type <node>case_expr, case_arg, when_clause, case_default |
@@ -3986,33 +3984,59 @@ a_expr: attr |
3986 | 3984 | makeA_Expr(OP, "<", $1, $4), |
3987 | 3985 | makeA_Expr(OP, ">", $1, $6)); |
3988 | 3986 | } |
3989 | | -| a_expr IN{ saved_In_Expr = lcons($1,saved_In_Expr); }'(' in_expr ')' |
| 3987 | +| a_expr IN '(' in_expr ')' |
3990 | 3988 | { |
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)) |
3993 | 3991 | { |
3994 | | -SubLink *n = (SubLink *)$5; |
| 3992 | +SubLink *n = (SubLink *)$4; |
3995 | 3993 | n->lefthand = lcons($1, NIL); |
3996 | 3994 | n->oper = lcons("=",NIL); |
3997 | 3995 | n->useor = false; |
3998 | 3996 | n->subLinkType = ANY_SUBLINK; |
3999 | 3997 | $$ = (Node *)n; |
4000 | 3998 | } |
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 | +} |
4002 | 4013 | } |
4003 | | -| a_expr NOT IN{ saved_In_Expr = lcons($1,saved_In_Expr); }'('not_in_expr ')' |
| 4014 | +| a_expr NOT IN '('in_expr ')' |
4004 | 4015 | { |
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)) |
4007 | 4018 | { |
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; |
4014 | 4039 | } |
4015 | | -else$$ = $6; |
4016 | 4040 | } |
4017 | 4041 | | a_expr Op '(' SubSelect ')' |
4018 | 4042 | { |
@@ -4632,33 +4656,13 @@ in_expr: SubSelect |
4632 | 4656 | $$ = (Node *)n; |
4633 | 4657 | } |
4634 | 4658 | | 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; } |
4644 | 4660 | ; |
4645 | 4661 |
|
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); } |
4662 | 4666 | ; |
4663 | 4667 |
|
4664 | 4668 | /* Case clause |
@@ -5239,7 +5243,6 @@ void parser_init(Oid *typev, int nargs) |
5239 | 5243 | { |
5240 | 5244 | QueryIsRule = FALSE; |
5241 | 5245 | saved_relname[0]= '\0'; |
5242 | | -saved_In_Expr = NULL; |
5243 | 5246 |
|
5244 | 5247 | param_type_init(typev, nargs); |
5245 | 5248 | } |
|