]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Creates the SubLink structure, and the Query->hasSubLink field,
authorBruce Momjian <bruce@momjian.us>
Sat, 17 Jan 1998 04:53:46 +0000 (04:53 +0000)
committerBruce Momjian <bruce@momjian.us>
Sat, 17 Jan 1998 04:53:46 +0000 (04:53 +0000)
with supporting code.

Creates SubLink node in gram.y.

psql.c patch for newatttypmod field.

src/backend/nodes/copyfuncs.c
src/backend/nodes/outfuncs.c
src/backend/nodes/readfuncs.c
src/backend/parser/gram.y
src/backend/parser/parse_node.c
src/bin/psql/psql.c
src/include/nodes/nodes.h
src/include/nodes/parsenodes.h
src/include/nodes/primnodes.h
src/include/parser/parse_node.h

index fe045539223572544678f039f322bce343330c1d..834cc8c25713e6556450bccf8df10340dcf590e2 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.31 1998/01/16 23:19:56 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.32 1998/01/17 04:53:07 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -892,6 +892,28 @@ _copyAggreg(Aggreg *from)
        return newnode;
 }
 
+/* ----------------
+ *             _copySubLink
+ * ----------------
+ */
+static SubLink *
+_copySubLink(SubLink *from)
+{
+       SubLink    *newnode = makeNode(SubLink);
+
+       /* ----------------
+        *      copy remainder of node
+        * ----------------
+        */
+       newnode->subLinkType = from->subLinkType;
+       newnode->useor = from->useor;
+       Node_Copy(from, newnode, lefthand);
+       Node_Copy(from, newnode, oper);
+       Node_Copy(from, newnode, subselect);
+
+       return newnode;
+}
+
 static Array *
 _copyArray(Array *from)
 {
@@ -1517,6 +1539,7 @@ _copyQuery(Query *from)
        Node_Copy(from, newnode, havingQual);
 
        newnode->hasAggs = from->hasAggs;
+       newnode->hasSubLinks = from->hasSubLinks;
 
        if (from->unionClause)
        {
@@ -1673,6 +1696,9 @@ copyObject(void *from)
                case T_Aggreg:
                        retval = _copyAggreg(from);
                        break;
+               case T_SubLink:
+                       retval = _copySubLink(from);
+                       break;
 
                        /*
                         * RELATION NODES
index 41f3022c135e2f92733459921d91e7dbf4edb126..63c2ffef434a8d1997e03e02a229414a288aebc6 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.22 1998/01/16 23:19:59 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.23 1998/01/17 04:53:09 momjian Exp $
  *
  * NOTES
  *       Every (plan) node in POSTGRES has an associated "out" routine which
@@ -230,6 +230,8 @@ _outQuery(StringInfo str, Query *node)
        _outNode(str, node->havingQual);
        appendStringInfo(str, " :hasAggs ");
        appendStringInfo(str, (node->hasAggs ? "true" : "false"));
+       appendStringInfo(str, " :hasSubLinks ");
+       appendStringInfo(str, (node->hasSubLinks ? "true" : "false"));
        appendStringInfo(str, " :unionClause ");
        _outNode(str, node->unionClause);
 }
@@ -753,6 +755,27 @@ _outAggreg(StringInfo str, Aggreg *node)
        appendStringInfo(str, node->usenulls ? "true" : "false");
 }
 
+/*
+ *     SubLink
+ */
+static void
+_outSubLink(StringInfo str, SubLink *node)
+{
+       char            buf[500];
+
+       appendStringInfo(str, "SUBLINK");
+       sprintf(buf, " :subLinkType %d ", node->subLinkType);
+       appendStringInfo(str, buf);
+       appendStringInfo(str, " :useor ");
+       appendStringInfo(str, node->useor ? "true" : "false");
+       appendStringInfo(str, " :lefthand ");
+       _outNode(str, node->lefthand);
+       appendStringInfo(str, " :oper ");
+       _outNode(str, node->oper);
+       appendStringInfo(str, " :subselect ");
+       _outNode(str, node->subselect);
+}
+
 /*
  *     Array is a subclass of Expr
  */
@@ -1648,6 +1671,9 @@ _outNode(StringInfo str, void *obj)
                        case T_Aggreg:
                                _outAggreg(str, obj);
                                break;
+                       case T_SubLink:
+                               _outSubLink(str, obj);
+                               break;
                        case T_Array:
                                _outArray(str, obj);
                                break;
index 574d5c69e2c99028339cacf8c14316e39618ec0f..e2c458e293339eab88c711f480d991ef503b4102 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.18 1998/01/15 18:59:31 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/readfuncs.c,v 1.19 1998/01/17 04:53:11 momjian Exp $
  *
  * NOTES
  *       Most of the read functions for plan nodes are tested. (In fact, they
@@ -156,6 +156,10 @@ _readQuery()
        token = lsptok(NULL, &length);          /* get hasAggs */
        local_node->hasAggs = (token[0] == 't') ? true : false;
 
+       token = lsptok(NULL, &length);          /* skip the :hasSubLinks */
+       token = lsptok(NULL, &length);          /* get hasSubLinks */
+       local_node->hasSubLinks = (token[0] == 't') ? true : false;
+
        token = lsptok(NULL, &length);          /* skip :unionClause */
        local_node->unionClause = nodeRead(true);
 
@@ -1151,6 +1155,41 @@ _readAggreg()
        return (local_node);
 }
 
+/* ----------------
+ *             _readSubLink
+ *
+ *     SubLink is a subclass of Node
+ * ----------------
+ */
+static SubLink *
+_readSubLink()
+{
+       SubLink    *local_node;
+       char       *token;
+       int                     length;
+
+       local_node = makeNode(SubLink);
+
+       token = lsptok(NULL, &length);          /* eat :subLinkType */
+       token = lsptok(NULL, &length);          /* get subLinkType */
+       local_node->subLinkType = atoi(token);
+
+       token = lsptok(NULL, &length);          /* eat :useor */
+       token = lsptok(NULL, &length);          /* get useor */
+       local_node->useor = (token[0] == 't') ? true : false;
+
+       token = lsptok(NULL, &length);          /* eat :lefthand */
+       local_node->lefthand = nodeRead(true);          /* now read it */
+
+       token = lsptok(NULL, &length);          /* eat :oper */
+       local_node->oper = nodeRead(true);              /* now read it */
+
+       token = lsptok(NULL, &length);          /* eat :subselect */
+       local_node->subselect = nodeRead(true);         /* now read it */
+
+       return (local_node);
+}
+
 /*
  *     Stuff from execnodes.h
  */
@@ -1971,6 +2010,10 @@ parsePlanString(void)
        {
                return_value = _readAggreg();
        }
+       else if (!strncmp(token, "SUBLINK", 6))
+       {
+               return_value = _readSubLink();
+       }
        else if (!strncmp(token, "AGG", 3))
        {
                return_value = _readAgg();
index 77a2e0b7c2911718ba35c5a2fde6faa566e2f0a2..a13a07aa2ce0234edc30501ffe064d4b6417c02f 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.91 1998/01/16 23:20:14 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.92 1998/01/17 04:53:16 momjian Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -63,7 +63,6 @@ extern List *parsetree;
 
 static char *xlateSqlType(char *);
 static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
-static Node *makeRowExpr(char *opr, List *largs, List *rargs);
 void mapTargetColumns(List *source, List *target);
 static List *makeConstantList( A_Const *node);
 static char *FlattenStringList(List *list);
@@ -2151,9 +2150,9 @@ insert_rest:  VALUES '(' res_target_list2 ')'
                                        $$->unique = NULL;
                                        $$->targetList = $3;
                                        $$->fromClause = NIL;
-                                       $$->whereClause = NIL;
+                                       $$->whereClause = NULL;
                                        $$->groupClause = NIL;
-                                       $$->havingClause = NIL;
+                                       $$->havingClause = NULL;
                                        $$->unionClause = NIL;
                                }
                | SELECT opt_unique res_target_list2
@@ -2869,28 +2868,41 @@ a_expr_or_null:  a_expr
  */
 row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
                                {
-                                       $$ = NULL;
+                                       SubLink *n = makeNode(SubLink);
+                                       n->lefthand = $2;
+                                       n->subLinkType = IN_SUBLINK;
+                                       n->subselect = $6;
+                                       $$ = (Node *)n;
                                }
                | '(' row_descriptor ')' NOT IN '(' SubSelect ')'
                                {
-                                       $$ = NULL;
-                               }
-               | '(' row_descriptor ')' '=' '(' row_descriptor ')'
-                               {
-                                       $$ = makeRowExpr("=", $2, $6);
-                               }
-               | '(' row_descriptor ')' '<' '(' row_descriptor ')'
-                               {
-                                       $$ = makeRowExpr("<", $2, $6);
+                                       SubLink *n = makeNode(SubLink);
+                                       n->lefthand = $2;
+                                       n->subLinkType = NOTIN_SUBLINK;
+                                       n->subselect = $7;
+                                       $$ = (Node *)n;
                                }
-               | '(' row_descriptor ')' '>' '(' row_descriptor ')'
+/* We accept all Operators? */
+               | '(' row_descriptor ')' Op '(' SubSelect ')'
                                {
-                                       $$ = makeRowExpr("<", $2, $6);
+                                       SubLink *n = makeNode(SubLink);
+                                       n->lefthand = $2;
+                                       n->subLinkType = OPER_SUBLINK;
+                                       n->oper = lcons($4, NIL);
+                                       n->subselect = $6;
+                                       $$ = (Node *)n;
                                }
+/* Do we need this?
                | '(' row_descriptor ')' Op '(' row_descriptor ')'
                                {
-                                       $$ = makeRowExpr($4, $2, $6);
+                                       SubLink *n = makeNode(SubLink);
+                                       n->lefthand = $2;
+                                       n->subLinkType = OPER_SUBLINK;
+                                       n->oper = lcons($4, NIL);
+                                       n->subselect = $6;
+                                       $$ = (Node *)n;
                                }
+*/
                ;
 
 row_descriptor:  row_list ',' a_expr
@@ -3116,8 +3128,12 @@ a_expr:  attr opt_indirection
                 */
                | EXISTS '(' SubSelect ')'
                                {
-                                       elog(ERROR,"EXISTS not yet implemented");
-                                       $$ = $3;
+                                       SubLink *n = makeNode(SubLink);
+                                       n->lefthand = NIL;
+                                       n->subLinkType = EXISTS_SUBLINK;
+                                       n->oper = NIL;
+                                       n->subselect = $3;
+                                       $$ = (Node *)n;
                                }
                | EXTRACT '(' extract_list ')'
                                {
@@ -3231,9 +3247,25 @@ a_expr:  attr opt_indirection
                                                makeA_Expr(OP, ">", $1, $6));
                                }
                | a_expr IN { saved_In_Expr = $1; } '(' in_expr ')'
-                               {       $$ = $5; }
+                               {
+                                       if (nodeTag($5) == T_SubLink)
+                                       {
+                                               ((SubLink *)$5)->lefthand = lcons($1, NIL);
+                                               ((SubLink *)$5)->subLinkType = IN_SUBLINK;
+                                               $$ = (Node *)$5;
+                                       }
+                                       else    $$ = $5;
+                               }
                | a_expr NOT IN { saved_In_Expr = $1; } '(' not_in_expr ')'
-                               {       $$ = $6; }
+                               {
+                                       if (nodeTag($6) == T_SubLink)
+                                       {
+                                               ((SubLink *)$6)->lefthand = lcons($1, NIL);
+                                               ((SubLink *)$6)->subLinkType = NOTIN_SUBLINK;
+                                               $$ = (Node *)$6;
+                                       }
+                                       else    $$ = $6;
+                               }
                | a_expr AND a_expr
                                {       $$ = makeA_Expr(AND, NULL, $1, $3); }
                | a_expr OR a_expr
@@ -3446,8 +3478,9 @@ trim_list:  a_expr FROM expr_list
 
 in_expr:  SubSelect
                                {
-                                       elog(ERROR,"IN (SUBSELECT) not yet implemented");
-                                       $$ = $1;
+                                       SubLink *n = makeNode(SubLink);
+                                       n->subselect = $1;
+                                       $$ = (Node *)n;
                                }
                | in_expr_nodes
                                {       $$ = $1; }
@@ -3463,8 +3496,9 @@ in_expr_nodes:  AexprConst
 
 not_in_expr:  SubSelect
                                {
-                                       elog(ERROR,"NOT IN (SUBSELECT) not yet implemented");
-                                       $$ = $1;
+                                       SubLink *n = makeNode(SubLink);
+                                       n->subselect = $1;
+                                       $$ = (Node *)n;
                                }
                | not_in_expr_nodes
                                {       $$ = $1; }
@@ -3807,68 +3841,6 @@ makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
        return (Node *)a;
 }
 
-/* makeRowExpr()
- * Generate separate operator nodes for a single row descriptor expression.
- * Perhaps this should go deeper in the parser someday... - thomas 1997-12-22
- */
-static Node *
-makeRowExpr(char *opr, List *largs, List *rargs)
-{
-       Node *expr = NULL;
-       Node *larg, *rarg;
-
-       if (length(largs) != length(rargs))
-               elog(ERROR,"Unequal number of entries in row expression");
-
-       if (lnext(largs) != NIL)
-               expr = makeRowExpr(opr,lnext(largs),lnext(rargs));
-
-       larg = lfirst(largs);
-       rarg = lfirst(rargs);
-
-       if ((strcmp(opr, "=") == 0)
-        || (strcmp(opr, "<") == 0)
-        || (strcmp(opr, "<=") == 0)
-        || (strcmp(opr, ">") == 0)
-        || (strcmp(opr, ">=") == 0))
-       {
-               if (expr == NULL)
-                       expr = makeA_Expr(OP, opr, larg, rarg);
-               else
-                       expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
-       }
-       else if (strcmp(opr, "<>") == 0)
-       {
-               if (expr == NULL)
-                       expr = makeA_Expr(OP, opr, larg, rarg);
-               else
-                       expr = makeA_Expr(OR, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
-       }
-       else
-       {
-               elog(ERROR,"Operator '%s' not implemented for row expressions",opr);
-       }
-
-#if FALSE
-       while ((largs != NIL) && (rargs != NIL))
-       {
-               larg = lfirst(largs);
-               rarg = lfirst(rargs);
-
-               if (expr == NULL)
-                       expr = makeA_Expr(OP, opr, larg, rarg);
-               else
-                       expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
-
-               largs = lnext(largs);
-               rargs = lnext(rargs);
-       }
-       pprint(expr);
-#endif
-
-       return expr;
-} /* makeRowExpr() */
-
 void
 mapTargetColumns(List *src, List *dst)
 {
index 04b40041b9df3629817a1298ae80d5fcac75e830..15a47993a7fd8cc67c37bfa758913e2c2fafca23 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.6 1998/01/15 19:00:04 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.7 1998/01/17 04:53:19 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -47,16 +47,9 @@ make_parsestate(void)
        ParseState *pstate;
 
        pstate = palloc(sizeof(ParseState));
+       MemSet(pstate, 0, sizeof(ParseState));
+
        pstate->p_last_resno = 1;
-       pstate->p_rtable = NIL;
-       pstate->p_hasAggs = false;
-       pstate->p_is_insert = false;
-       pstate->p_insert_columns = NIL;
-       pstate->p_is_update = false;
-       pstate->p_is_rule = false;
-       pstate->p_in_where_clause = false;
-       pstate->p_target_relation = NULL;
-       pstate->p_target_rangetblentry = NULL;
 
        return (pstate);
 }
index 1f5e7d9d44da851cee31d93fc9403271fc6bcc8e..b2d4b434269c819961871507e785dd24dbaebd23 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.125 1998/01/09 19:34:38 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.126 1998/01/17 04:53:32 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -562,7 +562,7 @@ tableDesc(PsqlSettings *pset, char *table, FILE *fout)
        char       *rnotnull;
        char       *rhasdef;
        int                     i;
-       int                     rsize;
+       int                     attlen, atttypmod;
        PGresult   *res, *res2;
        int                     usePipe = 0;
        char       *pagerenv;
@@ -598,7 +598,8 @@ tableDesc(PsqlSettings *pset, char *table, FILE *fout)
        }
 
        descbuf[0] = '\0';
-       strcat(descbuf, "SELECT a.attnum, a.attname, t.typname, a.attlen, a.attnotnull, a.atthasdef ");
+       strcat(descbuf, "SELECT a.attnum, a.attname, t.typname, a.attlen, ");
+       strcat(descbuf, "a.atttypmod, a.attnotnull, a.atthasdef ");
        strcat(descbuf, "FROM pg_class c, pg_attribute a, pg_type t ");
        strcat(descbuf, "WHERE c.relname = '");
        strcat(descbuf, table);
@@ -643,9 +644,10 @@ tableDesc(PsqlSettings *pset, char *table, FILE *fout)
                        
                        fprintf(fout,"| %-32.32s | ", PQgetvalue(res, i, 1));
                        rtype = PQgetvalue(res, i, 2);
-                       rsize = atoi(PQgetvalue(res, i, 3));
-                       rnotnull = PQgetvalue(res, i, 4);
-                       rhasdef = PQgetvalue(res, i, 5);
+                       attlen = atoi(PQgetvalue(res, i, 3));
+                       atttypmod = atoi(PQgetvalue(res, i, 4));
+                       rnotnull = PQgetvalue(res, i, 5);
+                       rhasdef = PQgetvalue(res, i, 6);
 
                        strcpy(type_str, rtype);
                        if (strcmp(rtype, "bpchar") == 0)
@@ -687,11 +689,11 @@ tableDesc(PsqlSettings *pset, char *table, FILE *fout)
                                fprintf(fout,"%6s |", "var");
                        else if (strcmp(rtype, "bpchar") == 0 ||
                                         strcmp(rtype, "varchar") == 0)
-                               fprintf(fout,"%6i |", rsize > 0 ? rsize - VARHDRSZ : 0);
+                               fprintf(fout,"%6i |", atttypmod > 0 ? atttypmod - VARHDRSZ : 0);
                        else
                        {
-                               if (rsize > 0)
-                                       fprintf(fout,"%6i |", rsize);
+                               if (attlen > 0)
+                                       fprintf(fout,"%6i |", attlen);
                                else
                                        fprintf(fout,"%6s |", "var");
                        }
index 3f87ca202ace52d3baec271219cd84fb05428da8..9c913797dd4b01a01106585049468906978ba5df 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: nodes.h,v 1.22 1998/01/10 04:30:08 momjian Exp $
+ * $Id: nodes.h,v 1.23 1998/01/17 04:53:38 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -60,6 +60,7 @@ typedef enum NodeTag
        T_Const,
        T_Param,
        T_Aggreg,
+       T_SubLink,
        T_Func,
        T_Array,
        T_ArrayRef,
index 02fa069df61d483c7e724540c4ab5d08e6808b42..fc30cbf3e0a81a06bdd7a464111b7abbe55ad2f7 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parsenodes.h,v 1.45 1998/01/16 23:20:55 momjian Exp $
+ * $Id: parsenodes.h,v 1.46 1998/01/17 04:53:40 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -45,6 +45,7 @@ typedef struct Query
        bool            isBinary;               /* binary portal? */
        bool            unionall;               /* union without unique sort */
        bool            hasAggs;                /* has aggregates in target list */
+       bool            hasSubLinks;    /* has subquery SubLink */
        
        char       *uniqueFlag;         /* NULL, '*', or Unique attribute name */
        List       *sortClause;         /* a list of SortClause's */
index 1e896e5e1365fe7b3dc06d49225b97c18dbce922..3da2c433cb787e744e1cbbe9f15fb7ae8883800d 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: primnodes.h,v 1.12 1998/01/04 04:31:37 momjian Exp $
+ * $Id: primnodes.h,v 1.13 1998/01/17 04:53:42 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -270,6 +270,33 @@ typedef struct Aggreg
        bool            usenulls;
 } Aggreg;
 
+/* ----------------
+ * SubLink
+ *             subLinkType             - EXISTS, ALL, ANY, EXPR
+ *             useor                   - TRUE for <>
+ *             lefthand                - list of Var/Const nodes on the left
+ *             oper                    - list of Oper nodes
+ *             subselect               - subselect as Query* or parsetree
+ * ----------------
+ */
+typedef enum SubLinkType
+{
+       EXISTS_SUBLINK, ALL_SUBLINK, ANY_SUBLINK, EXPR_SUBLINK,
+       IN_SUBLINK, NOTIN_SUBLINK, OPER_SUBLINK
+} SubLinkType;
+
+
+typedef struct SubLink
+{
+struct Query;
+       NodeTag         type;
+       SubLinkType     subLinkType;
+       bool            useor;
+       List            *lefthand;
+       List            *oper;
+       Node            *subselect;
+} SubLink;
+
 /* ----------------
  * Array
  *             arrayelemtype   - base type of the array's elements (homogenous!)
index be49fe7a0fa421f08130e80e3b49270575c87e06..a0915574a1d4f5555e49f70584e9761ecd75527a 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parse_node.h,v 1.4 1998/01/15 19:00:16 momjian Exp $
+ * $Id: parse_node.h,v 1.5 1998/01/17 04:53:46 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -32,6 +32,7 @@ typedef struct ParseState
        List       *p_rtable;
        List       *p_insert_columns;
        bool            p_hasAggs;
+       bool            p_hasSubLinks;
        bool            p_is_insert;
        bool            p_is_update;
        bool            p_is_rule;