Merge Resdom nodes into TargetEntry nodes to simplify code and save a
authorTom Lane
Wed, 6 Apr 2005 16:34:07 +0000 (16:34 +0000)
committerTom Lane
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 : "");
-       if (tle->resdom->ressortgroupref != 0)
-           printf("(%u):\t", tle->resdom->ressortgroupref);
+       printf("\t%d %s\t", tle->resno,
+              tle->resname ? tle->resname : "");
+       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().  Query.rtable holds the query's range table.

 Certain queries, like SELECT, return columns of data.  Other
 queries, like INSERT and UPDATE, specify the columns
 modified by the query.  These column references are converted to 
-HREF="../../include/nodes/primnodes.h">Resdom entries, which are
-placed in target list
-entries, and linked together to make up the target list of
+HREF="../../include/nodes/primnodes.h">TargetEntry entries, which are
+linked together to make up the target list of
 the query. The target list is stored in Query.targetList, which is
 generated by 
 HREF="../../backend/parser/parse_target.c">transformTargetList().