cleanup
authorBruce Momjian
Sun, 23 Aug 1998 14:43:46 +0000 (14:43 +0000)
committerBruce Momjian
Sun, 23 Aug 1998 14:43:46 +0000 (14:43 +0000)
src/backend/parser/README
src/backend/parser/parse_target.c

index b67e1909d9e1ab11aac1136f5d323ca790db84bb..effa9008fa9c923a8423f04a21701307e9c645b7 100644 (file)
@@ -9,11 +9,11 @@ keywords.c    turn keywords into specific tokens
 gram.y     parse the tokens and fill query-type-specific structures
 analyze.c  handle post-parse processing for each query type
 parse_clause.c handle clauses like WHERE, ORDER BY, GROUP BY, ...
+parse_coerce.c used for coercing expressions of different types
 parse_expr.c   handle expressions like col, col + 3, x = 3 or x = 4
 parse_oper.c   handle operations in expressions
 parse_agg.c    handle aggregates, like SUM(col1),  AVG(col2), ...
 parse_func.c   handle functions, table.column and column identifiers
-
 parse_node.c   create nodes for various structures
 parse_target.c handle the result list of the query
 parse_relation.c support routines for tables and column handling
index a71df492799ce74d83af3a45e411462c3777a9d9..b54e1b6786dfb615d13fb61c0d305fbf55242eb7 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.21 1998/08/19 02:02:26 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.22 1998/08/23 14:43:46 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -187,6 +187,154 @@ printf("transformTargetIdent- attrtype_target = %d; type_mod = %d\n", attrtype_t
 } /* transformTargetIdent() */
 
 
+/* MakeTargetlistExpr()
+ * Make a TargetEntry from an expression.
+ * arrayRef is a list of transformed A_Indices.
+ *
+ * For type mismatches between expressions and targets, use the same
+ *  techniques as for function and operator type coersion.
+ * - thomas 1998-05-08
+ *
+ * Added resjunk flag and made extern so that it can be use by GROUP/
+ * ORDER BY a function or expersion not in the target_list
+ * -  [email protected] 1998-07-31 
+ */
+TargetEntry *
+MakeTargetlistExpr(ParseState *pstate,
+                    char *colname,
+                    Node *expr,
+                    List *arrayRef,
+                    int16 resjunk)
+{
+   Oid         type_id,
+               attrtype;
+   int32       type_mod,
+               attrtypmod;
+   int         resdomno;
+   Relation    rd;
+   bool        attrisset;
+   TargetEntry *tent;
+   Resdom     *resnode;
+
+   if (expr == NULL)
+       elog(ERROR, "MakeTargetlistExpr: invalid use of NULL expression");
+
+   type_id = exprType(expr);
+   if (nodeTag(expr) == T_Var)
+       type_mod = ((Var *) expr)->vartypmod;
+   else
+       type_mod = -1;
+
+   /* Processes target columns that will be receiving results */
+   if (pstate->p_is_insert || pstate->p_is_update)
+   {
+       /*
+        * insert or update query -- insert, update work only on one
+        * relation, so multiple occurence of same resdomno is bogus
+        */
+       rd = pstate->p_target_relation;
+       Assert(rd != NULL);
+       resdomno = attnameAttNum(rd, colname);
+       attrisset = attnameIsSet(rd, colname);
+       attrtype = attnumTypeId(rd, resdomno);
+       if ((arrayRef != NIL) && (lfirst(arrayRef) == NIL))
+           attrtype = GetArrayElementType(attrtype);
+       attrtypmod = rd->rd_att->attrs[resdomno - 1]->atttypmod;
+
+       /* Check for InvalidOid since that seems to indicate a NULL constant... */
+       if (type_id != InvalidOid)
+       {
+           /* Mismatch on types? then try to coerce to target...  */
+           if (attrtype != type_id)
+           {
+               Oid typelem;
+
+               if (arrayRef && !(((A_Indices *) lfirst(arrayRef))->lidx))
+                   typelem = typeidTypElem(attrtype);
+               else
+                   typelem = attrtype;
+
+               expr = CoerceTargetExpr(pstate, expr, type_id, typelem);
+
+               if (!HeapTupleIsValid(expr))
+                   elog(ERROR, "parser: attribute '%s' is of type '%s'"
+                        " but expression is of type '%s'"
+                        "\n\tYou will need to rewrite or cast the expression",
+                        colname,
+                        typeidTypeName(attrtype),
+                        typeidTypeName(type_id));
+           }
+
+#ifdef PARSEDEBUG
+printf("MakeTargetlistExpr: attrtypmod is %d\n", (int4) attrtypmod);
+#endif
+
+           /* Apparently going to a fixed-length string?
+            * Then explicitly size for storage...
+            */
+           if (attrtypmod > 0)
+               expr = SizeTargetExpr(pstate, expr, attrtype, attrtypmod);
+       }
+
+       if (arrayRef != NIL)
+       {
+           Expr       *target_expr;
+           Attr       *att = makeNode(Attr);
+           List       *ar = arrayRef;
+           List       *upperIndexpr = NIL;
+           List       *lowerIndexpr = NIL;
+
+           att->relname = pstrdup(RelationGetRelationName(rd)->data);
+           att->attrs = lcons(makeString(colname), NIL);
+           target_expr = (Expr *) ParseNestedFuncOrColumn(pstate, att,
+                                                          &pstate->p_last_resno,
+                                                          EXPR_COLUMN_FIRST);
+           while (ar != NIL)
+           {
+               A_Indices  *ind = lfirst(ar);
+
+               if (lowerIndexpr || (!upperIndexpr && ind->lidx))
+               {
+
+                   /*
+                    * XXX assume all lowerIndexpr is non-null in this
+                    * case
+                    */
+                   lowerIndexpr = lappend(lowerIndexpr, ind->lidx);
+               }
+               upperIndexpr = lappend(upperIndexpr, ind->uidx);
+               ar = lnext(ar);
+           }
+
+           expr = (Node *) make_array_set(target_expr,
+                                          upperIndexpr,
+                                          lowerIndexpr,
+                                          (Expr *) expr);
+           attrtype = attnumTypeId(rd, resdomno);
+           attrtypmod = get_atttypmod(RelationGetRelid(rd), resdomno);
+       }
+   }
+   else
+   {
+       resdomno = pstate->p_last_resno++;
+       attrtype = type_id;
+       attrtypmod = type_mod;
+   }
+
+   resnode = makeResdom((AttrNumber) resdomno,
+                        (Oid) attrtype,
+                        attrtypmod,
+                        colname,
+                        (Index) 0,
+                        (Oid) 0,
+                        resjunk);
+
+   tent = makeTargetEntry(resnode, expr);
+
+   return tent;
+} /* MakeTargetlistExpr() */
+
+
 /* transformTargetList()
  * Turns a list of ResTarget's into a list of TargetEntry's.
  */
@@ -299,7 +447,6 @@ printf("transformTargetList: decode T_Expr\n");
                        /* this is not an array assignment */
                        if (colname == NULL)
                        {
-
                            /*
                             * if you're wondering why this is here, look
                             * at the yacc grammar for why a name can be
@@ -559,154 +706,6 @@ printf("SizeTargetExpr: no conversion function for sizing\n");
 } /* SizeTargetExpr() */
 
 
-/* MakeTargetlistExpr()
- * Make a TargetEntry from an expression.
- * arrayRef is a list of transformed A_Indices.
- *
- * For type mismatches between expressions and targets, use the same
- *  techniques as for function and operator type coersion.
- * - thomas 1998-05-08
- *
- * Added resjunk flag and made extern so that it can be use by GROUP/
- * ORDER BY a function or expersion not in the target_list
- * -  [email protected] 1998-07-31 
- */
-TargetEntry *
-MakeTargetlistExpr(ParseState *pstate,
-                    char *colname,
-                    Node *expr,
-                    List *arrayRef,
-                    int16 resjunk)
-{
-   Oid         type_id,
-               attrtype;
-   int32       type_mod,
-               attrtypmod;
-   int         resdomno;
-   Relation    rd;
-   bool        attrisset;
-   TargetEntry *tent;
-   Resdom     *resnode;
-
-   if (expr == NULL)
-       elog(ERROR, "MakeTargetlistExpr: invalid use of NULL expression");
-
-   type_id = exprType(expr);
-   if (nodeTag(expr) == T_Var)
-       type_mod = ((Var *) expr)->vartypmod;
-   else
-       type_mod = -1;
-
-   /* Processes target columns that will be receiving results */
-   if (pstate->p_is_insert || pstate->p_is_update)
-   {
-       /*
-        * insert or update query -- insert, update work only on one
-        * relation, so multiple occurence of same resdomno is bogus
-        */
-       rd = pstate->p_target_relation;
-       Assert(rd != NULL);
-       resdomno = attnameAttNum(rd, colname);
-       attrisset = attnameIsSet(rd, colname);
-       attrtype = attnumTypeId(rd, resdomno);
-       if ((arrayRef != NIL) && (lfirst(arrayRef) == NIL))
-           attrtype = GetArrayElementType(attrtype);
-       attrtypmod = rd->rd_att->attrs[resdomno - 1]->atttypmod;
-
-       /* Check for InvalidOid since that seems to indicate a NULL constant... */
-       if (type_id != InvalidOid)
-       {
-           /* Mismatch on types? then try to coerce to target...  */
-           if (attrtype != type_id)
-           {
-               Oid typelem;
-
-               if (arrayRef && !(((A_Indices *) lfirst(arrayRef))->lidx))
-                   typelem = typeidTypElem(attrtype);
-               else
-                   typelem = attrtype;
-
-               expr = CoerceTargetExpr(pstate, expr, type_id, typelem);
-
-               if (!HeapTupleIsValid(expr))
-                   elog(ERROR, "parser: attribute '%s' is of type '%s'"
-                        " but expression is of type '%s'"
-                        "\n\tYou will need to rewrite or cast the expression",
-                        colname,
-                        typeidTypeName(attrtype),
-                        typeidTypeName(type_id));
-           }
-
-#ifdef PARSEDEBUG
-printf("MakeTargetlistExpr: attrtypmod is %d\n", (int4) attrtypmod);
-#endif
-
-           /* Apparently going to a fixed-length string?
-            * Then explicitly size for storage...
-            */
-           if (attrtypmod > 0)
-               expr = SizeTargetExpr(pstate, expr, attrtype, attrtypmod);
-       }
-
-       if (arrayRef != NIL)
-       {
-           Expr       *target_expr;
-           Attr       *att = makeNode(Attr);
-           List       *ar = arrayRef;
-           List       *upperIndexpr = NIL;
-           List       *lowerIndexpr = NIL;
-
-           att->relname = pstrdup(RelationGetRelationName(rd)->data);
-           att->attrs = lcons(makeString(colname), NIL);
-           target_expr = (Expr *) ParseNestedFuncOrColumn(pstate, att,
-                                                          &pstate->p_last_resno,
-                                                          EXPR_COLUMN_FIRST);
-           while (ar != NIL)
-           {
-               A_Indices  *ind = lfirst(ar);
-
-               if (lowerIndexpr || (!upperIndexpr && ind->lidx))
-               {
-
-                   /*
-                    * XXX assume all lowerIndexpr is non-null in this
-                    * case
-                    */
-                   lowerIndexpr = lappend(lowerIndexpr, ind->lidx);
-               }
-               upperIndexpr = lappend(upperIndexpr, ind->uidx);
-               ar = lnext(ar);
-           }
-
-           expr = (Node *) make_array_set(target_expr,
-                                          upperIndexpr,
-                                          lowerIndexpr,
-                                          (Expr *) expr);
-           attrtype = attnumTypeId(rd, resdomno);
-           attrtypmod = get_atttypmod(RelationGetRelid(rd), resdomno);
-       }
-   }
-   else
-   {
-       resdomno = pstate->p_last_resno++;
-       attrtype = type_id;
-       attrtypmod = type_mod;
-   }
-
-   resnode = makeResdom((AttrNumber) resdomno,
-                        (Oid) attrtype,
-                        attrtypmod,
-                        colname,
-                        (Index) 0,
-                        (Oid) 0,
-                        resjunk);
-
-   tent = makeTargetEntry(resnode, expr);
-
-   return tent;
-} /* MakeTargetlistExpr() */
-
-
 /*
  * makeTargetNames -
  *   generate a list of column names if not supplied or