mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-10-01 12:41:20 +02:00
Replace the switching function ExecEvalExpr() with a macro that jumps
directly to the appropriate per-node execution function, using a function pointer stored by ExecInitExpr. This speeds things up by eliminating one level of function call. The function-pointer technique also enables further small improvements such as only making one-time tests once (and then changing the function pointer). Overall this seems to gain about 10% on evaluation of simple expressions, which isn't earthshaking but seems a worthwhile gain for a relatively small hack. Per recent discussion on pghackers.
This commit is contained in:
parent
2c7e473434
commit
c1352052ef
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/executor/nodeHash.c,v 1.82 2004/02/03 17:34:02 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/executor/nodeHash.c,v 1.83 2004/03/17 01:02:23 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -532,6 +532,7 @@ ExecHashGetBucket(HashJoinTable hashtable,
|
|||||||
|
|
||||||
foreach(hk, hashkeys)
|
foreach(hk, hashkeys)
|
||||||
{
|
{
|
||||||
|
ExprState *keyexpr = (ExprState *) lfirst(hk);
|
||||||
Datum keyval;
|
Datum keyval;
|
||||||
bool isNull;
|
bool isNull;
|
||||||
|
|
||||||
@ -541,8 +542,7 @@ ExecHashGetBucket(HashJoinTable hashtable,
|
|||||||
/*
|
/*
|
||||||
* Get the join attribute value of the tuple
|
* Get the join attribute value of the tuple
|
||||||
*/
|
*/
|
||||||
keyval = ExecEvalExpr((ExprState *) lfirst(hk),
|
keyval = ExecEvalExpr(keyexpr, econtext, &isNull, NULL);
|
||||||
econtext, &isNull, NULL);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compute the hash function
|
* Compute the hash function
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/executor/nodeMergejoin.c,v 1.63 2003/11/29 19:51:48 pgsql Exp $
|
* $PostgreSQL: pgsql/src/backend/executor/nodeMergejoin.c,v 1.64 2004/03/17 01:02:23 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -191,6 +191,8 @@ MergeCompare(List *eqQual, List *compareQual, ExprContext *econtext)
|
|||||||
eqclause = eqQual;
|
eqclause = eqQual;
|
||||||
foreach(clause, compareQual)
|
foreach(clause, compareQual)
|
||||||
{
|
{
|
||||||
|
ExprState *clauseexpr = (ExprState *) lfirst(clause);
|
||||||
|
ExprState *eqclauseexpr = (ExprState *) lfirst(eqclause);
|
||||||
Datum const_value;
|
Datum const_value;
|
||||||
bool isNull;
|
bool isNull;
|
||||||
|
|
||||||
@ -200,10 +202,7 @@ MergeCompare(List *eqQual, List *compareQual, ExprContext *econtext)
|
|||||||
*
|
*
|
||||||
* A NULL result is considered false.
|
* A NULL result is considered false.
|
||||||
*/
|
*/
|
||||||
const_value = ExecEvalExpr((ExprState *) lfirst(clause),
|
const_value = ExecEvalExpr(clauseexpr, econtext, &isNull, NULL);
|
||||||
econtext,
|
|
||||||
&isNull,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (DatumGetBool(const_value) && !isNull)
|
if (DatumGetBool(const_value) && !isNull)
|
||||||
{
|
{
|
||||||
@ -217,10 +216,7 @@ MergeCompare(List *eqQual, List *compareQual, ExprContext *econtext)
|
|||||||
* key1 = key2 so we move on to the next pair of keys.
|
* key1 = key2 so we move on to the next pair of keys.
|
||||||
*-----------
|
*-----------
|
||||||
*/
|
*/
|
||||||
const_value = ExecEvalExpr((ExprState *) lfirst(eqclause),
|
const_value = ExecEvalExpr(eqclauseexpr, econtext, &isNull, NULL);
|
||||||
econtext,
|
|
||||||
&isNull,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (!DatumGetBool(const_value) || isNull)
|
if (!DatumGetBool(const_value) || isNull)
|
||||||
break; /* return false */
|
break; /* return false */
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/executor/nodeSubplan.c,v 1.60 2004/01/14 23:01:54 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/executor/nodeSubplan.c,v 1.61 2004/03/17 01:02:23 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -47,10 +47,16 @@ static bool tupleAllNulls(HeapTuple tuple);
|
|||||||
Datum
|
Datum
|
||||||
ExecSubPlan(SubPlanState *node,
|
ExecSubPlan(SubPlanState *node,
|
||||||
ExprContext *econtext,
|
ExprContext *econtext,
|
||||||
bool *isNull)
|
bool *isNull,
|
||||||
|
ExprDoneCond *isDone)
|
||||||
{
|
{
|
||||||
SubPlan *subplan = (SubPlan *) node->xprstate.expr;
|
SubPlan *subplan = (SubPlan *) node->xprstate.expr;
|
||||||
|
|
||||||
|
/* Set default values for result flags: non-null, not a set result */
|
||||||
|
*isNull = false;
|
||||||
|
if (isDone)
|
||||||
|
*isDone = ExprSingleResult;
|
||||||
|
|
||||||
if (subplan->setParam != NIL)
|
if (subplan->setParam != NIL)
|
||||||
elog(ERROR, "cannot set parent params from subquery");
|
elog(ERROR, "cannot set parent params from subquery");
|
||||||
|
|
||||||
@ -819,6 +825,7 @@ ExecInitSubPlan(SubPlanState *node, EState *estate)
|
|||||||
expr);
|
expr);
|
||||||
tlestate = makeNode(GenericExprState);
|
tlestate = makeNode(GenericExprState);
|
||||||
tlestate->xprstate.expr = (Expr *) tle;
|
tlestate->xprstate.expr = (Expr *) tle;
|
||||||
|
tlestate->xprstate.evalfunc = NULL;
|
||||||
tlestate->arg = exstate;
|
tlestate->arg = exstate;
|
||||||
lefttlist = lappend(lefttlist, tlestate);
|
lefttlist = lappend(lefttlist, tlestate);
|
||||||
leftptlist = lappend(leftptlist, tle);
|
leftptlist = lappend(leftptlist, tle);
|
||||||
@ -834,6 +841,7 @@ ExecInitSubPlan(SubPlanState *node, EState *estate)
|
|||||||
expr);
|
expr);
|
||||||
tlestate = makeNode(GenericExprState);
|
tlestate = makeNode(GenericExprState);
|
||||||
tlestate->xprstate.expr = (Expr *) tle;
|
tlestate->xprstate.expr = (Expr *) tle;
|
||||||
|
tlestate->xprstate.evalfunc = NULL;
|
||||||
tlestate->arg = exstate;
|
tlestate->arg = exstate;
|
||||||
righttlist = lappend(righttlist, tlestate);
|
righttlist = lappend(righttlist, tlestate);
|
||||||
rightptlist = lappend(rightptlist, tle);
|
rightptlist = lappend(rightptlist, tle);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/executor/executor.h,v 1.107 2004/03/02 18:56:15 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/executor/executor.h,v 1.108 2004/03/17 01:02:24 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -17,17 +17,26 @@
|
|||||||
#include "executor/execdesc.h"
|
#include "executor/execdesc.h"
|
||||||
|
|
||||||
|
|
||||||
/* ----------------
|
/*
|
||||||
* TupIsNull
|
* TupIsNull
|
||||||
*
|
*
|
||||||
* This is used mainly to detect when there are no more
|
* This is used mainly to detect when there are no more
|
||||||
* tuples to process.
|
* tuples to process.
|
||||||
* ----------------
|
|
||||||
*/
|
*/
|
||||||
/* return: true if tuple in slot is NULL, slot is slot to test */
|
/* return: true if tuple in slot is NULL, slot is slot to test */
|
||||||
#define TupIsNull(slot) \
|
#define TupIsNull(slot) \
|
||||||
((slot) == NULL || (slot)->val == NULL)
|
((slot) == NULL || (slot)->val == NULL)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ExecEvalExpr was formerly a function containing a switch statement;
|
||||||
|
* now it's just a macro invoking the function pointed to by an ExprState
|
||||||
|
* node. Beware of double evaluation of the ExprState argument!
|
||||||
|
*/
|
||||||
|
#define ExecEvalExpr(expr, econtext, isNull, isDone) \
|
||||||
|
((*(expr)->evalfunc) (expr, econtext, isNull, isDone))
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* prototypes from functions in execAmi.c
|
* prototypes from functions in execAmi.c
|
||||||
*/
|
*/
|
||||||
@ -125,8 +134,6 @@ extern Tuplestorestate *ExecMakeTableFunctionResult(ExprState *funcexpr,
|
|||||||
ExprContext *econtext,
|
ExprContext *econtext,
|
||||||
TupleDesc expectedDesc,
|
TupleDesc expectedDesc,
|
||||||
TupleDesc *returnDesc);
|
TupleDesc *returnDesc);
|
||||||
extern Datum ExecEvalExpr(ExprState *expression, ExprContext *econtext,
|
|
||||||
bool *isNull, ExprDoneCond *isDone);
|
|
||||||
extern Datum ExecEvalExprSwitchContext(ExprState *expression, ExprContext *econtext,
|
extern Datum ExecEvalExprSwitchContext(ExprState *expression, ExprContext *econtext,
|
||||||
bool *isNull, ExprDoneCond *isDone);
|
bool *isNull, ExprDoneCond *isDone);
|
||||||
extern ExprState *ExecInitExpr(Expr *node, PlanState *parent);
|
extern ExprState *ExecInitExpr(Expr *node, PlanState *parent);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/executor/nodeSubplan.h,v 1.19 2003/11/29 22:41:01 pgsql Exp $
|
* $PostgreSQL: pgsql/src/include/executor/nodeSubplan.h,v 1.20 2004/03/17 01:02:24 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -19,7 +19,8 @@
|
|||||||
extern void ExecInitSubPlan(SubPlanState *node, EState *estate);
|
extern void ExecInitSubPlan(SubPlanState *node, EState *estate);
|
||||||
extern Datum ExecSubPlan(SubPlanState *node,
|
extern Datum ExecSubPlan(SubPlanState *node,
|
||||||
ExprContext *econtext,
|
ExprContext *econtext,
|
||||||
bool *isNull);
|
bool *isNull,
|
||||||
|
ExprDoneCond *isDone);
|
||||||
extern void ExecEndSubPlan(SubPlanState *node);
|
extern void ExecEndSubPlan(SubPlanState *node);
|
||||||
extern void ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent);
|
extern void ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent);
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.112 2004/02/28 19:46:06 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.113 2004/03/17 01:02:24 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -390,13 +390,25 @@ typedef HASH_SEQ_STATUS TupleHashIterator;
|
|||||||
*
|
*
|
||||||
* It can also be instantiated directly for leaf Expr nodes that need no
|
* It can also be instantiated directly for leaf Expr nodes that need no
|
||||||
* local run-time state (such as Var, Const, or Param).
|
* local run-time state (such as Var, Const, or Param).
|
||||||
|
*
|
||||||
|
* To save on dispatch overhead, each ExprState node contains a function
|
||||||
|
* pointer to the routine to execute to evaluate the node.
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
typedef struct ExprState
|
|
||||||
|
typedef struct ExprState ExprState;
|
||||||
|
|
||||||
|
typedef Datum (*ExprStateEvalFunc) (ExprState *expression,
|
||||||
|
ExprContext *econtext,
|
||||||
|
bool *isNull,
|
||||||
|
ExprDoneCond *isDone);
|
||||||
|
|
||||||
|
struct ExprState
|
||||||
{
|
{
|
||||||
NodeTag type;
|
NodeTag type;
|
||||||
Expr *expr; /* associated Expr node */
|
Expr *expr; /* associated Expr node */
|
||||||
} ExprState;
|
ExprStateEvalFunc evalfunc; /* routine to run to execute node */
|
||||||
|
};
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* GenericExprState node
|
* GenericExprState node
|
||||||
|
Loading…
Reference in New Issue
Block a user