mirror of
https://github.com/postgres/postgres.git
synced 2025-08-19 23:22:23 +03:00
Multi-column GIN indexes. Teodor Sigaev
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/gin/ginbulk.c,v 1.12 2008/06/29 21:04:01 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/gin/ginbulk.c,v 1.13 2008/07/11 21:06:29 tgl Exp $
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@@ -82,16 +82,16 @@ ginInsertData(BuildAccumulator *accum, EntryAccumulator *entry, ItemPointer heap
|
||||
* palloc'd space in accum.
|
||||
*/
|
||||
static Datum
|
||||
getDatumCopy(BuildAccumulator *accum, Datum value)
|
||||
getDatumCopy(BuildAccumulator *accum, OffsetNumber attnum, Datum value)
|
||||
{
|
||||
Form_pg_attribute *att = accum->ginstate->tupdesc->attrs;
|
||||
Form_pg_attribute att = accum->ginstate->origTupdesc->attrs[ attnum - 1 ];
|
||||
Datum res;
|
||||
|
||||
if (att[0]->attbyval)
|
||||
if (att->attbyval)
|
||||
res = value;
|
||||
else
|
||||
{
|
||||
res = datumCopy(value, false, att[0]->attlen);
|
||||
res = datumCopy(value, false, att->attlen);
|
||||
accum->allocatedMemory += GetMemoryChunkSpace(DatumGetPointer(res));
|
||||
}
|
||||
return res;
|
||||
@@ -101,7 +101,7 @@ getDatumCopy(BuildAccumulator *accum, Datum value)
|
||||
* Find/store one entry from indexed value.
|
||||
*/
|
||||
static void
|
||||
ginInsertEntry(BuildAccumulator *accum, ItemPointer heapptr, Datum entry)
|
||||
ginInsertEntry(BuildAccumulator *accum, ItemPointer heapptr, OffsetNumber attnum, Datum entry)
|
||||
{
|
||||
EntryAccumulator *ea = accum->entries,
|
||||
*pea = NULL;
|
||||
@@ -110,7 +110,7 @@ ginInsertEntry(BuildAccumulator *accum, ItemPointer heapptr, Datum entry)
|
||||
|
||||
while (ea)
|
||||
{
|
||||
res = compareEntries(accum->ginstate, entry, ea->value);
|
||||
res = compareAttEntries(accum->ginstate, attnum, entry, ea->attnum, ea->value);
|
||||
if (res == 0)
|
||||
break; /* found */
|
||||
else
|
||||
@@ -132,7 +132,8 @@ ginInsertEntry(BuildAccumulator *accum, ItemPointer heapptr, Datum entry)
|
||||
ea = EAAllocate(accum);
|
||||
|
||||
ea->left = ea->right = NULL;
|
||||
ea->value = getDatumCopy(accum, entry);
|
||||
ea->attnum = attnum;
|
||||
ea->value = getDatumCopy(accum, attnum, entry);
|
||||
ea->length = DEF_NPTR;
|
||||
ea->number = 1;
|
||||
ea->shouldSort = FALSE;
|
||||
@@ -160,7 +161,8 @@ ginInsertEntry(BuildAccumulator *accum, ItemPointer heapptr, Datum entry)
|
||||
* then calls itself for each parts
|
||||
*/
|
||||
static void
|
||||
ginChooseElem(BuildAccumulator *accum, ItemPointer heapptr, Datum *entries, uint32 nentry,
|
||||
ginChooseElem(BuildAccumulator *accum, ItemPointer heapptr, OffsetNumber attnum,
|
||||
Datum *entries, uint32 nentry,
|
||||
uint32 low, uint32 high, uint32 offset)
|
||||
{
|
||||
uint32 pos;
|
||||
@@ -168,15 +170,15 @@ ginChooseElem(BuildAccumulator *accum, ItemPointer heapptr, Datum *entries, uint
|
||||
|
||||
pos = (low + middle) >> 1;
|
||||
if (low != middle && pos >= offset && pos - offset < nentry)
|
||||
ginInsertEntry(accum, heapptr, entries[pos - offset]);
|
||||
ginInsertEntry(accum, heapptr, attnum, entries[pos - offset]);
|
||||
pos = (high + middle + 1) >> 1;
|
||||
if (middle + 1 != high && pos >= offset && pos - offset < nentry)
|
||||
ginInsertEntry(accum, heapptr, entries[pos - offset]);
|
||||
ginInsertEntry(accum, heapptr, attnum, entries[pos - offset]);
|
||||
|
||||
if (low != middle)
|
||||
ginChooseElem(accum, heapptr, entries, nentry, low, middle, offset);
|
||||
ginChooseElem(accum, heapptr, attnum, entries, nentry, low, middle, offset);
|
||||
if (high != middle + 1)
|
||||
ginChooseElem(accum, heapptr, entries, nentry, middle + 1, high, offset);
|
||||
ginChooseElem(accum, heapptr, attnum, entries, nentry, middle + 1, high, offset);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -185,7 +187,8 @@ ginChooseElem(BuildAccumulator *accum, ItemPointer heapptr, Datum *entries, uint
|
||||
* next middle on left part and middle of right part.
|
||||
*/
|
||||
void
|
||||
ginInsertRecordBA(BuildAccumulator *accum, ItemPointer heapptr, Datum *entries, int32 nentry)
|
||||
ginInsertRecordBA(BuildAccumulator *accum, ItemPointer heapptr, OffsetNumber attnum,
|
||||
Datum *entries, int32 nentry)
|
||||
{
|
||||
uint32 i,
|
||||
nbit = 0,
|
||||
@@ -201,8 +204,8 @@ ginInsertRecordBA(BuildAccumulator *accum, ItemPointer heapptr, Datum *entries,
|
||||
nbit = 1 << nbit;
|
||||
offset = (nbit - nentry) / 2;
|
||||
|
||||
ginInsertEntry(accum, heapptr, entries[(nbit >> 1) - offset]);
|
||||
ginChooseElem(accum, heapptr, entries, nentry, 0, nbit, offset);
|
||||
ginInsertEntry(accum, heapptr, attnum, entries[(nbit >> 1) - offset]);
|
||||
ginChooseElem(accum, heapptr, attnum, entries, nentry, 0, nbit, offset);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -259,7 +262,7 @@ walkTree(BuildAccumulator *accum)
|
||||
}
|
||||
|
||||
ItemPointerData *
|
||||
ginGetEntry(BuildAccumulator *accum, Datum *value, uint32 *n)
|
||||
ginGetEntry(BuildAccumulator *accum, OffsetNumber *attnum, Datum *value, uint32 *n)
|
||||
{
|
||||
EntryAccumulator *entry;
|
||||
ItemPointerData *list;
|
||||
@@ -299,6 +302,7 @@ ginGetEntry(BuildAccumulator *accum, Datum *value, uint32 *n)
|
||||
return NULL;
|
||||
|
||||
*n = entry->number;
|
||||
*attnum = entry->attnum;
|
||||
*value = entry->value;
|
||||
list = entry->list;
|
||||
|
||||
|
Reference in New Issue
Block a user