Skip to content

Commit ea0b5c8

Browse files
committed
Use Params, rather than run-time-modified Const nodes, to handle
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.
1 parent ac47950 commit ea0b5c8

File tree

9 files changed

+165
-189
lines changed

9 files changed

+165
-189
lines changed

src/backend/commands/copy.c

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.182 2002/11/25 21:29:34 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.183 2002/11/26 03:01:57 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -749,7 +749,6 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
749749
FmgrInfo *in_functions;
750750
Oid *elements;
751751
Node **constraintexprs;
752-
Const **constraintconsts;
753752
bool hasConstraints = false;
754753
int i;
755754
List *cur;
@@ -805,7 +804,6 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
805804
defmap = (int *) palloc(num_phys_attrs * sizeof(int));
806805
defexprs = (Node **) palloc(num_phys_attrs * sizeof(Node *));
807806
constraintexprs = (Node **) palloc0(num_phys_attrs * sizeof(Node *));
808-
constraintconsts = (Const **) palloc(num_phys_attrs * sizeof(Const *));
809807

810808
for (i = 0; i < num_phys_attrs; i++)
811809
{
@@ -840,36 +838,29 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
840838
/* If it's a domain type, get info on domain constraints */
841839
if (get_typtype(attr[i]->atttypid) == 'd')
842840
{
843-
Const *con;
841+
Param *prm;
844842
Node *node;
845843

846844
/*
847845
* Easiest way to do this is to use parse_coerce.c to set up
848846
* an expression that checks the constraints. (At present,
849847
* the expression might contain a length-coercion-function call
850848
* and/or ConstraintTest nodes.) The bottom of the expression
851-
* is a Const node that we fill in with the actual datum during
849+
* is a Param node so that we can fill in the actual datum during
852850
* the data input loop.
853-
*
854-
* XXX to prevent premature constant folding in parse_coerce,
855-
* pass in a NULL constant to start with. See the comments in
856-
* coerce_type; this should be changed someday to use some sort
857-
* of Param node instead of a Const.
858851
*/
859-
con = makeConst(attr[i]->atttypid,
860-
attr[i]->attlen,
861-
(Datum) 0,
862-
true, /* is null */
863-
attr[i]->attbyval);
852+
prm = makeNode(Param);
853+
prm->paramkind = PARAM_EXEC;
854+
prm->paramid = 0;
855+
prm->paramtype = attr[i]->atttypid;
864856

865-
node = coerce_type_constraints((Node *) con, attr[i]->atttypid,
857+
node = coerce_type_constraints((Node *) prm, attr[i]->atttypid,
866858
COERCE_IMPLICIT_CAST);
867859

868860
/* check whether any constraints actually found */
869-
if (node != (Node *) con)
861+
if (node != (Node *) prm)
870862
{
871863
constraintexprs[i] = node;
872-
constraintconsts[i] = con;
873864
hasConstraints = true;
874865
}
875866
}
@@ -931,6 +922,11 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
931922

932923
econtext = GetPerTupleExprContext(estate);
933924

925+
/* Make room for a PARAM_EXEC value for domain constraint checks */
926+
if (hasConstraints)
927+
econtext->ecxt_param_exec_vals = (ParamExecData *)
928+
palloc0(sizeof(ParamExecData));
929+
934930
while (!done)
935931
{
936932
bool skip_tuple;
@@ -1153,19 +1149,19 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids,
11531149
*/
11541150
if (hasConstraints)
11551151
{
1152+
ParamExecData *prmdata = &econtext->ecxt_param_exec_vals[0];
1153+
11561154
for (i = 0; i < num_phys_attrs; i++)
11571155
{
11581156
Node *node = constraintexprs[i];
1159-
Const *con;
11601157
bool isnull;
11611158

11621159
if (node == NULL)
11631160
continue; /* no constraint for this attr */
11641161

1165-
/* Insert current row's value into the Const node */
1166-
con = constraintconsts[i];
1167-
con->constvalue = values[i];
1168-
con->constisnull = (nulls[i] == 'n');
1162+
/* Insert current row's value into the Param value */
1163+
prmdata->value = values[i];
1164+
prmdata->isnull = (nulls[i] == 'n');
11691165

11701166
/*
11711167
* Execute the constraint expression. Allow the expression

src/backend/executor/nodeSubplan.c

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/executor/nodeSubplan.c,v 1.33 2002/06/20 20:29:28 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/executor/nodeSubplan.c,v 1.34 2002/11/26 03:01:57 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -150,37 +150,44 @@ ExecSubPlan(SubPlan *node, List *pvar, ExprContext *econtext, bool *isNull)
150150
foreach(lst, sublink->oper)
151151
{
152152
Expr *expr = (Expr *) lfirst(lst);
153-
Const *con = lsecond(expr->args);
153+
Param *prm = lsecond(expr->args);
154+
ParamExecData *prmdata;
154155
Datum expresult;
155156
bool expnull;
156157

157158
/*
158159
* The righthand side of the expression should be either a
159-
* Const or a function call or RelabelType node taking a Const
160+
* Param or a function call or RelabelType node taking a Param
160161
* as arg (these nodes represent run-time type coercions
161162
* inserted by the parser to get to the input type needed by
162-
* the operator). Find the Const node and insert the actual
163-
* righthand-side value into it.
163+
* the operator). Find the Param node and insert the actual
164+
* righthand-side value into the param's econtext slot.
165+
*
166+
* XXX possible improvement: could make a list of the ParamIDs
167+
* at startup time, instead of repeating this check at each row.
164168
*/
165-
if (!IsA(con, Const))
169+
if (!IsA(prm, Param))
166170
{
167-
switch (con->type)
171+
switch (nodeTag(prm))
168172
{
169173
case T_Expr:
170-
con = lfirst(((Expr *) con)->args);
174+
prm = lfirst(((Expr *) prm)->args);
171175
break;
172176
case T_RelabelType:
173-
con = (Const *) (((RelabelType *) con)->arg);
177+
prm = (Param *) (((RelabelType *) prm)->arg);
174178
break;
175179
default:
176180
/* will fail below */
177181
break;
178182
}
179-
if (!IsA(con, Const))
183+
if (!IsA(prm, Param))
180184
elog(ERROR, "ExecSubPlan: failed to find placeholder for subplan result");
181185
}
182-
con->constvalue = heap_getattr(tup, col, tdesc,
183-
&(con->constisnull));
186+
Assert(prm->paramkind == PARAM_EXEC);
187+
prmdata = &(econtext->ecxt_param_exec_vals[prm->paramid]);
188+
Assert(prmdata->execPlan == NULL);
189+
prmdata->value = heap_getattr(tup, col, tdesc,
190+
&(prmdata->isnull));
184191

185192
/*
186193
* Now we can eval the combining operator for this column.

src/backend/optimizer/plan/planner.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.130 2002/11/21 00:42:19 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.131 2002/11/26 03:01:58 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -720,8 +720,6 @@ preprocess_expression(Query *parse, Node *expr, int kind)
720720
*
721721
* Note that at this point quals have not yet been converted to
722722
* implicit-AND form, so we can apply eval_const_expressions directly.
723-
* Also note that we need to do this before SS_process_sublinks,
724-
* because that routine inserts bogus "Const" nodes.
725723
*/
726724
expr = eval_const_expressions(expr);
727725

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy