Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit d04db37

Browse files
committed
Arrange for function default arguments to be processed properly in expressions
that are set up for execution with ExecPrepareExpr rather than going through the full planner process. By introducing an explicit notion of "expression planning", this patch also lays a bit of groundwork for maybe someday allowing sub-selects in standalone expressions.
1 parent d3706cb commit d04db37

File tree

7 files changed

+73
-21
lines changed

7 files changed

+73
-21
lines changed

src/backend/commands/typecmds.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.129 2009/01/01 17:23:40 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.130 2009/01/09 15:46:10 tgl Exp $
1212
*
1313
* DESCRIPTION
1414
* The "DefineFoo" routines take the parse tree and pick out the
@@ -50,7 +50,7 @@
5050
#include "executor/executor.h"
5151
#include "miscadmin.h"
5252
#include "nodes/makefuncs.h"
53-
#include "optimizer/planmain.h"
53+
#include "optimizer/planner.h"
5454
#include "optimizer/var.h"
5555
#include "parser/parse_coerce.h"
5656
#include "parser/parse_expr.h"
@@ -2390,8 +2390,8 @@ GetDomainConstraints(Oid typeOid)
23902390

23912391
check_expr = (Expr *) stringToNode(TextDatumGetCString(val));
23922392

2393-
/* ExecInitExpr assumes we already fixed opfuncids */
2394-
fix_opfuncids((Node *) check_expr);
2393+
/* ExecInitExpr assumes we've planned the expression */
2394+
check_expr = expression_planner(check_expr);
23952395

23962396
r = makeNode(DomainConstraintState);
23972397
r->constrainttype = DOM_CONSTRAINT_CHECK;

src/backend/executor/README

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
$PostgreSQL: pgsql/src/backend/executor/README,v 1.7 2008/03/21 13:23:28 momjian Exp $
1+
$PostgreSQL: pgsql/src/backend/executor/README,v 1.8 2009/01/09 15:46:10 tgl Exp $
22

33
The Postgres Executor
44
=====================
@@ -124,7 +124,8 @@ be hidden inside function calls). This case has a flow of control like
124124
creates per-tuple context
125125

126126
ExecPrepareExpr
127-
switch to per-query context to run ExecInitExpr
127+
temporarily switch to per-query context
128+
run the expression through expression_planner
128129
ExecInitExpr
129130

130131
Repeatedly do:

src/backend/executor/execQual.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.240 2009/01/01 17:23:41 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.241 2009/01/09 15:46:10 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -45,7 +45,7 @@
4545
#include "miscadmin.h"
4646
#include "nodes/makefuncs.h"
4747
#include "nodes/nodeFuncs.h"
48-
#include "optimizer/planmain.h"
48+
#include "optimizer/planner.h"
4949
#include "pgstat.h"
5050
#include "utils/acl.h"
5151
#include "utils/builtins.h"
@@ -4794,21 +4794,22 @@ ExecInitExpr(Expr *node, PlanState *parent)
47944794
* Plan tree context.
47954795
*
47964796
* This differs from ExecInitExpr in that we don't assume the caller is
4797-
* already running in the EState's per-query context. Also, we apply
4798-
* fix_opfuncids() to the passed expression tree to be sure it is ready
4799-
* to run. (In ordinary Plan trees the planner will have fixed opfuncids,
4800-
* but callers outside the executor will not have done this.)
4797+
* already running in the EState's per-query context. Also, we run the
4798+
* passed expression tree through expression_planner() to prepare it for
4799+
* execution. (In ordinary Plan trees the regular planning process will have
4800+
* made the appropriate transformations on expressions, but for standalone
4801+
* expressions this won't have happened.)
48014802
*/
48024803
ExprState *
48034804
ExecPrepareExpr(Expr *node, EState *estate)
48044805
{
48054806
ExprState *result;
48064807
MemoryContext oldcontext;
48074808

4808-
fix_opfuncids((Node *) node);
4809-
48104809
oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
48114810

4811+
node = expression_planner(node);
4812+
48124813
result = ExecInitExpr(node, NULL);
48134814

48144815
MemoryContextSwitchTo(oldcontext);

src/backend/optimizer/plan/planner.c

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.250 2009/01/01 17:23:44 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.251 2009/01/09 15:46:10 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -2576,3 +2576,39 @@ get_column_info_for_window(PlannerInfo *root, WindowClause *wc, List *tlist,
25762576
elog(ERROR, "failed to deconstruct sort operators into partitioning/ordering operators");
25772577
}
25782578
}
2579+
2580+
2581+
/*
2582+
* expression_planner
2583+
* Perform planner's transformations on a standalone expression.
2584+
*
2585+
* Various utility commands need to evaluate expressions that are not part
2586+
* of a plannable query. They can do so using the executor's regular
2587+
* expression-execution machinery, but first the expression has to be fed
2588+
* through here to transform it from parser output to something executable.
2589+
*
2590+
* Currently, we disallow sublinks in standalone expressions, so there's no
2591+
* real "planning" involved here. (That might not always be true though.)
2592+
* What we must do is run eval_const_expressions to ensure that any function
2593+
* default arguments get inserted. The fact that constant subexpressions
2594+
* get simplified is a side-effect that is useful when the expression will
2595+
* get evaluated more than once. Also, we must fix operator function IDs.
2596+
*
2597+
* Note: this must not make any damaging changes to the passed-in expression
2598+
* tree. (It would actually be okay to apply fix_opfuncids to it, but since
2599+
* we first do an expression_tree_mutator-based walk, what is returned will
2600+
* be a new node tree.)
2601+
*/
2602+
Expr *
2603+
expression_planner(Expr *expr)
2604+
{
2605+
Node *result;
2606+
2607+
/* Insert default arguments and simplify constant subexprs */
2608+
result = eval_const_expressions(NULL, (Node *) expr);
2609+
2610+
/* Fill in opfuncid values if missing */
2611+
fix_opfuncids(result);
2612+
2613+
return (Expr *) result;
2614+
}

src/backend/optimizer/util/clauses.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.274 2009/01/06 01:23:21 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.275 2009/01/09 15:46:10 tgl Exp $
1212
*
1313
* HISTORY
1414
* AUTHOR DATE MAJOR EVENT
@@ -2018,6 +2018,9 @@ rowtype_field_matches(Oid rowtypeid, int fieldnum,
20182018
*
20192019
* NOTE: the planner assumes that this will always flatten nested AND and
20202020
* OR clauses into N-argument form. See comments in prepqual.c.
2021+
*
2022+
* NOTE: another critical effect is that any function calls that require
2023+
* default arguments will be expanded.
20212024
*--------------------
20222025
*/
20232026
Node *
@@ -3854,10 +3857,14 @@ evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod)
38543857
/* We can use the estate's working context to avoid memory leaks. */
38553858
oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
38563859

3860+
/* Make sure any opfuncids are filled in. */
3861+
fix_opfuncids((Node *) expr);
3862+
38573863
/*
3858-
* Prepare expr for execution.
3864+
* Prepare expr for execution. (Note: we can't use ExecPrepareExpr
3865+
* because it'd result in recursively invoking eval_const_expressions.)
38593866
*/
3860-
exprstate = ExecPrepareExpr(expr, estate);
3867+
exprstate = ExecInitExpr(expr, NULL);
38613868

38623869
/*
38633870
* And evaluate it.

src/backend/optimizer/util/predtest.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/optimizer/util/predtest.c,v 1.23 2009/01/01 17:23:45 momjian Exp $
12+
* $PostgreSQL: pgsql/src/backend/optimizer/util/predtest.c,v 1.24 2009/01/09 15:46:10 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -22,6 +22,7 @@
2222
#include "miscadmin.h"
2323
#include "nodes/nodeFuncs.h"
2424
#include "optimizer/clauses.h"
25+
#include "optimizer/planmain.h"
2526
#include "optimizer/predtest.h"
2627
#include "utils/array.h"
2728
#include "utils/inval.h"
@@ -1405,8 +1406,11 @@ btree_predicate_proof(Expr *predicate, Node *clause, bool refute_it)
14051406
(Expr *) pred_const,
14061407
(Expr *) clause_const);
14071408

1409+
/* Fill in opfuncids */
1410+
fix_opfuncids((Node *) test_expr);
1411+
14081412
/* Prepare it for execution */
1409-
test_exprstate = ExecPrepareExpr(test_expr, estate);
1413+
test_exprstate = ExecInitExpr(test_expr, NULL);
14101414

14111415
/* And execute it. */
14121416
test_result = ExecEvalExprSwitchContext(test_exprstate,

src/include/optimizer/planner.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/optimizer/planner.h,v 1.46 2009/01/01 17:24:00 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/optimizer/planner.h,v 1.47 2009/01/09 15:46:11 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -29,9 +29,12 @@ extern PlannedStmt *planner(Query *parse, int cursorOptions,
2929
ParamListInfo boundParams);
3030
extern PlannedStmt *standard_planner(Query *parse, int cursorOptions,
3131
ParamListInfo boundParams);
32+
3233
extern Plan *subquery_planner(PlannerGlobal *glob, Query *parse,
3334
PlannerInfo *parent_root,
3435
bool hasRecursion, double tuple_fraction,
3536
PlannerInfo **subroot);
3637

38+
extern Expr *expression_planner(Expr *expr);
39+
3740
#endif /* PLANNER_H */

0 commit comments

Comments
 (0)