8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.219 2006/08/12 20:05:55 tgl Exp $
11
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.220 2006/09/06 20:40:47 tgl Exp $
12
12
*
13
13
* HISTORY
14
14
* AUTHOR DATE MAJOR EVENT
@@ -1462,7 +1462,9 @@ eval_const_expressions(Node *node)
1462
1462
*
1463
1463
* Currently the extra steps that are taken in this mode are:
1464
1464
* 1. Substitute values for Params, where a bound Param value has been made
1465
- * available by the caller of planner().
1465
+ * available by the caller of planner(), even if the Param isn't marked
1466
+ * constant. This effectively means that we plan using the first supplied
1467
+ * value of the Param.
1466
1468
* 2. Fold stable, as well as immutable, functions to constants.
1467
1469
*--------------------
1468
1470
*/
@@ -1487,33 +1489,38 @@ eval_const_expressions_mutator(Node *node,
1487
1489
{
1488
1490
Param * param = (Param * ) node ;
1489
1491
1490
- /* OK to try to substitute value? */
1491
- if (context -> estimate && param -> paramkind == PARAM_EXTERN &&
1492
- PlannerBoundParamList != NULL )
1492
+ /* Look to see if we've been given a value for this Param */
1493
+ if (param -> paramkind == PARAM_EXTERN &&
1494
+ PlannerBoundParamList != NULL &&
1495
+ param -> paramid > 0 &&
1496
+ param -> paramid <= PlannerBoundParamList -> numParams )
1493
1497
{
1494
- /* Look to see if we've been given a value for this Param */
1495
- if (param -> paramid > 0 &&
1496
- param -> paramid <= PlannerBoundParamList -> numParams )
1497
- {
1498
- ParamExternData * prm = & PlannerBoundParamList -> params [param -> paramid - 1 ];
1498
+ ParamExternData * prm = & PlannerBoundParamList -> params [param -> paramid - 1 ];
1499
1499
1500
- if (OidIsValid (prm -> ptype ))
1500
+ if (OidIsValid (prm -> ptype ))
1501
+ {
1502
+ /* OK to substitute parameter value? */
1503
+ if (context -> estimate || (prm -> pflags & PARAM_FLAG_CONST ))
1501
1504
{
1502
1505
/*
1503
- * Found it, so return a Const representing the param
1504
- * value. Note that we don't copy pass-by-ref datatypes,
1505
- * so the Const will only be valid as long as the bound
1506
- * parameter list exists. This is okay for intended uses
1507
- * of estimate_expression_value().
1506
+ * Return a Const representing the param value. Must copy
1507
+ * pass-by-ref datatypes, since the Param might be in a
1508
+ * memory context shorter-lived than our output plan
1509
+ * should be.
1508
1510
*/
1509
1511
int16 typLen ;
1510
1512
bool typByVal ;
1513
+ Datum pval ;
1511
1514
1512
1515
Assert (prm -> ptype == param -> paramtype );
1513
1516
get_typlenbyval (param -> paramtype , & typLen , & typByVal );
1517
+ if (prm -> isnull || typByVal )
1518
+ pval = prm -> value ;
1519
+ else
1520
+ pval = datumCopy (prm -> value , typByVal , typLen );
1514
1521
return (Node * ) makeConst (param -> paramtype ,
1515
1522
(int ) typLen ,
1516
- prm -> value ,
1523
+ pval ,
1517
1524
prm -> isnull ,
1518
1525
typByVal );
1519
1526
}
@@ -3016,10 +3023,9 @@ evaluate_expr(Expr *expr, Oid result_type)
3016
3023
* stage. In particular, it handles List nodes since a cnf-ified qual clause
3017
3024
* will have List structure at the top level, and it handles TargetEntry nodes
3018
3025
* so that a scan of a target list can be handled without additional code.
3019
- * (But only the "expr" part of a TargetEntry is examined, unless the walker
3020
- * chooses to process TargetEntry nodes specially.) Also, RangeTblRef,
3021
- * FromExpr, JoinExpr, and SetOperationStmt nodes are handled, so that query
3022
- * jointrees and setOperation trees can be processed without additional code.
3026
+ * Also, RangeTblRef, FromExpr, JoinExpr, and SetOperationStmt nodes are
3027
+ * handled, so that query jointrees and setOperation trees can be processed
3028
+ * without additional code.
3023
3029
*
3024
3030
* expression_tree_walker will handle SubLink nodes by recursing normally
3025
3031
* into the "testexpr" subtree (which is an expression belonging to the outer
@@ -3364,6 +3370,38 @@ query_tree_walker(Query *query,
3364
3370
return true;
3365
3371
if (range_table_walker (query -> rtable , walker , context , flags ))
3366
3372
return true;
3373
+ if (query -> utilityStmt )
3374
+ {
3375
+ /*
3376
+ * Certain utility commands contain general-purpose Querys embedded
3377
+ * in them --- if this is one, invoke the walker on the sub-Query.
3378
+ */
3379
+ if (IsA (query -> utilityStmt , CopyStmt ))
3380
+ {
3381
+ if (walker (((CopyStmt * ) query -> utilityStmt )-> query , context ))
3382
+ return true;
3383
+ }
3384
+ if (IsA (query -> utilityStmt , DeclareCursorStmt ))
3385
+ {
3386
+ if (walker (((DeclareCursorStmt * ) query -> utilityStmt )-> query , context ))
3387
+ return true;
3388
+ }
3389
+ if (IsA (query -> utilityStmt , ExplainStmt ))
3390
+ {
3391
+ if (walker (((ExplainStmt * ) query -> utilityStmt )-> query , context ))
3392
+ return true;
3393
+ }
3394
+ if (IsA (query -> utilityStmt , PrepareStmt ))
3395
+ {
3396
+ if (walker (((PrepareStmt * ) query -> utilityStmt )-> query , context ))
3397
+ return true;
3398
+ }
3399
+ if (IsA (query -> utilityStmt , ViewStmt ))
3400
+ {
3401
+ if (walker (((ViewStmt * ) query -> utilityStmt )-> query , context ))
3402
+ return true;
3403
+ }
3404
+ }
3367
3405
return false;
3368
3406
}
3369
3407
0 commit comments