Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
35026079
Commit
35026079
authored
Dec 18, 2002
by
Tom Lane
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update EvalPlanQual() to work with new executor memory management method.
It doesn't leak memory anymore ...
parent
68965976
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
186 additions
and
139 deletions
+186
-139
src/backend/executor/execMain.c
src/backend/executor/execMain.c
+178
-131
src/backend/executor/execUtils.c
src/backend/executor/execUtils.c
+2
-2
src/include/nodes/execnodes.h
src/include/nodes/execnodes.h
+6
-6
No files found.
src/backend/executor/execMain.c
View file @
35026079
...
@@ -26,7 +26,7 @@
...
@@ -26,7 +26,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.19
4 2002/12/15 21:01:34
tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.19
5 2002/12/18 00:14:47
tgl Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -46,6 +46,22 @@
...
@@ -46,6 +46,22 @@
#include "utils/lsyscache.h"
#include "utils/lsyscache.h"
typedef
struct
execRowMark
{
Relation
relation
;
Index
rti
;
char
resname
[
32
];
}
execRowMark
;
typedef
struct
evalPlanQual
{
Index
rti
;
EState
*
estate
;
PlanState
*
planstate
;
struct
evalPlanQual
*
next
;
/* stack of active PlanQual plans */
struct
evalPlanQual
*
free
;
/* list of free PlanQual plans */
}
evalPlanQual
;
/* decls for local routines only used within this module */
/* decls for local routines only used within this module */
static
void
InitPlan
(
QueryDesc
*
queryDesc
);
static
void
InitPlan
(
QueryDesc
*
queryDesc
);
static
void
initResultRelInfo
(
ResultRelInfo
*
resultRelInfo
,
static
void
initResultRelInfo
(
ResultRelInfo
*
resultRelInfo
,
...
@@ -69,6 +85,9 @@ static void ExecUpdate(TupleTableSlot *slot, ItemPointer tupleid,
...
@@ -69,6 +85,9 @@ static void ExecUpdate(TupleTableSlot *slot, ItemPointer tupleid,
static
TupleTableSlot
*
EvalPlanQualNext
(
EState
*
estate
);
static
TupleTableSlot
*
EvalPlanQualNext
(
EState
*
estate
);
static
void
EndEvalPlanQual
(
EState
*
estate
);
static
void
EndEvalPlanQual
(
EState
*
estate
);
static
void
ExecCheckRTEPerms
(
RangeTblEntry
*
rte
,
CmdType
operation
);
static
void
ExecCheckRTEPerms
(
RangeTblEntry
*
rte
,
CmdType
operation
);
static
void
EvalPlanQualStart
(
evalPlanQual
*
epq
,
EState
*
estate
,
evalPlanQual
*
priorepq
);
static
void
EvalPlanQualStop
(
evalPlanQual
*
epq
);
/* end of local decls */
/* end of local decls */
...
@@ -365,21 +384,6 @@ ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation)
...
@@ -365,21 +384,6 @@ ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation)
* ===============================================================
* ===============================================================
*/
*/
typedef
struct
execRowMark
{
Relation
relation
;
Index
rti
;
char
resname
[
32
];
}
execRowMark
;
typedef
struct
evalPlanQual
{
Plan
*
plan
;
/* XXX temporary */
PlanState
*
planstate
;
Index
rti
;
EState
estate
;
struct
evalPlanQual
*
free
;
}
evalPlanQual
;
/* ----------------------------------------------------------------
/* ----------------------------------------------------------------
* InitPlan
* InitPlan
...
@@ -518,10 +522,10 @@ InitPlan(QueryDesc *queryDesc)
...
@@ -518,10 +522,10 @@ InitPlan(QueryDesc *queryDesc)
}
}
/* mark EvalPlanQual not active */
/* mark EvalPlanQual not active */
estate
->
es_
orig
Plan
=
plan
;
estate
->
es_
top
Plan
=
plan
;
estate
->
es_evalPlanQual
=
NULL
;
estate
->
es_evalPlanQual
=
NULL
;
estate
->
es_evTuple
=
NULL
;
estate
->
es_evTupleNull
=
NULL
;
estate
->
es_evTupleNull
=
NULL
;
estate
->
es_evTuple
=
NULL
;
estate
->
es_useEvalPlan
=
false
;
estate
->
es_useEvalPlan
=
false
;
/*
/*
...
@@ -1594,7 +1598,6 @@ EvalPlanQual(EState *estate, Index rti, ItemPointer tid)
...
@@ -1594,7 +1598,6 @@ EvalPlanQual(EState *estate, Index rti, ItemPointer tid)
Relation
relation
;
Relation
relation
;
HeapTupleData
tuple
;
HeapTupleData
tuple
;
HeapTuple
copyTuple
=
NULL
;
HeapTuple
copyTuple
=
NULL
;
int
rtsize
;
bool
endNode
;
bool
endNode
;
Assert
(
rti
!=
0
);
Assert
(
rti
!=
0
);
...
@@ -1686,15 +1689,13 @@ EvalPlanQual(EState *estate, Index rti, ItemPointer tid)
...
@@ -1686,15 +1689,13 @@ EvalPlanQual(EState *estate, Index rti, ItemPointer tid)
/*
/*
* Need to run a recheck subquery. Find or create a PQ stack entry.
* Need to run a recheck subquery. Find or create a PQ stack entry.
*/
*/
epq
=
(
evalPlanQual
*
)
estate
->
es_evalPlanQual
;
epq
=
estate
->
es_evalPlanQual
;
rtsize
=
length
(
estate
->
es_range_table
);
endNode
=
true
;
endNode
=
true
;
if
(
epq
!=
NULL
&&
epq
->
rti
==
0
)
if
(
epq
!=
NULL
&&
epq
->
rti
==
0
)
{
{
/* Top PQ stack entry is idle, so re-use it */
/* Top PQ stack entry is idle, so re-use it */
Assert
(
!
(
estate
->
es_useEvalPlan
)
&&
Assert
(
!
(
estate
->
es_useEvalPlan
)
&&
epq
->
next
==
NULL
);
epq
->
estate
.
es_evalPlanQual
==
NULL
);
epq
->
rti
=
rti
;
epq
->
rti
=
rti
;
endNode
=
false
;
endNode
=
false
;
}
}
...
@@ -1706,26 +1707,21 @@ EvalPlanQual(EState *estate, Index rti, ItemPointer tid)
...
@@ -1706,26 +1707,21 @@ EvalPlanQual(EState *estate, Index rti, ItemPointer tid)
* forget all what we done after Ra was suspended. Cool? -:))
* forget all what we done after Ra was suspended. Cool? -:))
*/
*/
if
(
epq
!=
NULL
&&
epq
->
rti
!=
rti
&&
if
(
epq
!=
NULL
&&
epq
->
rti
!=
rti
&&
epq
->
estate
.
es_evTuple
[
rti
-
1
]
!=
NULL
)
epq
->
estate
->
es_evTuple
[
rti
-
1
]
!=
NULL
)
{
{
do
do
{
{
evalPlanQual
*
oldepq
;
evalPlanQual
*
oldepq
;
/* pop previous PlanQual from the stack */
epqstate
=
&
(
epq
->
estate
);
oldepq
=
(
evalPlanQual
*
)
epqstate
->
es_evalPlanQual
;
Assert
(
oldepq
->
rti
!=
0
);
/* stop execution */
/* stop execution */
ExecEndNode
(
epq
->
planstate
);
EvalPlanQualStop
(
epq
);
ExecDropTupleTable
(
epqstate
->
es_tupleTable
,
true
);
/* pop previous PlanQual from the stack */
epqstate
->
es_tupleTable
=
NULL
;
oldepq
=
epq
->
next
;
heap_freetuple
(
epqstate
->
es_evTuple
[
epq
->
rti
-
1
]);
Assert
(
oldepq
&&
oldepq
->
rti
!=
0
);
epqstate
->
es_evTuple
[
epq
->
rti
-
1
]
=
NULL
;
/* push current PQ to freePQ stack */
/* push current PQ to freePQ stack */
oldepq
->
free
=
epq
;
oldepq
->
free
=
epq
;
epq
=
oldepq
;
epq
=
oldepq
;
estate
->
es_evalPlanQual
=
(
Pointer
)
epq
;
estate
->
es_evalPlanQual
=
epq
;
}
while
(
epq
->
rti
!=
rti
);
}
while
(
epq
->
rti
!=
rti
);
}
}
...
@@ -1740,62 +1736,26 @@ EvalPlanQual(EState *estate, Index rti, ItemPointer tid)
...
@@ -1740,62 +1736,26 @@ EvalPlanQual(EState *estate, Index rti, ItemPointer tid)
if
(
newepq
==
NULL
)
/* first call or freePQ stack is empty */
if
(
newepq
==
NULL
)
/* first call or freePQ stack is empty */
{
{
newepq
=
(
evalPlanQual
*
)
palloc
(
sizeof
(
evalPlanQual
));
newepq
=
(
evalPlanQual
*
)
palloc
0
(
sizeof
(
evalPlanQual
));
newepq
->
free
=
NULL
;
newepq
->
free
=
NULL
;
newepq
->
estate
=
NULL
;
/*
newepq
->
planstate
=
NULL
;
* Each stack level has its own copy of the plan tree. This
* is wasteful, but necessary until plan trees are fully
* read-only.
*/
newepq
->
plan
=
copyObject
(
estate
->
es_origPlan
);
/*
* Init stack level's EState. We share top level's copy of
* es_result_relations array and other non-changing status. We
* need our own tupletable, es_param_exec_vals, and other
* changeable state.
*/
epqstate
=
&
(
newepq
->
estate
);
memcpy
(
epqstate
,
estate
,
sizeof
(
EState
));
epqstate
->
es_direction
=
ForwardScanDirection
;
if
(
estate
->
es_origPlan
->
nParamExec
>
0
)
epqstate
->
es_param_exec_vals
=
(
ParamExecData
*
)
palloc
(
estate
->
es_origPlan
->
nParamExec
*
sizeof
(
ParamExecData
));
epqstate
->
es_tupleTable
=
NULL
;
epqstate
->
es_per_tuple_exprcontext
=
NULL
;
/*
* Each epqstate must have its own es_evTupleNull state, but
* all the stack entries share es_evTuple state. This allows
* sub-rechecks to inherit the value being examined by an
* outer recheck.
*/
epqstate
->
es_evTupleNull
=
(
bool
*
)
palloc
(
rtsize
*
sizeof
(
bool
));
if
(
epq
==
NULL
)
/* first PQ stack entry */
epqstate
->
es_evTuple
=
(
HeapTuple
*
)
palloc0
(
rtsize
*
sizeof
(
HeapTuple
));
else
/* later stack entries share the same storage */
epqstate
->
es_evTuple
=
epq
->
estate
.
es_evTuple
;
}
}
else
else
{
{
/* recycle previously used EState */
/* recycle previously used PlanQual */
epqstate
=
&
(
newepq
->
estate
);
Assert
(
newepq
->
estate
==
NULL
);
epq
->
free
=
NULL
;
}
}
/* push current PQ to the stack */
/* push current PQ to the stack */
epqstate
->
es_evalPlanQual
=
(
Pointer
)
epq
;
newepq
->
next
=
epq
;
epq
=
newepq
;
epq
=
newepq
;
estate
->
es_evalPlanQual
=
(
Pointer
)
epq
;
estate
->
es_evalPlanQual
=
epq
;
epq
->
rti
=
rti
;
epq
->
rti
=
rti
;
endNode
=
false
;
endNode
=
false
;
}
}
Assert
(
epq
->
rti
==
rti
);
Assert
(
epq
->
rti
==
rti
);
epqstate
=
&
(
epq
->
estate
);
/*
/*
* Ok - we're requested for the same RTE. Unfortunately we still have
* Ok - we're requested for the same RTE. Unfortunately we still have
...
@@ -1804,81 +1764,78 @@ EvalPlanQual(EState *estate, Index rti, ItemPointer tid)
...
@@ -1804,81 +1764,78 @@ EvalPlanQual(EState *estate, Index rti, ItemPointer tid)
* could make that work if insertion of the target tuple were
* could make that work if insertion of the target tuple were
* integrated with the Param mechanism somehow, so that the upper plan
* integrated with the Param mechanism somehow, so that the upper plan
* nodes know that their children's outputs have changed.
* nodes know that their children's outputs have changed.
*
* Note that the stack of free evalPlanQual nodes is quite useless at
* the moment, since it only saves us from pallocing/releasing the
* evalPlanQual nodes themselves. But it will be useful once we
* implement ReScan instead of end/restart for re-using PlanQual nodes.
*/
*/
if
(
endNode
)
if
(
endNode
)
{
{
/* stop execution */
/* stop execution */
ExecEndNode
(
epq
->
planstate
);
EvalPlanQualStop
(
epq
);
ExecDropTupleTable
(
epqstate
->
es_tupleTable
,
true
);
epqstate
->
es_tupleTable
=
NULL
;
}
}
/*
* Initialize new recheck query.
*
* Note: if we were re-using PlanQual plans via ExecReScan, we'd need
* to instead copy down changeable state from the top plan (including
* es_result_relation_info, es_junkFilter) and reset locally changeable
* state in the epq (including es_param_exec_vals, es_evTupleNull).
*/
EvalPlanQualStart
(
epq
,
estate
,
epq
->
next
);
/*
/*
* free old RTE' tuple, if any, and store target tuple where
* free old RTE' tuple, if any, and store target tuple where
* relation's scan node will see it
* relation's scan node will see it
*/
*/
epqstate
=
epq
->
estate
;
if
(
epqstate
->
es_evTuple
[
rti
-
1
]
!=
NULL
)
if
(
epqstate
->
es_evTuple
[
rti
-
1
]
!=
NULL
)
heap_freetuple
(
epqstate
->
es_evTuple
[
rti
-
1
]);
heap_freetuple
(
epqstate
->
es_evTuple
[
rti
-
1
]);
epqstate
->
es_evTuple
[
rti
-
1
]
=
copyTuple
;
epqstate
->
es_evTuple
[
rti
-
1
]
=
copyTuple
;
/*
* Initialize for new recheck query; be careful to copy down state
* that might have changed in top EState.
*/
epqstate
->
es_result_relation_info
=
estate
->
es_result_relation_info
;
epqstate
->
es_junkFilter
=
estate
->
es_junkFilter
;
if
(
estate
->
es_origPlan
->
nParamExec
>
0
)
memset
(
epqstate
->
es_param_exec_vals
,
0
,
estate
->
es_origPlan
->
nParamExec
*
sizeof
(
ParamExecData
));
memset
(
epqstate
->
es_evTupleNull
,
false
,
rtsize
*
sizeof
(
bool
));
epqstate
->
es_useEvalPlan
=
false
;
Assert
(
epqstate
->
es_tupleTable
==
NULL
);
epqstate
->
es_tupleTable
=
ExecCreateTupleTable
(
estate
->
es_tupleTable
->
size
);
epq
->
planstate
=
ExecInitNode
(
epq
->
plan
,
epqstate
);
return
EvalPlanQualNext
(
estate
);
return
EvalPlanQualNext
(
estate
);
}
}
static
TupleTableSlot
*
static
TupleTableSlot
*
EvalPlanQualNext
(
EState
*
estate
)
EvalPlanQualNext
(
EState
*
estate
)
{
{
evalPlanQual
*
epq
=
(
evalPlanQual
*
)
estate
->
es_evalPlanQual
;
evalPlanQual
*
epq
=
estate
->
es_evalPlanQual
;
EState
*
epqstate
=
&
(
epq
->
estate
);
MemoryContext
oldcontext
;
evalPlanQual
*
oldepq
;
TupleTableSlot
*
slot
;
TupleTableSlot
*
slot
;
Assert
(
epq
->
rti
!=
0
);
Assert
(
epq
->
rti
!=
0
);
lpqnext:
;
lpqnext:
;
oldcontext
=
MemoryContextSwitchTo
(
epq
->
estate
->
es_query_cxt
);
slot
=
ExecProcNode
(
epq
->
planstate
);
slot
=
ExecProcNode
(
epq
->
planstate
);
MemoryContextSwitchTo
(
oldcontext
);
/*
/*
* No more tuples for this PQ. Continue previous one.
* No more tuples for this PQ. Continue previous one.
*/
*/
if
(
TupIsNull
(
slot
))
if
(
TupIsNull
(
slot
))
{
{
evalPlanQual
*
oldepq
;
/* stop execution */
/* stop execution */
ExecEndNode
(
epq
->
planstate
);
EvalPlanQualStop
(
epq
);
ExecDropTupleTable
(
epqstate
->
es_tupleTable
,
true
);
epqstate
->
es_tupleTable
=
NULL
;
heap_freetuple
(
epqstate
->
es_evTuple
[
epq
->
rti
-
1
]);
epqstate
->
es_evTuple
[
epq
->
rti
-
1
]
=
NULL
;
/* pop old PQ from the stack */
/* pop old PQ from the stack */
oldepq
=
(
evalPlanQual
*
)
epqstate
->
es_evalPlanQual
;
oldepq
=
epq
->
next
;
if
(
oldepq
==
(
evalPlanQual
*
)
NULL
)
if
(
oldepq
==
NULL
)
{
{
epq
->
rti
=
0
;
/* this is the first (oldest) */
/* this is the first (oldest) PQ - mark as free */
estate
->
es_useEvalPlan
=
false
;
/* PQ - mark as free and */
epq
->
rti
=
0
;
return
(
NULL
);
/* continue Query execution */
estate
->
es_useEvalPlan
=
false
;
/* and continue Query execution */
return
(
NULL
);
}
}
Assert
(
oldepq
->
rti
!=
0
);
Assert
(
oldepq
->
rti
!=
0
);
/* push current PQ to freePQ stack */
/* push current PQ to freePQ stack */
oldepq
->
free
=
epq
;
oldepq
->
free
=
epq
;
epq
=
oldepq
;
epq
=
oldepq
;
epqstate
=
&
(
epq
->
estate
);
estate
->
es_evalPlanQual
=
epq
;
estate
->
es_evalPlanQual
=
(
Pointer
)
epq
;
goto
lpqnext
;
goto
lpqnext
;
}
}
...
@@ -1888,40 +1845,130 @@ lpqnext:;
...
@@ -1888,40 +1845,130 @@ lpqnext:;
static
void
static
void
EndEvalPlanQual
(
EState
*
estate
)
EndEvalPlanQual
(
EState
*
estate
)
{
{
evalPlanQual
*
epq
=
(
evalPlanQual
*
)
estate
->
es_evalPlanQual
;
evalPlanQual
*
epq
=
estate
->
es_evalPlanQual
;
EState
*
epqstate
=
&
(
epq
->
estate
);
evalPlanQual
*
oldepq
;
if
(
epq
->
rti
==
0
)
/* plans already shutdowned */
if
(
epq
->
rti
==
0
)
/* plans already shutdowned */
{
{
Assert
(
epq
->
estate
.
es_evalPlanQual
==
NULL
);
Assert
(
epq
->
next
==
NULL
);
return
;
return
;
}
}
for
(;;)
for
(;;)
{
{
evalPlanQual
*
oldepq
;
/* stop execution */
/* stop execution */
ExecEndNode
(
epq
->
planstate
);
EvalPlanQualStop
(
epq
);
ExecDropTupleTable
(
epqstate
->
es_tupleTable
,
true
);
epqstate
->
es_tupleTable
=
NULL
;
if
(
epqstate
->
es_evTuple
[
epq
->
rti
-
1
]
!=
NULL
)
{
heap_freetuple
(
epqstate
->
es_evTuple
[
epq
->
rti
-
1
]);
epqstate
->
es_evTuple
[
epq
->
rti
-
1
]
=
NULL
;
}
/* pop old PQ from the stack */
/* pop old PQ from the stack */
oldepq
=
(
evalPlanQual
*
)
epqstate
->
es_evalPlanQual
;
oldepq
=
epq
->
next
;
if
(
oldepq
==
(
evalPlanQual
*
)
NULL
)
if
(
oldepq
==
NULL
)
{
{
epq
->
rti
=
0
;
/* this is the first (oldest) */
/* this is the first (oldest) PQ - mark as free */
estate
->
es_useEvalPlan
=
false
;
/* PQ - mark as free */
epq
->
rti
=
0
;
estate
->
es_useEvalPlan
=
false
;
break
;
break
;
}
}
Assert
(
oldepq
->
rti
!=
0
);
Assert
(
oldepq
->
rti
!=
0
);
/* push current PQ to freePQ stack */
/* push current PQ to freePQ stack */
oldepq
->
free
=
epq
;
oldepq
->
free
=
epq
;
epq
=
oldepq
;
epq
=
oldepq
;
epqstate
=
&
(
epq
->
estate
);
estate
->
es_evalPlanQual
=
epq
;
estate
->
es_evalPlanQual
=
(
Pointer
)
epq
;
}
}
/*
* Start execution of one level of PlanQual.
*
* This is a cut-down version of ExecutorStart(): we copy some state from
* the top-level estate rather than initializing it fresh.
*/
static
void
EvalPlanQualStart
(
evalPlanQual
*
epq
,
EState
*
estate
,
evalPlanQual
*
priorepq
)
{
EState
*
epqstate
;
int
rtsize
;
MemoryContext
oldcontext
;
rtsize
=
length
(
estate
->
es_range_table
);
epq
->
estate
=
epqstate
=
CreateExecutorState
();
oldcontext
=
MemoryContextSwitchTo
(
epqstate
->
es_query_cxt
);
/*
* The epqstates share the top query's copy of unchanging state such
* as the snapshot, rangetable, result-rel info, and external Param info.
* They need their own copies of local state, including a tuple table,
* es_param_exec_vals, etc.
*/
epqstate
->
es_direction
=
ForwardScanDirection
;
epqstate
->
es_snapshot
=
estate
->
es_snapshot
;
epqstate
->
es_range_table
=
estate
->
es_range_table
;
epqstate
->
es_result_relations
=
estate
->
es_result_relations
;
epqstate
->
es_num_result_relations
=
estate
->
es_num_result_relations
;
epqstate
->
es_result_relation_info
=
estate
->
es_result_relation_info
;
epqstate
->
es_junkFilter
=
estate
->
es_junkFilter
;
epqstate
->
es_into_relation_descriptor
=
estate
->
es_into_relation_descriptor
;
epqstate
->
es_param_list_info
=
estate
->
es_param_list_info
;
if
(
estate
->
es_topPlan
->
nParamExec
>
0
)
epqstate
->
es_param_exec_vals
=
(
ParamExecData
*
)
palloc0
(
estate
->
es_topPlan
->
nParamExec
*
sizeof
(
ParamExecData
));
epqstate
->
es_rowMark
=
estate
->
es_rowMark
;
epqstate
->
es_instrument
=
estate
->
es_instrument
;
epqstate
->
es_topPlan
=
estate
->
es_topPlan
;
/*
* Each epqstate must have its own es_evTupleNull state, but
* all the stack entries share es_evTuple state. This allows
* sub-rechecks to inherit the value being examined by an
* outer recheck.
*/
epqstate
->
es_evTupleNull
=
(
bool
*
)
palloc0
(
rtsize
*
sizeof
(
bool
));
if
(
priorepq
==
NULL
)
/* first PQ stack entry */
epqstate
->
es_evTuple
=
(
HeapTuple
*
)
palloc0
(
rtsize
*
sizeof
(
HeapTuple
));
else
/* later stack entries share the same storage */
epqstate
->
es_evTuple
=
priorepq
->
estate
->
es_evTuple
;
epqstate
->
es_tupleTable
=
ExecCreateTupleTable
(
estate
->
es_tupleTable
->
size
);
epq
->
planstate
=
ExecInitNode
(
estate
->
es_topPlan
,
epqstate
);
MemoryContextSwitchTo
(
oldcontext
);
}
/*
* End execution of one level of PlanQual.
*
* This is a cut-down version of ExecutorEnd(); basically we want to do most
* of the normal cleanup, but *not* close result relations (which we are
* just sharing from the outer query).
*/
static
void
EvalPlanQualStop
(
evalPlanQual
*
epq
)
{
EState
*
epqstate
=
epq
->
estate
;
MemoryContext
oldcontext
;
oldcontext
=
MemoryContextSwitchTo
(
epqstate
->
es_query_cxt
);
ExecEndNode
(
epq
->
planstate
);
ExecDropTupleTable
(
epqstate
->
es_tupleTable
,
true
);
epqstate
->
es_tupleTable
=
NULL
;
if
(
epqstate
->
es_evTuple
[
epq
->
rti
-
1
]
!=
NULL
)
{
heap_freetuple
(
epqstate
->
es_evTuple
[
epq
->
rti
-
1
]);
epqstate
->
es_evTuple
[
epq
->
rti
-
1
]
=
NULL
;
}
}
MemoryContextSwitchTo
(
oldcontext
);
FreeExecutorState
(
epqstate
);
epq
->
estate
=
NULL
;
epq
->
planstate
=
NULL
;
}
}
src/backend/executor/execUtils.c
View file @
35026079
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.9
3 2002/12/15 16:17:46
tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.9
4 2002/12/18 00:14:47
tgl Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -204,7 +204,7 @@ CreateExecutorState(void)
...
@@ -204,7 +204,7 @@ CreateExecutorState(void)
estate
->
es_per_tuple_exprcontext
=
NULL
;
estate
->
es_per_tuple_exprcontext
=
NULL
;
estate
->
es_
orig
Plan
=
NULL
;
estate
->
es_
top
Plan
=
NULL
;
estate
->
es_evalPlanQual
=
NULL
;
estate
->
es_evalPlanQual
=
NULL
;
estate
->
es_evTupleNull
=
NULL
;
estate
->
es_evTupleNull
=
NULL
;
estate
->
es_evTuple
=
NULL
;
estate
->
es_evTuple
=
NULL
;
...
...
src/include/nodes/execnodes.h
View file @
35026079
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* $Id: execnodes.h,v 1.8
7 2002/12/15 21:01:34
tgl Exp $
* $Id: execnodes.h,v 1.8
8 2002/12/18 00:14:47
tgl Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -316,11 +316,11 @@ typedef struct EState
...
@@ -316,11 +316,11 @@ typedef struct EState
ExprContext
*
es_per_tuple_exprcontext
;
ExprContext
*
es_per_tuple_exprcontext
;
/* Below is to re-evaluate plan qual in READ COMMITTED mode */
/* Below is to re-evaluate plan qual in READ COMMITTED mode */
struct
Plan
*
es_origPlan
;
Plan
*
es_topPlan
;
/* link to top of plan tree */
Pointer
es_evalPlanQual
;
struct
evalPlanQual
*
es_evalPlanQual
;
/* chain of PlanQual states */
bool
*
es_evTupleNull
;
bool
*
es_evTupleNull
;
/* local array of EPQ status */
HeapTuple
*
es_evTuple
;
HeapTuple
*
es_evTuple
;
/* shared array of EPQ substitute tuples */
bool
es_useEvalPlan
;
bool
es_useEvalPlan
;
/* evaluating EPQ tuples? */
}
EState
;
}
EState
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment