Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0147b19

Browse files
committed
Fix a many-legged critter reported by chifungfan@yahoo.com: under the
right circumstances a hash join executed as a DECLARE CURSOR/FETCHquery would crash the backend. Problem as seen in current sources wasthat the hash tables were stored in a context that was a child ofTransactionCommandContext, which got zapped at completion of the FETCHcommand --- but cursor cleanup executed at COMMIT expected the tablesto still be valid. I haven't chased down the details as seen in 7.0.*but I'm sure it's the same general problem.
1 parent94e90d9 commit0147b19

File tree

7 files changed

+84
-51
lines changed

7 files changed

+84
-51
lines changed

‎src/backend/commands/copy.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.120 2000/08/06 04:26:40 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.121 2000/08/22 04:06:21 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -29,6 +29,7 @@
2929
#include"executor/executor.h"
3030
#include"libpq/libpq.h"
3131
#include"miscadmin.h"
32+
#include"tcop/pquery.h"
3233
#include"tcop/tcopprot.h"
3334
#include"utils/acl.h"
3435
#include"utils/builtins.h"
@@ -598,7 +599,7 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp,
598599
tuples_read=0;
599600
boolreading_to_eof= true;
600601
RelationInfo*relationInfo;
601-
EState*estate=makeNode(EState);/* for ExecConstraints() */
602+
EState*estate=CreateExecutorState();/* for ExecConstraints() */
602603
TupleTabletupleTable;
603604
TupleTableSlot*slot;
604605
Oidloaded_oid=InvalidOid;

‎src/backend/executor/execMain.c

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
*
2828
*
2929
* IDENTIFICATION
30-
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.123 2000/08/06 04:26:26 tgl Exp $
30+
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.124 2000/08/22 04:06:19 tgl Exp $
3131
*
3232
*-------------------------------------------------------------------------
3333
*/
@@ -1574,31 +1574,32 @@ ExecRelCheck(Relation rel, TupleTableSlot *slot, EState *estate)
15741574
{
15751575
intncheck=rel->rd_att->constr->num_check;
15761576
ConstrCheck*check=rel->rd_att->constr->check;
1577-
MemoryContextoldContext;
15781577
ExprContext*econtext;
1578+
MemoryContextoldContext;
15791579
List*qual;
15801580
inti;
15811581

15821582
/*
1583-
* Make sure econtext, expressions, etc are placed in appropriate context.
1583+
* We will use the EState's per-tuple context for evaluating constraint
1584+
* expressions. Create it if it's not already there; if it is, reset it
1585+
* to free previously-used storage.
15841586
*/
1585-
oldContext=MemoryContextSwitchTo(TransactionCommandContext);
1586-
1587-
/*
1588-
* Create or reset the exprcontext for evaluating constraint expressions.
1589-
*/
1590-
econtext=estate->es_constraint_exprcontext;
1587+
econtext=estate->es_per_tuple_exprcontext;
15911588
if (econtext==NULL)
1592-
estate->es_constraint_exprcontext=econtext=
1593-
MakeExprContext(NULL,TransactionCommandContext);
1589+
{
1590+
oldContext=MemoryContextSwitchTo(estate->es_query_cxt);
1591+
estate->es_per_tuple_exprcontext=econtext=
1592+
MakeExprContext(NULL,estate->es_query_cxt);
1593+
MemoryContextSwitchTo(oldContext);
1594+
}
15941595
else
15951596
ResetExprContext(econtext);
15961597

15971598
/*
15981599
* If first time through for current result relation, set up econtext's
15991600
* range table to refer to result rel, and build expression nodetrees
1600-
* for rel's constraint expressions. All this stuff is kept in
1601-
*TransactionCommandContext so it will still be here next time through.
1601+
* for rel's constraint expressions. All this stuff is kept in the
1602+
*per-query memory context so it will still be here next time through.
16021603
*
16031604
* NOTE: if there are multiple result relations (eg, due to inheritance)
16041605
* then we leak storage for prior rel's expressions and rangetable.
@@ -1608,7 +1609,14 @@ ExecRelCheck(Relation rel, TupleTableSlot *slot, EState *estate)
16081609
if (econtext->ecxt_range_table==NIL||
16091610
getrelid(1,econtext->ecxt_range_table)!=RelationGetRelid(rel))
16101611
{
1611-
RangeTblEntry*rte=makeNode(RangeTblEntry);
1612+
RangeTblEntry*rte;
1613+
1614+
/*
1615+
* Make sure expressions, etc are placed in appropriate context.
1616+
*/
1617+
oldContext=MemoryContextSwitchTo(estate->es_query_cxt);
1618+
1619+
rte=makeNode(RangeTblEntry);
16121620

16131621
rte->relname=RelationGetRelationName(rel);
16141622
rte->ref=makeNode(Attr);
@@ -1627,10 +1635,10 @@ ExecRelCheck(Relation rel, TupleTableSlot *slot, EState *estate)
16271635
qual= (List*)stringToNode(check[i].ccbin);
16281636
estate->es_result_relation_constraints[i]=qual;
16291637
}
1630-
}
16311638

1632-
/* Done with building long-lived items */
1633-
MemoryContextSwitchTo(oldContext);
1639+
/* Done with building long-lived items */
1640+
MemoryContextSwitchTo(oldContext);
1641+
}
16341642

16351643
/* Arrange for econtext's scan tuple to be the tuple under test */
16361644
econtext->ecxt_scantuple=slot;

‎src/backend/executor/execUtils.c

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.64 2000/07/14 22:17:45 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.65 2000/08/22 04:06:19 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -866,9 +866,8 @@ ExecInsertIndexTuples(TupleTableSlot *slot,
866866

867867
heapTuple=slot->val;
868868

869-
/* ----------------
870-
*get information from the result relation info structure.
871-
* ----------------
869+
/*
870+
* Get information from the result relation info structure.
872871
*/
873872
resultRelationInfo=estate->es_result_relation_info;
874873
numIndices=resultRelationInfo->ri_NumIndices;
@@ -877,14 +876,26 @@ ExecInsertIndexTuples(TupleTableSlot *slot,
877876
heapRelation=resultRelationInfo->ri_RelationDesc;
878877
heapDescriptor=RelationGetDescr(heapRelation);
879878

880-
/* ----------------
881-
*Make a temporary expr/memory context for evaluating predicates
882-
*and functional-index functions.
883-
*XXX should do this once per command not once per tuple, and
884-
*just reset it once per tuple.
885-
* ----------------
879+
/*
880+
* We will use the EState's per-tuple context for evaluating predicates
881+
* and functional-index functions. Create it if it's not already there;
882+
* if it is, reset it to free previously-used storage.
886883
*/
887-
econtext=MakeExprContext(slot,TransactionCommandContext);
884+
econtext=estate->es_per_tuple_exprcontext;
885+
if (econtext==NULL)
886+
{
887+
MemoryContextoldContext;
888+
889+
oldContext=MemoryContextSwitchTo(estate->es_query_cxt);
890+
estate->es_per_tuple_exprcontext=econtext=
891+
MakeExprContext(NULL,estate->es_query_cxt);
892+
MemoryContextSwitchTo(oldContext);
893+
}
894+
else
895+
ResetExprContext(econtext);
896+
897+
/* Arrange for econtext's scan tuple to be the tuple under test */
898+
econtext->ecxt_scantuple=slot;
888899

889900
/* ----------------
890901
*for each index, form and insert the index tuple
@@ -935,8 +946,6 @@ ExecInsertIndexTuples(TupleTableSlot *slot,
935946
if (result)
936947
pfree(result);
937948
}
938-
939-
FreeExprContext(econtext);
940949
}
941950

942951
void

‎src/backend/executor/nodeHash.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
*
10-
*$Id: nodeHash.c,v 1.50 2000/07/17 03:04:53 tgl Exp $
10+
*$Id: nodeHash.c,v 1.51 2000/08/2204:06:19 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -334,7 +334,8 @@ ExecHashTableCreate(Hash *node)
334334

335335
/* ----------------
336336
*Initialize the hash table control block.
337-
*The hashtable control block is just palloc'd from executor memory.
337+
*The hashtable control block is just palloc'd from the executor's
338+
*per-query memory context.
338339
* ----------------
339340
*/
340341
hashtable= (HashJoinTable)palloc(sizeof(HashTableData));
@@ -361,7 +362,7 @@ ExecHashTableCreate(Hash *node)
361362
*working storage. See notes in executor/hashjoin.h.
362363
* ----------------
363364
*/
364-
hashtable->hashCxt=AllocSetContextCreate(TransactionCommandContext,
365+
hashtable->hashCxt=AllocSetContextCreate(CurrentMemoryContext,
365366
"HashTableContext",
366367
ALLOCSET_DEFAULT_MINSIZE,
367368
ALLOCSET_DEFAULT_INITSIZE,

‎src/backend/tcop/pquery.c

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/tcop/pquery.c,v 1.37 2000/07/17 03:05:15 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/tcop/pquery.c,v 1.38 2000/08/22 04:06:20 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -68,8 +68,8 @@ CreateExecutorState(void)
6868
state->es_direction=ForwardScanDirection;
6969
state->es_range_table=NIL;
7070

71-
state->es_into_relation_descriptor=NULL;
7271
state->es_result_relation_info=NULL;
72+
state->es_into_relation_descriptor=NULL;
7373

7474
state->es_param_list_info=NULL;
7575
state->es_param_exec_vals=NULL;
@@ -78,6 +78,10 @@ CreateExecutorState(void)
7878

7979
state->es_junkFilter=NULL;
8080

81+
state->es_query_cxt=CurrentMemoryContext;
82+
83+
state->es_per_tuple_exprcontext=NULL;
84+
8185
/* ----------------
8286
*return the executor state structure
8387
* ----------------
@@ -144,13 +148,11 @@ PreparePortal(char *portalName)
144148
}
145149

146150
/* ----------------
147-
* Create the new portal and make its memory context active.
151+
* Create the new portal.
148152
* ----------------
149153
*/
150154
portal=CreatePortal(portalName);
151155

152-
MemoryContextSwitchTo(PortalGetHeapMemory(portal));
153-
154156
returnportal;
155157
}
156158

@@ -170,8 +172,9 @@ ProcessQuery(Query *parsetree,
170172
char*tag;
171173
boolisRetrieveIntoPortal;
172174
boolisRetrieveIntoRelation;
173-
Portalportal=NULL;
174175
char*intoName=NULL;
176+
Portalportal=NULL;
177+
MemoryContextoldContext=NULL;
175178
QueryDesc*queryDesc;
176179
EState*state;
177180
TupleDescattinfo;
@@ -217,14 +220,18 @@ ProcessQuery(Query *parsetree,
217220
if (isRetrieveIntoPortal)
218221
{
219222
portal=PreparePortal(intoName);
220-
/* CurrentMemoryContext is now pointing toportal's context */
223+
oldContext=MemoryContextSwitchTo(PortalGetHeapMemory(portal));
221224
parsetree=copyObject(parsetree);
222225
plan=copyObject(plan);
226+
/*
227+
* We stay in portal's memory context for now, so that query desc,
228+
* EState, and plan startup info are also allocated in the portal
229+
* context.
230+
*/
223231
}
224232

225233
/* ----------------
226-
*Now we can create the QueryDesc object (this is also in
227-
*the portal context, if portal retrieve).
234+
*Now we can create the QueryDesc object.
228235
* ----------------
229236
*/
230237
queryDesc=CreateQueryDesc(parsetree,plan,dest);
@@ -241,7 +248,7 @@ ProcessQuery(Query *parsetree,
241248
queryDesc->dest= (int)None;
242249

243250
/* ----------------
244-
*create a default executor state..
251+
*create a default executor state.
245252
* ----------------
246253
*/
247254
state=CreateExecutorState();
@@ -279,9 +286,11 @@ ProcessQuery(Query *parsetree,
279286
state,
280287
PortalCleanup);
281288

282-
MemoryContextSwitchTo(TransactionCommandContext);
289+
/* Now we can return to caller's memory context. */
290+
MemoryContextSwitchTo(oldContext);
283291

284292
EndCommand(tag,dest);
293+
285294
return;
286295
}
287296

‎src/include/executor/hashjoin.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: hashjoin.h,v 1.18 2000/07/12 02:37:30 tgl Exp $
10+
* $Id: hashjoin.h,v 1.19 2000/08/22 04:06:21 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -26,7 +26,7 @@
2626
* This makes it easy and fast to release the storage when we don't need it
2727
* anymore.
2828
*
29-
* The contexts are made children ofTransactionCommandContext, ensuring
29+
* Thehashtablecontexts are made children ofthe per-query context, ensuring
3030
* that they will be discarded at end of statement even if the join is
3131
* aborted early by an error. (Likewise, any temporary files we make will
3232
* be cleaned up by the virtual file manager in event of an error.)

‎src/include/nodes/execnodes.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: execnodes.h,v 1.46 2000/08/13 02:50:24 tgl Exp $
10+
* $Id: execnodes.h,v 1.47 2000/08/22 04:06:22 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -223,9 +223,14 @@ typedef struct EState
223223
uint32es_processed;/* # of tuples processed */
224224
Oides_lastoid;/* last oid processed (by INSERT) */
225225
List*es_rowMark;/* not good place, but there is no other */
226-
/* these two fields are storage space for ExecConstraints(): */
226+
MemoryContextes_query_cxt;/* per-query context in which EState lives */
227+
/* this ExprContext is for per-output-tuple operations, such as
228+
* constraint checks and index-value computations. It can be reset
229+
* for each output tuple. Note that it will be created only if needed.
230+
*/
231+
ExprContext*es_per_tuple_exprcontext;
232+
/* this field is storage space for ExecConstraints(): */
227233
List**es_result_relation_constraints;
228-
ExprContext*es_constraint_exprcontext;
229234
/* Below is to re-evaluate plan qual in READ COMMITTED mode */
230235
structPlan*es_origPlan;
231236
Pointeres_evalPlanQual;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp