diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 60ff7a6ef259f266e7e10db93f41e244f3c04a55..cf2139a9cc4aa41ac3a5bfc6f1f1229c86771991 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.95 1999/07/27 03:51:06 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.96 1999/07/28 17:39:38 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -55,7 +55,6 @@ static char saved_relname[NAMEDATALEN]; /* need this for complex attributes */ static bool QueryIsRule = FALSE; -static List *saved_In_Expr = NIL; static Oid *param_type_info; static int pfunc_num_args; extern List *parsetree; @@ -213,9 +212,8 @@ Oid param_type(int t); /* used in parse_expr.c */ %type def_elem %type def_arg, columnElem, where_clause, a_expr, a_expr_or_null, b_expr, AexprConst, - in_expr, in_expr_nodes, not_in_expr, not_in_expr_nodes, - having_clause -%type row_descriptor, row_list, c_list, c_expr + in_expr, having_clause +%type row_descriptor, row_list, c_list, c_expr, in_expr_nodes %type row_expr %type row_op %type case_expr, case_arg, when_clause, case_default @@ -3986,33 +3984,59 @@ a_expr: attr makeA_Expr(OP, "<", $1, $4), makeA_Expr(OP, ">", $1, $6)); } - | a_expr IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' in_expr ')' + | a_expr IN '(' in_expr ')' { - saved_In_Expr = lnext(saved_In_Expr); - if (nodeTag($5) == T_SubLink) + /* in_expr returns a SubLink or a list of a_exprs */ + if (IsA($4, SubLink)) { - SubLink *n = (SubLink *)$5; + SubLink *n = (SubLink *)$4; n->lefthand = lcons($1, NIL); n->oper = lcons("=",NIL); n->useor = false; n->subLinkType = ANY_SUBLINK; $$ = (Node *)n; } - else $$ = $5; + else + { + Node *n = NULL; + List *l; + foreach(l, (List *) $4) + { + Node *cmp = makeA_Expr(OP, "=", $1, lfirst(l)); + if (n == NULL) + n = cmp; + else + n = makeA_Expr(OR, NULL, n, cmp); + } + $$ = n; + } } - | a_expr NOT IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' not_in_expr ')' + | a_expr NOT IN '(' in_expr ')' { - saved_In_Expr = lnext(saved_In_Expr); - if (nodeTag($6) == T_SubLink) + /* in_expr returns a SubLink or a list of a_exprs */ + if (IsA($5, SubLink)) { - SubLink *n = (SubLink *)$6; - n->lefthand = lcons($1, NIL); - n->oper = lcons("<>",NIL); - n->useor = false; - n->subLinkType = ALL_SUBLINK; - $$ = (Node *)n; + SubLink *n = (SubLink *)$5; + n->lefthand = lcons($1, NIL); + n->oper = lcons("<>",NIL); + n->useor = false; + n->subLinkType = ALL_SUBLINK; + $$ = (Node *)n; + } + else + { + Node *n = NULL; + List *l; + foreach(l, (List *) $5) + { + Node *cmp = makeA_Expr(OP, "<>", $1, lfirst(l)); + if (n == NULL) + n = cmp; + else + n = makeA_Expr(AND, NULL, n, cmp); + } + $$ = n; } - else $$ = $6; } | a_expr Op '(' SubSelect ')' { @@ -4632,33 +4656,13 @@ in_expr: SubSelect $$ = (Node *)n; } | in_expr_nodes - { $$ = $1; } - ; - -in_expr_nodes: AexprConst - { $$ = makeA_Expr(OP, "=", lfirst(saved_In_Expr), $1); } - | in_expr_nodes ',' AexprConst - { $$ = makeA_Expr(OR, NULL, $1, - makeA_Expr(OP, "=", lfirst(saved_In_Expr), $3)); - } + { $$ = (Node *)$1; } ; -not_in_expr: SubSelect - { - SubLink *n = makeNode(SubLink); - n->subselect = $1; - $$ = (Node *)n; - } - | not_in_expr_nodes - { $$ = $1; } - ; - -not_in_expr_nodes: AexprConst - { $$ = makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $1); } - | not_in_expr_nodes ',' AexprConst - { $$ = makeA_Expr(AND, NULL, $1, - makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $3)); - } +in_expr_nodes: a_expr + { $$ = lcons($1, NIL); } + | in_expr_nodes ',' a_expr + { $$ = lappend($1, $3); } ; /* Case clause @@ -5239,7 +5243,6 @@ void parser_init(Oid *typev, int nargs) { QueryIsRule = FALSE; saved_relname[0]= '\0'; - saved_In_Expr = NULL; param_type_init(typev, nargs); }