Merge Resdom nodes into TargetEntry nodes to simplify code and save a
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 6 Apr 2005 16:34:07 +0000 (16:34 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 6 Apr 2005 16:34:07 +0000 (16:34 +0000)
few palloc's.  I also chose to eliminate the restype and restypmod fields
entirely, since they are redundant with information stored in the node's
contained expression; re-examining the expression at need seems simpler
and more reliable than trying to keep restype/restypmod up to date.

initdb forced due to change in contents of stored rules.

43 files changed:
src/backend/access/common/printtup.c
src/backend/commands/view.c
src/backend/executor/execJunk.c
src/backend/executor/execMain.c
src/backend/executor/execQual.c
src/backend/executor/execTuples.c
src/backend/executor/execUtils.c
src/backend/executor/functions.c
src/backend/executor/nodeSubplan.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/nodes/makefuncs.c
src/backend/nodes/outfuncs.c
src/backend/nodes/print.c
src/backend/nodes/readfuncs.c
src/backend/optimizer/path/allpaths.c
src/backend/optimizer/path/pathkeys.c
src/backend/optimizer/plan/createplan.c
src/backend/optimizer/plan/planner.c
src/backend/optimizer/plan/setrefs.c
src/backend/optimizer/plan/subselect.c
src/backend/optimizer/prep/prepjointree.c
src/backend/optimizer/prep/preptlist.c
src/backend/optimizer/prep/prepunion.c
src/backend/optimizer/util/clauses.c
src/backend/optimizer/util/pathnode.c
src/backend/optimizer/util/plancat.c
src/backend/optimizer/util/tlist.c
src/backend/parser/analyze.c
src/backend/parser/parse_clause.c
src/backend/parser/parse_expr.c
src/backend/parser/parse_relation.c
src/backend/parser/parse_target.c
src/backend/rewrite/rewriteDefine.c
src/backend/rewrite/rewriteHandler.c
src/backend/utils/adt/ruleutils.c
src/include/catalog/catversion.h
src/include/nodes/makefuncs.h
src/include/nodes/nodes.h
src/include/nodes/parsenodes.h
src/include/nodes/primnodes.h
src/include/optimizer/tlist.h
src/tools/backend/index.html

index 6f44533822baa7e35a70994e9447aa24e993074a..e78dc19a03fddf18d624449f4e38de158a5009d1 100644 (file)
@@ -9,7 +9,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/access/common/printtup.c,v 1.87 2005/03/16 21:38:04 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/access/common/printtup.c,v 1.88 2005/04/06 16:34:04 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -190,14 +190,14 @@ SendRowDescriptionMessage(TupleDesc typeinfo, List *targetlist, int16 *formats)
        {
            /* Do we have a non-resjunk tlist item? */
            while (tlist_item &&
-                  ((TargetEntry *) lfirst(tlist_item))->resdom->resjunk)
+                  ((TargetEntry *) lfirst(tlist_item))->resjunk)
                tlist_item = lnext(tlist_item);
            if (tlist_item)
            {
-               Resdom     *res = ((TargetEntry *) lfirst(tlist_item))->resdom;
+               TargetEntry *tle = (TargetEntry *) lfirst(tlist_item);
 
-               pq_sendint(&buf, res->resorigtbl, 4);
-               pq_sendint(&buf, res->resorigcol, 2);
+               pq_sendint(&buf, tle->resorigtbl, 4);
+               pq_sendint(&buf, tle->resorigcol, 2);
                tlist_item = lnext(tlist_item);
            }
            else
index 10caef1375b3f0fe3878655de51efe8bc8d07cca..21609e063fa83ec665ff3a156b96b07e0d72a585 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.87 2005/02/02 06:36:00 neilc Exp $
+ *   $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.88 2005/04/06 16:34:04 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -22,6 +22,7 @@
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
 #include "optimizer/clauses.h"
+#include "parser/parse_expr.h"
 #include "parser/parse_relation.h"
 #include "rewrite/rewriteDefine.h"
 #include "rewrite/rewriteManip.h"
@@ -106,18 +107,17 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace)
    attrList = NIL;
    foreach(t, tlist)
    {
-       TargetEntry *entry = lfirst(t);
-       Resdom     *res = entry->resdom;
+       TargetEntry *tle = lfirst(t);
 
-       if (!res->resjunk)
+       if (!tle->resjunk)
        {
            ColumnDef  *def = makeNode(ColumnDef);
            TypeName   *typename = makeNode(TypeName);
 
-           def->colname = pstrdup(res->resname);
+           def->colname = pstrdup(tle->resname);
 
-           typename->typeid = res->restype;
-           typename->typmod = res->restypmod;
+           typename->typeid = exprType((Node *) tle->expr);
+           typename->typmod = exprTypmod((Node *) tle->expr);
            def->typename = typename;
 
            def->inhcount = 0;
index 2dfd90b51fa7ddfab3a8365b580fdd785d276530..1cf403f88dd538bc403a78878535c9161d7f1fc9 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/executor/execJunk.c,v 1.48 2005/03/16 21:38:06 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/executor/execJunk.c,v 1.49 2005/04/06 16:34:04 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -31,8 +31,8 @@
  * of some system attributes like "ctid" or rule locks.
  *
  * The general idea is the following: A target list consists of a list of
- * Resdom nodes & expression pairs. Each Resdom node has an attribute
- * called 'resjunk'. If the value of this attribute is true then the
+ * TargetEntry nodes containing expressions. Each TargetEntry has a field
+ * called 'resjunk'. If the value of this field is true then the
  * corresponding attribute is a "junk" attribute.
  *
  * When we initialize a plan we call 'ExecInitJunkFilter' to create
@@ -101,11 +101,10 @@ ExecInitJunkFilter(List *targetList, bool hasoid, TupleTableSlot *slot)
        foreach(t, targetList)
        {
            TargetEntry *tle = lfirst(t);
-           Resdom     *resdom = tle->resdom;
 
-           if (!resdom->resjunk)
+           if (!tle->resjunk)
            {
-               cleanMap[cleanResno - 1] = resdom->resno;
+               cleanMap[cleanResno - 1] = tle->resno;
                cleanResno++;
            }
        }
@@ -177,12 +176,11 @@ ExecInitJunkFilterConversion(List *targetList,
            for (;;)
            {
                TargetEntry *tle = lfirst(t);
-               Resdom     *resdom = tle->resdom;
 
                t = lnext(t);
-               if (!resdom->resjunk)
+               if (!tle->resjunk)
                {
-                   cleanMap[i] = resdom->resno;
+                   cleanMap[i] = tle->resno;
                    break;
                }
            }
@@ -228,13 +226,12 @@ ExecGetJunkAttribute(JunkFilter *junkfilter,
    foreach(t, junkfilter->jf_targetList)
    {
        TargetEntry *tle = lfirst(t);
-       Resdom     *resdom = tle->resdom;
 
-       if (resdom->resjunk && resdom->resname &&
-           (strcmp(resdom->resname, attrName) == 0))
+       if (tle->resjunk && tle->resname &&
+           (strcmp(tle->resname, attrName) == 0))
        {
            /* We found it ! */
-           *value = slot_getattr(slot, resdom->resno, isNull);
+           *value = slot_getattr(slot, tle->resno, isNull);
            return true;
        }
    }
index 304f1ba6b10924bd1d712e754eb28a8421c7b02f..0ba61044222836e3d9e0c93f01247fc6b45a5b33 100644 (file)
@@ -26,7 +26,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.244 2005/03/25 21:57:58 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.245 2005/04/06 16:34:04 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -640,7 +640,7 @@ InitPlan(QueryDesc *queryDesc, bool explainOnly)
                {
                    TargetEntry *tle = (TargetEntry *) lfirst(tlist);
 
-                   if (tle->resdom->resjunk)
+                   if (tle->resjunk)
                    {
                        junk_filter_needed = true;
                        break;
index 9d915af91a5d9622135b218dee1d729655d3753d..67c962398e8eaedeca78523b8ba5b6a249a070dd 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.175 2005/03/29 00:16:59 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.176 2005/04/06 16:34:04 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -3467,7 +3467,7 @@ ExecCleanTargetListLength(List *targetlist)
        TargetEntry *curTle = (TargetEntry *) lfirst(tl);
 
        Assert(IsA(curTle, TargetEntry));
-       if (!curTle->resdom->resjunk)
+       if (!curTle->resjunk)
            len++;
    }
    return len;
@@ -3516,7 +3516,7 @@ ExecTargetList(List *targetlist,
    {
        GenericExprState *gstate = (GenericExprState *) lfirst(tl);
        TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
-       AttrNumber  resind = tle->resdom->resno - 1;
+       AttrNumber  resind = tle->resno - 1;
 
        values[resind] = ExecEvalExpr(gstate->arg,
                                      econtext,
@@ -3568,7 +3568,7 @@ ExecTargetList(List *targetlist,
            {
                GenericExprState *gstate = (GenericExprState *) lfirst(tl);
                TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
-               AttrNumber  resind = tle->resdom->resno - 1;
+               AttrNumber  resind = tle->resno - 1;
 
                if (itemIsDone[resind] == ExprEndResult)
                {
@@ -3602,7 +3602,7 @@ ExecTargetList(List *targetlist,
                {
                    GenericExprState *gstate = (GenericExprState *) lfirst(tl);
                    TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
-                   AttrNumber  resind = tle->resdom->resno - 1;
+                   AttrNumber  resind = tle->resno - 1;
 
                    while (itemIsDone[resind] == ExprMultipleResult)
                    {
index 7941cebad6b8b008c0908d5bf791c83ac76743a5..1c82a3b64be529df9a72911e7abefeb2499ef096 100644 (file)
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/executor/execTuples.c,v 1.86 2005/03/17 15:25:51 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/executor/execTuples.c,v 1.87 2005/04/06 16:34:04 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -784,15 +784,14 @@ ExecTypeFromTLInternal(List *targetList, bool hasoid, bool skipjunk)
    foreach(l, targetList)
    {
        TargetEntry *tle = lfirst(l);
-       Resdom     *resdom = tle->resdom;
 
-       if (skipjunk && resdom->resjunk)
+       if (skipjunk && tle->resjunk)
            continue;
        TupleDescInitEntry(typeInfo,
                           cur_resno++,
-                          resdom->resname,
-                          resdom->restype,
-                          resdom->restypmod,
+                          tle->resname,
+                          exprType((Node *) tle->expr),
+                          exprTypmod((Node *) tle->expr),
                           0);
    }
 
index b1840b45cf963ec833a95aa5e013e5486cb60be0..820c04291329b070c0278ef070ed2d8bba2d7c13 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.119 2005/03/21 01:24:03 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.120 2005/04/06 16:34:04 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -561,7 +561,7 @@ ExecBuildProjectionInfo(List *targetList,
            Var        *variable = (Var *) gstate->arg->expr;
            AttrNumber  attnum = variable->varattno;
            TargetEntry *tle = (TargetEntry *) gstate->xprstate.expr;
-           AttrNumber  resind = tle->resdom->resno - 1;
+           AttrNumber  resind = tle->resno - 1;
 
            Assert(resind >= 0 && resind < len);
            varNumbers[resind] = attnum;
index d2e101a2d616a007a54c859b4268f7ea50f73926..521d656ff16d6db0569e57093958a0d9a4e1beee 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.95 2005/03/31 22:46:08 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.96 2005/04/06 16:34:04 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -935,7 +935,7 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList,
                            format_type_be(rettype)),
             errdetail("Final SELECT must return exactly one column.")));
 
-       restype = ((TargetEntry *) linitial(tlist))->resdom->restype;
+       restype = exprType((Node *) ((TargetEntry *) linitial(tlist))->expr);
        if (!IsBinaryCoercible(restype, rettype))
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
@@ -961,7 +961,7 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList,
         */
        if (tlistlen == 1)
        {
-           restype = ((TargetEntry *) linitial(tlist))->resdom->restype;
+           restype = exprType((Node *) ((TargetEntry *) linitial(tlist))->expr);
            if (IsBinaryCoercible(restype, rettype))
                return false;   /* NOT returning whole tuple */
        }
@@ -996,7 +996,7 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList,
            Oid         tletype;
            Oid         atttype;
 
-           if (tle->resdom->resjunk)
+           if (tle->resjunk)
                continue;
 
            do
index 7d40fe8b1ed9f70aad6398c8cba9f2a597bbdb24..de3187e2472b98b39da4767bd7ff6b5d1e021599 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/executor/nodeSubplan.c,v 1.67 2005/03/16 21:38:08 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/executor/nodeSubplan.c,v 1.68 2005/04/06 16:34:04 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -828,12 +828,10 @@ ExecInitSubPlan(SubPlanState *node, EState *estate)
            /* Process lefthand argument */
            exstate = (ExprState *) linitial(fstate->args);
            expr = exstate->expr;
-           tle = makeTargetEntry(makeResdom(i,
-                                            exprType((Node *) expr),
-                                            exprTypmod((Node *) expr),
-                                            NULL,
-                                            false),
-                                 expr);
+           tle = makeTargetEntry(expr,
+                                 i,
+                                 NULL,
+                                 false);
            tlestate = makeNode(GenericExprState);
            tlestate->xprstate.expr = (Expr *) tle;
            tlestate->xprstate.evalfunc = NULL;
@@ -844,12 +842,10 @@ ExecInitSubPlan(SubPlanState *node, EState *estate)
            /* Process righthand argument */
            exstate = (ExprState *) lsecond(fstate->args);
            expr = exstate->expr;
-           tle = makeTargetEntry(makeResdom(i,
-                                            exprType((Node *) expr),
-                                            exprTypmod((Node *) expr),
-                                            NULL,
-                                            false),
-                                 expr);
+           tle = makeTargetEntry(expr,
+                                 i,
+                                 NULL,
+                                 false);
            tlestate = makeNode(GenericExprState);
            tlestate->xprstate.expr = (Expr *) tle;
            tlestate->xprstate.evalfunc = NULL;
index c2130e370d4b8b8277725d131c617d1e11f9e40b..e314959e3739a22ef8321c66051de657b1bf620d 100644 (file)
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.299 2005/03/29 17:58:50 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.300 2005/04/06 16:34:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -539,26 +539,6 @@ _copyLimit(Limit *from)
  * ****************************************************************
  */
 
-/*
- * _copyResdom
- */
-static Resdom *
-_copyResdom(Resdom *from)
-{
-   Resdom     *newnode = makeNode(Resdom);
-
-   COPY_SCALAR_FIELD(resno);
-   COPY_SCALAR_FIELD(restype);
-   COPY_SCALAR_FIELD(restypmod);
-   COPY_STRING_FIELD(resname);
-   COPY_SCALAR_FIELD(ressortgroupref);
-   COPY_SCALAR_FIELD(resorigtbl);
-   COPY_SCALAR_FIELD(resorigcol);
-   COPY_SCALAR_FIELD(resjunk);
-
-   return newnode;
-}
-
 /*
  * _copyAlias
  */
@@ -1077,8 +1057,13 @@ _copyTargetEntry(TargetEntry *from)
 {
    TargetEntry *newnode = makeNode(TargetEntry);
 
-   COPY_NODE_FIELD(resdom);
    COPY_NODE_FIELD(expr);
+   COPY_SCALAR_FIELD(resno);
+   COPY_STRING_FIELD(resname);
+   COPY_SCALAR_FIELD(ressortgroupref);
+   COPY_SCALAR_FIELD(resorigtbl);
+   COPY_SCALAR_FIELD(resorigcol);
+   COPY_SCALAR_FIELD(resjunk);
 
    return newnode;
 }
@@ -2670,9 +2655,6 @@ copyObject(void *from)
            /*
             * PRIMITIVE NODES
             */
-       case T_Resdom:
-           retval = _copyResdom(from);
-           break;
        case T_Alias:
            retval = _copyAlias(from);
            break;
index bcf8c36393725505e5a7ee600b577dd47d061326..958e320b47d4b18646e90bf6f2fc46ead0fc12d8 100644 (file)
@@ -18,7 +18,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.238 2005/03/29 17:58:50 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.239 2005/04/06 16:34:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
  * Stuff from primnodes.h
  */
 
-static bool
-_equalResdom(Resdom *a, Resdom *b)
-{
-   COMPARE_SCALAR_FIELD(resno);
-   COMPARE_SCALAR_FIELD(restype);
-   COMPARE_SCALAR_FIELD(restypmod);
-   COMPARE_STRING_FIELD(resname);
-   COMPARE_SCALAR_FIELD(ressortgroupref);
-   COMPARE_SCALAR_FIELD(resorigtbl);
-   COMPARE_SCALAR_FIELD(resorigcol);
-   COMPARE_SCALAR_FIELD(resjunk);
-
-   return true;
-}
-
 static bool
 _equalAlias(Alias *a, Alias *b)
 {
@@ -546,8 +531,13 @@ _equalSetToDefault(SetToDefault *a, SetToDefault *b)
 static bool
 _equalTargetEntry(TargetEntry *a, TargetEntry *b)
 {
-   COMPARE_NODE_FIELD(resdom);
    COMPARE_NODE_FIELD(expr);
+   COMPARE_SCALAR_FIELD(resno);
+   COMPARE_STRING_FIELD(resname);
+   COMPARE_SCALAR_FIELD(ressortgroupref);
+   COMPARE_SCALAR_FIELD(resorigtbl);
+   COMPARE_SCALAR_FIELD(resorigcol);
+   COMPARE_SCALAR_FIELD(resjunk);
 
    return true;
 }
@@ -1814,9 +1804,6 @@ equal(void *a, void *b)
            /*
             * PRIMITIVE NODES
             */
-       case T_Resdom:
-           retval = _equalResdom(a, b);
-           break;
        case T_Alias:
            retval = _equalAlias(a, b);
            break;
index 026b962bb992b9a2fc01df1ebefac4371adb72df..e1e6c3da8361b2835781d3f8947e825d05355a13 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/nodes/makefuncs.c,v 1.46 2004/12/31 21:59:55 pgsql Exp $
+ *   $PostgreSQL: pgsql/src/backend/nodes/makefuncs.c,v 1.47 2005/04/06 16:34:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -87,48 +87,49 @@ makeVar(Index varno,
 
 /*
  * makeTargetEntry -
- *   creates a TargetEntry node (contains a Resdom)
+ *   creates a TargetEntry node
  */
 TargetEntry *
-makeTargetEntry(Resdom *resdom, Expr *expr)
+makeTargetEntry(Expr *expr,
+               AttrNumber resno,
+               char *resname,
+               bool resjunk)
 {
-   TargetEntry *rt = makeNode(TargetEntry);
+   TargetEntry *tle = makeNode(TargetEntry);
 
-   rt->resdom = resdom;
-   rt->expr = expr;
-   return rt;
-}
-
-/*
- * makeResdom -
- *   creates a Resdom (Result Domain) node
- */
-Resdom *
-makeResdom(AttrNumber resno,
-          Oid restype,
-          int32 restypmod,
-          char *resname,
-          bool resjunk)
-{
-   Resdom     *resdom = makeNode(Resdom);
-
-   resdom->resno = resno;
-   resdom->restype = restype;
-   resdom->restypmod = restypmod;
-   resdom->resname = resname;
+   tle->expr = expr;
+   tle->resno = resno;
+   tle->resname = resname;
 
    /*
     * We always set these fields to 0. If the caller wants to change them
     * he must do so explicitly.  Few callers do that, so omitting these
     * arguments reduces the chance of error.
     */
-   resdom->ressortgroupref = 0;
-   resdom->resorigtbl = InvalidOid;
-   resdom->resorigcol = 0;
+   tle->ressortgroupref = 0;
+   tle->resorigtbl = InvalidOid;
+   tle->resorigcol = 0;
+
+   tle->resjunk = resjunk;
 
-   resdom->resjunk = resjunk;
+   return tle;
+}
+
+/*
+ * flatCopyTargetEntry -
+ *   duplicate a TargetEntry, but don't copy substructure
+ *
+ * This is commonly used when we just want to modify the resno or substitute
+ * a new expression.
+ */
+TargetEntry *
+flatCopyTargetEntry(TargetEntry *src_tle)
+{
+   TargetEntry *tle = makeNode(TargetEntry);
 
-   return resdom;
+   Assert(IsA(src_tle, TargetEntry));
+   memcpy(tle, src_tle, sizeof(TargetEntry));
+   return tle;
 }
 
 /*
index bb2b2c35f907a0fb228d101bdc8423669af9811f..91a7abf5749327c968432cac9e4321354ac624c1 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.245 2004/12/31 21:59:55 pgsql Exp $
+ *   $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.246 2005/04/06 16:34:05 tgl Exp $
  *
  * NOTES
  *   Every node type that can appear in stored rules' parsetrees *must*
@@ -520,21 +520,6 @@ _outHash(StringInfo str, Hash *node)
  *
  *****************************************************************************/
 
-static void
-_outResdom(StringInfo str, Resdom *node)
-{
-   WRITE_NODE_TYPE("RESDOM");
-
-   WRITE_INT_FIELD(resno);
-   WRITE_OID_FIELD(restype);
-   WRITE_INT_FIELD(restypmod);
-   WRITE_STRING_FIELD(resname);
-   WRITE_UINT_FIELD(ressortgroupref);
-   WRITE_OID_FIELD(resorigtbl);
-   WRITE_INT_FIELD(resorigcol);
-   WRITE_BOOL_FIELD(resjunk);
-}
-
 static void
 _outAlias(StringInfo str, Alias *node)
 {
@@ -900,8 +885,13 @@ _outTargetEntry(StringInfo str, TargetEntry *node)
 {
    WRITE_NODE_TYPE("TARGETENTRY");
 
-   WRITE_NODE_FIELD(resdom);
    WRITE_NODE_FIELD(expr);
+   WRITE_INT_FIELD(resno);
+   WRITE_STRING_FIELD(resname);
+   WRITE_UINT_FIELD(ressortgroupref);
+   WRITE_OID_FIELD(resorigtbl);
+   WRITE_INT_FIELD(resorigcol);
+   WRITE_BOOL_FIELD(resjunk);
 }
 
 static void
@@ -1684,9 +1674,6 @@ _outNode(StringInfo str, void *obj)
            case T_Hash:
                _outHash(str, obj);
                break;
-           case T_Resdom:
-               _outResdom(str, obj);
-               break;
            case T_Alias:
                _outAlias(str, obj);
                break;
index e62d731a6cfd5627d541c2bc92c0319889cc5366..35bb99b62fdc7893d9561cd2736a6e686feb99c7 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/nodes/print.c,v 1.73 2005/03/16 21:38:08 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/nodes/print.c,v 1.74 2005/04/06 16:34:05 tgl Exp $
  *
  * HISTORY
  *   AUTHOR            DATE            MAJOR EVENT
@@ -449,10 +449,10 @@ print_tl(List *tlist, List *rtable)
    {
        TargetEntry *tle = (TargetEntry *) lfirst(tl);
 
-       printf("\t%d %s\t", tle->resdom->resno,
-              tle->resdom->resname ? tle->resdom->resname : "<null>");
-       if (tle->resdom->ressortgroupref != 0)
-           printf("(%u):\t", tle->resdom->ressortgroupref);
+       printf("\t%d %s\t", tle->resno,
+              tle->resname ? tle->resname : "<null>");
+       if (tle->ressortgroupref != 0)
+           printf("(%u):\t", tle->ressortgroupref);
        else
            printf("    :\t");
        print_expr((Node *) tle->expr, rtable);
index f04668b6be721c1f6b0fcf6d5a51370d4e159c3c..f457d0633154036be88823ffcb967a2ba043d1a4 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.175 2004/12/31 21:59:55 pgsql Exp $
+ *   $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.176 2005/04/06 16:34:05 tgl Exp $
  *
  * NOTES
  *   Path and Plan nodes do not have any readfuncs support, because we
@@ -238,26 +238,6 @@ _readSetOperationStmt(void)
  * Stuff from primnodes.h.
  */
 
-/*
- * _readResdom
- */
-static Resdom *
-_readResdom(void)
-{
-   READ_LOCALS(Resdom);
-
-   READ_INT_FIELD(resno);
-   READ_OID_FIELD(restype);
-   READ_INT_FIELD(restypmod);
-   READ_STRING_FIELD(resname);
-   READ_UINT_FIELD(ressortgroupref);
-   READ_OID_FIELD(resorigtbl);
-   READ_INT_FIELD(resorigcol);
-   READ_BOOL_FIELD(resjunk);
-
-   READ_DONE();
-}
-
 static Alias *
 _readAlias(void)
 {
@@ -787,8 +767,13 @@ _readTargetEntry(void)
 {
    READ_LOCALS(TargetEntry);
 
-   READ_NODE_FIELD(resdom);
    READ_NODE_FIELD(expr);
+   READ_INT_FIELD(resno);
+   READ_STRING_FIELD(resname);
+   READ_UINT_FIELD(ressortgroupref);
+   READ_OID_FIELD(resorigtbl);
+   READ_INT_FIELD(resorigcol);
+   READ_BOOL_FIELD(resjunk);
 
    READ_DONE();
 }
@@ -952,8 +937,6 @@ parseNodeString(void)
        return_value = _readGroupClause();
    else if (MATCH("SETOPERATIONSTMT", 16))
        return_value = _readSetOperationStmt();
-   else if (MATCH("RESDOM", 6))
-       return_value = _readResdom();
    else if (MATCH("ALIAS", 5))
        return_value = _readAlias();
    else if (MATCH("RANGEVAR", 8))
index 42d8761845c5791e2ea922ba5baafb4bd99b0b2e..1651310845020be7259831073af78b1095af25c8 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.124 2005/03/10 23:21:21 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.125 2005/04/06 16:34:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -29,6 +29,7 @@
 #include "optimizer/var.h"
 #include "parser/parsetree.h"
 #include "parser/parse_clause.h"
+#include "parser/parse_expr.h"
 #include "rewrite/rewriteManip.h"
 
 
@@ -656,12 +657,12 @@ compare_tlist_datatypes(List *tlist, List *colTypes,
    {
        TargetEntry *tle = (TargetEntry *) lfirst(l);
 
-       if (tle->resdom->resjunk)
+       if (tle->resjunk)
            continue;           /* ignore resjunk columns */
        if (colType == NULL)
            elog(ERROR, "wrong number of tlist entries");
-       if (tle->resdom->restype != lfirst_oid(colType))
-           differentTypes[tle->resdom->resno] = true;
+       if (exprType((Node *) tle->expr) != lfirst_oid(colType))
+           differentTypes[tle->resno] = true;
        colType = lnext(colType);
    }
    if (colType != NULL)
@@ -740,7 +741,7 @@ qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual,
        /* Must find the tlist element referenced by the Var */
        tle = get_tle_by_resno(subquery->targetList, var->varattno);
        Assert(tle != NULL);
-       Assert(!tle->resdom->resjunk);
+       Assert(!tle->resjunk);
 
        /* If subquery uses DISTINCT or DISTINCT ON, check point 3 */
        if (subquery->distinctClause != NIL &&
index 0e23045fef93a55100933d1ce266fc8673c115ea..766aa1d11651bfeb01cfa7438461e2208a04f08b 100644 (file)
@@ -11,7 +11,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.65 2005/03/27 06:29:36 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.66 2005/04/06 16:34:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -791,7 +791,7 @@ build_subquery_pathkeys(Query *root, RelOptInfo *rel, Query *subquery)
            {
                TargetEntry *tle = (TargetEntry *) lfirst(k);
 
-               if (!tle->resdom->resjunk &&
+               if (!tle->resjunk &&
                    equal(tle->expr, sub_key))
                {
                    /* Found a representation for this sub_key */
@@ -800,9 +800,9 @@ build_subquery_pathkeys(Query *root, RelOptInfo *rel, Query *subquery)
                    int         score;
 
                    outer_var = makeVar(rel->relid,
-                                       tle->resdom->resno,
-                                       tle->resdom->restype,
-                                       tle->resdom->restypmod,
+                                       tle->resno,
+                                       exprType((Node *) tle->expr),
+                                       exprTypmod((Node *) tle->expr),
                                        0);
                    outer_item = makePathKeyItem((Node *) outer_var,
                                                 sub_item->sortop,
index f4a76a9b3b49437cd087970cd4567774173be4a7..41e2edceb26511d53b7b908d19b8350a91038cc8 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.177 2005/03/27 06:29:38 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.178 2005/04/06 16:34:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -259,7 +259,7 @@ static List *
 build_relation_tlist(RelOptInfo *rel)
 {
    List       *tlist = NIL;
-   int         resdomno = 1;
+   int         resno = 1;
    ListCell   *v;
 
    foreach(v, rel->reltargetlist)
@@ -267,8 +267,11 @@ build_relation_tlist(RelOptInfo *rel)
        /* Do we really need to copy here?  Not sure */
        Var        *var = (Var *) copyObject(lfirst(v));
 
-       tlist = lappend(tlist, create_tl_element(var, resdomno));
-       resdomno++;
+       tlist = lappend(tlist, makeTargetEntry((Expr *) var,
+                                              resno,
+                                              NULL,
+                                              false));
+       resno++;
    }
    return tlist;
 }
@@ -557,20 +560,18 @@ create_unique_plan(Query *root, UniquePath *best_path)
        Node       *uniqexpr = lfirst(l);
        TargetEntry *tle;
 
-       tle = tlistentry_member(uniqexpr, newtlist);
+       tle = tlist_member(uniqexpr, newtlist);
        if (!tle)
        {
-           tle = makeTargetEntry(makeResdom(nextresno,
-                                            exprType(uniqexpr),
-                                            exprTypmod(uniqexpr),
-                                            NULL,
-                                            false),
-                                 (Expr *) uniqexpr);
+           tle = makeTargetEntry((Expr *) uniqexpr,
+                                 nextresno,
+                                 NULL,
+                                 false);
            newtlist = lappend(newtlist, tle);
            nextresno++;
            newitems = true;
        }
-       groupColIdx[groupColPos++] = tle->resdom->resno;
+       groupColIdx[groupColPos++] = tle->resno;
    }
 
    if (newitems)
@@ -1844,7 +1845,7 @@ make_sort_from_pathkeys(Query *root, Plan *lefttree, List *pathkeys)
    {
        List       *keysublist = (List *) lfirst(i);
        PathKeyItem *pathkey = NULL;
-       Resdom     *resdom = NULL;
+       TargetEntry *tle = NULL;
        ListCell   *j;
 
        /*
@@ -1863,11 +1864,11 @@ make_sort_from_pathkeys(Query *root, Plan *lefttree, List *pathkeys)
        {
            pathkey = (PathKeyItem *) lfirst(j);
            Assert(IsA(pathkey, PathKeyItem));
-           resdom = tlist_member(pathkey->key, tlist);
-           if (resdom)
+           tle = tlist_member(pathkey->key, tlist);
+           if (tle)
                break;
        }
-       if (!resdom)
+       if (!tle)
        {
            /* No matching Var; look for a computable expression */
            foreach(j, keysublist)
@@ -1901,14 +1902,11 @@ make_sort_from_pathkeys(Query *root, Plan *lefttree, List *pathkeys)
            /*
             * Add resjunk entry to input's tlist
             */
-           resdom = makeResdom(list_length(tlist) + 1,
-                               exprType(pathkey->key),
-                               exprTypmod(pathkey->key),
-                               NULL,
-                               true);
-           tlist = lappend(tlist,
-                           makeTargetEntry(resdom,
-                                           (Expr *) pathkey->key));
+           tle = makeTargetEntry((Expr *) pathkey->key,
+                                 list_length(tlist) + 1,
+                                 NULL,
+                                 true);
+           tlist = lappend(tlist, tle);
            lefttree->targetlist = tlist;       /* just in case NIL before */
        }
 
@@ -1918,7 +1916,7 @@ make_sort_from_pathkeys(Query *root, Plan *lefttree, List *pathkeys)
         * scenarios where multiple mergejoinable clauses mention the same
         * var, for example.)  So enter it only once in the sort arrays.
         */
-       numsortkeys = add_sort_column(resdom->resno, pathkey->sortop,
+       numsortkeys = add_sort_column(tle->resno, pathkey->sortop,
                                 numsortkeys, sortColIdx, sortOperators);
    }
 
@@ -1964,7 +1962,7 @@ make_sort_from_sortclauses(Query *root, List *sortcls, Plan *lefttree)
         * parser should have removed 'em, but no point in sorting
         * redundantly.
         */
-       numsortkeys = add_sort_column(tle->resdom->resno, sortcl->sortop,
+       numsortkeys = add_sort_column(tle->resno, sortcl->sortop,
                                 numsortkeys, sortColIdx, sortOperators);
    }
 
@@ -2020,7 +2018,7 @@ make_sort_from_groupcols(Query *root,
         * parser should have removed 'em, but no point in sorting
         * redundantly.
         */
-       numsortkeys = add_sort_column(tle->resdom->resno, grpcl->sortop,
+       numsortkeys = add_sort_column(tle->resno, grpcl->sortop,
                                 numsortkeys, sortColIdx, sortOperators);
        grpno++;
    }
@@ -2253,7 +2251,7 @@ make_unique(Plan *lefttree, List *distinctList)
        SortClause *sortcl = (SortClause *) lfirst(slitem);
        TargetEntry *tle = get_sortgroupclause_tle(sortcl, plan->targetlist);
 
-       uniqColIdx[keyno++] = tle->resdom->resno;
+       uniqColIdx[keyno++] = tle->resno;
    }
 
    node->numCols = numCols;
@@ -2311,7 +2309,7 @@ make_setop(SetOpCmd cmd, Plan *lefttree,
        SortClause *sortcl = (SortClause *) lfirst(slitem);
        TargetEntry *tle = get_sortgroupclause_tle(sortcl, plan->targetlist);
 
-       dupColIdx[keyno++] = tle->resdom->resno;
+       dupColIdx[keyno++] = tle->resno;
    }
 
    node->cmd = cmd;
index 5f3c7510cdd90450e35d97412915855d663c2fdc..9f898997f0064882ddf981ab4074afae6d71ff0b 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.181 2005/03/28 00:58:23 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.182 2005/04/06 16:34:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1349,7 +1349,7 @@ hash_safe_grouping(Query *parse)
        Operator    optup;
        bool        oprcanhash;
 
-       optup = equality_oper(tle->resdom->restype, true);
+       optup = equality_oper(exprType((Node *) tle->expr), true);
        if (!optup)
            return false;
        oprcanhash = ((Form_pg_operator) GETSTRUCT(optup))->oprcanhash;
@@ -1467,18 +1467,16 @@ make_subplanTargetList(Query *parse,
            }
            if (!sl)
            {
-               te = makeTargetEntry(makeResdom(list_length(sub_tlist) + 1,
-                                               exprType(groupexpr),
-                                               exprTypmod(groupexpr),
-                                               NULL,
-                                               false),
-                                    (Expr *) groupexpr);
+               te = makeTargetEntry((Expr *) groupexpr,
+                                    list_length(sub_tlist) + 1,
+                                    NULL,
+                                    false);
                sub_tlist = lappend(sub_tlist, te);
                *need_tlist_eval = true;        /* it's not flat anymore */
            }
 
            /* and save its resno */
-           grpColIdx[keyno++] = te->resdom->resno;
+           grpColIdx[keyno++] = te->resno;
        }
    }
 
@@ -1528,7 +1526,7 @@ locate_grouping_columns(Query *parse,
        if (!sl)
            elog(ERROR, "failed to locate grouping columns");
 
-       groupColIdx[keyno++] = te->resdom->resno;
+       groupColIdx[keyno++] = te->resno;
    }
 }
 
@@ -1554,17 +1552,16 @@ postprocess_setop_tlist(List *new_tlist, List *orig_tlist)
        TargetEntry *orig_tle;
 
        /* ignore resjunk columns in setop result */
-       if (new_tle->resdom->resjunk)
+       if (new_tle->resjunk)
            continue;
 
        Assert(orig_tlist_item != NULL);
        orig_tle = (TargetEntry *) lfirst(orig_tlist_item);
        orig_tlist_item = lnext(orig_tlist_item);
-       if (orig_tle->resdom->resjunk)  /* should not happen */
+       if (orig_tle->resjunk)          /* should not happen */
            elog(ERROR, "resjunk output columns are not implemented");
-       Assert(new_tle->resdom->resno == orig_tle->resdom->resno);
-       Assert(new_tle->resdom->restype == orig_tle->resdom->restype);
-       new_tle->resdom->ressortgroupref = orig_tle->resdom->ressortgroupref;
+       Assert(new_tle->resno == orig_tle->resno);
+       new_tle->ressortgroupref = orig_tle->ressortgroupref;
    }
    if (orig_tlist_item != NULL)
        elog(ERROR, "resjunk output columns are not implemented");
index df3fbbe3aebabc3e691199333d4a1798c19eebec..075c6a339dfb2600e7c598c069bdbabab01ac828 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/optimizer/plan/setrefs.c,v 1.105 2004/12/31 22:00:09 pgsql Exp $
+ *   $PostgreSQL: pgsql/src/backend/optimizer/plan/setrefs.c,v 1.106 2005/04/06 16:34:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -20,6 +20,7 @@
 #include "optimizer/planmain.h"
 #include "optimizer/tlist.h"
 #include "optimizer/var.h"
+#include "parser/parse_expr.h"
 #include "parser/parsetree.h"
 #include "utils/lsyscache.h"
 
@@ -462,9 +463,9 @@ set_uppernode_references(Plan *plan, Index subvarno)
                                                 subvarno,
                                                 subplan_targetlist,
                                                 tlist_has_non_vars);
-       output_targetlist = lappend(output_targetlist,
-                                   makeTargetEntry(tle->resdom,
-                                                   (Expr *) newexpr));
+       tle = flatCopyTargetEntry(tle);
+       tle->expr = (Expr *) newexpr;
+       output_targetlist = lappend(output_targetlist, tle);
    }
    plan->targetlist = output_targetlist;
 
@@ -550,25 +551,25 @@ join_references_mutator(Node *node,
    if (IsA(node, Var))
    {
        Var        *var = (Var *) node;
-       Resdom     *resdom;
+       TargetEntry *tle;
 
        /* First look for the var in the input tlists */
-       resdom = tlist_member((Node *) var, context->outer_tlist);
-       if (resdom)
+       tle = tlist_member((Node *) var, context->outer_tlist);
+       if (tle)
        {
            Var        *newvar = (Var *) copyObject(var);
 
            newvar->varno = OUTER;
-           newvar->varattno = resdom->resno;
+           newvar->varattno = tle->resno;
            return (Node *) newvar;
        }
-       resdom = tlist_member((Node *) var, context->inner_tlist);
-       if (resdom)
+       tle = tlist_member((Node *) var, context->inner_tlist);
+       if (tle)
        {
            Var        *newvar = (Var *) copyObject(var);
 
            newvar->varno = INNER;
-           newvar->varattno = resdom->resno;
+           newvar->varattno = tle->resno;
            return (Node *) newvar;
        }
 
@@ -582,33 +583,33 @@ join_references_mutator(Node *node,
    /* Try matching more complex expressions too, if tlists have any */
    if (context->tlists_have_non_vars)
    {
-       Resdom     *resdom;
+       TargetEntry *tle;
 
-       resdom = tlist_member(node, context->outer_tlist);
-       if (resdom)
+       tle = tlist_member(node, context->outer_tlist);
+       if (tle)
        {
            /* Found a matching subplan output expression */
            Var        *newvar;
 
            newvar = makeVar(OUTER,
-                            resdom->resno,
-                            resdom->restype,
-                            resdom->restypmod,
+                            tle->resno,
+                            exprType((Node *) tle->expr),
+                            exprTypmod((Node *) tle->expr),
                             0);
            newvar->varnoold = 0;       /* wasn't ever a plain Var */
            newvar->varoattno = 0;
            return (Node *) newvar;
        }
-       resdom = tlist_member(node, context->inner_tlist);
-       if (resdom)
+       tle = tlist_member(node, context->inner_tlist);
+       if (tle)
        {
            /* Found a matching subplan output expression */
            Var        *newvar;
 
            newvar = makeVar(INNER,
-                            resdom->resno,
-                            resdom->restype,
-                            resdom->restypmod,
+                            tle->resno,
+                            exprType((Node *) tle->expr),
+                            exprTypmod((Node *) tle->expr),
                             0);
            newvar->varnoold = 0;       /* wasn't ever a plain Var */
            newvar->varoattno = 0;
@@ -668,32 +669,32 @@ replace_vars_with_subplan_refs_mutator(Node *node,
    if (IsA(node, Var))
    {
        Var        *var = (Var *) node;
-       Resdom     *resdom;
+       TargetEntry *tle;
        Var        *newvar;
 
-       resdom = tlist_member((Node *) var, context->subplan_targetlist);
-       if (!resdom)
+       tle = tlist_member((Node *) var, context->subplan_targetlist);
+       if (!tle)
            elog(ERROR, "variable not found in subplan target list");
        newvar = (Var *) copyObject(var);
        newvar->varno = context->subvarno;
-       newvar->varattno = resdom->resno;
+       newvar->varattno = tle->resno;
        return (Node *) newvar;
    }
    /* Try matching more complex expressions too, if tlist has any */
    if (context->tlist_has_non_vars)
    {
-       Resdom     *resdom;
+       TargetEntry *tle;
 
-       resdom = tlist_member(node, context->subplan_targetlist);
-       if (resdom)
+       tle = tlist_member(node, context->subplan_targetlist);
+       if (tle)
        {
            /* Found a matching subplan output expression */
            Var        *newvar;
 
            newvar = makeVar(context->subvarno,
-                            resdom->resno,
-                            resdom->restype,
-                            resdom->restypmod,
+                            tle->resno,
+                            exprType((Node *) tle->expr),
+                            exprTypmod((Node *) tle->expr),
                             0);
            newvar->varnoold = 0;       /* wasn't ever a plain Var */
            newvar->varoattno = 0;
index f89f8a8af7edac23af99bc56dc5f1e5f29c2ecb8..c92fb3153167fe10adffea424bdbf35b1413ec93 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.94 2004/12/31 22:00:09 pgsql Exp $
+ *   $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.95 2005/04/06 16:34:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -350,8 +350,9 @@ make_subplan(SubLink *slink, List *lefthand, bool isTopQual)
        TargetEntry *te = linitial(plan->targetlist);
        Param      *prm;
 
-       Assert(!te->resdom->resjunk);
-       prm = generate_new_param(te->resdom->restype, te->resdom->restypmod);
+       Assert(!te->resjunk);
+       prm = generate_new_param(exprType((Node *) te->expr),
+                                exprTypmod((Node *) te->expr));
        node->setParam = list_make1_int(prm->paramid);
        PlannerInitPlan = lappend(PlannerInitPlan, node);
        result = (Node *) prm;
@@ -362,11 +363,11 @@ make_subplan(SubLink *slink, List *lefthand, bool isTopQual)
        Oid         arraytype;
        Param      *prm;
 
-       Assert(!te->resdom->resjunk);
-       arraytype = get_array_type(te->resdom->restype);
+       Assert(!te->resjunk);
+       arraytype = get_array_type(exprType((Node *) te->expr));
        if (!OidIsValid(arraytype))
            elog(ERROR, "could not find array type for datatype %s",
-                format_type_be(te->resdom->restype));
+                format_type_be(exprType((Node *) te->expr)));
        prm = generate_new_param(arraytype, -1);
        node->setParam = list_make1_int(prm->paramid);
        PlannerInitPlan = lappend(PlannerInitPlan, node);
@@ -525,15 +526,15 @@ convert_sublink_opers(List *lefthand, List *operOids,
        Node       *rightop;
        Operator    tup;
 
-       Assert(!te->resdom->resjunk);
+       Assert(!te->resjunk);
 
        if (rtindex)
        {
            /* Make the Var node representing the subplan's result */
            rightop = (Node *) makeVar(rtindex,
-                                      te->resdom->resno,
-                                      te->resdom->restype,
-                                      te->resdom->restypmod,
+                                      te->resno,
+                                      exprType((Node *) te->expr),
+                                      exprTypmod((Node *) te->expr),
                                       0);
 
            /*
@@ -547,8 +548,8 @@ convert_sublink_opers(List *lefthand, List *operOids,
            /* Make the Param node representing the subplan's result */
            Param      *prm;
 
-           prm = generate_new_param(te->resdom->restype,
-                                    te->resdom->restypmod);
+           prm = generate_new_param(exprType((Node *) te->expr),
+                                    exprTypmod((Node *) te->expr));
            /* Record its ID */
            *righthandIds = lappend_int(*righthandIds, prm->paramid);
            rightop = (Node *) prm;
@@ -575,7 +576,7 @@ convert_sublink_opers(List *lefthand, List *operOids,
                                      leftop,
                                      rightop,
                                      exprType(leftop),
-                                     te->resdom->restype));
+                                     exprType((Node *) te->expr)));
 
        ReleaseSysCache(tup);
 
index cb5618cfbcf66078ac13b49853e2171cc9f909d4..603b8c43582706642e39f07b98838a4cff5d4a69 100644 (file)
@@ -16,7 +16,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.25 2004/12/31 22:00:20 pgsql Exp $
+ *   $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.26 2005/04/06 16:34:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -458,7 +458,7 @@ has_nullable_targetlist(Query *subquery)
        TargetEntry *tle = (TargetEntry *) lfirst(l);
 
        /* ignore resjunk columns */
-       if (tle->resdom->resjunk)
+       if (tle->resjunk)
            continue;
 
        /* Must contain a Var of current level */
index 69dc30c63d5da7a8735eda1c74e532806ae06834..ac8dae65ce7e391728c9571ea67648a08e5e1e3c 100644 (file)
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/optimizer/prep/preptlist.c,v 1.73 2005/03/17 23:44:52 neilc Exp $
+ *   $PostgreSQL: pgsql/src/backend/optimizer/prep/preptlist.c,v 1.74 2005/04/06 16:34:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -79,18 +79,17 @@ preprocess_targetlist(Query *parse, List *tlist)
     */
    if (command_type == CMD_UPDATE || command_type == CMD_DELETE)
    {
-       Resdom     *resdom;
+       TargetEntry *tle;
        Var        *var;
 
-       resdom = makeResdom(list_length(tlist) + 1,
-                           TIDOID,
-                           -1,
-                           pstrdup("ctid"),
-                           true);
-
        var = makeVar(result_relation, SelfItemPointerAttributeNumber,
                      TIDOID, -1, 0);
 
+       tle = makeTargetEntry((Expr *) var,
+                             list_length(tlist) + 1,
+                             pstrdup("ctid"),
+                             true);
+
        /*
         * For an UPDATE, expand_targetlist already created a fresh tlist.
         * For DELETE, better do a listCopy so that we don't destructively
@@ -99,7 +98,7 @@ preprocess_targetlist(Query *parse, List *tlist)
        if (command_type == CMD_DELETE)
            tlist = list_copy(tlist);
 
-       tlist = lappend(tlist, makeTargetEntry(resdom, (Expr *) var));
+       tlist = lappend(tlist, tle);
    }
 
    /*
@@ -132,18 +131,9 @@ preprocess_targetlist(Query *parse, List *tlist)
        foreach(l, parse->rowMarks)
        {
            Index       rti = lfirst_int(l);
-           char       *resname;
-           Resdom     *resdom;
            Var        *var;
-           TargetEntry *ctid;
-
-           resname = (char *) palloc(32);
-           snprintf(resname, 32, "ctid%u", rti);
-           resdom = makeResdom(list_length(tlist) + 1,
-                               TIDOID,
-                               -1,
-                               resname,
-                               true);
+           char       *resname;
+           TargetEntry *tle;
 
            var = makeVar(rti,
                          SelfItemPointerAttributeNumber,
@@ -151,8 +141,15 @@ preprocess_targetlist(Query *parse, List *tlist)
                          -1,
                          0);
 
-           ctid = makeTargetEntry(resdom, (Expr *) var);
-           tlist = lappend(tlist, ctid);
+           resname = (char *) palloc(32);
+           snprintf(resname, 32, "ctid%u", rti);
+
+           tle = makeTargetEntry((Expr *) var,
+                                 list_length(tlist) + 1,
+                                 resname,
+                                 true);
+
+           tlist = lappend(tlist, tle);
        }
    }
 
@@ -206,9 +203,8 @@ expand_targetlist(List *tlist, int command_type,
        if (tlist_item != NULL)
        {
            TargetEntry *old_tle = (TargetEntry *) lfirst(tlist_item);
-           Resdom     *resdom = old_tle->resdom;
 
-           if (!resdom->resjunk && resdom->resno == attrno)
+           if (!old_tle->resjunk && old_tle->resno == attrno)
            {
                new_tle = old_tle;
                tlist_item = lnext(tlist_item);
@@ -268,9 +264,6 @@ expand_targetlist(List *tlist, int command_type,
                                                      (Datum) 0,
                                                      true,     /* isnull */
                                                      true /* byval */ );
-                       /* label resdom with INT4, too */
-                       atttype = INT4OID;
-                       atttypmod = -1;
                    }
                    break;
                case CMD_UPDATE:
@@ -290,9 +283,6 @@ expand_targetlist(List *tlist, int command_type,
                                                      (Datum) 0,
                                                      true,     /* isnull */
                                                      true /* byval */ );
-                       /* label resdom with INT4, too */
-                       atttype = INT4OID;
-                       atttypmod = -1;
                    }
                    break;
                default:
@@ -302,12 +292,10 @@ expand_targetlist(List *tlist, int command_type,
                    break;
            }
 
-           new_tle = makeTargetEntry(makeResdom(attrno,
-                                                atttype,
-                                                atttypmod,
+           new_tle = makeTargetEntry((Expr *) new_expr,
+                                     attrno,
                                      pstrdup(NameStr(att_tup->attname)),
-                                                false),
-                                     (Expr *) new_expr);
+                                     false);
        }
 
        new_tlist = lappend(new_tlist, new_tle);
@@ -324,16 +312,14 @@ expand_targetlist(List *tlist, int command_type,
    while (tlist_item)
    {
        TargetEntry *old_tle = (TargetEntry *) lfirst(tlist_item);
-       Resdom     *resdom = old_tle->resdom;
 
-       if (!resdom->resjunk)
+       if (!old_tle->resjunk)
            elog(ERROR, "targetlist is not sorted correctly");
        /* Get the resno right, but don't copy unnecessarily */
-       if (resdom->resno != attrno)
+       if (old_tle->resno != attrno)
        {
-           resdom = (Resdom *) copyObject((Node *) resdom);
-           resdom->resno = attrno;
-           old_tle = makeTargetEntry(resdom, old_tle->expr);
+           old_tle = flatCopyTargetEntry(old_tle);
+           old_tle->resno = attrno;
        }
        new_tlist = lappend(new_tlist, old_tle);
        attrno++;
index f9e937aaa609ca698e78999531afa7dbb386ead8..ae3c3a8c18219d39a0671f6b6409fa3b4fa5e09e 100644 (file)
@@ -14,7 +14,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.119 2004/12/31 22:00:20 pgsql Exp $
+ *   $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.120 2005/04/06 16:34:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -32,6 +32,7 @@
 #include "optimizer/tlist.h"
 #include "parser/parse_clause.h"
 #include "parser/parse_coerce.h"
+#include "parser/parse_expr.h"
 #include "parser/parsetree.h"
 #include "utils/lsyscache.h"
 
@@ -429,7 +430,7 @@ generate_setop_tlist(List *colTypes, int flag,
    ListCell   *i,
               *j,
               *k;
-   Resdom     *resdom;
+   TargetEntry *tle;
    Node       *expr;
 
    j = list_head(input_tlist);
@@ -439,12 +440,11 @@ generate_setop_tlist(List *colTypes, int flag,
        Oid         colType = lfirst_oid(i);
        TargetEntry *inputtle = (TargetEntry *) lfirst(j);
        TargetEntry *reftle = (TargetEntry *) lfirst(k);
-       int32       colTypmod;
 
-       Assert(inputtle->resdom->resno == resno);
-       Assert(reftle->resdom->resno == resno);
-       Assert(!inputtle->resdom->resjunk);
-       Assert(!reftle->resdom->resjunk);
+       Assert(inputtle->resno == resno);
+       Assert(reftle->resno == resno);
+       Assert(!inputtle->resjunk);
+       Assert(!reftle->resjunk);
 
        /*
         * Generate columns referencing input columns and having
@@ -463,29 +463,23 @@ generate_setop_tlist(List *colTypes, int flag,
            expr = (Node *) inputtle->expr;
        else
            expr = (Node *) makeVar(0,
-                                   inputtle->resdom->resno,
-                                   inputtle->resdom->restype,
-                                   inputtle->resdom->restypmod,
+                                   inputtle->resno,
+                                   exprType((Node *) inputtle->expr),
+                                   exprTypmod((Node *) inputtle->expr),
                                    0);
-       if (inputtle->resdom->restype == colType)
-       {
-           /* no coercion needed, and believe the input typmod */
-           colTypmod = inputtle->resdom->restypmod;
-       }
-       else
+       if (exprType(expr) != colType)
        {
            expr = coerce_to_common_type(NULL,  /* no UNKNOWNs here */
                                         expr,
                                         colType,
                                         "UNION/INTERSECT/EXCEPT");
-           colTypmod = -1;
        }
-       resdom = makeResdom((AttrNumber) resno++,
-                           colType,
-                           colTypmod,
-                           pstrdup(reftle->resdom->resname),
-                           false);
-       tlist = lappend(tlist, makeTargetEntry(resdom, (Expr *) expr));
+       tle = makeTargetEntry((Expr *) expr,
+                             (AttrNumber) resno++,
+                             pstrdup(reftle->resname),
+                             false);
+       tlist = lappend(tlist, tle);
+
        j = lnext(j);
        k = lnext(k);
    }
@@ -493,18 +487,17 @@ generate_setop_tlist(List *colTypes, int flag,
    if (flag >= 0)
    {
        /* Add a resjunk flag column */
-       resdom = makeResdom((AttrNumber) resno++,
-                           INT4OID,
-                           -1,
-                           pstrdup("flag"),
-                           true);
        /* flag value is the given constant */
        expr = (Node *) makeConst(INT4OID,
                                  sizeof(int4),
                                  Int32GetDatum(flag),
                                  false,
                                  true);
-       tlist = lappend(tlist, makeTargetEntry(resdom, (Expr *) expr));
+       tle = makeTargetEntry((Expr *) expr,
+                             (AttrNumber) resno++,
+                             pstrdup("flag"),
+                             true);
+       tlist = lappend(tlist, tle);
    }
 
    return tlist;
@@ -531,7 +524,7 @@ generate_append_tlist(List *colTypes, bool flag,
    ListCell   *curColType;
    ListCell   *ref_tl_item;
    int         colindex;
-   Resdom     *resdom;
+   TargetEntry *tle;
    Node       *expr;
    ListCell   *planl;
    int32      *colTypmods;
@@ -555,15 +548,17 @@ generate_append_tlist(List *colTypes, bool flag,
        {
            TargetEntry *subtle = (TargetEntry *) lfirst(subtlist);
 
-           if (subtle->resdom->resjunk)
+           if (subtle->resjunk)
                continue;
            Assert(curColType != NULL);
-           if (subtle->resdom->restype == lfirst_oid(curColType))
+           if (exprType((Node *) subtle->expr) == lfirst_oid(curColType))
            {
                /* If first subplan, copy the typmod; else compare */
+               int32       subtypmod = exprTypmod((Node *) subtle->expr);
+
                if (planl == list_head(input_plans))
-                   colTypmods[colindex] = subtle->resdom->restypmod;
-               else if (subtle->resdom->restypmod != colTypmods[colindex])
+                   colTypmods[colindex] = subtypmod;
+               else if (subtypmod != colTypmods[colindex])
                    colTypmods[colindex] = -1;
            }
            else
@@ -587,36 +582,34 @@ generate_append_tlist(List *colTypes, bool flag,
        int32       colTypmod = colTypmods[colindex++];
        TargetEntry *reftle = (TargetEntry *) lfirst(ref_tl_item);
 
-       Assert(reftle->resdom->resno == resno);
-       Assert(!reftle->resdom->resjunk);
+       Assert(reftle->resno == resno);
+       Assert(!reftle->resjunk);
        expr = (Node *) makeVar(0,
                                resno,
                                colType,
                                colTypmod,
                                0);
-       resdom = makeResdom((AttrNumber) resno++,
-                           colType,
-                           colTypmod,
-                           pstrdup(reftle->resdom->resname),
-                           false);
-       tlist = lappend(tlist, makeTargetEntry(resdom, (Expr *) expr));
+       tle = makeTargetEntry((Expr *) expr,
+                             (AttrNumber) resno++,
+                             pstrdup(reftle->resname),
+                             false);
+       tlist = lappend(tlist, tle);
    }
 
    if (flag)
    {
        /* Add a resjunk flag column */
-       resdom = makeResdom((AttrNumber) resno++,
-                           INT4OID,
-                           -1,
-                           pstrdup("flag"),
-                           true);
        /* flag value is shown as copied up from subplan */
        expr = (Node *) makeVar(0,
-                               resdom->resno,
+                               resno,
                                INT4OID,
                                -1,
                                0);
-       tlist = lappend(tlist, makeTargetEntry(resdom, (Expr *) expr));
+       tle = makeTargetEntry((Expr *) expr,
+                             (AttrNumber) resno++,
+                             pstrdup("flag"),
+                             true);
+       tlist = lappend(tlist, tle);
    }
 
    pfree(colTypmods);
@@ -640,7 +633,7 @@ tlist_same_datatypes(List *tlist, List *colTypes, bool junkOK)
    {
        TargetEntry *tle = (TargetEntry *) lfirst(l);
 
-       if (tle->resdom->resjunk)
+       if (tle->resjunk)
        {
            if (!junkOK)
                return false;
@@ -649,7 +642,7 @@ tlist_same_datatypes(List *tlist, List *colTypes, bool junkOK)
        {
            if (curColType == NULL)
                return false;
-           if (tle->resdom->restype != lfirst_oid(curColType))
+           if (exprType((Node *) tle->expr) != lfirst_oid(curColType))
                return false;
            curColType = lnext(curColType);
        }
@@ -1105,8 +1098,7 @@ adjust_relid_set(Relids relids, Index oldrelid, Index newrelid)
  *
  * The given tlist has already been through expression_tree_mutator;
  * therefore the TargetEntry nodes are fresh copies that it's okay to
- * scribble on.  But the Resdom nodes have not been copied; make new ones
- * if we need to change them!
+ * scribble on.
  *
  * Note that this is not needed for INSERT because INSERT isn't inheritable.
  */
@@ -1124,18 +1116,15 @@ adjust_inherited_tlist(List *tlist,
    foreach(tl, tlist)
    {
        TargetEntry *tle = (TargetEntry *) lfirst(tl);
-       Resdom     *resdom = tle->resdom;
 
-       if (resdom->resjunk)
+       if (tle->resjunk)
            continue;           /* ignore junk items */
 
-       attrno = translate_inherited_attnum(resdom->resno, context);
+       attrno = translate_inherited_attnum(tle->resno, context);
 
-       if (resdom->resno != attrno)
+       if (tle->resno != attrno)
        {
-           resdom = (Resdom *) copyObject((Node *) resdom);
-           resdom->resno = attrno;
-           tle->resdom = resdom;
+           tle->resno = attrno;
            changed_it = true;
        }
    }
@@ -1157,14 +1146,13 @@ adjust_inherited_tlist(List *tlist,
        foreach(tl, tlist)
        {
            TargetEntry *tle = (TargetEntry *) lfirst(tl);
-           Resdom     *resdom = tle->resdom;
 
-           if (resdom->resjunk)
+           if (tle->resjunk)
                continue;       /* ignore junk items */
 
-           if (resdom->resno == attrno)
+           if (tle->resno == attrno)
                new_tlist = lappend(new_tlist, tle);
-           else if (resdom->resno > attrno)
+           else if (tle->resno > attrno)
                more = true;
        }
    }
@@ -1172,17 +1160,11 @@ adjust_inherited_tlist(List *tlist,
    foreach(tl, tlist)
    {
        TargetEntry *tle = (TargetEntry *) lfirst(tl);
-       Resdom     *resdom = tle->resdom;
 
-       if (!resdom->resjunk)
+       if (!tle->resjunk)
            continue;           /* here, ignore non-junk items */
 
-       if (resdom->resno != attrno)
-       {
-           resdom = (Resdom *) copyObject((Node *) resdom);
-           resdom->resno = attrno;
-           tle->resdom = resdom;
-       }
+       tle->resno = attrno;
        new_tlist = lappend(new_tlist, tle);
        attrno++;
    }
index 2cf4fcd663d5e6641530c93278b242027a0a1408..24d74523c3713532d015f9d0f9e78a69f7d475c7 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.192 2005/03/31 22:46:09 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.193 2005/04/06 16:34:06 tgl Exp $
  *
  * HISTORY
  *   AUTHOR            DATE            MAJOR EVENT
@@ -966,22 +966,22 @@ has_distinct_on_clause(Query *query)
    {
        TargetEntry *tle = (TargetEntry *) lfirst(l);
 
-       if (tle->resdom->ressortgroupref == 0)
+       if (tle->ressortgroupref == 0)
        {
-           if (tle->resdom->resjunk)
+           if (tle->resjunk)
                continue;       /* we can ignore unsorted junk cols */
            return true;        /* definitely not in DISTINCT list */
        }
        if (targetIsInSortList(tle, query->distinctClause))
        {
-           if (tle->resdom->resjunk)
+           if (tle->resjunk)
                return true;    /* junk TLE in DISTINCT means DISTINCT ON */
            /* else this TLE is okay, keep looking */
        }
        else
        {
            /* This TLE is not in DISTINCT list */
-           if (!tle->resdom->resjunk)
+           if (!tle->resjunk)
                return true;    /* non-junk, non-DISTINCT, so DISTINCT ON */
            if (targetIsInSortList(tle, query->sortClause))
                return true;    /* sorted, non-distinct junk */
@@ -3314,10 +3314,6 @@ expression_tree_mutator(Node *node,
            break;
        case T_TargetEntry:
            {
-               /*
-                * We mutate the expression, but not the resdom, by
-                * default.
-                */
                TargetEntry *targetentry = (TargetEntry *) node;
                TargetEntry *newnode;
 
index b6b0cc505f39dcb58aaa98849e80e88446b1aaaa..14b62b80fc81739cddb44c99f74017bf167f84d1 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.114 2005/03/27 06:29:42 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.115 2005/04/06 16:34:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -789,7 +789,7 @@ is_distinct_query(Query *query)
            TargetEntry *tle = get_sortgroupclause_tle(grpcl,
                                                       query->targetList);
 
-           if (tle->resdom->resjunk)
+           if (tle->resjunk)
                break;
        }
        if (!gl)                /* got to the end? */
index c64f2aad1ffbef010febc7da53e91ea811d7f474..e01a1d76a597befded661a356ee629cc7df202c6 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.103 2005/03/29 00:17:02 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.104 2005/04/06 16:34:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -378,6 +378,7 @@ build_physical_tlist(Query *root, RelOptInfo *rel)
    for (attrno = 1; attrno <= numattrs; attrno++)
    {
        Form_pg_attribute att_tup = relation->rd_att->attrs[attrno - 1];
+       Var    *var;
 
        if (att_tup->attisdropped)
        {
@@ -386,13 +387,17 @@ build_physical_tlist(Query *root, RelOptInfo *rel)
            break;
        }
 
+       var = makeVar(varno,
+                     attrno,
+                     att_tup->atttypid,
+                     att_tup->atttypmod,
+                     0);
+
        tlist = lappend(tlist,
-                       create_tl_element(makeVar(varno,
-                                                 attrno,
-                                                 att_tup->atttypid,
-                                                 att_tup->atttypmod,
-                                                 0),
-                                         attrno));
+                       makeTargetEntry((Expr *) var,
+                                       attrno,
+                                       NULL,
+                                       false));
    }
 
    heap_close(relation, AccessShareLock);
index d5118de296aa562deab3b7895654a767df7568ba..1672cda77c0a632b43a7a7f27106c97d1fad0d97 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/optimizer/util/tlist.c,v 1.68 2004/12/31 22:00:23 pgsql Exp $
+ *   $PostgreSQL: pgsql/src/backend/optimizer/util/tlist.c,v 1.69 2005/04/06 16:34:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
  *****************************************************************************/
 
 /*
- * tlistentry_member
+ * tlist_member
  *   Finds the (first) member of the given tlist whose expression is
  *   equal() to the given expression.  Result is NULL if no such member.
  */
 TargetEntry *
-tlistentry_member(Node *node, List *targetlist)
+tlist_member(Node *node, List *targetlist)
 {
    ListCell   *temp;
 
@@ -44,77 +44,6 @@ tlistentry_member(Node *node, List *targetlist)
    return NULL;
 }
 
-#ifdef NOT_USED
-/*
- * matching_tlist_expr
- *   Same as tlistentry_member(), except returns the tlist expression
- *   rather than its parent TargetEntry node.
- */
-Node *
-matching_tlist_expr(Node *node, List *targetlist)
-{
-   TargetEntry *tlentry;
-
-   tlentry = tlistentry_member(node, targetlist);
-   if (tlentry)
-       return tlentry->expr;
-
-   return NULL;
-}
-#endif
-
-/*
- * tlist_member
- *   Same as tlistentry_member(), except returns the Resdom node
- *   rather than its parent TargetEntry node.
- */
-Resdom *
-tlist_member(Node *node, List *targetlist)
-{
-   TargetEntry *tlentry;
-
-   tlentry = tlistentry_member(node, targetlist);
-   if (tlentry)
-       return tlentry->resdom;
-
-   return NULL;
-}
-
-/*
- * create_tl_element
- *   Creates a target list entry node and its associated (resdom var) pair
- *   with its resdom number equal to 'resdomno'.
- *
- * Note: the argument is almost always a Var, but occasionally not.
- */
-TargetEntry *
-create_tl_element(Var *var, int resdomno)
-{
-   Oid         vartype;
-   int32       vartypmod;
-
-   if (IsA(var, Var))
-   {
-       vartype = var->vartype;
-       vartypmod = var->vartypmod;
-   }
-   else
-   {
-       vartype = exprType((Node *) var);
-       vartypmod = exprTypmod((Node *) var);
-   }
-   return makeTargetEntry(makeResdom(resdomno,
-                                     vartype,
-                                     vartypmod,
-                                     NULL,
-                                     false),
-                          (Expr *) var);
-}
-
-/*****************************************************************************
- *     ---------- GENERAL target list routines ----------
- *****************************************************************************/
-
 /*
  * flatten_tlist
  *   Create a target list that only contains unique variables.
@@ -153,24 +82,22 @@ flatten_tlist(List *tlist)
 List *
 add_to_flat_tlist(List *tlist, List *vars)
 {
-   int         next_resdomno = list_length(tlist) + 1;
+   int         next_resno = list_length(tlist) + 1;
    ListCell   *v;
 
    foreach(v, vars)
    {
        Var        *var = (Var *) lfirst(v);
 
-       if (!tlistentry_member((Node *) var, tlist))
+       if (!tlist_member((Node *) var, tlist))
        {
-           Resdom     *r;
-
-           r = makeResdom(next_resdomno++,
-                          var->vartype,
-                          var->vartypmod,
-                          NULL,
-                          false);
-           tlist = lappend(tlist,
-                           makeTargetEntry(r, copyObject(var)));
+           TargetEntry *tle;
+
+           tle = makeTargetEntry(copyObject(var), /* copy needed?? */
+                                 next_resno++,
+                                 NULL,
+                                 false);
+           tlist = lappend(tlist, tle);
        }
    }
    return tlist;
@@ -195,7 +122,7 @@ get_sortgroupclause_tle(SortClause *sortClause,
    {
        TargetEntry *tle = (TargetEntry *) lfirst(l);
 
-       if (tle->resdom->ressortgroupref == refnumber)
+       if (tle->ressortgroupref == refnumber)
            return tle;
    }
 
index 6e16086991995ab0796988811aabb2492a6d09b9..191f4446b0697df667f1013b1bc402666a6893ee 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.316 2005/03/10 23:21:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.317 2005/04/06 16:34:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -438,15 +438,12 @@ transformViewStmt(ParseState *pstate, ViewStmt *stmt,
        foreach(targetList, stmt->query->targetList)
        {
            TargetEntry *te = (TargetEntry *) lfirst(targetList);
-           Resdom     *rd;
 
            Assert(IsA(te, TargetEntry));
-           rd = te->resdom;
-           Assert(IsA(rd, Resdom));
            /* junk columns don't get aliases */
-           if (rd->resjunk)
+           if (te->resjunk)
                continue;
-           rd->resname = pstrdup(strVal(lfirst(alist_item)));
+           te->resname = pstrdup(strVal(lfirst(alist_item)));
            alist_item = lnext(alist_item);
            if (alist_item == NULL)
                break;          /* done assigning aliases */
@@ -507,7 +504,6 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
 {
    Query      *qry = makeNode(Query);
    Query      *selectQuery = NULL;
-   bool        copy_up_hack = false;
    List       *sub_rtable;
    List       *sub_namespace;
    List       *icolumns;
@@ -615,7 +611,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
         * separate from the subquery's tlist because we may add columns,
         * insert datatype coercions, etc.)
         *
-        * HACK: unknown-type constants and params in the INSERT's targetlist
+        * HACK: unknown-type constants and params in the SELECT's targetlist
         * are copied up as-is rather than being referenced as subquery
         * outputs.  This is to ensure that when we try to coerce them to
         * the target column's datatype, the right things happen (see
@@ -627,28 +623,25 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
        foreach(tl, selectQuery->targetList)
        {
            TargetEntry *tle = (TargetEntry *) lfirst(tl);
-           Resdom     *resnode = tle->resdom;
            Expr       *expr;
 
-           if (resnode->resjunk)
+           if (tle->resjunk)
                continue;
            if (tle->expr &&
                (IsA(tle->expr, Const) || IsA(tle->expr, Param)) &&
                exprType((Node *) tle->expr) == UNKNOWNOID)
-           {
                expr = tle->expr;
-               copy_up_hack = true;
-           }
            else
                expr = (Expr *) makeVar(rtr->rtindex,
-                                       resnode->resno,
-                                       resnode->restype,
-                                       resnode->restypmod,
+                                       tle->resno,
+                                       exprType((Node *) tle->expr),
+                                       exprTypmod((Node *) tle->expr),
                                        0);
-           resnode = copyObject(resnode);
-           resnode->resno = (AttrNumber) pstate->p_next_resno++;
-           qry->targetList = lappend(qry->targetList,
-                                     makeTargetEntry(resnode, expr));
+           tle = makeTargetEntry(expr,
+                                 (AttrNumber) pstate->p_next_resno++,
+                                 tle->resname,
+                                 false);
+           qry->targetList = lappend(qry->targetList, tle);
        }
    }
    else
@@ -690,7 +683,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
        col = (ResTarget *) lfirst(icols);
        Assert(IsA(col, ResTarget));
 
-       Assert(!tle->resdom->resjunk);
+       Assert(!tle->resjunk);
        updateTargetListEntry(pstate, tle, col->name, lfirst_int(attnos),
                              col->indirection);
 
@@ -708,28 +701,6 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
                (errcode(ERRCODE_SYNTAX_ERROR),
             errmsg("INSERT has more target columns than expressions")));
 
-   /*
-    * If we copied up any unknown Params (see HACK above) then their
-    * resolved types need to be propagated into the Resdom nodes of
-    * the sub-INSERT's tlist.  One hack begets another :-(
-    */
-   if (copy_up_hack)
-   {
-       foreach(tl, selectQuery->targetList)
-       {
-           TargetEntry *tle = (TargetEntry *) lfirst(tl);
-           Resdom     *resnode = tle->resdom;
-
-           if (resnode->resjunk)
-               continue;
-           if (resnode->restype == UNKNOWNOID)
-           {
-               resnode->restype = exprType((Node *) tle->expr);
-               resnode->restypmod = exprTypmod((Node *) tle->expr);
-           }
-       }
-   }
-
    /* done building the range table and jointree */
    qry->rtable = pstate->p_rtable;
    qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
@@ -2007,26 +1978,23 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
    foreach(dtlist, sostmt->colTypes)
    {
        Oid         colType = lfirst_oid(dtlist);
-       Resdom     *leftResdom;
+       TargetEntry *lefttle = (TargetEntry *) lfirst(left_tlist);
        char       *colName;
-       Resdom     *resdom;
+       TargetEntry *tle;
        Expr       *expr;
 
-       leftResdom = ((TargetEntry *) lfirst(left_tlist))->resdom;
-       Assert(!leftResdom->resjunk);
-       colName = pstrdup(leftResdom->resname);
-       resdom = makeResdom((AttrNumber) pstate->p_next_resno++,
-                           colType,
-                           -1,
-                           colName,
-                           false);
+       Assert(!lefttle->resjunk);
+       colName = pstrdup(lefttle->resname);
        expr = (Expr *) makeVar(leftmostRTI,
-                               leftResdom->resno,
+                               lefttle->resno,
                                colType,
                                -1,
                                0);
-       qry->targetList = lappend(qry->targetList,
-                                 makeTargetEntry(resdom, expr));
+       tle = makeTargetEntry(expr,
+                             (AttrNumber) pstate->p_next_resno++,
+                             colName,
+                             false);
+       qry->targetList = lappend(qry->targetList, tle);
        targetvars = lappend(targetvars, expr);
        targetnames = lappend(targetnames, makeString(colName));
        left_tlist = lnext(left_tlist);
@@ -2284,11 +2252,10 @@ getSetColTypes(ParseState *pstate, Node *node)
        foreach(tl, selectQuery->targetList)
        {
            TargetEntry *tle = (TargetEntry *) lfirst(tl);
-           Resdom     *resnode = tle->resdom;
 
-           if (resnode->resjunk)
+           if (tle->resjunk)
                continue;
-           result = lappend_oid(result, resnode->restype);
+           result = lappend_oid(result, exprType((Node *) tle->expr));
        }
        return result;
    }
@@ -2324,8 +2291,8 @@ applyColumnNames(List *dst, List *src)
        TargetEntry *d = (TargetEntry *) lfirst(dst_item);
        ColumnDef  *s = (ColumnDef *) lfirst(src_item);
 
-       Assert(d->resdom && !d->resdom->resjunk);
-       d->resdom->resname = pstrdup(s->colname);
+       Assert(!d->resjunk);
+       d->resname = pstrdup(s->colname);
    }
 }
 
@@ -2383,10 +2350,9 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
    foreach(tl, qry->targetList)
    {
        TargetEntry *tle = (TargetEntry *) lfirst(tl);
-       Resdom     *resnode = tle->resdom;
        ResTarget  *origTarget;
 
-       if (resnode->resjunk)
+       if (tle->resjunk)
        {
            /*
             * Resjunk nodes need no additional processing, but be sure
@@ -2394,8 +2360,8 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
             * rewriter or planner might get confused.  They don't need a
             * resname either.
             */
-           resnode->resno = (AttrNumber) pstate->p_next_resno++;
-           resnode->resname = NULL;
+           tle->resno = (AttrNumber) pstate->p_next_resno++;
+           tle->resname = NULL;
            continue;
        }
        if (origTargetList == NULL)
index 2885ff51ec0d77eb5dd88cec2c580058d77c97e5..6d13e485b2e895eda47d316b46fcba03b25be29a 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.138 2004/12/31 22:00:27 pgsql Exp $
+ *   $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.139 2005/04/06 16:34:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1161,10 +1161,9 @@ findTargetlistEntry(ParseState *pstate, Node *node, List **tlist, int clause)
            foreach(tl, *tlist)
            {
                TargetEntry *tle = (TargetEntry *) lfirst(tl);
-               Resdom     *resnode = tle->resdom;
 
-               if (!resnode->resjunk &&
-                   strcmp(resnode->resname, name) == 0)
+               if (!tle->resjunk &&
+                   strcmp(tle->resname, name) == 0)
                {
                    if (target_result != NULL)
                    {
@@ -1204,9 +1203,8 @@ findTargetlistEntry(ParseState *pstate, Node *node, List **tlist, int clause)
        foreach(tl, *tlist)
        {
            TargetEntry *tle = (TargetEntry *) lfirst(tl);
-           Resdom     *resnode = tle->resdom;
 
-           if (!resnode->resjunk)
+           if (!tle->resjunk)
            {
                if (++targetlist_pos == target_pos)
                    return tle; /* return the unique match */
@@ -1282,7 +1280,7 @@ transformGroupClause(ParseState *pstate, List *grouplist,
            continue;
 
        /* if tlist item is an UNKNOWN literal, change it to TEXT */
-       restype = tle->resdom->restype;
+       restype = exprType((Node *) tle->expr);
 
        if (restype == UNKNOWNOID)
        {
@@ -1290,8 +1288,7 @@ transformGroupClause(ParseState *pstate, List *grouplist,
                                             restype, TEXTOID, -1,
                                             COERCION_IMPLICIT,
                                             COERCE_IMPLICIT_CAST);
-           restype = tle->resdom->restype = TEXTOID;
-           tle->resdom->restypmod = -1;
+           restype = TEXTOID;
        }
 
        /*
@@ -1304,7 +1301,7 @@ transformGroupClause(ParseState *pstate, List *grouplist,
         */
        if (sortItem &&
            ((SortClause *) lfirst(sortItem))->tleSortGroupRef ==
-           tle->resdom->ressortgroupref)
+           tle->ressortgroupref)
        {
            ordering_op = ((SortClause *) lfirst(sortItem))->sortop;
            sortItem = lnext(sortItem);
@@ -1405,7 +1402,7 @@ transformDistinctClause(ParseState *pstate, List *distinctlist,
            SortClause *scl = (SortClause *) lfirst(slitem);
            TargetEntry *tle = get_sortgroupclause_tle(scl, *targetlist);
 
-           if (tle->resdom->resjunk)
+           if (tle->resjunk)
                ereport(ERROR,
                        (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
                         errmsg("for SELECT DISTINCT, ORDER BY expressions must appear in select list")));
@@ -1445,7 +1442,7 @@ transformDistinctClause(ParseState *pstate, List *distinctlist,
            {
                SortClause *scl = (SortClause *) lfirst(nextsortlist);
 
-               if (tle->resdom->ressortgroupref != scl->tleSortGroupRef)
+               if (tle->ressortgroupref != scl->tleSortGroupRef)
                    ereport(ERROR,
                            (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
                             errmsg("SELECT DISTINCT ON expressions must match initial ORDER BY expressions")));
@@ -1466,7 +1463,7 @@ transformDistinctClause(ParseState *pstate, List *distinctlist,
                {
                    SortClause *scl = (SortClause *) lfirst(slitem);
 
-                   if (tle->resdom->ressortgroupref == scl->tleSortGroupRef)
+                   if (tle->ressortgroupref == scl->tleSortGroupRef)
                    {
                        result = lappend(result, copyObject(scl));
                        break;
@@ -1501,7 +1498,7 @@ addAllTargetsToSortList(ParseState *pstate, List *sortlist,
    {
        TargetEntry *tle = (TargetEntry *) lfirst(l);
 
-       if (!tle->resdom->resjunk)
+       if (!tle->resjunk)
            sortlist = addTargetToSortList(pstate, tle,
                                           sortlist, targetlist,
                                           SORTBY_ASC, NIL,
@@ -1533,7 +1530,7 @@ addTargetToSortList(ParseState *pstate, TargetEntry *tle,
    if (!targetIsInSortList(tle, sortlist))
    {
        SortClause *sortcl = makeNode(SortClause);
-       Oid         restype = tle->resdom->restype;
+       Oid         restype = exprType((Node *) tle->expr);
 
        /* if tlist item is an UNKNOWN literal, change it to TEXT */
        if (restype == UNKNOWNOID && resolveUnknown)
@@ -1542,8 +1539,7 @@ addTargetToSortList(ParseState *pstate, TargetEntry *tle,
                                             restype, TEXTOID, -1,
                                             COERCION_IMPLICIT,
                                             COERCE_IMPLICIT_CAST);
-           restype = tle->resdom->restype = TEXTOID;
-           tle->resdom->restypmod = -1;
+           restype = TEXTOID;
        }
 
        sortcl->tleSortGroupRef = assignSortGroupRef(tle, targetlist);
@@ -1586,20 +1582,20 @@ assignSortGroupRef(TargetEntry *tle, List *tlist)
    Index       maxRef;
    ListCell   *l;
 
-   if (tle->resdom->ressortgroupref)   /* already has one? */
-       return tle->resdom->ressortgroupref;
+   if (tle->ressortgroupref)           /* already has one? */
+       return tle->ressortgroupref;
 
    /* easiest way to pick an unused refnumber: max used + 1 */
    maxRef = 0;
    foreach(l, tlist)
    {
-       Index       ref = ((TargetEntry *) lfirst(l))->resdom->ressortgroupref;
+       Index       ref = ((TargetEntry *) lfirst(l))->ressortgroupref;
 
        if (ref > maxRef)
            maxRef = ref;
    }
-   tle->resdom->ressortgroupref = maxRef + 1;
-   return tle->resdom->ressortgroupref;
+   tle->ressortgroupref = maxRef + 1;
+   return tle->ressortgroupref;
 }
 
 /*
@@ -1613,7 +1609,7 @@ assignSortGroupRef(TargetEntry *tle, List *tlist)
 bool
 targetIsInSortList(TargetEntry *tle, List *sortList)
 {
-   Index       ref = tle->resdom->ressortgroupref;
+   Index       ref = tle->ressortgroupref;
    ListCell   *l;
 
    /* no need to scan list if tle has no marker */
index ba3dbcad75b8dcd7f24d2e6ab9f469b04c787aed..058a1566be0f1cf3858607f6489fadc4d03782fe 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.180 2005/01/19 23:45:24 neilc Exp $
+ *   $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.181 2005/04/06 16:34:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -960,13 +960,13 @@ transformSubLink(ParseState *pstate, SubLink *sublink)
         * resjunk targets).
         */
        if (tlist_item == NULL ||
-           ((TargetEntry *) lfirst(tlist_item))->resdom->resjunk)
+           ((TargetEntry *) lfirst(tlist_item))->resjunk)
            ereport(ERROR,
                    (errcode(ERRCODE_SYNTAX_ERROR),
                     errmsg("subquery must return a column")));
        while ((tlist_item = lnext(tlist_item)) != NULL)
        {
-           if (!((TargetEntry *) lfirst(tlist_item))->resdom->resjunk)
+           if (!((TargetEntry *) lfirst(tlist_item))->resjunk)
                ereport(ERROR,
                        (errcode(ERRCODE_SYNTAX_ERROR),
                         errmsg("subquery must return only one column")));
@@ -1045,7 +1045,7 @@ transformSubLink(ParseState *pstate, SubLink *sublink)
            Operator    optup;
            Form_pg_operator opform;
 
-           if (tent->resdom->resjunk)
+           if (tent->resjunk)
                continue;
 
            if (ll_item == NULL)
@@ -1417,18 +1417,16 @@ exprType(Node *expr)
                        elog(ERROR, "cannot get type for untransformed sublink");
                    tent = (TargetEntry *) linitial(qtree->targetList);
                    Assert(IsA(tent, TargetEntry));
-                   Assert(!tent->resdom->resjunk);
-                   if (sublink->subLinkType == EXPR_SUBLINK)
-                       type = tent->resdom->restype;
-                   else
+                   Assert(!tent->resjunk);
+                   type = exprType((Node *) tent->expr);
+                   if (sublink->subLinkType == ARRAY_SUBLINK)
                    {
-                       /* ARRAY_SUBLINK */
-                       type = get_array_type(tent->resdom->restype);
+                       type = get_array_type(type);
                        if (!OidIsValid(type))
                            ereport(ERROR,
                                    (errcode(ERRCODE_UNDEFINED_OBJECT),
                                     errmsg("could not find array type for data type %s",
-                               format_type_be(tent->resdom->restype))));
+                                           format_type_be(exprType((Node *) tent->expr)))));
                    }
                }
                else
@@ -1456,18 +1454,16 @@ exprType(Node *expr)
 
                    tent = (TargetEntry *) linitial(subplan->plan->targetlist);
                    Assert(IsA(tent, TargetEntry));
-                   Assert(!tent->resdom->resjunk);
-                   if (subplan->subLinkType == EXPR_SUBLINK)
-                       type = tent->resdom->restype;
-                   else
+                   Assert(!tent->resjunk);
+                   type = exprType((Node *) tent->expr);
+                   if (subplan->subLinkType == ARRAY_SUBLINK)
                    {
-                       /* ARRAY_SUBLINK */
-                       type = get_array_type(tent->resdom->restype);
+                       type = get_array_type(type);
                        if (!OidIsValid(type))
                            ereport(ERROR,
                                    (errcode(ERRCODE_UNDEFINED_OBJECT),
                                     errmsg("could not find array type for data type %s",
-                               format_type_be(tent->resdom->restype))));
+                                           format_type_be(exprType((Node *) tent->expr)))));
                    }
                }
                else
index 6e391f4eb8bd67a1ea3d3a6ed4f26c42dc5bbc90..031bfa8fe245af95515185d74f2cff5a6ee08382 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.103 2005/03/31 22:46:13 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.104 2005/04/06 16:34:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -910,15 +910,15 @@ addRangeTableEntryForSubquery(ParseState *pstate,
    {
        TargetEntry *te = (TargetEntry *) lfirst(tlistitem);
 
-       if (te->resdom->resjunk)
+       if (te->resjunk)
            continue;
        varattno++;
-       Assert(varattno == te->resdom->resno);
+       Assert(varattno == te->resno);
        if (varattno > numaliases)
        {
            char       *attrname;
 
-           attrname = pstrdup(te->resdom->resname);
+           attrname = pstrdup(te->resname);
            eref->colnames = lappend(eref->colnames, makeString(attrname));
        }
    }
@@ -1260,10 +1260,10 @@ expandRTE(List *rtable, int rtindex, int sublevels_up,
                {
                    TargetEntry *te = (TargetEntry *) lfirst(tlistitem);
 
-                   if (te->resdom->resjunk)
+                   if (te->resjunk)
                        continue;
                    varattno++;
-                   Assert(varattno == te->resdom->resno);
+                   Assert(varattno == te->resno);
 
                    if (colnames)
                    {
@@ -1279,8 +1279,8 @@ expandRTE(List *rtable, int rtindex, int sublevels_up,
                        Var        *varnode;
 
                        varnode = makeVar(rtindex, varattno,
-                                         te->resdom->restype,
-                                         te->resdom->restypmod,
+                                         exprType((Node *) te->expr),
+                                         exprTypmod((Node *) te->expr),
                                          sublevels_up);
 
                        *colvars = lappend(*colvars, varnode);
@@ -1532,14 +1532,12 @@ expandRelAttrs(ParseState *pstate, List *rtable, int rtindex, int sublevels_up)
    {
        char       *label = strVal(lfirst(name));
        Node       *varnode = (Node *) lfirst(var);
-       TargetEntry *te = makeNode(TargetEntry);
-
-       te->resdom = makeResdom((AttrNumber) pstate->p_next_resno++,
-                               exprType(varnode),
-                               exprTypmod(varnode),
-                               label,
-                               false);
-       te->expr = (Expr *) varnode;
+       TargetEntry *te;
+
+       te = makeTargetEntry((Expr *) varnode,
+                            (AttrNumber) pstate->p_next_resno++,
+                            label,
+                            false);
        te_list = lappend(te_list, te);
    }
 
@@ -1641,11 +1639,11 @@ get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
                TargetEntry *te = get_tle_by_resno(rte->subquery->targetList,
                                                   attnum);
 
-               if (te == NULL || te->resdom->resjunk)
+               if (te == NULL || te->resjunk)
                    elog(ERROR, "subquery %s does not have attribute %d",
                         rte->eref->aliasname, attnum);
-               *vartype = te->resdom->restype;
-               *vartypmod = te->resdom->restypmod;
+               *vartype = exprType((Node *) te->expr);
+               *vartypmod = exprTypmod((Node *) te->expr);
            }
            break;
        case RTE_FUNCTION:
@@ -1856,7 +1854,7 @@ get_tle_by_resno(List *tlist, AttrNumber resno)
    {
        TargetEntry *tle = (TargetEntry *) lfirst(l);
 
-       if (tle->resdom->resno == resno)
+       if (tle->resno == resno)
            return tle;
    }
    return NULL;
index 8675bc2683900734de25690ee7af364a64069167..d537f570bd4d9adaa673a117781702cee720c040 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.130 2005/03/26 06:28:59 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.131 2005/04/06 16:34:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -30,7 +30,7 @@
 #include "utils/typcache.h"
 
 
-static void markTargetListOrigin(ParseState *pstate, Resdom *res,
+static void markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
                                 Var *var, int levelsup);
 static Node *transformAssignmentIndirection(ParseState *pstate,
                               Node *basenode,
@@ -65,17 +65,10 @@ transformTargetEntry(ParseState *pstate,
                     char *colname,
                     bool resjunk)
 {
-   Oid         type_id;
-   int32       type_mod;
-   Resdom     *resnode;
-
    /* Transform the node if caller didn't do it already */
    if (expr == NULL)
        expr = transformExpr(pstate, node);
 
-   type_id = exprType(expr);
-   type_mod = exprTypmod(expr);
-
    if (colname == NULL && !resjunk)
    {
        /*
@@ -85,13 +78,10 @@ transformTargetEntry(ParseState *pstate,
        colname = FigureColname(node);
    }
 
-   resnode = makeResdom((AttrNumber) pstate->p_next_resno++,
-                        type_id,
-                        type_mod,
-                        colname,
-                        resjunk);
-
-   return makeTargetEntry(resnode, (Expr *) expr);
+   return makeTargetEntry((Expr *) expr,
+                          (AttrNumber) pstate->p_next_resno++,
+                          colname,
+                          resjunk);
 }
 
 
@@ -176,13 +166,13 @@ markTargetListOrigins(ParseState *pstate, List *targetlist)
    {
        TargetEntry *tle = (TargetEntry *) lfirst(l);
 
-       markTargetListOrigin(pstate, tle->resdom, (Var *) tle->expr, 0);
+       markTargetListOrigin(pstate, tle, (Var *) tle->expr, 0);
    }
 }
 
 /*
  * markTargetListOrigin()
- *     If 'var' is a Var of a plain relation, mark 'res' with its origin
+ *     If 'var' is a Var of a plain relation, mark 'tle' with its origin
  *
  * levelsup is an extra offset to interpret the Var's varlevelsup correctly.
  *
@@ -190,7 +180,8 @@ markTargetListOrigins(ParseState *pstate, List *targetlist)
  * do not drill down into views, but report the view as the column owner.
  */
 static void
-markTargetListOrigin(ParseState *pstate, Resdom *res, Var *var, int levelsup)
+markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
+                    Var *var, int levelsup)
 {
    int         netlevelsup;
    RangeTblEntry *rte;
@@ -206,20 +197,20 @@ markTargetListOrigin(ParseState *pstate, Resdom *res, Var *var, int levelsup)
    {
        case RTE_RELATION:
            /* It's a table or view, report it */
-           res->resorigtbl = rte->relid;
-           res->resorigcol = attnum;
+           tle->resorigtbl = rte->relid;
+           tle->resorigcol = attnum;
            break;
        case RTE_SUBQUERY:
            {
                /* Subselect-in-FROM: copy up from the subselect */
-               TargetEntry *te = get_tle_by_resno(rte->subquery->targetList,
-                                                  attnum);
+               TargetEntry *ste = get_tle_by_resno(rte->subquery->targetList,
+                                                   attnum);
 
-               if (te == NULL || te->resdom->resjunk)
+               if (ste == NULL || ste->resjunk)
                    elog(ERROR, "subquery %s does not have attribute %d",
                         rte->eref->aliasname, attnum);
-               res->resorigtbl = te->resdom->resorigtbl;
-               res->resorigcol = te->resdom->resorigcol;
+               tle->resorigtbl = ste->resorigtbl;
+               tle->resorigcol = ste->resorigcol;
            }
            break;
        case RTE_JOIN:
@@ -229,7 +220,7 @@ markTargetListOrigin(ParseState *pstate, Resdom *res, Var *var, int levelsup)
 
                Assert(attnum > 0 && attnum <= list_length(rte->joinaliasvars));
                aliasvar = (Var *) list_nth(rte->joinaliasvars, attnum - 1);
-               markTargetListOrigin(pstate, res, aliasvar, netlevelsup);
+               markTargetListOrigin(pstate, tle, aliasvar, netlevelsup);
            }
            break;
        case RTE_SPECIAL:
@@ -264,7 +255,6 @@ updateTargetListEntry(ParseState *pstate,
    Oid         type_id;        /* type of value provided */
    Oid         attrtype;       /* type of target column */
    int32       attrtypmod;
-   Resdom     *resnode = tle->resdom;
    Relation    rd = pstate->p_target_relation;
 
    Assert(rd != NULL);
@@ -368,13 +358,6 @@ updateTargetListEntry(ParseState *pstate,
            errhint("You will need to rewrite or cast the expression.")));
    }
 
-   /*
-    * The result of the target expression should now match the
-    * destination column's type.
-    */
-   resnode->restype = attrtype;
-   resnode->restypmod = attrtypmod;
-
    /*
     * Set the resno to identify the target column --- the rewriter and
     * planner depend on this.  We also set the resname to identify the
@@ -382,8 +365,8 @@ updateTargetListEntry(ParseState *pstate,
     * not be relied on.  (In particular, it might be out of date in a
     * stored rule.)
     */
-   resnode->resno = (AttrNumber) attrno;
-   resnode->resname = colname;
+   tle->resno = (AttrNumber) attrno;
+   tle->resname = colname;
 }
 
 /*
@@ -881,13 +864,10 @@ ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind)
            fieldnode = (Node *) fselect;
        }
 
-       te = makeNode(TargetEntry);
-       te->resdom = makeResdom((AttrNumber) pstate->p_next_resno++,
-                               att->atttypid,
-                               att->atttypmod,
-                               pstrdup(NameStr(att->attname)),
-                               false);
-       te->expr = (Expr *) fieldnode;
+       te = makeTargetEntry((Expr *) fieldnode,
+                            (AttrNumber) pstate->p_next_resno++,
+                            pstrdup(NameStr(att->attname)),
+                            false);
        te_list = lappend(te_list, te);
    }
 
index 1d9458e834ee19677ddc0cd08f714787a692df2f..45c44501a665e9cc403ea6f85a3f1061eca0130d 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/rewrite/rewriteDefine.c,v 1.101 2005/01/27 23:24:05 neilc Exp $
+ *   $PostgreSQL: pgsql/src/backend/rewrite/rewriteDefine.c,v 1.102 2005/04/06 16:34:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -22,6 +22,7 @@
 #include "commands/view.h"
 #include "miscadmin.h"
 #include "optimizer/clauses.h"
+#include "parser/parse_expr.h"
 #include "parser/parse_relation.h"
 #include "rewrite/rewriteDefine.h"
 #include "rewrite/rewriteManip.h"
@@ -290,11 +291,11 @@ DefineQueryRewrite(RuleStmt *stmt)
        foreach(tllist, query->targetList)
        {
            TargetEntry *tle = (TargetEntry *) lfirst(tllist);
-           Resdom     *resdom = tle->resdom;
+           int32       tletypmod;
            Form_pg_attribute attr;
            char       *attname;
 
-           if (resdom->resjunk)
+           if (tle->resjunk)
                continue;
            i++;
            if (i > event_relation->rd_att->natts)
@@ -318,12 +319,12 @@ DefineQueryRewrite(RuleStmt *stmt)
                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                         errmsg("cannot convert relation containing dropped columns to view")));
 
-           if (strcmp(resdom->resname, attname) != 0)
+           if (strcmp(tle->resname, attname) != 0)
                ereport(ERROR,
                        (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
                         errmsg("SELECT rule's target entry %d has different column name from \"%s\"", i, attname)));
 
-           if (attr->atttypid != resdom->restype)
+           if (attr->atttypid != exprType((Node *) tle->expr))
                ereport(ERROR,
                        (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
                         errmsg("SELECT rule's target entry %d has different type from column \"%s\"", i, attname)));
@@ -335,8 +336,9 @@ DefineQueryRewrite(RuleStmt *stmt)
             * length but the select rule's expression will probably have
             * typmod = -1.
             */
-           if (attr->atttypmod != resdom->restypmod &&
-               attr->atttypmod != -1 && resdom->restypmod != -1)
+           tletypmod = exprTypmod((Node *) tle->expr);
+           if (attr->atttypmod != tletypmod &&
+               attr->atttypmod != -1 && tletypmod != -1)
                ereport(ERROR,
                        (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
                         errmsg("SELECT rule's target entry %d has different size from column \"%s\"", i, attname)));
index 844ab38e83951523794403c571fb7172ce0d793c..c190b634b2735d17d442091e50a63ce441cede87 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.149 2005/03/26 05:53:01 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.150 2005/04/06 16:34:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -312,12 +312,11 @@ rewriteTargetList(Query *parsetree, Relation target_relation)
    foreach(temp, parsetree->targetList)
    {
        TargetEntry *old_tle = (TargetEntry *) lfirst(temp);
-       Resdom     *resdom = old_tle->resdom;
 
-       if (!resdom->resjunk)
+       if (!old_tle->resjunk)
        {
            /* Normal attr: stash it into new_tles[] */
-           attrno = resdom->resno;
+           attrno = old_tle->resno;
            if (attrno < 1 || attrno > numattrs)
                elog(ERROR, "bogus resno %d in targetlist", attrno);
            att_tup = target_relation->rd_att->attrs[attrno - 1];
@@ -344,11 +343,10 @@ rewriteTargetList(Query *parsetree, Relation target_relation)
             */
 
            /* Get the resno right, but don't copy unnecessarily */
-           if (resdom->resno != next_junk_attrno)
+           if (old_tle->resno != next_junk_attrno)
            {
-               resdom = (Resdom *) copyObject((Node *) resdom);
-               resdom->resno = next_junk_attrno;
-               old_tle = makeTargetEntry(resdom, old_tle->expr);
+               old_tle = flatCopyTargetEntry(old_tle);
+               old_tle->resno = next_junk_attrno;
            }
            junk_tlist = lappend(junk_tlist, old_tle);
            next_junk_attrno++;
@@ -407,12 +405,10 @@ rewriteTargetList(Query *parsetree, Relation target_relation)
            }
 
            if (new_expr)
-               new_tle = makeTargetEntry(makeResdom(attrno,
-                                                    att_tup->atttypid,
-                                                    att_tup->atttypmod,
-                                     pstrdup(NameStr(att_tup->attname)),
-                                                    false),
-                                         (Expr *) new_expr);
+               new_tle = makeTargetEntry((Expr *) new_expr,
+                                         attrno,
+                                         pstrdup(NameStr(att_tup->attname)),
+                                         false);
        }
 
        if (new_tle)
@@ -436,7 +432,7 @@ process_matched_tle(TargetEntry *src_tle,
                    TargetEntry *prior_tle,
                    const char *attrName)
 {
-   Resdom     *resdom = src_tle->resdom;
+   TargetEntry *result;
    Node       *src_expr;
    Node       *prior_expr;
    Node       *src_input;
@@ -547,7 +543,9 @@ process_matched_tle(TargetEntry *src_tle,
        newexpr = NULL;
    }
 
-   return makeTargetEntry(resdom, (Expr *) newexpr);
+   result = flatCopyTargetEntry(src_tle);
+   result->expr = (Expr *) newexpr;
+   return result;
 }
 
 /*
index 814deff5e3a3ac53e2997bd3cc8d0e34954c7afc..2f8e86e4b06e50ecfe3977c12f1b8d88218ba50e 100644 (file)
@@ -3,7 +3,7 @@
  *             back to source text
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.189 2005/03/29 00:17:08 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.190 2005/04/06 16:34:06 tgl Exp $
  *
  *   This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -1493,13 +1493,12 @@ deparse_context_for_subplan(const char *name, List *tlist,
    foreach(tl, tlist)
    {
        TargetEntry *tle = lfirst(tl);
-       Resdom     *resdom = tle->resdom;
 
        nattrs++;
-       Assert(resdom->resno == nattrs);
-       if (resdom->resname)
+       Assert(tle->resno == nattrs);
+       if (tle->resname)
        {
-           attrs = lappend(attrs, makeString(resdom->resname));
+           attrs = lappend(attrs, makeString(tle->resname));
            continue;
        }
        if (tle->expr && IsA(tle->expr, Var))
@@ -1518,7 +1517,7 @@ deparse_context_for_subplan(const char *name, List *tlist,
            }
        }
        /* Fallback if can't get name */
-       snprintf(buf, sizeof(buf), "?column%d?", resdom->resno);
+       snprintf(buf, sizeof(buf), "?column%d?", tle->resno);
        attrs = lappend(attrs, makeString(pstrdup(buf)));
    }
 
@@ -1974,7 +1973,7 @@ get_basic_select_query(Query *query, deparse_context *context,
        TargetEntry *tle = (TargetEntry *) lfirst(l);
        char       *colname;
 
-       if (tle->resdom->resjunk)
+       if (tle->resjunk)
            continue;           /* ignore junk entries */
 
        appendStringInfo(buf, sep);
@@ -1992,7 +1991,7 @@ get_basic_select_query(Query *query, deparse_context *context,
        if (resultDesc && colno <= resultDesc->natts)
            colname = NameStr(resultDesc->attrs[colno - 1]->attname);
        else
-           colname = tle->resdom->resname;
+           colname = tle->resname;
 
        if (colname)            /* resname could be NULL */
        {
@@ -2166,8 +2165,8 @@ get_rule_sortgroupclause(SortClause *srt, List *tlist, bool force_colno,
     */
    if (force_colno || (expr && IsA(expr, Const)))
    {
-       Assert(!tle->resdom->resjunk);
-       appendStringInfo(buf, "%d", tle->resdom->resno);
+       Assert(!tle->resjunk);
+       appendStringInfo(buf, "%d", tle->resno);
    }
    else
        get_rule_expr(expr, context, true);
@@ -2227,7 +2226,7 @@ get_insert_query_def(Query *query, deparse_context *context)
    {
        TargetEntry *tle = (TargetEntry *) lfirst(l);
 
-       if (tle->resdom->resjunk)
+       if (tle->resjunk)
            continue;           /* ignore junk entries */
 
        appendStringInfo(buf, sep);
@@ -2239,7 +2238,7 @@ get_insert_query_def(Query *query, deparse_context *context)
         */
        appendStringInfoString(buf,
                    quote_identifier(get_relid_attribute_name(rte->relid,
-                                                  tle->resdom->resno)));
+                                                             tle->resno)));
 
        /*
         * Print any indirection needed (subfields or subscripts), and
@@ -2299,7 +2298,7 @@ get_update_query_def(Query *query, deparse_context *context)
        TargetEntry *tle = (TargetEntry *) lfirst(l);
        Node       *expr;
 
-       if (tle->resdom->resjunk)
+       if (tle->resjunk)
            continue;           /* ignore junk entries */
 
        appendStringInfo(buf, sep);
@@ -2311,7 +2310,7 @@ get_update_query_def(Query *query, deparse_context *context)
         */
        appendStringInfoString(buf,
                    quote_identifier(get_relid_attribute_name(rte->relid,
-                                                  tle->resdom->resno)));
+                                                             tle->resno)));
 
        /*
         * Print any indirection needed (subfields or subscripts), and
index 45b1695fcaa3276fdf9870a7cdfe2035fbeb43e1..4243ce19b2820bb5cfe392a2d2aae591cc16e68a 100644 (file)
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.262 2005/03/29 19:44:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.263 2005/04/06 16:34:07 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*                         yyyymmddN */
-#define CATALOG_VERSION_NO 200503291
+#define CATALOG_VERSION_NO 200504061
 
 #endif
index 8d50f49971853ba229dbb8389046ffc447b98555..52444d258b6ab0d6716139389b3b72e65c3552f0 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/makefuncs.h,v 1.51 2004/12/31 22:03:34 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/makefuncs.h,v 1.52 2005/04/06 16:34:07 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -29,13 +29,12 @@ extern Var *makeVar(Index varno,
        int32 vartypmod,
        Index varlevelsup);
 
-extern TargetEntry *makeTargetEntry(Resdom *resdom, Expr *expr);
+extern TargetEntry *makeTargetEntry(Expr *expr,
+                                   AttrNumber resno,
+                                   char *resname,
+                                   bool resjunk);
 
-extern Resdom *makeResdom(AttrNumber resno,
-          Oid restype,
-          int32 restypmod,
-          char *resname,
-          bool resjunk);
+extern TargetEntry *flatCopyTargetEntry(TargetEntry *src_tle);
 
 extern Const *makeConst(Oid consttype,
          int constlen,
index 5d70180a0c5775dcbb2adc6b86427e47c7657efa..4822b5f6cc43bf9a99f86ee26935d6a878b82128 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.164 2005/03/14 00:19:37 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.165 2005/04/06 16:34:07 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -93,8 +93,7 @@ typedef enum NodeTag
    /*
     * TAGS FOR PRIMITIVE NODES (primnodes.h)
     */
-   T_Resdom = 300,
-   T_Alias,
+   T_Alias = 300,
    T_RangeVar,
    T_Expr,
    T_Var,
index a6a79e3a4fa5fc041bcdd3b9f9f8bb19915454cd..85016f351123ee92c3fe79ea3f0e2515a713b126 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.275 2005/03/29 17:58:51 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.276 2005/04/06 16:34:07 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -552,11 +552,11 @@ typedef struct RangeTblEntry
  * SortClause -
  *    representation of ORDER BY clauses
  *
- * tleSortGroupRef must match ressortgroupref of exactly one Resdom of the
+ * tleSortGroupRef must match ressortgroupref of exactly one entry of the
  * associated targetlist; that is the expression to be sorted (or grouped) by.
  * sortop is the OID of the ordering operator.
  *
- * SortClauses are also used to identify Resdoms that we will do a "Unique"
+ * SortClauses are also used to identify targets that we will do a "Unique"
  * filter step on (for SELECT DISTINCT and SELECT DISTINCT ON).  The
  * distinctClause list is simply a copy of the relevant members of the
  * sortClause list.  Note that distinctClause can be a subset of sortClause,
index 46de880565acadb40278701716d01164566aab73..a1d1ef3ebf06048e0adfdfb33796a3c88443ecbf 100644 (file)
@@ -10,7 +10,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.106 2004/12/31 22:03:34 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.107 2005/04/06 16:34:07 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
  * ----------------------------------------------------------------
  */
 
-/*--------------------
- * Resdom (Result Domain)
- *
- * Notes:
- *
- * In a SELECT's targetlist, resno should always be equal to the item's
- * ordinal position (counting from 1). However, in an INSERT or UPDATE
- * targetlist, resno represents the attribute number of the destination
- * column for the item; so there may be missing or out-of-order resnos.
- * It is even legal to have duplicated resnos; consider
- *     UPDATE table SET arraycol[1] = ..., arraycol[2] = ..., ...
- * The two meanings come together in the executor, because the planner
- * transforms INSERT/UPDATE tlists into a normalized form with exactly
- * one entry for each column of the destination table. Before that's
- * happened, however, it is risky to assume that resno == position.
- * Generally get_tle_by_resno() should be used rather than list_nth()
- * to fetch tlist entries by resno, and only in SELECT should you assume
- * that resno is a unique identifier.
- *
- * resname is required to represent the correct column name in non-resjunk
- * entries of top-level SELECT targetlists, since it will be used as the
- * column title sent to the frontend.  In most other contexts it is only
- * a debugging aid, and may be wrong or even NULL. (In particular, it may
- * be wrong in a tlist from a stored rule, if the referenced column has been
- * renamed by ALTER TABLE since the rule was made. Also, the planner tends
- * to store NULL rather than look up a valid name for tlist entries in
- * non-toplevel plan nodes.)  In resjunk entries, resname should be either
- * a specific system-generated name (such as "ctid") or NULL; anything else
- * risks confusing ExecGetJunkAttribute!
- *
- * ressortgroupref is used in the representation of ORDER BY and
- * GROUP BY items. Targetlist entries with ressortgroupref=0 are not
- * sort/group items.  If ressortgroupref>0, then this item is an ORDER BY or
- * GROUP BY value. No two entries in a targetlist may have the same nonzero
- * ressortgroupref --- but there is no particular meaning to the nonzero
- * values, except as tags. (For example, one must not assume that lower
- * ressortgroupref means a more significant sort key.) The order of the
- * associated SortClause or GroupClause lists determine the semantics.
- *
- * resorigtbl/resorigcol identify the source of the column, if it is a
- * simple reference to a column of a base table (or view). If it is not
- * a simple reference, these fields are zeroes.
- *
- * If resjunk is true then the column is a working column (such as a sort key)
- * that should be removed from the final output of the query.  Resjunk columns
- * must have resnos that cannot duplicate any regular column's resno.  Also
- * note that there are places that assume resjunk columns come after non-junk
- * columns.
- *--------------------
- */
-typedef struct Resdom
-{
-   NodeTag     type;
-   AttrNumber  resno;          /* attribute number (see notes above) */
-   Oid         restype;        /* type of the value */
-   int32       restypmod;      /* type-specific modifier of the value */
-   char       *resname;        /* name of the column (could be NULL) */
-   Index       ressortgroupref;/* nonzero if referenced by a sort/group
-                                * clause */
-   Oid         resorigtbl;     /* OID of column's source table */
-   AttrNumber  resorigcol;     /* column's number in source table */
-   bool        resjunk;        /* set to true to eliminate the attribute
-                                * from final target list */
-} Resdom;
-
-
 /*
  * Alias -
  *   specifies an alias for a range variable; the alias might also
@@ -822,7 +756,7 @@ typedef struct SetToDefault
    int32       typeMod;        /* typemod for substituted value */
 } SetToDefault;
 
-/*
+/*--------------------
  * TargetEntry -
  *    a target entry (used in query target lists)
  *
@@ -831,14 +765,63 @@ typedef struct SetToDefault
  * very many places it's convenient to process a whole query targetlist as a
  * single expression tree.
  *
- * The separation between TargetEntry and Resdom is historical.  One of these
- * days, Resdom should probably get folded into TargetEntry.
+ * In a SELECT's targetlist, resno should always be equal to the item's
+ * ordinal position (counting from 1). However, in an INSERT or UPDATE
+ * targetlist, resno represents the attribute number of the destination
+ * column for the item; so there may be missing or out-of-order resnos.
+ * It is even legal to have duplicated resnos; consider
+ *     UPDATE table SET arraycol[1] = ..., arraycol[2] = ..., ...
+ * The two meanings come together in the executor, because the planner
+ * transforms INSERT/UPDATE tlists into a normalized form with exactly
+ * one entry for each column of the destination table. Before that's
+ * happened, however, it is risky to assume that resno == position.
+ * Generally get_tle_by_resno() should be used rather than list_nth()
+ * to fetch tlist entries by resno, and only in SELECT should you assume
+ * that resno is a unique identifier.
+ *
+ * resname is required to represent the correct column name in non-resjunk
+ * entries of top-level SELECT targetlists, since it will be used as the
+ * column title sent to the frontend.  In most other contexts it is only
+ * a debugging aid, and may be wrong or even NULL. (In particular, it may
+ * be wrong in a tlist from a stored rule, if the referenced column has been
+ * renamed by ALTER TABLE since the rule was made. Also, the planner tends
+ * to store NULL rather than look up a valid name for tlist entries in
+ * non-toplevel plan nodes.)  In resjunk entries, resname should be either
+ * a specific system-generated name (such as "ctid") or NULL; anything else
+ * risks confusing ExecGetJunkAttribute!
+ *
+ * ressortgroupref is used in the representation of ORDER BY and
+ * GROUP BY items. Targetlist entries with ressortgroupref=0 are not
+ * sort/group items.  If ressortgroupref>0, then this item is an ORDER BY or
+ * GROUP BY value. No two entries in a targetlist may have the same nonzero
+ * ressortgroupref --- but there is no particular meaning to the nonzero
+ * values, except as tags. (For example, one must not assume that lower
+ * ressortgroupref means a more significant sort key.) The order of the
+ * associated SortClause or GroupClause lists determine the semantics.
+ *
+ * resorigtbl/resorigcol identify the source of the column, if it is a
+ * simple reference to a column of a base table (or view). If it is not
+ * a simple reference, these fields are zeroes.
+ *
+ * If resjunk is true then the column is a working column (such as a sort key)
+ * that should be removed from the final output of the query.  Resjunk columns
+ * must have resnos that cannot duplicate any regular column's resno.  Also
+ * note that there are places that assume resjunk columns come after non-junk
+ * columns.
+ *--------------------
  */
 typedef struct TargetEntry
 {
    Expr        xpr;
-   Resdom     *resdom;         /* descriptor for targetlist item */
    Expr       *expr;           /* expression to evaluate */
+   AttrNumber  resno;          /* attribute number (see notes above) */
+   char       *resname;        /* name of the column (could be NULL) */
+   Index       ressortgroupref;/* nonzero if referenced by a sort/group
+                                * clause */
+   Oid         resorigtbl;     /* OID of column's source table */
+   AttrNumber  resorigcol;     /* column's number in source table */
+   bool        resjunk;        /* set to true to eliminate the attribute
+                                * from final target list */
 } TargetEntry;
 
 
index 33df54cd5d68a8d1a1e19786d79722b2cd2ed44a..91418033ae1c00892452434422511b81f9483203 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/optimizer/tlist.h,v 1.41 2004/12/31 22:03:36 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/optimizer/tlist.h,v 1.42 2005/04/06 16:34:07 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "nodes/relation.h"
 
 
-extern TargetEntry *tlistentry_member(Node *node, List *targetlist);
-extern Resdom *tlist_member(Node *node, List *targetlist);
-
-extern TargetEntry *create_tl_element(Var *var, int resdomno);
+extern TargetEntry *tlist_member(Node *node, List *targetlist);
 
 extern List *flatten_tlist(List *tlist);
 extern List *add_to_flat_tlist(List *tlist, List *vars);
index 241c4bb5d57bf57fa3901256c0b7484dfeaf101e..6d85edfcf84a8fc181a8612f06cb0e6bdd53d1e0 100644 (file)
@@ -71,9 +71,8 @@ transformFromClause().</A>  Query.rtable holds the query's range table.</P><P>
 Certain queries, like <I>SELECT,</I> return columns of data.  Other
 queries, like <I>INSERT</I> and <I>UPDATE,</I> specify the columns
 modified by the query.  These column references are converted to <A
-HREF="../../include/nodes/primnodes.h">Resdom</A> entries, which are
-placed in <A HREF="../../include/nodes/parsenodes.h">target list
-entries,</A> and linked together to make up the <I>target list</I> of
+HREF="../../include/nodes/primnodes.h">TargetEntry</A> entries, which are
+linked together to make up the <I>target list</I> of
 the query. The target list is stored in Query.targetList, which is
 generated by <A
 HREF="../../backend/parser/parse_target.c">transformTargetList().</A></P><P>