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

Commit6bfe640

Browse files
committed
Cleanup of code for creating index entries. Functional indexes with
pass-by-ref data types --- eg, an index on lower(textfield) --- no longerleak memory during index creation or update. Clean up a lot of redundantcode ... did you know that copy, vacuum, truncate, reindex, extend index,and bootstrap each basically duplicated the main executor's logic forextracting information about an index and preparing index entries?Functional indexes should be a little faster now too, due to removalof repeated function lookups.CREATE INDEX 'opt_type' clause is deimplemented by these changes,but I haven't removed it from the parser yet (need to merge withThomas' latest change set first).
1 parenta30bc7c commit6bfe640

File tree

32 files changed

+900
-1736
lines changed

32 files changed

+900
-1736
lines changed

‎src/backend/access/gist/gist.c

Lines changed: 64 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
*
88
* IDENTIFICATION
9-
* $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.61 2000/07/12 02:36:46 tgl Exp $
9+
* $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.62 2000/07/14 22:17:28 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -65,53 +65,42 @@ gistbuild(PG_FUNCTION_ARGS)
6565
{
6666
Relationheap= (Relation)PG_GETARG_POINTER(0);
6767
Relationindex= (Relation)PG_GETARG_POINTER(1);
68-
int32natts=PG_GETARG_INT32(2);
69-
AttrNumber*attnum= (AttrNumber*)PG_GETARG_POINTER(3);
70-
FuncIndexInfo*finfo= (FuncIndexInfo*)PG_GETARG_POINTER(4);
71-
PredInfo*predInfo= (PredInfo*)PG_GETARG_POINTER(5);
68+
IndexInfo*indexInfo= (IndexInfo*)PG_GETARG_POINTER(2);
69+
Node*oldPred= (Node*)PG_GETARG_POINTER(3);
7270
#ifdefNOT_USED
73-
boolunique=PG_GETARG_BOOL(6);
74-
IndexStrategyistrat= (IndexStrategy)PG_GETARG_POINTER(7);
71+
IndexStrategyistrat= (IndexStrategy)PG_GETARG_POINTER(4);
7572
#endif
76-
HeapScanDescscan;
77-
AttrNumberi;
73+
HeapScanDeschscan;
7874
HeapTuplehtup;
7975
IndexTupleitup;
80-
TupleDeschd,
81-
id;
82-
InsertIndexResultres;
83-
Datum*d;
84-
bool*nulls;
85-
intnb,
86-
nh,
87-
ni;
76+
TupleDeschtupdesc,
77+
itupdesc;
78+
Datumattdata[INDEX_MAX_KEYS];
79+
charnulls[INDEX_MAX_KEYS];
80+
intnhtups,
81+
nitups;
82+
Node*pred=indexInfo->ii_Predicate;
8883
#ifndefOMIT_PARTIAL_INDEX
89-
ExprContext*econtext;
9084
TupleTabletupleTable;
9185
TupleTableSlot*slot;
9286
#endif
93-
Node*pred,
94-
*oldPred;
87+
ExprContext*econtext;
88+
InsertIndexResultres=NULL;
9589
GISTSTATEgiststate;
9690
GISTENTRYtmpcentry;
9791
Bufferbuffer=InvalidBuffer;
9892
bool*compvec;
93+
inti;
9994

10095
/* no locking is needed */
10196

102-
CommandCounterIncrement();/* so we can see the new pg_index tuple */
103-
10497
initGISTstate(&giststate,index);
10598

106-
pred=predInfo->pred;
107-
oldPred=predInfo->oldPred;
108-
10999
/*
110100
* We expect to be called exactly once for any index relation. If
111101
* that's not the case, big trouble's what we have.
112102
*/
113-
114-
if (oldPred==NULL&& (nb=RelationGetNumberOfBlocks(index))!=0)
103+
if (oldPred==NULL&&RelationGetNumberOfBlocks(index)!=0)
115104
elog(ERROR,"%s already contains data",RelationGetRelationName(index));
116105

117106
/* initialize the root page (if this is a new index) */
@@ -122,43 +111,50 @@ gistbuild(PG_FUNCTION_ARGS)
122111
WriteBuffer(buffer);
123112
}
124113

125-
/* init the tuple descriptors and get set for a heap scan */
126-
hd=RelationGetDescr(heap);
127-
id=RelationGetDescr(index);
128-
d= (Datum*)palloc(natts*sizeof(*d));
129-
nulls= (bool*)palloc(natts*sizeof(*nulls));
114+
/* get tuple descriptors for heap and index relations */
115+
htupdesc=RelationGetDescr(heap);
116+
itupdesc=RelationGetDescr(index);
130117

131118
/*
132119
* If this is a predicate (partial) index, we will need to evaluate
133120
* the predicate using ExecQual, which requires the current tuple to
134121
* be in a slot of a TupleTable. In addition, ExecQual must have an
135122
* ExprContext referring to that slot.Here, we initialize dummy
136-
* TupleTable and ExprContext objects for this purpose. --Nels, Feb
137-
* '92
123+
* TupleTable and ExprContext objects for this purpose. --Nels, Feb 92
124+
*
125+
* We construct the ExprContext anyway since we need a per-tuple
126+
* temporary memory context for function evaluation -- tgl July 00
138127
*/
139128
#ifndefOMIT_PARTIAL_INDEX
140129
if (pred!=NULL||oldPred!=NULL)
141130
{
142131
tupleTable=ExecCreateTupleTable(1);
143132
slot=ExecAllocTableSlot(tupleTable);
144-
ExecSetSlotDescriptor(slot,hd);
145-
econtext=MakeExprContext(slot,TransactionCommandContext);
133+
ExecSetSlotDescriptor(slot,htupdesc);
146134
}
147135
else
148136
{
149137
tupleTable=NULL;
150138
slot=NULL;
151-
econtext=NULL;
152139
}
140+
econtext=MakeExprContext(slot,TransactionCommandContext);
141+
#else
142+
econtext=MakeExprContext(NULL,TransactionCommandContext);
153143
#endif/* OMIT_PARTIAL_INDEX */
154-
/* int the tuples as we insert them */
155-
nh=ni=0;
156144

157-
scan=heap_beginscan(heap,0,SnapshotNow,0, (ScanKey)NULL);
145+
/* build the index */
146+
nhtups=nitups=0;
147+
148+
compvec= (bool*)palloc(sizeof(bool)*indexInfo->ii_NumIndexAttrs);
158149

159-
while (HeapTupleIsValid(htup=heap_getnext(scan,0)))
150+
/* start a heap scan */
151+
hscan=heap_beginscan(heap,0,SnapshotNow,0, (ScanKey)NULL);
152+
153+
while (HeapTupleIsValid(htup=heap_getnext(hscan,0)))
160154
{
161-
nh++;
155+
MemoryContextReset(econtext->ecxt_per_tuple_memory);
156+
157+
nhtups++;
162158

163159
#ifndefOMIT_PARTIAL_INDEX
164160
/*
@@ -167,11 +163,10 @@ gistbuild(PG_FUNCTION_ARGS)
167163
*/
168164
if (oldPred!=NULL)
169165
{
170-
/* SetSlotContents(slot, htup); */
171166
slot->val=htup;
172167
if (ExecQual((List*)oldPred,econtext, false))
173168
{
174-
ni++;
169+
nitups++;
175170
continue;
176171
}
177172
}
@@ -182,61 +177,41 @@ gistbuild(PG_FUNCTION_ARGS)
182177
*/
183178
if (pred!=NULL)
184179
{
185-
/* SetSlotContents(slot, htup); */
186180
slot->val=htup;
187181
if (!ExecQual((List*)pred,econtext, false))
188182
continue;
189183
}
190184
#endif/* OMIT_PARTIAL_INDEX */
191185

192-
ni++;
186+
nitups++;
193187

194188
/*
195189
* For the current heap tuple, extract all the attributes we use
196190
* in this index, and note which are null.
197191
*/
198-
199-
for (i=1;i <=natts;i++)
200-
{
201-
intattoff;
202-
boolattnull;
203-
204-
/*
205-
* Offsets are from the start of the tuple, and are
206-
* zero-based; indices are one-based. The next call returns i
207-
* - 1. That's data hiding for you.
208-
*/
209-
210-
attoff=AttrNumberGetAttrOffset(i);
211-
212-
/*
213-
* d[attoff] = HeapTupleGetAttributeValue(htup, buffer,
214-
*/
215-
d[attoff]=GetIndexValue(htup,
216-
hd,
217-
attoff,
218-
attnum,
219-
finfo,
220-
&attnull);
221-
nulls[attoff]= (attnull ?'n' :' ');
222-
}
192+
FormIndexDatum(indexInfo,
193+
htup,
194+
htupdesc,
195+
econtext->ecxt_per_tuple_memory,
196+
attdata,
197+
nulls);
223198

224199
/* immediately compress keys to normalize */
225-
compvec= (bool*)palloc(sizeof(bool)*natts);
226-
for (i=0;i<natts;i++)
200+
for (i=0;i<indexInfo->ii_NumIndexAttrs;i++)
227201
{
228-
gistcentryinit(&giststate,&tmpcentry, (char*)d[i],
202+
gistcentryinit(&giststate,&tmpcentry, (char*)attdata[i],
229203
(Relation)NULL, (Page)NULL, (OffsetNumber)0,
230204
-1/* size is currently bogus */ , TRUE);
231-
if (d[i]!= (Datum)tmpcentry.pred&& !(giststate.keytypbyval))
205+
if (attdata[i]!= (Datum)tmpcentry.pred&&
206+
!(giststate.keytypbyval))
232207
compvec[i]= TRUE;
233208
else
234209
compvec[i]= FALSE;
235-
d[i]= (Datum)tmpcentry.pred;
210+
attdata[i]= (Datum)tmpcentry.pred;
236211
}
237212

238213
/* form an index tuple and point it at the heap tuple */
239-
itup=index_formtuple(id,&d[0],nulls);
214+
itup=index_formtuple(itupdesc,attdata,nulls);
240215
itup->t_tid=htup->t_self;
241216

242217
/*
@@ -248,24 +223,27 @@ gistbuild(PG_FUNCTION_ARGS)
248223
*/
249224

250225
res=gistdoinsert(index,itup,&giststate);
251-
for (i=0;i<natts;i++)
252-
if (compvec[i]== TRUE)
253-
pfree((char*)d[i]);
226+
227+
for (i=0;i<indexInfo->ii_NumIndexAttrs;i++)
228+
if (compvec[i])
229+
pfree(DatumGetPointer(attdata[i]));
230+
254231
pfree(itup);
255232
pfree(res);
256-
pfree(compvec);
257233
}
258234

259235
/* okay, all heap tuples are indexed */
260-
heap_endscan(scan);
236+
heap_endscan(hscan);
237+
238+
pfree(compvec);
261239

262240
#ifndefOMIT_PARTIAL_INDEX
263241
if (pred!=NULL||oldPred!=NULL)
264242
{
265243
ExecDropTupleTable(tupleTable, true);
266-
FreeExprContext(econtext);
267244
}
268245
#endif/* OMIT_PARTIAL_INDEX */
246+
FreeExprContext(econtext);
269247

270248
/*
271249
* Since we just counted the tuples in the heap, we update its stats
@@ -286,20 +264,16 @@ gistbuild(PG_FUNCTION_ARGS)
286264

287265
heap_close(heap,NoLock);
288266
index_close(index);
289-
UpdateStats(hrelid,nh,inplace);
290-
UpdateStats(irelid,ni,inplace);
267+
UpdateStats(hrelid,nhtups,inplace);
268+
UpdateStats(irelid,nitups,inplace);
291269
if (oldPred!=NULL&& !inplace)
292270
{
293-
if (ni==nh)
271+
if (nitups==nhtups)
294272
pred=NULL;
295273
UpdateIndexPredicate(irelid,oldPred,pred);
296274
}
297275
}
298276

299-
/* be tidy */
300-
pfree(nulls);
301-
pfree(d);
302-
303277
PG_RETURN_VOID();
304278
}
305279

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp