aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/gin/gininsert.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-07-11 21:06:29 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-07-11 21:06:29 +0000
commit27cb66fdfe862f395cefa0d498b681ce142f59d8 (patch)
tree23f3223f8f963c4a5f9eca652b073467d85d5406 /src/backend/access/gin/gininsert.c
parent2d6599f47152fe898569ba07b0a0a79e244bbb99 (diff)
downloadpostgresql-27cb66fdfe862f395cefa0d498b681ce142f59d8.tar.gz
postgresql-27cb66fdfe862f395cefa0d498b681ce142f59d8.zip
Multi-column GIN indexes. Teodor Sigaev
Diffstat (limited to 'src/backend/access/gin/gininsert.c')
-rw-r--r--src/backend/access/gin/gininsert.c59
1 files changed, 32 insertions, 27 deletions
diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c
index 654bf137e23..ac35069d7f5 100644
--- a/src/backend/access/gin/gininsert.c
+++ b/src/backend/access/gin/gininsert.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/gin/gininsert.c,v 1.13 2008/05/16 01:27:06 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gin/gininsert.c,v 1.14 2008/07/11 21:06:29 tgl Exp $
*-------------------------------------------------------------------------
*/
@@ -99,9 +99,9 @@ static IndexTuple
addItemPointersToTuple(Relation index, GinState *ginstate, GinBtreeStack *stack,
IndexTuple old, ItemPointerData *items, uint32 nitem, bool isBuild)
{
- bool isnull;
- Datum key = index_getattr(old, FirstOffsetNumber, ginstate->tupdesc, &isnull);
- IndexTuple res = GinFormTuple(ginstate, key, NULL, nitem + GinGetNPosting(old));
+ Datum key = gin_index_getattr(ginstate, old);
+ OffsetNumber attnum = gintuple_get_attrnum(ginstate, old);
+ IndexTuple res = GinFormTuple(ginstate, attnum, key, NULL, nitem + GinGetNPosting(old));
if (res)
{
@@ -119,7 +119,7 @@ addItemPointersToTuple(Relation index, GinState *ginstate, GinBtreeStack *stack,
GinPostingTreeScan *gdi;
/* posting list becomes big, so we need to make posting's tree */
- res = GinFormTuple(ginstate, key, NULL, 0);
+ res = GinFormTuple(ginstate, attnum, key, NULL, 0);
postingRoot = createPostingTree(index, GinGetPosting(old), GinGetNPosting(old));
GinSetPostingTree(res, postingRoot);
@@ -138,14 +138,15 @@ addItemPointersToTuple(Relation index, GinState *ginstate, GinBtreeStack *stack,
* Inserts only one entry to the index, but it can add more than 1 ItemPointer.
*/
static void
-ginEntryInsert(Relation index, GinState *ginstate, Datum value, ItemPointerData *items, uint32 nitem, bool isBuild)
+ginEntryInsert(Relation index, GinState *ginstate, OffsetNumber attnum, Datum value,
+ ItemPointerData *items, uint32 nitem, bool isBuild)
{
GinBtreeData btree;
GinBtreeStack *stack;
IndexTuple itup;
Page page;
- prepareEntryScan(&btree, index, value, ginstate);
+ prepareEntryScan(&btree, index, attnum, value, ginstate);
stack = ginFindLeafPage(&btree, NULL);
page = BufferGetPage(stack->buffer);
@@ -180,7 +181,7 @@ ginEntryInsert(Relation index, GinState *ginstate, Datum value, ItemPointerData
else
{
/* We suppose, that tuple can store at list one itempointer */
- itup = GinFormTuple(ginstate, value, items, 1);
+ itup = GinFormTuple(ginstate, attnum, value, items, 1);
if (itup == NULL || IndexTupleSize(itup) >= GinMaxItemSize)
elog(ERROR, "huge tuple");
@@ -203,21 +204,21 @@ ginEntryInsert(Relation index, GinState *ginstate, Datum value, ItemPointerData
* Function isn't used during normal insert
*/
static uint32
-ginHeapTupleBulkInsert(GinBuildState *buildstate, Datum value, ItemPointer heapptr)
+ginHeapTupleBulkInsert(GinBuildState *buildstate, OffsetNumber attnum, Datum value, ItemPointer heapptr)
{
Datum *entries;
int32 nentries;
MemoryContext oldCtx;
oldCtx = MemoryContextSwitchTo(buildstate->funcCtx);
- entries = extractEntriesSU(buildstate->accum.ginstate, value, &nentries);
+ entries = extractEntriesSU(buildstate->accum.ginstate, attnum, value, &nentries);
MemoryContextSwitchTo(oldCtx);
if (nentries == 0)
/* nothing to insert */
return 0;
- ginInsertRecordBA(&buildstate->accum, heapptr, entries, nentries);
+ ginInsertRecordBA(&buildstate->accum, heapptr, attnum, entries, nentries);
MemoryContextReset(buildstate->funcCtx);
@@ -230,13 +231,15 @@ ginBuildCallback(Relation index, HeapTuple htup, Datum *values,
{
GinBuildState *buildstate = (GinBuildState *) state;
MemoryContext oldCtx;
-
- if (*isnull)
- return;
+ int i;
oldCtx = MemoryContextSwitchTo(buildstate->tmpCtx);
- buildstate->indtuples += ginHeapTupleBulkInsert(buildstate, *values, &htup->t_self);
+ for(i=0; i<buildstate->ginstate.origTupdesc->natts;i++)
+ if ( !isnull[i] )
+ buildstate->indtuples += ginHeapTupleBulkInsert(buildstate,
+ (OffsetNumber)(i+1), values[i],
+ &htup->t_self);
/* If we've maxed out our available memory, dump everything to the index */
if (buildstate->accum.allocatedMemory >= maintenance_work_mem * 1024L)
@@ -244,12 +247,13 @@ ginBuildCallback(Relation index, HeapTuple htup, Datum *values,
ItemPointerData *list;
Datum entry;
uint32 nlist;
+ OffsetNumber attnum;
- while ((list = ginGetEntry(&buildstate->accum, &entry, &nlist)) != NULL)
+ while ((list = ginGetEntry(&buildstate->accum, &attnum, &entry, &nlist)) != NULL)
{
/* there could be many entries, so be willing to abort here */
CHECK_FOR_INTERRUPTS();
- ginEntryInsert(index, &buildstate->ginstate, entry, list, nlist, TRUE);
+ ginEntryInsert(index, &buildstate->ginstate, attnum, entry, list, nlist, TRUE);
}
MemoryContextReset(buildstate->tmpCtx);
@@ -273,6 +277,7 @@ ginbuild(PG_FUNCTION_ARGS)
Datum entry;
uint32 nlist;
MemoryContext oldCtx;
+ OffsetNumber attnum;
if (RelationGetNumberOfBlocks(index) != 0)
elog(ERROR, "index \"%s\" already contains data",
@@ -337,11 +342,11 @@ ginbuild(PG_FUNCTION_ARGS)
/* dump remaining entries to the index */
oldCtx = MemoryContextSwitchTo(buildstate.tmpCtx);
- while ((list = ginGetEntry(&buildstate.accum, &entry, &nlist)) != NULL)
+ while ((list = ginGetEntry(&buildstate.accum, &attnum, &entry, &nlist)) != NULL)
{
/* there could be many entries, so be willing to abort here */
CHECK_FOR_INTERRUPTS();
- ginEntryInsert(index, &buildstate.ginstate, entry, list, nlist, TRUE);
+ ginEntryInsert(index, &buildstate.ginstate, attnum, entry, list, nlist, TRUE);
}
MemoryContextSwitchTo(oldCtx);
@@ -362,20 +367,20 @@ ginbuild(PG_FUNCTION_ARGS)
* Inserts value during normal insertion
*/
static uint32
-ginHeapTupleInsert(Relation index, GinState *ginstate, Datum value, ItemPointer item)
+ginHeapTupleInsert(Relation index, GinState *ginstate, OffsetNumber attnum, Datum value, ItemPointer item)
{
Datum *entries;
int32 i,
nentries;
- entries = extractEntriesSU(ginstate, value, &nentries);
+ entries = extractEntriesSU(ginstate, attnum, value, &nentries);
if (nentries == 0)
/* nothing to insert */
return 0;
for (i = 0; i < nentries; i++)
- ginEntryInsert(index, ginstate, entries[i], item, 1, FALSE);
+ ginEntryInsert(index, ginstate, attnum, entries[i], item, 1, FALSE);
return nentries;
}
@@ -395,10 +400,8 @@ gininsert(PG_FUNCTION_ARGS)
GinState ginstate;
MemoryContext oldCtx;
MemoryContext insertCtx;
- uint32 res;
-
- if (*isnull)
- PG_RETURN_BOOL(false);
+ uint32 res = 0;
+ int i;
insertCtx = AllocSetContextCreate(CurrentMemoryContext,
"Gin insert temporary context",
@@ -410,7 +413,9 @@ gininsert(PG_FUNCTION_ARGS)
initGinState(&ginstate, index);
- res = ginHeapTupleInsert(index, &ginstate, *values, ht_ctid);
+ for(i=0; i<ginstate.origTupdesc->natts;i++)
+ if ( !isnull[i] )
+ res += ginHeapTupleInsert(index, &ginstate, (OffsetNumber)(i+1), values[i], ht_ctid);
MemoryContextSwitchTo(oldCtx);
MemoryContextDelete(insertCtx);