Use Params, rather than run-time-modified Const nodes, to handle
authorTom Lane
Tue, 26 Nov 2002 03:01:59 +0000 (03:01 +0000)
committerTom Lane
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 = "";
                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.
  *