]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Create SubLink nodes in parser for Vadim.
authorBruce Momjian <bruce@momjian.us>
Mon, 19 Jan 1998 05:06:41 +0000 (05:06 +0000)
committerBruce Momjian <bruce@momjian.us>
Mon, 19 Jan 1998 05:06:41 +0000 (05:06 +0000)
src/backend/parser/analyze.c
src/backend/parser/gram.y
src/backend/parser/keywords.c
src/backend/parser/parse_clause.c
src/backend/parser/parse_expr.c
src/backend/parser/parse_node.c
src/backend/parser/parser.c
src/include/nodes/primnodes.h
src/include/parser/analyze.h
src/include/parser/parse_node.h

index 45c5d1406ba9e333bd158dc1d221c840b14b8798..5fc0bb1ac3688c2b38af1ae62465f3e7b39edbc3 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.65 1998/01/15 18:59:56 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.66 1998/01/19 05:06:13 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,7 +53,7 @@ List   *extras = NIL;
  *
  */
 QueryTreeList *
-parse_analyze(List *pl)
+parse_analyze(List *pl, ParseState *parentParseState)
 {
        QueryTreeList *result;
        ParseState *pstate;
@@ -65,7 +65,7 @@ parse_analyze(List *pl)
 
        while (pl != NIL)
        {
-               pstate = make_parsestate();
+               pstate = make_parsestate(parentParseState);
                result->qtrees[i++] = transformStmt(pstate, lfirst(pl));
                if (extras != NIL)
                {
index 0f43799d38b60cc6274ca71730c375e9412c30f9..244c834568693184421f2f8f951d02d0ae764134 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.93 1998/01/17 05:01:34 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.94 1998/01/19 05:06:15 momjian Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -48,7 +48,7 @@
 
 static char saved_relname[NAMEDATALEN];  /* need this for complex attributes */
 static bool QueryIsRule = FALSE;
-static Node *saved_In_Expr;
+static List *saved_In_Expr = NIL;
 static Oid     *param_type_info;
 static int     pfunc_num_args;
 extern List *parsetree;
@@ -242,7 +242,7 @@ Oid param_type(int t); /* used in parse_expr.c */
  */
 
 /* Keywords (in SQL92 reserved words) */
-%token ACTION, ADD, ALL, ALTER, AND, AS, ASC,
+%token ACTION, ADD, ALL, ALTER, AND, ANY AS, ASC,
                BEGIN_TRANS, BETWEEN, BOTH, BY,
                CASCADE, CAST, CHAR, CHARACTER, CHECK, CLOSE, COLLATE, COLUMN, COMMIT, 
                CONSTRAINT, CREATE, CROSS, CURRENT, CURRENT_DATE, CURRENT_TIME, 
@@ -2871,7 +2871,9 @@ row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
                                {
                                        SubLink *n = makeNode(SubLink);
                                        n->lefthand = $2;
-                                       n->subLinkType = IN_SUBLINK;
+                                       n->oper = lcons("=",NIL);
+                                       n->useor = false;
+                                       n->subLinkType = ANY_SUBLINK;
                                        n->subselect = $6;
                                        $$ = (Node *)n;
                                }
@@ -2879,7 +2881,29 @@ row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
                                {
                                        SubLink *n = makeNode(SubLink);
                                        n->lefthand = $2;
-                                       n->subLinkType = NOTIN_SUBLINK;
+                                       n->oper = lcons("<>",NIL);
+                                       n->useor = true;
+                                       n->subLinkType = ALL_SUBLINK;
+                                       n->subselect = $7;
+                                       $$ = (Node *)n;
+                               }
+               | '(' row_descriptor ')' Op ANY '(' SubSelect ')'
+                               {
+                                       SubLink *n = makeNode(SubLink);
+                                       n->lefthand = $2;
+                                       n->oper = lcons($4,NIL);
+                                       n->useor = false;
+                                       n->subLinkType = ANY_SUBLINK;
+                                       n->subselect = $7;
+                                       $$ = (Node *)n;
+                               }
+               | '(' row_descriptor ')' Op ALL '(' SubSelect ')'
+                               {
+                                       SubLink *n = makeNode(SubLink);
+                                       n->lefthand = $2;
+                                       n->oper = lcons($4,NIL);
+                                       n->useor = false;
+                                       n->subLinkType = ALL_SUBLINK;
                                        n->subselect = $7;
                                        $$ = (Node *)n;
                                }
@@ -2887,8 +2911,12 @@ row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
                                {
                                        SubLink *n = makeNode(SubLink);
                                        n->lefthand = $2;
-                                       n->subLinkType = OPER_SUBLINK;
                                        n->oper = lcons($4, NIL);
+                                       if (strcmp($4,"<>") == 0)
+                                               n->useor = true;
+                                       else
+                                               n->useor = false;
+                                       n->subLinkType = EXPR_SUBLINK;
                                        n->subselect = $6;
                                        $$ = (Node *)n;
                                }
@@ -3114,17 +3142,13 @@ a_expr:  attr opt_indirection
                                        n->args = NIL;
                                        $$ = (Node *)n;
                                }
-               /* We probably need to define an "exists" node,
-                *      since the optimizer could choose to find only one match.
-                * Perhaps the first implementation could just check for
-                *      count(*) > 0? - thomas 1997-07-19
-                */
                | EXISTS '(' SubSelect ')'
                                {
                                        SubLink *n = makeNode(SubLink);
                                        n->lefthand = NIL;
-                                       n->subLinkType = EXISTS_SUBLINK;
+                                       n->useor = false;
                                        n->oper = NIL;
+                                       n->subLinkType = EXISTS_SUBLINK;
                                        n->subselect = $3;
                                        $$ = (Node *)n;
                                }
@@ -3239,26 +3263,52 @@ a_expr:  attr opt_indirection
                                                makeA_Expr(OP, "<", $1, $4),
                                                makeA_Expr(OP, ">", $1, $6));
                                }
-               | a_expr IN { saved_In_Expr = $1; } '(' in_expr ')'
+               | a_expr IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' in_expr ')' { saved_In_Expr = lnext(saved_In_Expr); }
                                {
                                        if (nodeTag($5) == T_SubLink)
                                        {
-                                               ((SubLink *)$5)->lefthand = lcons($1, NIL);
-                                               ((SubLink *)$5)->subLinkType = IN_SUBLINK;
-                                               $$ = (Node *)$5;
+                                                       SubLink *n = (SubLink *)$5;
+                                                       n->lefthand = lcons($1, NIL);
+                                                       n->oper = lcons("=",NIL);
+                                                       n->useor = false;
+                                                       n->subLinkType = ANY_SUBLINK;
+                                                       $$ = (Node *)n;
                                        }
                                        else    $$ = $5;
                                }
-               | a_expr NOT IN { saved_In_Expr = $1; } '(' not_in_expr ')'
+               | a_expr NOT IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' not_in_expr ')' { saved_In_Expr = lnext(saved_In_Expr); }
                                {
                                        if (nodeTag($6) == T_SubLink)
                                        {
-                                               ((SubLink *)$6)->lefthand = lcons($1, NIL);
-                                               ((SubLink *)$6)->subLinkType = NOTIN_SUBLINK;
-                                               $$ = (Node *)$6;
+                                                       SubLink *n = (SubLink *)$6;
+                                                       n->lefthand = lcons($1, NIL);
+                                                       n->oper = lcons("<>",NIL);
+                                                       n->useor = false;
+                                                       n->subLinkType = ALL_SUBLINK;
+                                                       $$ = (Node *)n;
                                        }
                                        else    $$ = $6;
                                }
+               | a_expr Op ANY '(' SubSelect ')'
+                               {
+                                       SubLink *n = makeNode(SubLink);
+                                       n->lefthand = lcons($1,NIL);
+                                       n->oper = lcons($2,NIL);
+                                       n->useor = false;
+                                       n->subLinkType = ANY_SUBLINK;
+                                       n->subselect = $5;
+                                       $$ = (Node *)n;
+                               }
+               | a_expr Op ALL '(' SubSelect ')'
+                               {
+                                       SubLink *n = makeNode(SubLink);
+                                       n->lefthand = lcons($1, NULL);
+                                       n->oper = lcons($2,NIL);
+                                       n->useor = false;
+                                       n->subLinkType = ALL_SUBLINK;
+                                       n->subselect = $5;
+                                       $$ = (Node *)n;
+                               }
                | a_expr AND a_expr
                                {       $$ = makeA_Expr(AND, NULL, $1, $3); }
                | a_expr OR a_expr
@@ -3480,10 +3530,10 @@ in_expr:  SubSelect
                ;
 
 in_expr_nodes:  AexprConst
-                               {       $$ = makeA_Expr(OP, "=", saved_In_Expr, $1); }
+                               {       $$ = makeA_Expr(OP, "=", lfirst(saved_In_Expr), $1); }
                | in_expr_nodes ',' AexprConst
                                {       $$ = makeA_Expr(OR, NULL, $1,
-                                               makeA_Expr(OP, "=", saved_In_Expr, $3));
+                                               makeA_Expr(OP, "=", lfirst(saved_In_Expr), $3));
                                }
                ;
 
@@ -3498,10 +3548,10 @@ not_in_expr:  SubSelect
                ;
 
 not_in_expr_nodes:  AexprConst
-                               {       $$ = makeA_Expr(OP, "<>", saved_In_Expr, $1); }
+                               {       $$ = makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $1); }
                | not_in_expr_nodes ',' AexprConst
                                {       $$ = makeA_Expr(AND, NULL, $1,
-                                               makeA_Expr(OP, "<>", saved_In_Expr, $3));
+                                               makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $3));
                                }
                ;
 
index 45c450f7d025f343784164c8abaa23fec0004d5f..3049689aa1ee3f854bf250c30f14cf0e21625715 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.29 1998/01/05 03:32:22 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.30 1998/01/19 05:06:16 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -39,6 +39,7 @@ static ScanKeyword ScanKeywords[] = {
        {"alter", ALTER},
        {"analyze", ANALYZE},
        {"and", AND},
+       {"any", ANY},
        {"append", APPEND},
        {"archive", ARCHIVE},
        {"as", AS},
index 7b09518d4f9afc113bf50c4871956814bfaedb31..71aaf24423886d49d552c266a41436c20d7e0f00 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.8 1998/01/06 23:58:05 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.9 1998/01/19 05:06:17 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -387,7 +387,7 @@ transformUnionClause(List *unionClause, List *targetlist)
 
        if (unionClause)
        {
-               qlist = parse_analyze(unionClause);
+               qlist = parse_analyze(unionClause, NULL);
 
                for (i=0; i < qlist->len; i++)
                        union_list = lappend(union_list, qlist->qtrees[i]);
index 00efc044dcdf7a4188b4cf3806343f19fa9a232a..b1bf7d3a95f5246f48fc3d149f796b45d56ee3be 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.7 1998/01/16 23:20:18 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.8 1998/01/19 05:06:18 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -22,6 +22,7 @@
 #include "nodes/params.h"
 #include "nodes/relation.h"
 #include "parse.h"
+#include "parser/analyze.h"
 #include "parser/gramparse.h"
 #include "parser/parse_expr.h"
 #include "parser/parse_func.h"
@@ -249,6 +250,42 @@ transformExpr(ParseState *pstate, Node *expr, int precedence)
                                                  precedence);
                                break;
                        }
+               case T_SubLink:
+                       {
+                               SubLink                 *sublink = (SubLink *) expr;
+                               QueryTreeList   *qtree;
+                               Query                   *subselect;
+
+                               qtree = parse_analyze(lcons(sublink->subselect,NIL), pstate);
+                               
+                               Assert(qtree->len == 1);
+
+                               sublink->subselect = (Node *) subselect = qtree->qtrees[0];
+                       
+                               if (length(sublink->lefthand) !=
+                                       length(subselect->targetList))
+                                       elog(ERROR,"Subselect has too many or too few fields.");
+                                       
+                               if (sublink->subLinkType != EXISTS_SUBLINK)
+                               {
+                                       char *op = lfirst(sublink->oper);
+                                       List *left_expr = sublink->lefthand;
+                                       List *right_expr = subselect->targetList;
+                                       List *elist;
+                                       
+                                       foreach(elist, left_expr)
+                                       {
+                                               Node       *lexpr = transformExpr(pstate, lfirst(elist), precedence);
+                                               Node       *rexpr = lfirst(right_expr);
+                                               Expr       *op_expr;                                            
+
+                                               op_expr = make_op(op, lexpr, rexpr);
+                                               sublink->oper = lappend(sublink->oper, op_expr->oper);
+                                               right_expr = lnext(right_expr);
+                                       }
+                               }
+                               break;
+                       }
                default:
                        /* should not reach here */
                        elog(ERROR, "transformExpr: does not know how to transform node %d",
index 15a47993a7fd8cc67c37bfa758913e2c2fafca23..03bc54d531ff5b6024f8a2876f3e4dc57c11d1ed 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.7 1998/01/17 04:53:19 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.8 1998/01/19 05:06:19 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -42,7 +42,7 @@ static Node *make_operand(char *opname,
  */
 
 ParseState *
-make_parsestate(void)
+make_parsestate(ParseState *parentParseState)
 {
        ParseState *pstate;
 
@@ -50,7 +50,8 @@ make_parsestate(void)
        MemSet(pstate, 0, sizeof(ParseState));
 
        pstate->p_last_resno = 1;
-
+       pstate->parentParseState = parentParseState;
+       
        return (pstate);
 }
 
index d7e2344823ebbbcd09fa9d7bc868845991d97a4a..0a7a8d58005cb3e6739ac34af2867ad8dd72d2dd 100644 (file)
@@ -6,7 +6,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parser.c,v 1.31 1997/12/22 05:42:25 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parser.c,v 1.32 1998/01/19 05:06:20 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -61,7 +61,7 @@ parser(char *str, Oid *typev, int nargs)
        if (yyresult)           /* error */
                return ((QueryTreeList *) NULL);
 
-       queryList = parse_analyze(parsetree);
+       queryList = parse_analyze(parsetree, NULL);
 
 #ifdef SETS_FIXED
 
index 3da2c433cb787e744e1cbbe9f15fb7ae8883800d..531e5e9052bb4961d838b53ffc54b09f1c63994d 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: primnodes.h,v 1.13 1998/01/17 04:53:42 momjian Exp $
+ * $Id: primnodes.h,v 1.14 1998/01/19 05:06:36 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -281,8 +281,7 @@ typedef struct Aggreg
  */
 typedef enum SubLinkType
 {
-       EXISTS_SUBLINK, ALL_SUBLINK, ANY_SUBLINK, EXPR_SUBLINK,
-       IN_SUBLINK, NOTIN_SUBLINK, OPER_SUBLINK
+       EXISTS_SUBLINK, ALL_SUBLINK, ANY_SUBLINK, EXPR_SUBLINK
 } SubLinkType;
 
 
index b88d80f346f8b78e24499d8c148cf2f60ce74e98..85191a60c1b4088a374cc50ff5d91e897dc6a9cc 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: analyze.h,v 1.2 1997/11/26 01:13:56 momjian Exp $
+ * $Id: analyze.h,v 1.3 1998/01/19 05:06:39 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -14,6 +14,6 @@
 
 #include <parser/parse_node.h>
 
-extern QueryTreeList *parse_analyze(List *pl);
+extern QueryTreeList *parse_analyze(List *pl, ParseState *parentParseState);
 
 #endif                                                 /* ANALYZE_H */
index a0915574a1d4f5555e49f70584e9761ecd75527a..f09c7d0f86e50688bad3b0cd09687683d8cd92da 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parse_node.h,v 1.5 1998/01/17 04:53:46 momjian Exp $
+ * $Id: parse_node.h,v 1.6 1998/01/19 05:06:41 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -28,9 +28,11 @@ typedef struct QueryTreeList
 /* state information used during parse analysis */
 typedef struct ParseState
 {
+       struct          ParseState;
        int                     p_last_resno;
        List       *p_rtable;
        List       *p_insert_columns;
+       struct ParseState *parentParseState;
        bool            p_hasAggs;
        bool            p_hasSubLinks;
        bool            p_is_insert;
@@ -41,7 +43,7 @@ typedef struct ParseState
        RangeTblEntry *p_target_rangetblentry;
 } ParseState;
 
-extern ParseState *make_parsestate(void);
+extern ParseState *make_parsestate(ParseState *parentParseState);
 extern Expr *make_op(char *opname, Node *ltree, Node *rtree);
 extern Var *make_var(ParseState *pstate, char *refname, char *attrname, Oid *type_id);
 extern ArrayRef   *make_array_ref(Node *expr,