1996-07-09 08:22:35 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
1999-02-14 00:22:53 +01:00
|
|
|
* executor.h
|
1997-09-07 07:04:48 +02:00
|
|
|
* support for the POSTGRES executor module
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*
|
2015-01-06 17:43:47 +01:00
|
|
|
* Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
|
2000-01-26 06:58:53 +01:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
2010-09-20 22:08:53 +02:00
|
|
|
* src/include/executor/executor.h
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
#ifndef EXECUTOR_H
|
|
|
|
#define EXECUTOR_H
|
|
|
|
|
1999-07-16 01:04:24 +02:00
|
|
|
#include "executor/execdesc.h"
|
2007-02-20 18:32:18 +01:00
|
|
|
#include "nodes/parsenodes.h"
|
1996-11-05 09:18:44 +01:00
|
|
|
|
2002-12-05 16:50:39 +01:00
|
|
|
|
2006-02-28 05:10:28 +01:00
|
|
|
/*
|
|
|
|
* The "eflags" argument to ExecutorStart and the various ExecInitNode
|
|
|
|
* routines is a bitwise OR of the following flag bits, which tell the
|
|
|
|
* called plan node what to expect. Note that the flags will get modified
|
|
|
|
* as they are passed down the plan tree, since an upper node may require
|
|
|
|
* functionality in its subnode not demanded of the plan as a whole
|
|
|
|
* (example: MergeJoin requires mark/restore capability in its inner input),
|
|
|
|
* or an upper node may shield its input from some functionality requirement
|
|
|
|
* (example: Materialize shields its input from needing to do backward scan).
|
|
|
|
*
|
|
|
|
* EXPLAIN_ONLY indicates that the plan tree is being initialized just so
|
|
|
|
* EXPLAIN can print it out; it will not be run. Hence, no side-effects
|
Restructure SELECT INTO's parsetree representation into CreateTableAsStmt.
Making this operation look like a utility statement seems generally a good
idea, and particularly so in light of the desire to provide command
triggers for utility statements. The original choice of representing it as
SELECT with an IntoClause appendage had metastasized into rather a lot of
places, unfortunately, so that this patch is a great deal more complicated
than one might at first expect.
In particular, keeping EXPLAIN working for SELECT INTO and CREATE TABLE AS
subcommands required restructuring some EXPLAIN-related APIs. Add-on code
that calls ExplainOnePlan or ExplainOneUtility, or uses
ExplainOneQuery_hook, will need adjustment.
Also, the cases PREPARE ... SELECT INTO and CREATE RULE ... SELECT INTO,
which formerly were accepted though undocumented, are no longer accepted.
The PREPARE case can be replaced with use of CREATE TABLE AS EXECUTE.
The CREATE RULE case doesn't seem to have much real-world use (since the
rule would work only once before failing with "table already exists"),
so we'll not bother with that one.
Both SELECT INTO and CREATE TABLE AS still return a command tag of
"SELECT nnnn". There was some discussion of returning "CREATE TABLE nnnn",
but for the moment backwards compatibility wins the day.
Andres Freund and Tom Lane
2012-03-20 02:37:19 +01:00
|
|
|
* of startup should occur. However, error checks (such as permission checks)
|
|
|
|
* should be performed.
|
2006-02-28 05:10:28 +01:00
|
|
|
*
|
|
|
|
* REWIND indicates that the plan node should try to efficiently support
|
|
|
|
* rescans without parameter changes. (Nodes must support ExecReScan calls
|
|
|
|
* in any case, but if this flag was not given, they are at liberty to do it
|
2014-05-06 18:12:18 +02:00
|
|
|
* through complete recalculation. Note that a parameter change forces a
|
2006-02-28 05:10:28 +01:00
|
|
|
* full recalculation in any case.)
|
|
|
|
*
|
|
|
|
* BACKWARD indicates that the plan node must respect the es_direction flag.
|
|
|
|
* When this is not passed, the plan node will only be run forwards.
|
|
|
|
*
|
|
|
|
* MARK indicates that the plan node must support Mark/Restore calls.
|
|
|
|
* When this is not passed, no Mark/Restore will occur.
|
2011-02-27 19:43:29 +01:00
|
|
|
*
|
|
|
|
* SKIP_TRIGGERS tells ExecutorStart/ExecutorFinish to skip calling
|
|
|
|
* AfterTriggerBeginQuery/AfterTriggerEndQuery. This does not necessarily
|
|
|
|
* mean that the plan can't queue any AFTER triggers; just that the caller
|
|
|
|
* is responsible for there being a trigger context for them to be queued in.
|
Restructure SELECT INTO's parsetree representation into CreateTableAsStmt.
Making this operation look like a utility statement seems generally a good
idea, and particularly so in light of the desire to provide command
triggers for utility statements. The original choice of representing it as
SELECT with an IntoClause appendage had metastasized into rather a lot of
places, unfortunately, so that this patch is a great deal more complicated
than one might at first expect.
In particular, keeping EXPLAIN working for SELECT INTO and CREATE TABLE AS
subcommands required restructuring some EXPLAIN-related APIs. Add-on code
that calls ExplainOnePlan or ExplainOneUtility, or uses
ExplainOneQuery_hook, will need adjustment.
Also, the cases PREPARE ... SELECT INTO and CREATE RULE ... SELECT INTO,
which formerly were accepted though undocumented, are no longer accepted.
The PREPARE case can be replaced with use of CREATE TABLE AS EXECUTE.
The CREATE RULE case doesn't seem to have much real-world use (since the
rule would work only once before failing with "table already exists"),
so we'll not bother with that one.
Both SELECT INTO and CREATE TABLE AS still return a command tag of
"SELECT nnnn". There was some discussion of returning "CREATE TABLE nnnn",
but for the moment backwards compatibility wins the day.
Andres Freund and Tom Lane
2012-03-20 02:37:19 +01:00
|
|
|
*
|
|
|
|
* WITH/WITHOUT_OIDS tell the executor to emit tuples with or without space
|
2014-05-06 18:12:18 +02:00
|
|
|
* for OIDs, respectively. These are currently used only for CREATE TABLE AS.
|
Restructure SELECT INTO's parsetree representation into CreateTableAsStmt.
Making this operation look like a utility statement seems generally a good
idea, and particularly so in light of the desire to provide command
triggers for utility statements. The original choice of representing it as
SELECT with an IntoClause appendage had metastasized into rather a lot of
places, unfortunately, so that this patch is a great deal more complicated
than one might at first expect.
In particular, keeping EXPLAIN working for SELECT INTO and CREATE TABLE AS
subcommands required restructuring some EXPLAIN-related APIs. Add-on code
that calls ExplainOnePlan or ExplainOneUtility, or uses
ExplainOneQuery_hook, will need adjustment.
Also, the cases PREPARE ... SELECT INTO and CREATE RULE ... SELECT INTO,
which formerly were accepted though undocumented, are no longer accepted.
The PREPARE case can be replaced with use of CREATE TABLE AS EXECUTE.
The CREATE RULE case doesn't seem to have much real-world use (since the
rule would work only once before failing with "table already exists"),
so we'll not bother with that one.
Both SELECT INTO and CREATE TABLE AS still return a command tag of
"SELECT nnnn". There was some discussion of returning "CREATE TABLE nnnn",
but for the moment backwards compatibility wins the day.
Andres Freund and Tom Lane
2012-03-20 02:37:19 +01:00
|
|
|
* If neither is set, the plan may or may not produce tuples including OIDs.
|
2006-02-28 05:10:28 +01:00
|
|
|
*/
|
2006-10-04 02:30:14 +02:00
|
|
|
#define EXEC_FLAG_EXPLAIN_ONLY 0x0001 /* EXPLAIN, no ANALYZE */
|
|
|
|
#define EXEC_FLAG_REWIND 0x0002 /* need efficient rescan */
|
|
|
|
#define EXEC_FLAG_BACKWARD 0x0004 /* need backward scan */
|
|
|
|
#define EXEC_FLAG_MARK 0x0008 /* need mark/restore */
|
2011-04-10 17:42:00 +02:00
|
|
|
#define EXEC_FLAG_SKIP_TRIGGERS 0x0010 /* skip AfterTrigger calls */
|
Restructure SELECT INTO's parsetree representation into CreateTableAsStmt.
Making this operation look like a utility statement seems generally a good
idea, and particularly so in light of the desire to provide command
triggers for utility statements. The original choice of representing it as
SELECT with an IntoClause appendage had metastasized into rather a lot of
places, unfortunately, so that this patch is a great deal more complicated
than one might at first expect.
In particular, keeping EXPLAIN working for SELECT INTO and CREATE TABLE AS
subcommands required restructuring some EXPLAIN-related APIs. Add-on code
that calls ExplainOnePlan or ExplainOneUtility, or uses
ExplainOneQuery_hook, will need adjustment.
Also, the cases PREPARE ... SELECT INTO and CREATE RULE ... SELECT INTO,
which formerly were accepted though undocumented, are no longer accepted.
The PREPARE case can be replaced with use of CREATE TABLE AS EXECUTE.
The CREATE RULE case doesn't seem to have much real-world use (since the
rule would work only once before failing with "table already exists"),
so we'll not bother with that one.
Both SELECT INTO and CREATE TABLE AS still return a command tag of
"SELECT nnnn". There was some discussion of returning "CREATE TABLE nnnn",
but for the moment backwards compatibility wins the day.
Andres Freund and Tom Lane
2012-03-20 02:37:19 +01:00
|
|
|
#define EXEC_FLAG_WITH_OIDS 0x0020 /* force OIDs in returned tuples */
|
|
|
|
#define EXEC_FLAG_WITHOUT_OIDS 0x0040 /* force no OIDs in returned tuples */
|
2013-03-04 01:23:31 +01:00
|
|
|
#define EXEC_FLAG_WITH_NO_DATA 0x0080 /* rel scannability doesn't matter */
|
2006-02-28 05:10:28 +01:00
|
|
|
|
|
|
|
|
2004-03-17 02:02:24 +01:00
|
|
|
/*
|
|
|
|
* 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))
|
|
|
|
|
|
|
|
|
2008-11-19 02:10:24 +01:00
|
|
|
/* Hook for plugins to get control in ExecutorStart() */
|
|
|
|
typedef void (*ExecutorStart_hook_type) (QueryDesc *queryDesc, int eflags);
|
|
|
|
extern PGDLLIMPORT ExecutorStart_hook_type ExecutorStart_hook;
|
|
|
|
|
2008-07-18 20:23:47 +02:00
|
|
|
/* Hook for plugins to get control in ExecutorRun() */
|
2008-10-31 22:07:55 +01:00
|
|
|
typedef void (*ExecutorRun_hook_type) (QueryDesc *queryDesc,
|
2009-06-11 16:49:15 +02:00
|
|
|
ScanDirection direction,
|
|
|
|
long count);
|
2008-07-18 20:23:47 +02:00
|
|
|
extern PGDLLIMPORT ExecutorRun_hook_type ExecutorRun_hook;
|
|
|
|
|
2011-02-27 19:43:29 +01:00
|
|
|
/* Hook for plugins to get control in ExecutorFinish() */
|
|
|
|
typedef void (*ExecutorFinish_hook_type) (QueryDesc *queryDesc);
|
|
|
|
extern PGDLLIMPORT ExecutorFinish_hook_type ExecutorFinish_hook;
|
|
|
|
|
2008-11-19 02:10:24 +01:00
|
|
|
/* Hook for plugins to get control in ExecutorEnd() */
|
|
|
|
typedef void (*ExecutorEnd_hook_type) (QueryDesc *queryDesc);
|
|
|
|
extern PGDLLIMPORT ExecutorEnd_hook_type ExecutorEnd_hook;
|
|
|
|
|
2010-07-09 16:06:01 +02:00
|
|
|
/* Hook for plugins to get control in ExecCheckRTPerms() */
|
2010-07-22 02:47:59 +02:00
|
|
|
typedef bool (*ExecutorCheckPerms_hook_type) (List *, bool);
|
2010-07-09 16:06:01 +02:00
|
|
|
extern PGDLLIMPORT ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook;
|
|
|
|
|
2008-07-18 20:23:47 +02:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
/*
|
|
|
|
* prototypes from functions in execAmi.c
|
|
|
|
*/
|
2014-11-21 00:36:07 +01:00
|
|
|
struct Path; /* avoid including relation.h here */
|
|
|
|
|
2010-07-12 19:01:06 +02:00
|
|
|
extern void ExecReScan(PlanState *node);
|
2003-08-08 23:42:59 +02:00
|
|
|
extern void ExecMarkPos(PlanState *node);
|
|
|
|
extern void ExecRestrPos(PlanState *node);
|
2014-11-21 00:36:07 +01:00
|
|
|
extern bool ExecSupportsMarkRestore(struct Path *pathnode);
|
2003-03-10 04:53:52 +01:00
|
|
|
extern bool ExecSupportsBackwardScan(Plan *node);
|
2009-09-13 00:12:09 +02:00
|
|
|
extern bool ExecMaterializesOutput(NodeTag plantype);
|
1996-07-09 08:22:35 +02:00
|
|
|
|
2007-06-11 03:16:30 +02:00
|
|
|
/*
|
|
|
|
* prototypes from functions in execCurrent.c
|
|
|
|
*/
|
2007-11-15 23:25:18 +01:00
|
|
|
extern bool execCurrentOf(CurrentOfExpr *cexpr,
|
2007-11-15 22:14:46 +01:00
|
|
|
ExprContext *econtext,
|
|
|
|
Oid table_oid,
|
|
|
|
ItemPointer current_tid);
|
2007-06-11 03:16:30 +02:00
|
|
|
|
2003-01-11 00:54:24 +01:00
|
|
|
/*
|
|
|
|
* prototypes from functions in execGrouping.c
|
|
|
|
*/
|
2005-03-16 22:38:10 +01:00
|
|
|
extern bool execTuplesMatch(TupleTableSlot *slot1,
|
2005-10-15 04:49:52 +02:00
|
|
|
TupleTableSlot *slot2,
|
|
|
|
int numCols,
|
|
|
|
AttrNumber *matchColIdx,
|
|
|
|
FmgrInfo *eqfunctions,
|
|
|
|
MemoryContext evalContext);
|
2005-03-16 22:38:10 +01:00
|
|
|
extern bool execTuplesUnequal(TupleTableSlot *slot1,
|
2005-10-15 04:49:52 +02:00
|
|
|
TupleTableSlot *slot2,
|
|
|
|
int numCols,
|
|
|
|
AttrNumber *matchColIdx,
|
|
|
|
FmgrInfo *eqfunctions,
|
|
|
|
MemoryContext evalContext);
|
2007-01-10 19:06:05 +01:00
|
|
|
extern FmgrInfo *execTuplesMatchPrepare(int numCols,
|
|
|
|
Oid *eqOperators);
|
|
|
|
extern void execTuplesHashPrepare(int numCols,
|
|
|
|
Oid *eqOperators,
|
|
|
|
FmgrInfo **eqFunctions,
|
|
|
|
FmgrInfo **hashFunctions);
|
2003-01-11 00:54:24 +01:00
|
|
|
extern TupleHashTable BuildTupleHashTable(int numCols, AttrNumber *keyColIdx,
|
2003-08-04 02:43:34 +02:00
|
|
|
FmgrInfo *eqfunctions,
|
|
|
|
FmgrInfo *hashfunctions,
|
Install defenses against overflow in BuildTupleHashTable().
The planner can sometimes compute very large values for numGroups, and in
cases where we have no alternative to building a hashtable, such a value
will get fed directly to BuildTupleHashTable as its nbuckets parameter.
There were two ways in which that could go bad. First, BuildTupleHashTable
declared the parameter as "int" but most callers were passing "long"s,
so on 64-bit machines undetected overflow could occur leading to a bogus
negative value. The obvious fix for that is to change the parameter to
"long", which is what I've done in HEAD. In the back branches that seems a
bit risky, though, since third-party code might be calling this function.
So for them, just put in a kluge to treat negative inputs as INT_MAX.
Second, hash_create can go nuts with extremely large requested table sizes
(notably, my_log2 becomes an infinite loop for inputs larger than
LONG_MAX/2). What seems most appropriate to avoid that is to bound the
initial table size request to work_mem.
This fixes bug #6035 reported by Daniel Schreiber. Although the reported
case only occurs back to 8.4 since it involves WITH RECURSIVE, I think
it's a good idea to install the defenses in all supported branches.
2011-05-23 18:52:46 +02:00
|
|
|
long nbuckets, Size entrysize,
|
2003-08-04 02:43:34 +02:00
|
|
|
MemoryContext tablecxt,
|
|
|
|
MemoryContext tempcxt);
|
2003-01-11 00:54:24 +01:00
|
|
|
extern TupleHashEntry LookupTupleHashEntry(TupleHashTable hashtable,
|
2003-08-04 02:43:34 +02:00
|
|
|
TupleTableSlot *slot,
|
|
|
|
bool *isnew);
|
2007-02-06 03:59:15 +01:00
|
|
|
extern TupleHashEntry FindTupleHashEntry(TupleHashTable hashtable,
|
2007-11-15 22:14:46 +01:00
|
|
|
TupleTableSlot *slot,
|
|
|
|
FmgrInfo *eqfunctions,
|
|
|
|
FmgrInfo *hashfunctions);
|
2003-01-11 00:54:24 +01:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
/*
|
|
|
|
* prototypes from functions in execJunk.c
|
|
|
|
*/
|
2004-10-07 20:38:51 +02:00
|
|
|
extern JunkFilter *ExecInitJunkFilter(List *targetList, bool hasoid,
|
2001-10-25 07:50:21 +02:00
|
|
|
TupleTableSlot *slot);
|
2004-10-07 20:38:51 +02:00
|
|
|
extern JunkFilter *ExecInitJunkFilterConversion(List *targetList,
|
2005-10-15 04:49:52 +02:00
|
|
|
TupleDesc cleanTupType,
|
|
|
|
TupleTableSlot *slot);
|
2006-12-04 03:06:55 +01:00
|
|
|
extern AttrNumber ExecFindJunkAttribute(JunkFilter *junkfilter,
|
2007-11-15 22:14:46 +01:00
|
|
|
const char *attrName);
|
2011-01-13 02:47:02 +01:00
|
|
|
extern AttrNumber ExecFindJunkAttributeInTlist(List *targetlist,
|
2011-04-10 17:42:00 +02:00
|
|
|
const char *attrName);
|
2006-12-04 03:06:55 +01:00
|
|
|
extern Datum ExecGetJunkAttribute(TupleTableSlot *slot, AttrNumber attno,
|
2007-11-15 22:14:46 +01:00
|
|
|
bool *isNull);
|
2005-03-16 22:38:10 +01:00
|
|
|
extern TupleTableSlot *ExecFilterJunk(JunkFilter *junkfilter,
|
2005-10-15 04:49:52 +02:00
|
|
|
TupleTableSlot *slot);
|
1996-07-09 08:22:35 +02:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* prototypes from functions in execMain.c
|
|
|
|
*/
|
2006-02-28 05:10:28 +01:00
|
|
|
extern void ExecutorStart(QueryDesc *queryDesc, int eflags);
|
2008-11-19 02:10:24 +01:00
|
|
|
extern void standard_ExecutorStart(QueryDesc *queryDesc, int eflags);
|
2008-10-31 22:07:55 +01:00
|
|
|
extern void ExecutorRun(QueryDesc *queryDesc,
|
2009-06-11 16:49:15 +02:00
|
|
|
ScanDirection direction, long count);
|
2008-10-31 22:07:55 +01:00
|
|
|
extern void standard_ExecutorRun(QueryDesc *queryDesc,
|
2009-06-11 16:49:15 +02:00
|
|
|
ScanDirection direction, long count);
|
2011-02-27 19:43:29 +01:00
|
|
|
extern void ExecutorFinish(QueryDesc *queryDesc);
|
|
|
|
extern void standard_ExecutorFinish(QueryDesc *queryDesc);
|
2002-12-05 16:50:39 +01:00
|
|
|
extern void ExecutorEnd(QueryDesc *queryDesc);
|
2008-11-19 02:10:24 +01:00
|
|
|
extern void standard_ExecutorEnd(QueryDesc *queryDesc);
|
2003-03-11 20:40:24 +01:00
|
|
|
extern void ExecutorRewind(QueryDesc *queryDesc);
|
2010-07-22 02:47:59 +02:00
|
|
|
extern bool ExecCheckRTPerms(List *rangeTable, bool ereport_on_violation);
|
2011-02-26 00:56:23 +01:00
|
|
|
extern void CheckValidResultRel(Relation resultRel, CmdType operation);
|
2008-03-28 01:21:56 +01:00
|
|
|
extern void InitResultRelInfo(ResultRelInfo *resultRelInfo,
|
|
|
|
Relation resultRelationDesc,
|
|
|
|
Index resultRelationIndex,
|
2009-12-15 05:57:48 +01:00
|
|
|
int instrument_options);
|
2007-08-15 23:39:50 +02:00
|
|
|
extern ResultRelInfo *ExecGetTriggerResultRel(EState *estate, Oid relid);
|
2004-01-22 03:23:21 +01:00
|
|
|
extern bool ExecContextForcesOids(PlanState *planstate, bool *hasoids);
|
2003-07-21 19:05:12 +02:00
|
|
|
extern void ExecConstraints(ResultRelInfo *resultRelInfo,
|
2001-03-22 05:01:46 +01:00
|
|
|
TupleTableSlot *slot, EState *estate);
|
2013-07-18 23:10:16 +02:00
|
|
|
extern void ExecWithCheckOptions(ResultRelInfo *resultRelInfo,
|
|
|
|
TupleTableSlot *slot, EState *estate);
|
2011-01-13 02:47:02 +01:00
|
|
|
extern ExecRowMark *ExecFindRowMark(EState *estate, Index rti);
|
|
|
|
extern ExecAuxRowMark *ExecBuildAuxRowMark(ExecRowMark *erm, List *targetlist);
|
Re-implement EvalPlanQual processing to improve its performance and eliminate
a lot of strange behaviors that occurred in join cases. We now identify the
"current" row for every joined relation in UPDATE, DELETE, and SELECT FOR
UPDATE/SHARE queries. If an EvalPlanQual recheck is necessary, we jam the
appropriate row into each scan node in the rechecking plan, forcing it to emit
only that one row. The former behavior could rescan the whole of each joined
relation for each recheck, which was terrible for performance, and what's much
worse could result in duplicated output tuples.
Also, the original implementation of EvalPlanQual could not re-use the recheck
execution tree --- it had to go through a full executor init and shutdown for
every row to be tested. To avoid this overhead, I've associated a special
runtime Param with each LockRows or ModifyTable plan node, and arranged to
make every scan node below such a node depend on that Param. Thus, by
signaling a change in that Param, the EPQ machinery can just rescan the
already-built test plan.
This patch also adds a prohibition on set-returning functions in the
targetlist of SELECT FOR UPDATE/SHARE. This is needed to avoid the
duplicate-output-tuple problem. It seems fairly reasonable since the
other restrictions on SELECT FOR UPDATE are meant to ensure that there
is a unique correspondence between source tuples and result tuples,
which an output SRF destroys as much as anything else does.
2009-10-26 03:26:45 +01:00
|
|
|
extern TupleTableSlot *EvalPlanQual(EState *estate, EPQState *epqstate,
|
Improve concurrency of foreign key locking
This patch introduces two additional lock modes for tuples: "SELECT FOR
KEY SHARE" and "SELECT FOR NO KEY UPDATE". These don't block each
other, in contrast with already existing "SELECT FOR SHARE" and "SELECT
FOR UPDATE". UPDATE commands that do not modify the values stored in
the columns that are part of the key of the tuple now grab a SELECT FOR
NO KEY UPDATE lock on the tuple, allowing them to proceed concurrently
with tuple locks of the FOR KEY SHARE variety.
Foreign key triggers now use FOR KEY SHARE instead of FOR SHARE; this
means the concurrency improvement applies to them, which is the whole
point of this patch.
The added tuple lock semantics require some rejiggering of the multixact
module, so that the locking level that each transaction is holding can
be stored alongside its Xid. Also, multixacts now need to persist
across server restarts and crashes, because they can now represent not
only tuple locks, but also tuple updates. This means we need more
careful tracking of lifetime of pg_multixact SLRU files; since they now
persist longer, we require more infrastructure to figure out when they
can be removed. pg_upgrade also needs to be careful to copy
pg_multixact files over from the old server to the new, or at least part
of multixact.c state, depending on the versions of the old and new
servers.
Tuple time qualification rules (HeapTupleSatisfies routines) need to be
careful not to consider tuples with the "is multi" infomask bit set as
being only locked; they might need to look up MultiXact values (i.e.
possibly do pg_multixact I/O) to find out the Xid that updated a tuple,
whereas they previously were assured to only use information readily
available from the tuple header. This is considered acceptable, because
the extra I/O would involve cases that would previously cause some
commands to block waiting for concurrent transactions to finish.
Another important change is the fact that locking tuples that have
previously been updated causes the future versions to be marked as
locked, too; this is essential for correctness of foreign key checks.
This causes additional WAL-logging, also (there was previously a single
WAL record for a locked tuple; now there are as many as updated copies
of the tuple there exist.)
With all this in place, contention related to tuples being checked by
foreign key rules should be much reduced.
As a bonus, the old behavior that a subtransaction grabbing a stronger
tuple lock than the parent (sub)transaction held on a given tuple and
later aborting caused the weaker lock to be lost, has been fixed.
Many new spec files were added for isolation tester framework, to ensure
overall behavior is sane. There's probably room for several more tests.
There were several reviewers of this patch; in particular, Noah Misch
and Andres Freund spent considerable time in it. Original idea for the
patch came from Simon Riggs, after a problem report by Joel Jacobson.
Most code is from me, with contributions from Marti Raudsepp, Alexander
Shulgin, Noah Misch and Andres Freund.
This patch was discussed in several pgsql-hackers threads; the most
important start at the following message-ids:
AANLkTimo9XVcEzfiBR-ut3KVNDkjm2Vxh+t8kAmWjPuv@mail.gmail.com
1290721684-sup-3951@alvh.no-ip.org
1294953201-sup-2099@alvh.no-ip.org
1320343602-sup-2290@alvh.no-ip.org
1339690386-sup-8927@alvh.no-ip.org
4FE5FF020200002500048A3D@gw.wicourts.gov
4FEAB90A0200002500048B7D@gw.wicourts.gov
2013-01-23 16:04:59 +01:00
|
|
|
Relation relation, Index rti, int lockmode,
|
2007-11-30 22:22:54 +01:00
|
|
|
ItemPointer tid, TransactionId priorXmax);
|
Re-implement EvalPlanQual processing to improve its performance and eliminate
a lot of strange behaviors that occurred in join cases. We now identify the
"current" row for every joined relation in UPDATE, DELETE, and SELECT FOR
UPDATE/SHARE queries. If an EvalPlanQual recheck is necessary, we jam the
appropriate row into each scan node in the rechecking plan, forcing it to emit
only that one row. The former behavior could rescan the whole of each joined
relation for each recheck, which was terrible for performance, and what's much
worse could result in duplicated output tuples.
Also, the original implementation of EvalPlanQual could not re-use the recheck
execution tree --- it had to go through a full executor init and shutdown for
every row to be tested. To avoid this overhead, I've associated a special
runtime Param with each LockRows or ModifyTable plan node, and arranged to
make every scan node below such a node depend on that Param. Thus, by
signaling a change in that Param, the EPQ machinery can just rescan the
already-built test plan.
This patch also adds a prohibition on set-returning functions in the
targetlist of SELECT FOR UPDATE/SHARE. This is needed to avoid the
duplicate-output-tuple problem. It seems fairly reasonable since the
other restrictions on SELECT FOR UPDATE are meant to ensure that there
is a unique correspondence between source tuples and result tuples,
which an output SRF destroys as much as anything else does.
2009-10-26 03:26:45 +01:00
|
|
|
extern HeapTuple EvalPlanQualFetch(EState *estate, Relation relation,
|
2014-10-07 22:23:34 +02:00
|
|
|
int lockmode, LockWaitPolicy wait_policy, ItemPointer tid,
|
|
|
|
TransactionId priorXmax);
|
Re-implement EvalPlanQual processing to improve its performance and eliminate
a lot of strange behaviors that occurred in join cases. We now identify the
"current" row for every joined relation in UPDATE, DELETE, and SELECT FOR
UPDATE/SHARE queries. If an EvalPlanQual recheck is necessary, we jam the
appropriate row into each scan node in the rechecking plan, forcing it to emit
only that one row. The former behavior could rescan the whole of each joined
relation for each recheck, which was terrible for performance, and what's much
worse could result in duplicated output tuples.
Also, the original implementation of EvalPlanQual could not re-use the recheck
execution tree --- it had to go through a full executor init and shutdown for
every row to be tested. To avoid this overhead, I've associated a special
runtime Param with each LockRows or ModifyTable plan node, and arranged to
make every scan node below such a node depend on that Param. Thus, by
signaling a change in that Param, the EPQ machinery can just rescan the
already-built test plan.
This patch also adds a prohibition on set-returning functions in the
targetlist of SELECT FOR UPDATE/SHARE. This is needed to avoid the
duplicate-output-tuple problem. It seems fairly reasonable since the
other restrictions on SELECT FOR UPDATE are meant to ensure that there
is a unique correspondence between source tuples and result tuples,
which an output SRF destroys as much as anything else does.
2009-10-26 03:26:45 +01:00
|
|
|
extern void EvalPlanQualInit(EPQState *epqstate, EState *estate,
|
2011-01-13 02:47:02 +01:00
|
|
|
Plan *subplan, List *auxrowmarks, int epqParam);
|
|
|
|
extern void EvalPlanQualSetPlan(EPQState *epqstate,
|
2011-04-10 17:42:00 +02:00
|
|
|
Plan *subplan, List *auxrowmarks);
|
Re-implement EvalPlanQual processing to improve its performance and eliminate
a lot of strange behaviors that occurred in join cases. We now identify the
"current" row for every joined relation in UPDATE, DELETE, and SELECT FOR
UPDATE/SHARE queries. If an EvalPlanQual recheck is necessary, we jam the
appropriate row into each scan node in the rechecking plan, forcing it to emit
only that one row. The former behavior could rescan the whole of each joined
relation for each recheck, which was terrible for performance, and what's much
worse could result in duplicated output tuples.
Also, the original implementation of EvalPlanQual could not re-use the recheck
execution tree --- it had to go through a full executor init and shutdown for
every row to be tested. To avoid this overhead, I've associated a special
runtime Param with each LockRows or ModifyTable plan node, and arranged to
make every scan node below such a node depend on that Param. Thus, by
signaling a change in that Param, the EPQ machinery can just rescan the
already-built test plan.
This patch also adds a prohibition on set-returning functions in the
targetlist of SELECT FOR UPDATE/SHARE. This is needed to avoid the
duplicate-output-tuple problem. It seems fairly reasonable since the
other restrictions on SELECT FOR UPDATE are meant to ensure that there
is a unique correspondence between source tuples and result tuples,
which an output SRF destroys as much as anything else does.
2009-10-26 03:26:45 +01:00
|
|
|
extern void EvalPlanQualSetTuple(EPQState *epqstate, Index rti,
|
2010-02-26 03:01:40 +01:00
|
|
|
HeapTuple tuple);
|
Re-implement EvalPlanQual processing to improve its performance and eliminate
a lot of strange behaviors that occurred in join cases. We now identify the
"current" row for every joined relation in UPDATE, DELETE, and SELECT FOR
UPDATE/SHARE queries. If an EvalPlanQual recheck is necessary, we jam the
appropriate row into each scan node in the rechecking plan, forcing it to emit
only that one row. The former behavior could rescan the whole of each joined
relation for each recheck, which was terrible for performance, and what's much
worse could result in duplicated output tuples.
Also, the original implementation of EvalPlanQual could not re-use the recheck
execution tree --- it had to go through a full executor init and shutdown for
every row to be tested. To avoid this overhead, I've associated a special
runtime Param with each LockRows or ModifyTable plan node, and arranged to
make every scan node below such a node depend on that Param. Thus, by
signaling a change in that Param, the EPQ machinery can just rescan the
already-built test plan.
This patch also adds a prohibition on set-returning functions in the
targetlist of SELECT FOR UPDATE/SHARE. This is needed to avoid the
duplicate-output-tuple problem. It seems fairly reasonable since the
other restrictions on SELECT FOR UPDATE are meant to ensure that there
is a unique correspondence between source tuples and result tuples,
which an output SRF destroys as much as anything else does.
2009-10-26 03:26:45 +01:00
|
|
|
extern HeapTuple EvalPlanQualGetTuple(EPQState *epqstate, Index rti);
|
2010-02-26 03:01:40 +01:00
|
|
|
|
Re-implement EvalPlanQual processing to improve its performance and eliminate
a lot of strange behaviors that occurred in join cases. We now identify the
"current" row for every joined relation in UPDATE, DELETE, and SELECT FOR
UPDATE/SHARE queries. If an EvalPlanQual recheck is necessary, we jam the
appropriate row into each scan node in the rechecking plan, forcing it to emit
only that one row. The former behavior could rescan the whole of each joined
relation for each recheck, which was terrible for performance, and what's much
worse could result in duplicated output tuples.
Also, the original implementation of EvalPlanQual could not re-use the recheck
execution tree --- it had to go through a full executor init and shutdown for
every row to be tested. To avoid this overhead, I've associated a special
runtime Param with each LockRows or ModifyTable plan node, and arranged to
make every scan node below such a node depend on that Param. Thus, by
signaling a change in that Param, the EPQ machinery can just rescan the
already-built test plan.
This patch also adds a prohibition on set-returning functions in the
targetlist of SELECT FOR UPDATE/SHARE. This is needed to avoid the
duplicate-output-tuple problem. It seems fairly reasonable since the
other restrictions on SELECT FOR UPDATE are meant to ensure that there
is a unique correspondence between source tuples and result tuples,
which an output SRF destroys as much as anything else does.
2009-10-26 03:26:45 +01:00
|
|
|
#define EvalPlanQualSetSlot(epqstate, slot) ((epqstate)->origslot = (slot))
|
|
|
|
extern void EvalPlanQualFetchRowMarks(EPQState *epqstate);
|
|
|
|
extern TupleTableSlot *EvalPlanQualNext(EPQState *epqstate);
|
|
|
|
extern void EvalPlanQualBegin(EPQState *epqstate, EState *parentestate);
|
|
|
|
extern void EvalPlanQualEnd(EPQState *epqstate);
|
1999-05-25 18:15:34 +02:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
/*
|
|
|
|
* prototypes from functions in execProcnode.c
|
|
|
|
*/
|
2006-02-28 05:10:28 +01:00
|
|
|
extern PlanState *ExecInitNode(Plan *node, EState *estate, int eflags);
|
2003-08-08 23:42:59 +02:00
|
|
|
extern TupleTableSlot *ExecProcNode(PlanState *node);
|
2005-04-16 22:07:35 +02:00
|
|
|
extern Node *MultiExecProcNode(PlanState *node);
|
2003-08-08 23:42:59 +02:00
|
|
|
extern void ExecEndNode(PlanState *node);
|
1996-07-09 08:22:35 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* prototypes from functions in execQual.c
|
|
|
|
*/
|
2004-04-01 23:28:47 +02:00
|
|
|
extern Datum GetAttributeByNum(HeapTupleHeader tuple, AttrNumber attrno,
|
2001-03-22 05:01:46 +01:00
|
|
|
bool *isNull);
|
2004-04-01 23:28:47 +02:00
|
|
|
extern Datum GetAttributeByName(HeapTupleHeader tuple, const char *attname,
|
2001-03-22 05:01:46 +01:00
|
|
|
bool *isNull);
|
2003-08-08 23:42:59 +02:00
|
|
|
extern Tuplestorestate *ExecMakeTableFunctionResult(ExprState *funcexpr,
|
2002-09-04 22:31:48 +02:00
|
|
|
ExprContext *econtext,
|
2014-06-20 04:13:41 +02:00
|
|
|
MemoryContext argContext,
|
2008-10-29 01:00:39 +01:00
|
|
|
TupleDesc expectedDesc,
|
|
|
|
bool randomAccess);
|
2003-08-08 23:42:59 +02:00
|
|
|
extern Datum ExecEvalExprSwitchContext(ExprState *expression, ExprContext *econtext,
|
2001-03-22 05:01:46 +01:00
|
|
|
bool *isNull, ExprDoneCond *isDone);
|
2003-08-08 23:42:59 +02:00
|
|
|
extern ExprState *ExecInitExpr(Expr *node, PlanState *parent);
|
2002-12-15 17:17:59 +01:00
|
|
|
extern ExprState *ExecPrepareExpr(Expr *node, EState *estate);
|
2000-01-20 00:55:03 +01:00
|
|
|
extern bool ExecQual(List *qual, ExprContext *econtext, bool resultForNull);
|
1997-09-08 23:56:23 +02:00
|
|
|
extern int ExecTargetListLength(List *targetlist);
|
2000-08-21 22:55:31 +02:00
|
|
|
extern int ExecCleanTargetListLength(List *targetlist);
|
2000-08-24 05:29:15 +02:00
|
|
|
extern TupleTableSlot *ExecProject(ProjectionInfo *projInfo,
|
2001-03-22 05:01:46 +01:00
|
|
|
ExprDoneCond *isDone);
|
1996-07-09 08:22:35 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* prototypes from functions in execScan.c
|
|
|
|
*/
|
2003-08-08 23:42:59 +02:00
|
|
|
typedef TupleTableSlot *(*ExecScanAccessMtd) (ScanState *node);
|
Re-implement EvalPlanQual processing to improve its performance and eliminate
a lot of strange behaviors that occurred in join cases. We now identify the
"current" row for every joined relation in UPDATE, DELETE, and SELECT FOR
UPDATE/SHARE queries. If an EvalPlanQual recheck is necessary, we jam the
appropriate row into each scan node in the rechecking plan, forcing it to emit
only that one row. The former behavior could rescan the whole of each joined
relation for each recheck, which was terrible for performance, and what's much
worse could result in duplicated output tuples.
Also, the original implementation of EvalPlanQual could not re-use the recheck
execution tree --- it had to go through a full executor init and shutdown for
every row to be tested. To avoid this overhead, I've associated a special
runtime Param with each LockRows or ModifyTable plan node, and arranged to
make every scan node below such a node depend on that Param. Thus, by
signaling a change in that Param, the EPQ machinery can just rescan the
already-built test plan.
This patch also adds a prohibition on set-returning functions in the
targetlist of SELECT FOR UPDATE/SHARE. This is needed to avoid the
duplicate-output-tuple problem. It seems fairly reasonable since the
other restrictions on SELECT FOR UPDATE are meant to ensure that there
is a unique correspondence between source tuples and result tuples,
which an output SRF destroys as much as anything else does.
2009-10-26 03:26:45 +01:00
|
|
|
typedef bool (*ExecScanRecheckMtd) (ScanState *node, TupleTableSlot *slot);
|
2000-07-12 04:37:39 +02:00
|
|
|
|
Re-implement EvalPlanQual processing to improve its performance and eliminate
a lot of strange behaviors that occurred in join cases. We now identify the
"current" row for every joined relation in UPDATE, DELETE, and SELECT FOR
UPDATE/SHARE queries. If an EvalPlanQual recheck is necessary, we jam the
appropriate row into each scan node in the rechecking plan, forcing it to emit
only that one row. The former behavior could rescan the whole of each joined
relation for each recheck, which was terrible for performance, and what's much
worse could result in duplicated output tuples.
Also, the original implementation of EvalPlanQual could not re-use the recheck
execution tree --- it had to go through a full executor init and shutdown for
every row to be tested. To avoid this overhead, I've associated a special
runtime Param with each LockRows or ModifyTable plan node, and arranged to
make every scan node below such a node depend on that Param. Thus, by
signaling a change in that Param, the EPQ machinery can just rescan the
already-built test plan.
This patch also adds a prohibition on set-returning functions in the
targetlist of SELECT FOR UPDATE/SHARE. This is needed to avoid the
duplicate-output-tuple problem. It seems fairly reasonable since the
other restrictions on SELECT FOR UPDATE are meant to ensure that there
is a unique correspondence between source tuples and result tuples,
which an output SRF destroys as much as anything else does.
2009-10-26 03:26:45 +01:00
|
|
|
extern TupleTableSlot *ExecScan(ScanState *node, ExecScanAccessMtd accessMtd,
|
2010-02-26 03:01:40 +01:00
|
|
|
ExecScanRecheckMtd recheckMtd);
|
2003-08-08 23:42:59 +02:00
|
|
|
extern void ExecAssignScanProjectionInfo(ScanState *node);
|
Re-implement EvalPlanQual processing to improve its performance and eliminate
a lot of strange behaviors that occurred in join cases. We now identify the
"current" row for every joined relation in UPDATE, DELETE, and SELECT FOR
UPDATE/SHARE queries. If an EvalPlanQual recheck is necessary, we jam the
appropriate row into each scan node in the rechecking plan, forcing it to emit
only that one row. The former behavior could rescan the whole of each joined
relation for each recheck, which was terrible for performance, and what's much
worse could result in duplicated output tuples.
Also, the original implementation of EvalPlanQual could not re-use the recheck
execution tree --- it had to go through a full executor init and shutdown for
every row to be tested. To avoid this overhead, I've associated a special
runtime Param with each LockRows or ModifyTable plan node, and arranged to
make every scan node below such a node depend on that Param. Thus, by
signaling a change in that Param, the EPQ machinery can just rescan the
already-built test plan.
This patch also adds a prohibition on set-returning functions in the
targetlist of SELECT FOR UPDATE/SHARE. This is needed to avoid the
duplicate-output-tuple problem. It seems fairly reasonable since the
other restrictions on SELECT FOR UPDATE are meant to ensure that there
is a unique correspondence between source tuples and result tuples,
which an output SRF destroys as much as anything else does.
2009-10-26 03:26:45 +01:00
|
|
|
extern void ExecScanReScan(ScanState *node);
|
1996-07-09 08:22:35 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* prototypes from functions in execTuples.c
|
|
|
|
*/
|
2003-08-08 23:42:59 +02:00
|
|
|
extern void ExecInitResultTupleSlot(EState *estate, PlanState *planstate);
|
|
|
|
extern void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate);
|
2000-09-12 23:07:18 +02:00
|
|
|
extern TupleTableSlot *ExecInitExtraTupleSlot(EState *estate);
|
|
|
|
extern TupleTableSlot *ExecInitNullTupleSlot(EState *estate,
|
2001-03-22 05:01:46 +01:00
|
|
|
TupleDesc tupType);
|
2002-09-02 03:05:06 +02:00
|
|
|
extern TupleDesc ExecTypeFromTL(List *targetList, bool hasoid);
|
2003-05-06 22:26:28 +02:00
|
|
|
extern TupleDesc ExecCleanTypeFromTL(List *targetList, bool hasoid);
|
Ensure that RowExprs and whole-row Vars produce the expected column names.
At one time it wasn't terribly important what column names were associated
with the fields of a composite Datum, but since the introduction of
operations like row_to_json(), it's important that looking up the rowtype
ID embedded in the Datum returns the column names that users would expect.
That did not work terribly well before this patch: you could get the column
names of the underlying table, or column aliases from any level of the
query, depending on minor details of the plan tree. You could even get
totally empty field names, which is disastrous for cases like row_to_json().
To fix this for whole-row Vars, look to the RTE referenced by the Var, and
make sure its column aliases are applied to the rowtype associated with
the result Datums. This is a tad scary because we might have to return
a transient RECORD type even though the Var is declared as having some
named rowtype. In principle it should be all right because the record
type will still be physically compatible with the named rowtype; but
I had to weaken one Assert in ExecEvalConvertRowtype, and there might be
third-party code containing similar assumptions.
Similarly, RowExprs have to be willing to override the column names coming
from a named composite result type and produce a RECORD when the column
aliases visible at the site of the RowExpr differ from the underlying
table's column names.
In passing, revert the decision made in commit 398f70ec070fe601 to add
an alias-list argument to ExecTypeFromExprList: better to provide that
functionality in a separate function. This also reverts most of the code
changes in d68581483564ec0f, which we don't need because we're no longer
depending on the tupdesc found in the child plan node's result slot to be
blessed.
Back-patch to 9.4, but not earlier, since this solution changes the results
in some cases that users might not have realized were buggy. We'll apply a
more restricted form of this patch in older branches.
2014-11-10 21:21:09 +01:00
|
|
|
extern TupleDesc ExecTypeFromExprList(List *exprList);
|
|
|
|
extern void ExecTypeSetColNames(TupleDesc typeInfo, List *namesList);
|
2003-08-08 23:42:59 +02:00
|
|
|
extern void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg);
|
1996-07-09 08:22:35 +02:00
|
|
|
|
2002-07-20 07:49:28 +02:00
|
|
|
typedef struct TupOutputState
|
|
|
|
{
|
2005-03-16 22:38:10 +01:00
|
|
|
TupleTableSlot *slot;
|
2003-05-06 22:26:28 +02:00
|
|
|
DestReceiver *dest;
|
2002-07-20 07:49:28 +02:00
|
|
|
} TupOutputState;
|
|
|
|
|
2003-05-06 22:26:28 +02:00
|
|
|
extern TupOutputState *begin_tup_output_tupdesc(DestReceiver *dest,
|
2003-08-04 02:43:34 +02:00
|
|
|
TupleDesc tupdesc);
|
2009-07-22 19:00:23 +02:00
|
|
|
extern void do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull);
|
2002-07-20 07:49:28 +02:00
|
|
|
extern void do_text_output_multiline(TupOutputState *tstate, char *text);
|
|
|
|
extern void end_tup_output(TupOutputState *tstate);
|
|
|
|
|
2002-08-29 02:17:06 +02:00
|
|
|
/*
|
|
|
|
* Write a single line of text given as a C string.
|
|
|
|
*
|
|
|
|
* Should only be used with a single-TEXT-attribute tupdesc.
|
|
|
|
*/
|
2009-07-22 19:00:23 +02:00
|
|
|
#define do_text_output_oneline(tstate, str_to_emit) \
|
2002-07-20 07:49:28 +02:00
|
|
|
do { \
|
2009-07-22 19:00:23 +02:00
|
|
|
Datum values_[1]; \
|
|
|
|
bool isnull_[1]; \
|
|
|
|
values_[0] = PointerGetDatum(cstring_to_text(str_to_emit)); \
|
|
|
|
isnull_[0] = false; \
|
|
|
|
do_tup_output(tstate, values_, isnull_); \
|
|
|
|
pfree(DatumGetPointer(values_[0])); \
|
2002-07-20 07:49:28 +02:00
|
|
|
} while (0)
|
|
|
|
|
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
/*
|
1999-04-16 23:27:23 +02:00
|
|
|
* prototypes from functions in execUtils.c
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
2002-12-15 17:17:59 +01:00
|
|
|
extern EState *CreateExecutorState(void);
|
|
|
|
extern void FreeExecutorState(EState *estate);
|
|
|
|
extern ExprContext *CreateExprContext(EState *estate);
|
2006-08-04 23:33:36 +02:00
|
|
|
extern ExprContext *CreateStandaloneExprContext(void);
|
2009-07-18 21:15:42 +02:00
|
|
|
extern void FreeExprContext(ExprContext *econtext, bool isCommit);
|
2003-12-18 21:21:37 +01:00
|
|
|
extern void ReScanExprContext(ExprContext *econtext);
|
2000-07-12 04:37:39 +02:00
|
|
|
|
|
|
|
#define ResetExprContext(econtext) \
|
|
|
|
MemoryContextReset((econtext)->ecxt_per_tuple_memory)
|
|
|
|
|
2001-01-22 01:50:07 +01:00
|
|
|
extern ExprContext *MakePerTupleExprContext(EState *estate);
|
|
|
|
|
|
|
|
/* Get an EState's per-output-tuple exprcontext, making it if first use */
|
|
|
|
#define GetPerTupleExprContext(estate) \
|
|
|
|
((estate)->es_per_tuple_exprcontext ? \
|
|
|
|
(estate)->es_per_tuple_exprcontext : \
|
|
|
|
MakePerTupleExprContext(estate))
|
|
|
|
|
|
|
|
#define GetPerTupleMemoryContext(estate) \
|
|
|
|
(GetPerTupleExprContext(estate)->ecxt_per_tuple_memory)
|
|
|
|
|
|
|
|
/* Reset an EState's per-output-tuple exprcontext, if one's been created */
|
|
|
|
#define ResetPerTupleExprContext(estate) \
|
|
|
|
do { \
|
|
|
|
if ((estate)->es_per_tuple_exprcontext) \
|
|
|
|
ResetExprContext((estate)->es_per_tuple_exprcontext); \
|
|
|
|
} while (0)
|
|
|
|
|
2003-08-08 23:42:59 +02:00
|
|
|
extern void ExecAssignExprContext(EState *estate, PlanState *planstate);
|
2006-06-16 20:42:24 +02:00
|
|
|
extern void ExecAssignResultType(PlanState *planstate, TupleDesc tupDesc);
|
2003-08-08 23:42:59 +02:00
|
|
|
extern void ExecAssignResultTypeFromTL(PlanState *planstate);
|
|
|
|
extern TupleDesc ExecGetResultType(PlanState *planstate);
|
2003-01-12 05:03:34 +01:00
|
|
|
extern ProjectionInfo *ExecBuildProjectionInfo(List *targetList,
|
2003-08-04 02:43:34 +02:00
|
|
|
ExprContext *econtext,
|
2007-02-02 01:07:03 +01:00
|
|
|
TupleTableSlot *slot,
|
|
|
|
TupleDesc inputDesc);
|
|
|
|
extern void ExecAssignProjectionInfo(PlanState *planstate,
|
2007-11-15 22:14:46 +01:00
|
|
|
TupleDesc inputDesc);
|
2003-08-08 23:42:59 +02:00
|
|
|
extern void ExecFreeExprContext(PlanState *planstate);
|
|
|
|
extern TupleDesc ExecGetScanType(ScanState *scanstate);
|
2006-06-16 20:42:24 +02:00
|
|
|
extern void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc);
|
2003-08-08 23:42:59 +02:00
|
|
|
extern void ExecAssignScanTypeFromOuterPlan(ScanState *scanstate);
|
2002-12-15 17:17:59 +01:00
|
|
|
|
2005-12-03 06:51:03 +01:00
|
|
|
extern bool ExecRelationIsTargetRelation(EState *estate, Index scanrelid);
|
|
|
|
|
2013-04-27 23:48:57 +02:00
|
|
|
extern Relation ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags);
|
2005-12-02 21:03:42 +01:00
|
|
|
extern void ExecCloseScanRelation(Relation scanrel);
|
|
|
|
|
2000-11-12 01:37:02 +01:00
|
|
|
extern void ExecOpenIndices(ResultRelInfo *resultRelInfo);
|
|
|
|
extern void ExecCloseIndices(ResultRelInfo *resultRelInfo);
|
2009-07-29 22:56:21 +02:00
|
|
|
extern List *ExecInsertIndexTuples(TupleTableSlot *slot, ItemPointer tupleid,
|
2010-02-08 05:33:55 +01:00
|
|
|
EState *estate);
|
2009-12-07 06:22:23 +01:00
|
|
|
extern bool check_exclusion_constraint(Relation heap, Relation index,
|
2010-02-26 03:01:40 +01:00
|
|
|
IndexInfo *indexInfo,
|
|
|
|
ItemPointer tupleid,
|
|
|
|
Datum *values, bool *isnull,
|
|
|
|
EState *estate,
|
|
|
|
bool newIndex, bool errorOK);
|
2001-10-28 07:26:15 +01:00
|
|
|
|
2002-05-12 22:10:05 +02:00
|
|
|
extern void RegisterExprContextCallback(ExprContext *econtext,
|
2002-09-04 22:31:48 +02:00
|
|
|
ExprContextCallbackFunction function,
|
|
|
|
Datum arg);
|
2002-05-12 22:10:05 +02:00
|
|
|
extern void UnregisterExprContextCallback(ExprContext *econtext,
|
2002-09-04 22:31:48 +02:00
|
|
|
ExprContextCallbackFunction function,
|
|
|
|
Datum arg);
|
2002-05-12 22:10:05 +02:00
|
|
|
|
2001-11-05 18:46:40 +01:00
|
|
|
#endif /* EXECUTOR_H */
|