]> granicus.if.org Git - postgresql/commitdiff
Use Params, rather than run-time-modified Const nodes, to handle
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 26 Nov 2002 03:01:59 +0000 (03:01 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 26 Nov 2002 03:01:59 +0000 (03:01 +0000)
sublink results and COPY's domain constraint checking.  A Const that
isn't really constant is just a Bad Idea(tm).  Remove hacks in
parse_coerce and other places that were needed because of the former
klugery.

src/backend/commands/copy.c
src/backend/executor/nodeSubplan.c
src/backend/optimizer/plan/planner.c
src/backend/optimizer/plan/subselect.c
src/backend/optimizer/util/clauses.c
src/backend/parser/parse_coerce.c
src/backend/parser/parse_expr.c
src/backend/utils/adt/ruleutils.c
src/include/nodes/primnodes.h

index 39f13e5a3e5cf107775fa8cecd123ef1f995736a..242973f20f656eee0cf19e04a64a8b5023a0d644 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.182 2002/11/25 21:29:34 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.183 2002/11/26 03:01:57 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -749,7 +749,6 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
        FmgrInfo   *in_functions;
        Oid                *elements;
        Node      **constraintexprs;
-       Const     **constraintconsts;
        bool            hasConstraints = false;
        int                     i;
        List       *cur;
@@ -805,7 +804,6 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
        defmap = (int *) palloc(num_phys_attrs * sizeof(int));
        defexprs = (Node **) palloc(num_phys_attrs * sizeof(Node *));
        constraintexprs = (Node **) palloc0(num_phys_attrs * sizeof(Node *));
-       constraintconsts = (Const **) palloc(num_phys_attrs * sizeof(Const *));
 
        for (i = 0; i < num_phys_attrs; i++)
        {
@@ -840,7 +838,7 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
                /* If it's a domain type, get info on domain constraints */
                if (get_typtype(attr[i]->atttypid) == 'd')
                {
-                       Const      *con;
+                       Param      *prm;
                        Node       *node;
 
                        /*
@@ -848,28 +846,21 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
                         * an expression that checks the constraints.  (At present,
                         * the expression might contain a length-coercion-function call
                         * and/or ConstraintTest nodes.)  The bottom of the expression
-                        * is a Const node that we fill in with the actual datum during
+                        * is a Param node so that we can fill in the actual datum during
                         * the data input loop.
-                        *
-                        * XXX to prevent premature constant folding in parse_coerce,
-                        * pass in a NULL constant to start with.  See the comments in
-                        * coerce_type; this should be changed someday to use some sort
-                        * of Param node instead of a Const.
                         */
-                       con = makeConst(attr[i]->atttypid,
-                                                       attr[i]->attlen,
-                                                       (Datum) 0,
-                                                       true,            /* is null */
-                                                       attr[i]->attbyval);
+                       prm = makeNode(Param);
+                       prm->paramkind = PARAM_EXEC;
+                       prm->paramid = 0;
+                       prm->paramtype = attr[i]->atttypid;
 
-                       node = coerce_type_constraints((Node *) con, attr[i]->atttypid,
+                       node = coerce_type_constraints((Node *) prm, attr[i]->atttypid,
                                                                                   COERCE_IMPLICIT_CAST);
 
                        /* check whether any constraints actually found */
-                       if (node != (Node *) con)
+                       if (node != (Node *) prm)
                        {
                                constraintexprs[i] = node;
-                               constraintconsts[i] = con;
                                hasConstraints = true;
                        }
                }
@@ -931,6 +922,11 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
 
        econtext = GetPerTupleExprContext(estate);
 
+       /* Make room for a PARAM_EXEC value for domain constraint checks */
+       if (hasConstraints)
+               econtext->ecxt_param_exec_vals = (ParamExecData *)
+                       palloc0(sizeof(ParamExecData));
+
        while (!done)
        {
                bool            skip_tuple;
@@ -1153,19 +1149,19 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
                 */
                if (hasConstraints)
                {
+                       ParamExecData *prmdata = &econtext->ecxt_param_exec_vals[0];
+
                        for (i = 0; i < num_phys_attrs; i++)
                        {
                                Node       *node = constraintexprs[i];
-                               Const      *con;
                                bool            isnull;
 
                                if (node == NULL)
                                        continue;       /* no constraint for this attr */
 
-                               /* Insert current row's value into the Const node */
-                               con = constraintconsts[i];
-                               con->constvalue = values[i];
-                               con->constisnull = (nulls[i] == 'n');
+                               /* Insert current row's value into the Param value */
+                               prmdata->value = values[i];
+                               prmdata->isnull = (nulls[i] == 'n');
 
                                /*
                                 * Execute the constraint expression.  Allow the expression
index 0c7b3557cff89a9af577217b7e71453a0462b2d3..73ff6370fbcd99a935124ad07540d392351e0605 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/executor/nodeSubplan.c,v 1.33 2002/06/20 20:29:28 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/executor/nodeSubplan.c,v 1.34 2002/11/26 03:01:57 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -150,37 +150,44 @@ ExecSubPlan(SubPlan *node, List *pvar, ExprContext *econtext, bool *isNull)
                foreach(lst, sublink->oper)
                {
                        Expr       *expr = (Expr *) lfirst(lst);
-                       Const      *con = lsecond(expr->args);
+                       Param      *prm = lsecond(expr->args);
+                       ParamExecData *prmdata;
                        Datum           expresult;
                        bool            expnull;
 
                        /*
                         * The righthand side of the expression should be either a
-                        * Const or a function call or RelabelType node taking a Const
+                        * Param or a function call or RelabelType node taking a Param
                         * as arg (these nodes represent run-time type coercions
                         * inserted by the parser to get to the input type needed by
-                        * the operator). Find the Const node and insert the actual
-                        * righthand-side value into it.
+                        * the operator). Find the Param node and insert the actual
+                        * righthand-side value into the param's econtext slot.
+                        *
+                        * XXX possible improvement: could make a list of the ParamIDs
+                        * at startup time, instead of repeating this check at each row.
                         */
-                       if (!IsA(con, Const))
+                       if (!IsA(prm, Param))
                        {
-                               switch (con->type)
+                               switch (nodeTag(prm))
                                {
                                        case T_Expr:
-                                               con = lfirst(((Expr *) con)->args);
+                                               prm = lfirst(((Expr *) prm)->args);
                                                break;
                                        case T_RelabelType:
-                                               con = (Const *) (((RelabelType *) con)->arg);
+                                               prm = (Param *) (((RelabelType *) prm)->arg);
                                                break;
                                        default:
                                                /* will fail below */
                                                break;
                                }
-                               if (!IsA(con, Const))
+                               if (!IsA(prm, Param))
                                        elog(ERROR, "ExecSubPlan: failed to find placeholder for subplan result");
                        }
-                       con->constvalue = heap_getattr(tup, col, tdesc,
-                                                                                  &(con->constisnull));
+                       Assert(prm->paramkind == PARAM_EXEC);
+                       prmdata = &(econtext->ecxt_param_exec_vals[prm->paramid]);
+                       Assert(prmdata->execPlan == NULL);
+                       prmdata->value = heap_getattr(tup, col, tdesc,
+                                                                                 &(prmdata->isnull));
 
                        /*
                         * Now we can eval the combining operator for this column.
index 9a5141ea6b94891b55eda99014626783568652a0..2c1081f2677ac7ddefaf9c24cbc63316c708dc76 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.130 2002/11/21 00:42:19 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.131 2002/11/26 03:01:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -720,8 +720,6 @@ preprocess_expression(Query *parse, Node *expr, int kind)
         *
         * Note that at this point quals have not yet been converted to
         * implicit-AND form, so we can apply eval_const_expressions directly.
-        * Also note that we need to do this before SS_process_sublinks,
-        * because that routine inserts bogus "Const" nodes.
         */
        expr = eval_const_expressions(expr);
 
index 1dcebba2e773282b9de52722f6ec63b8e9c28f57..5b171fb819a20babcc31e48250bdf0364a59a686 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.55 2002/09/04 20:31:21 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.56 2002/11/26 03:01:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -44,24 +44,32 @@ int                 PlannerPlanId = 0;      /* to assign unique ID to subquery plans */
  * and update the list elements when we enter or exit a subplan
  * recursion level.  But we must pay attention not to confuse this
  * meaning with the normal meaning of varlevelsup.
+ *
+ * We also need to create Param slots that don't correspond to any outer Var.
+ * For these, we set varno = 0 and varlevelsup = 0, so that they can't
+ * accidentally match an outer Var.
  *--------------------
  */
 
 
+static void convert_sublink_opers(SubLink *slink, List *targetlist,
+                                                                 List **setParams);
+
+
 /*
  * Create a new entry in the PlannerParamVar list, and return its index.
  *
- * var contains the data to be copied, except for varlevelsup which
- * is set from the absolute level value given by varlevel.
+ * var contains the data to use, except for varlevelsup which
+ * is set from the absolute level value given by varlevel.  NOTE that
+ * the passed var is scribbled on and placed directly into the list!
+ * Generally, caller should have just created or copied it.
  */
 static int
 new_param(Var *var, Index varlevel)
 {
-       Var                *paramVar = (Var *) copyObject(var);
+       var->varlevelsup = varlevel;
 
-       paramVar->varlevelsup = varlevel;
-
-       PlannerParamVar = lappend(PlannerParamVar, paramVar);
+       PlannerParamVar = lappend(PlannerParamVar, var);
 
        return length(PlannerParamVar) - 1;
 }
@@ -107,7 +115,7 @@ replace_var(Var *var)
        if (!ppv)
        {
                /* Nope, so make a new one */
-               i = new_param(var, varlevel);
+               i = new_param((Var *) copyObject(var), varlevel);
        }
 
        retval = makeNode(Param);
@@ -118,6 +126,22 @@ replace_var(Var *var)
        return retval;
 }
 
+/*
+ * Generate a new Param node that will not conflict with any other.
+ */
+static Param *
+generate_new_param(Oid paramtype, int32 paramtypmod)
+{
+       Var                *var = makeVar(0, 0, paramtype, paramtypmod, 0);
+       Param      *retval = makeNode(Param);
+
+       retval->paramkind = PARAM_EXEC;
+       retval->paramid = (AttrNumber) new_param(var, 0);
+       retval->paramtype = paramtype;
+
+       return retval;
+}
+
 /*
  * Convert a bare SubLink (as created by the parser) into a SubPlan.
  */
@@ -216,13 +240,9 @@ make_subplan(SubLink *slink)
         */
        if (node->parParam == NIL && slink->subLinkType == EXISTS_SUBLINK)
        {
-               Var                *var = makeVar(0, 0, BOOLOID, -1, 0);
-               Param      *prm = makeNode(Param);
+               Param      *prm;
 
-               prm->paramkind = PARAM_EXEC;
-               prm->paramid = (AttrNumber) new_param(var, PlannerQueryLevel);
-               prm->paramtype = var->vartype;
-               pfree(var);                             /* var is only needed for new_param */
+               prm = generate_new_param(BOOLOID, -1);
                node->setParam = lappendi(node->setParam, prm->paramid);
                PlannerInitPlan = lappend(PlannerInitPlan, node);
                result = (Node *) prm;
@@ -230,89 +250,27 @@ make_subplan(SubLink *slink)
        else if (node->parParam == NIL && slink->subLinkType == EXPR_SUBLINK)
        {
                TargetEntry *te = lfirst(plan->targetlist);
+               Param      *prm;
 
-               /* need a var node just to pass to new_param()... */
-               Var                *var = makeVar(0, 0, te->resdom->restype,
-                                                                 te->resdom->restypmod, 0);
-               Param      *prm = makeNode(Param);
-
-               prm->paramkind = PARAM_EXEC;
-               prm->paramid = (AttrNumber) new_param(var, PlannerQueryLevel);
-               prm->paramtype = var->vartype;
-               pfree(var);                             /* var is only needed for new_param */
+               prm = generate_new_param(te->resdom->restype, te->resdom->restypmod);
                node->setParam = lappendi(node->setParam, prm->paramid);
                PlannerInitPlan = lappend(PlannerInitPlan, node);
                result = (Node *) prm;
        }
        else if (node->parParam == NIL && slink->subLinkType == MULTIEXPR_SUBLINK)
        {
-               List       *newoper = NIL;
-               int                     i = 0;
-
-               /*
-                * Convert oper list of Opers into a list of Exprs, using lefthand
-                * arguments and Params representing inside results.
-                */
-               foreach(lst, slink->oper)
-               {
-                       Oper       *oper = (Oper *) lfirst(lst);
-                       Node       *lefthand = nth(i, slink->lefthand);
-                       TargetEntry *te = nth(i, plan->targetlist);
-
-                       /* need a var node just to pass to new_param()... */
-                       Var                *var = makeVar(0, 0, te->resdom->restype,
-                                                                         te->resdom->restypmod, 0);
-                       Param      *prm = makeNode(Param);
-                       Operator        tup;
-                       Form_pg_operator opform;
-                       Node       *left,
-                                          *right;
-
-                       prm->paramkind = PARAM_EXEC;
-                       prm->paramid = (AttrNumber) new_param(var, PlannerQueryLevel);
-                       prm->paramtype = var->vartype;
-                       pfree(var);                     /* var is only needed for new_param */
-
-                       Assert(IsA(oper, Oper));
-                       tup = SearchSysCache(OPEROID,
-                                                                ObjectIdGetDatum(oper->opno),
-                                                                0, 0, 0);
-                       if (!HeapTupleIsValid(tup))
-                               elog(ERROR, "cache lookup failed for operator %u", oper->opno);
-                       opform = (Form_pg_operator) GETSTRUCT(tup);
-
-                       /*
-                        * Note: we use make_operand in case runtime type conversion
-                        * function calls must be inserted for this operator!
-                        */
-                       left = make_operand(lefthand,
-                                                               exprType(lefthand), opform->oprleft);
-                       right = make_operand((Node *) prm,
-                                                                prm->paramtype, opform->oprright);
-                       ReleaseSysCache(tup);
-
-                       newoper = lappend(newoper,
-                                                         make_opclause(oper,
-                                                                                       (Var *) left,
-                                                                                       (Var *) right));
-                       node->setParam = lappendi(node->setParam, prm->paramid);
-                       i++;
-               }
-               slink->oper = newoper;
-               slink->lefthand = NIL;
+               convert_sublink_opers(slink, plan->targetlist, &node->setParam);
                PlannerInitPlan = lappend(PlannerInitPlan, node);
-               if (i > 1)
-                       result = (Node *) ((slink->useor) ? make_orclause(newoper) :
-                                                          make_andclause(newoper));
+               if (length(slink->oper) > 1)
+                       result = (Node *) ((slink->useor) ? make_orclause(slink->oper) :
+                                                          make_andclause(slink->oper));
                else
-                       result = (Node *) lfirst(newoper);
+                       result = (Node *) lfirst(slink->oper);
        }
        else
        {
                Expr       *expr = makeNode(Expr);
                List       *args = NIL;
-               List       *newoper = NIL;
-               int                     i = 0;
 
                /*
                 * We can't convert subplans of ALL_SUBLINK or ANY_SUBLINK types
@@ -379,6 +337,9 @@ make_subplan(SubLink *slink)
                        }
                }
 
+               /* Fix the SubLink's oper list */
+               convert_sublink_opers(slink, plan->targetlist, NULL);
+
                /*
                 * Make expression of SUBPLAN type
                 */
@@ -405,53 +366,82 @@ make_subplan(SubLink *slink)
                }
                expr->args = args;
 
+               result = (Node *) expr;
+       }
+
+       return result;
+}
+
+/*
+ * convert_sublink_opers: convert a SubLink's oper list from the
+ * parser/rewriter format into the executor's format.
+ *
+ * The oper list is initially just a list of Oper nodes.  We replace it
+ * with a list of actually executable expressions, in which the specified
+ * operators are applied to corresponding elements of the lefthand list
+ * and Params representing the results of the subplan.  lefthand is then
+ * set to NIL.
+ *
+ * If setParams is not NULL, the paramids of the Params created are added
+ * to the *setParams list.
+ */
+static void
+convert_sublink_opers(SubLink *slink, List *targetlist,
+                                         List **setParams)
+{
+       List       *newoper = NIL;
+       List       *leftlist = slink->lefthand;
+       List       *lst;
+
+       foreach(lst, slink->oper)
+       {
+               Oper       *oper = (Oper *) lfirst(lst);
+               Node       *lefthand = lfirst(leftlist);
+               TargetEntry *te = lfirst(targetlist);
+               Param      *prm;
+               Operator        tup;
+               Form_pg_operator opform;
+               Node       *left,
+                                  *right;
+
+               /* Make the Param node representing the subplan's result */
+               prm = generate_new_param(te->resdom->restype,
+                                                                te->resdom->restypmod);
+
+               /* Record its ID if needed */
+               if (setParams)
+                       *setParams = lappendi(*setParams, prm->paramid);
+
+               /* Look up the operator to check its declared input types */
+               Assert(IsA(oper, Oper));
+               tup = SearchSysCache(OPEROID,
+                                                        ObjectIdGetDatum(oper->opno),
+                                                        0, 0, 0);
+               if (!HeapTupleIsValid(tup))
+                       elog(ERROR, "cache lookup failed for operator %u", oper->opno);
+               opform = (Form_pg_operator) GETSTRUCT(tup);
+
                /*
-                * Convert oper list of Opers into a list of Exprs, using lefthand
-                * arguments and Consts representing inside results.
+                * Make the expression node.
+                *
+                * Note: we use make_operand in case runtime type conversion
+                * function calls must be inserted for this operator!
                 */
-               foreach(lst, slink->oper)
-               {
-                       Oper       *oper = (Oper *) lfirst(lst);
-                       Node       *lefthand = nth(i, slink->lefthand);
-                       TargetEntry *te = nth(i, plan->targetlist);
-                       Const      *con;
-                       Operator        tup;
-                       Form_pg_operator opform;
-                       Node       *left,
-                                          *right;
-
-                       con = makeNullConst(te->resdom->restype);
-
-                       Assert(IsA(oper, Oper));
-                       tup = SearchSysCache(OPEROID,
-                                                                ObjectIdGetDatum(oper->opno),
-                                                                0, 0, 0);
-                       if (!HeapTupleIsValid(tup))
-                               elog(ERROR, "cache lookup failed for operator %u", oper->opno);
-                       opform = (Form_pg_operator) GETSTRUCT(tup);
+               left = make_operand(lefthand, exprType(lefthand), opform->oprleft);
+               right = make_operand((Node *) prm, prm->paramtype, opform->oprright);
+               newoper = lappend(newoper,
+                                                 make_opclause(oper,
+                                                                               (Var *) left,
+                                                                               (Var *) right));
 
-                       /*
-                        * Note: we use make_operand in case runtime type conversion
-                        * function calls must be inserted for this operator!
-                        */
-                       left = make_operand(lefthand,
-                                                               exprType(lefthand), opform->oprleft);
-                       right = make_operand((Node *) con,
-                                                                con->consttype, opform->oprright);
-                       ReleaseSysCache(tup);
-
-                       newoper = lappend(newoper,
-                                                         make_opclause(oper,
-                                                                                       (Var *) left,
-                                                                                       (Var *) right));
-                       i++;
-               }
-               slink->oper = newoper;
-               slink->lefthand = NIL;
-               result = (Node *) expr;
+               ReleaseSysCache(tup);
+
+               leftlist = lnext(leftlist);
+               targetlist = lnext(targetlist);
        }
 
-       return result;
+       slink->oper = newoper;
+       slink->lefthand = NIL;
 }
 
 /*
index 2bc1c2afbec244d0c1c975bfb6c2d9661ddd4ab7..8ba8483a9573d536357faaef3f24379e18293551 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.112 2002/11/25 21:29:40 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.113 2002/11/26 03:01:58 tgl Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -1135,14 +1135,6 @@ CommuteClause(Expr *clause)
  *
  * We assume that the tree has already been type-checked and contains
  * only operators and functions that are reasonable to try to execute.
- *
- * This routine should be invoked before converting sublinks to subplans
- * (subselect.c's SS_process_sublinks()).  The converted form contains
- * bogus "Const" nodes that are actually placeholders where the executor
- * will insert values from the inner plan, and obviously we mustn't try
- * to reduce the expression as though these were really constants.
- * As a safeguard, if we happen to find an already-converted SubPlan node,
- * we will return it unchanged rather than recursing into it.
  *--------------------
  */
 Node *
@@ -1411,11 +1403,13 @@ eval_const_expressions_mutator(Node *node, void *context)
                        case SUBPLAN_EXPR:
 
                                /*
-                                * Safety measure per notes at head of this routine:
-                                * return a SubPlan unchanged.  Too late to do anything
+                                * Return a SubPlan unchanged --- too late to do anything
                                 * with it.  The arglist simplification above was wasted
                                 * work (the list probably only contains Var nodes
                                 * anyway).
+                                *
+                                * XXX should we elog() here instead?  Probably this routine
+                                * should never be invoked after SubPlan creation.
                                 */
                                return (Node *) expr;
                        default:
@@ -1629,7 +1623,6 @@ simplify_op_or_func(Expr *expr, List *args)
         *
         * Note we take the result type from the Oper or Func node, not the
         * pg_proc tuple; probably necessary for binary-compatibility cases.
-        *
         */
        if (expr->opType == OP_EXPR)
        {
index e65590862862964f36590103a0e2716e6af9bb38..2809a9a17f15a98814c8158af53bd12589b5a76c 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.87 2002/11/25 21:29:41 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.88 2002/11/26 03:01:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -241,14 +241,8 @@ coerce_type(Node *node, Oid inputTypeId, Oid targetTypeId,
                         *
                         * Note that no folding will occur if the conversion function is
                         * not marked 'immutable'.
-                        *
-                        * HACK: if constant is NULL, don't fold it here.  This is needed
-                        * by make_subplan(), which calls this routine on placeholder
-                        * Const nodes that mustn't be collapsed.  (It'd be a lot
-                        * cleaner to make a separate node type for that purpose...)
                         */
-                       if (IsA(node, Const) &&
-                               !((Const *) node)->constisnull)
+                       if (IsA(node, Const))
                                result = eval_const_expressions(result);
                }
                else
index 9a4a9c8bc91e33fb226d0a883db5fef03782bd32..fd2cd4f34b3427da83ff319678d523d1e2776088 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.130 2002/11/15 02:50:09 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.131 2002/11/26 03:01:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -122,7 +122,6 @@ transformExpr(ParseState *pstate, Node *expr, ConstraintTestValue *domVal)
                                param = makeNode(Param);
                                param->paramkind = PARAM_NUM;
                                param->paramid = (AttrNumber) paramno;
-                               param->paramname = "<unnamed>";
                                param->paramtype = paramtyp;
                                result = (Node *) param;
                                /* handle qualification, if any */
index 01aac333b5e49fb3b07516834ec3431a740bca30..c5a0f0d75d853fa8d70399c8c317acfc090e4535 100644 (file)
@@ -3,7 +3,7 @@
  *                             back to source text
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.126 2002/11/25 21:29:41 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.127 2002/11/26 03:01:58 tgl Exp $
  *
  *       This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -1921,7 +1921,6 @@ get_rule_expr(Node *node, deparse_context *context,
         * same expression tree.
         *
         * There might be some work left here to support additional node types.
-        * Can we ever see Param nodes here?
         */
        switch (nodeTag(node))
        {
index f0f37c3d9d33dd5dda9d8d7169641027dbf3db8f..089f7362a6b42a3e6163d5d630ec4f54812bcea0 100644 (file)
@@ -10,7 +10,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: primnodes.h,v 1.69 2002/11/25 21:29:42 tgl Exp $
+ * $Id: primnodes.h,v 1.70 2002/11/26 03:01:59 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -357,7 +357,7 @@ typedef struct Aggref
  * 3. Finally, the planner converts the oper list to a list of normal Expr
  *       nodes representing the application of the operator(s) to the lefthand
  *       expressions and values from the inner targetlist.  The inner
- *       targetlist items are represented by placeholder Param or Const nodes.
+ *       targetlist items are represented by placeholder Param nodes.
  *       The lefthand field is set to NIL, since its expressions are now in
  *       the Expr list.  This representation is passed to the executor.
  *