mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
Updates to make GIST work with multi-key indexes (from Oleg Bartunov
and Teodor Sigaev). Declare key values as Datum where appropriate, rather than char* (Tom Lane).
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/gist/gistget.c,v 1.27 2001/05/30 19:53:40 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/gist/gistget.c,v 1.28 2001/05/31 18:16:54 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -238,16 +238,21 @@ gistindex_keytest(IndexTuple tuple,
|
||||
while (scanKeySize > 0)
|
||||
{
|
||||
datum = index_getattr(tuple,
|
||||
1,
|
||||
key[0].sk_attno,
|
||||
tupdesc,
|
||||
&isNull);
|
||||
if (isNull || IndexTupleSize(tuple) == sizeof(IndexTupleData) )
|
||||
if (isNull)
|
||||
{
|
||||
/* XXX eventually should check if SK_ISNULL */
|
||||
return false;
|
||||
}
|
||||
|
||||
gistdentryinit(giststate, &de, (char *) datum, r, p, offset,
|
||||
/* this code from backend/access/common/indexvalid.c. But why and what???
|
||||
if (key[0].sk_flags & SK_ISNULL)
|
||||
return false;
|
||||
*/
|
||||
gistdentryinit(giststate, key[0].sk_attno-1, &de,
|
||||
datum, r, p, offset,
|
||||
IndexTupleSize(tuple) - sizeof(IndexTupleData),
|
||||
FALSE);
|
||||
|
||||
@ -266,16 +271,16 @@ gistindex_keytest(IndexTuple tuple,
|
||||
ObjectIdGetDatum(key[0].sk_procedure));
|
||||
}
|
||||
|
||||
if ( (char*)de.pred != (char*)datum )
|
||||
if ( de.pred ) pfree( de.pred );
|
||||
if ( de.key != datum )
|
||||
if ( DatumGetPointer(de.key) != NULL )
|
||||
pfree( DatumGetPointer(de.key) );
|
||||
|
||||
if (DatumGetBool(test) == !!(key[0].sk_flags & SK_NEGATE))
|
||||
return false;
|
||||
|
||||
scanKeySize -= 1;
|
||||
scanKeySize--;
|
||||
key++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -284,7 +289,7 @@ static OffsetNumber
|
||||
gistfindnext(IndexScanDesc s, Page p, OffsetNumber n, ScanDirection dir)
|
||||
{
|
||||
OffsetNumber maxoff;
|
||||
char *it;
|
||||
IndexTuple it;
|
||||
GISTPageOpaque po;
|
||||
GISTScanOpaque so;
|
||||
GISTSTATE *giststate;
|
||||
@ -307,8 +312,8 @@ gistfindnext(IndexScanDesc s, Page p, OffsetNumber n, ScanDirection dir)
|
||||
|
||||
while (n >= FirstOffsetNumber && n <= maxoff)
|
||||
{
|
||||
it = (char *) PageGetItem(p, PageGetItemId(p, n));
|
||||
if (gistindex_keytest((IndexTuple) it,
|
||||
it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
|
||||
if (gistindex_keytest(it,
|
||||
RelationGetDescr(s->relation),
|
||||
s->numberOfKeys, s->keyData, giststate,
|
||||
s->relation, p, n))
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/gist/gistscan.c,v 1.34 2001/05/30 19:53:40 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/gist/gistscan.c,v 1.35 2001/05/31 18:16:54 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -122,7 +122,7 @@ gistrescan(PG_FUNCTION_ARGS)
|
||||
s->keyData[i].sk_procedure
|
||||
= RelationGetGISTStrategy(s->relation, s->keyData[i].sk_attno,
|
||||
s->keyData[i].sk_procedure);
|
||||
s->keyData[i].sk_func = p->giststate->consistentFn;
|
||||
s->keyData[i].sk_func = p->giststate->consistentFn[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -153,7 +153,7 @@ gistrescan(PG_FUNCTION_ARGS)
|
||||
s->keyData[i].sk_procedure
|
||||
= RelationGetGISTStrategy(s->relation, s->keyData[i].sk_attno,
|
||||
s->keyData[i].sk_procedure);
|
||||
s->keyData[i].sk_func = p->giststate->consistentFn;
|
||||
s->keyData[i].sk_func = p->giststate->consistentFn[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.48 2001/03/22 06:16:07 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.49 2001/05/31 18:16:54 tgl Exp $
|
||||
*
|
||||
* INTERFACE ROUTINES
|
||||
* index_open - open an index relation by relationId
|
||||
@ -410,13 +410,13 @@ index_getprocid(Relation irel,
|
||||
uint16 procnum)
|
||||
{
|
||||
RegProcedure *loc;
|
||||
int natts;
|
||||
int nproc;
|
||||
|
||||
natts = irel->rd_rel->relnatts;
|
||||
nproc = irel->rd_am->amsupport;
|
||||
|
||||
loc = irel->rd_support;
|
||||
|
||||
Assert(loc != NULL);
|
||||
|
||||
return loc[(natts * (procnum - 1)) + (attnum - 1)];
|
||||
return loc[(nproc * (attnum - 1)) + (procnum - 1)];
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.48 2001/05/30 20:52:32 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.49 2001/05/31 18:16:55 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -120,13 +120,15 @@ DefineIndex(char *heapRelationName,
|
||||
/*
|
||||
* XXX Hardwired hacks to check for limitations on supported index
|
||||
* types. We really ought to be learning this info from entries in the
|
||||
* pg_am table, instead of having it wired in here!
|
||||
* pg_am table, instead of having it wired-in here!
|
||||
*/
|
||||
if (unique && accessMethodId != BTREE_AM_OID)
|
||||
elog(ERROR, "DefineIndex: unique indices are only available with the btree access method");
|
||||
|
||||
if (numberOfAttributes > 1 && accessMethodId != BTREE_AM_OID)
|
||||
elog(ERROR, "DefineIndex: multi-column indices are only available with the btree access method");
|
||||
if (numberOfAttributes > 1 &&
|
||||
!( accessMethodId == BTREE_AM_OID ||
|
||||
accessMethodId == GIST_AM_OID))
|
||||
elog(ERROR, "DefineIndex: multi-column indices are only available with the btree or GiST access methods");
|
||||
|
||||
/*
|
||||
* WITH clause reinstated to handle lossy indices. -- JMH, 7/22/96
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: gist.h,v 1.27 2001/05/30 19:53:39 tgl Exp $
|
||||
* $Id: gist.h,v 1.28 2001/05/31 18:16:55 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -65,13 +65,13 @@ typedef struct GISTSTACK
|
||||
|
||||
typedef struct GISTSTATE
|
||||
{
|
||||
FmgrInfo consistentFn;
|
||||
FmgrInfo unionFn;
|
||||
FmgrInfo compressFn;
|
||||
FmgrInfo decompressFn;
|
||||
FmgrInfo penaltyFn;
|
||||
FmgrInfo picksplitFn;
|
||||
FmgrInfo equalFn;
|
||||
FmgrInfo consistentFn[INDEX_MAX_KEYS];
|
||||
FmgrInfo unionFn[INDEX_MAX_KEYS];
|
||||
FmgrInfo compressFn[INDEX_MAX_KEYS];
|
||||
FmgrInfo decompressFn[INDEX_MAX_KEYS];
|
||||
FmgrInfo penaltyFn[INDEX_MAX_KEYS];
|
||||
FmgrInfo picksplitFn[INDEX_MAX_KEYS];
|
||||
FmgrInfo equalFn[INDEX_MAX_KEYS];
|
||||
bool haskeytype;
|
||||
bool keytypbyval;
|
||||
} GISTSTATE;
|
||||
@ -121,21 +121,30 @@ typedef struct GIST_SPLITVEC
|
||||
{
|
||||
OffsetNumber *spl_left; /* array of entries that go left */
|
||||
int spl_nleft; /* size of this array */
|
||||
char *spl_ldatum; /* Union of keys in spl_left */
|
||||
Datum spl_ldatum; /* Union of keys in spl_left */
|
||||
Datum spl_lattr[INDEX_MAX_KEYS]; /* Union of subkeys in spl_left */
|
||||
int spl_lattrsize[INDEX_MAX_KEYS];
|
||||
|
||||
OffsetNumber *spl_right; /* array of entries that go right */
|
||||
int spl_nright; /* size of the array */
|
||||
char *spl_rdatum; /* Union of keys in spl_right */
|
||||
Datum spl_rdatum; /* Union of keys in spl_right */
|
||||
Datum spl_rattr[INDEX_MAX_KEYS]; /* Union of subkeys in spl_right */
|
||||
int spl_rattrsize[INDEX_MAX_KEYS];
|
||||
|
||||
int *spl_idgrp;
|
||||
int *spl_ngrp; /* number in each group */
|
||||
char *spl_grpflag; /* flags of each group */
|
||||
} GIST_SPLITVEC;
|
||||
|
||||
/*
|
||||
* An entry on a GiST node. Contains the key (pred), as well as
|
||||
* An entry on a GiST node. Contains the key, as well as
|
||||
* its own location (rel,page,offset) which can supply the matching
|
||||
* pointer. The size of the pred is in bytes, and leafkey is a flag to
|
||||
* pointer. The size of the key is in bytes, and leafkey is a flag to
|
||||
* tell us if the entry is in a leaf node.
|
||||
*/
|
||||
typedef struct GISTENTRY
|
||||
{
|
||||
char *pred;
|
||||
Datum key;
|
||||
Relation rel;
|
||||
Page page;
|
||||
OffsetNumber offset;
|
||||
@ -146,43 +155,20 @@ typedef struct GISTENTRY
|
||||
/*
|
||||
* macro to initialize a GISTENTRY
|
||||
*/
|
||||
#define gistentryinit(e, pr, r, pg, o, b, l)\
|
||||
do {(e).pred = (pr); (e).rel = (r); (e).page = (pg); (e).offset = (o); (e).bytes = (b); (e).leafkey = (l);} while (0)
|
||||
|
||||
/* defined in gist.c */
|
||||
#define TRLOWER(tr) (((tr)->bytes))
|
||||
#define TRUPPER(tr) (&((tr)->bytes[MAXALIGN(VARSIZE(TRLOWER(tr)))]))
|
||||
|
||||
typedef struct txtrange
|
||||
{
|
||||
int32 vl_len;
|
||||
/*
|
||||
* flag: NINF means that lower is negative infinity; PINF means that *
|
||||
* upper is positive infinity. 0 means that both are numbers.
|
||||
*/
|
||||
int32 flag;
|
||||
char bytes[2];
|
||||
} TXTRANGE;
|
||||
|
||||
typedef struct intrange
|
||||
{
|
||||
int lower;
|
||||
int upper;
|
||||
/*
|
||||
* flag: NINF means that lower is negative infinity; PINF means that *
|
||||
* upper is positive infinity. 0 means that both are numbers.
|
||||
*/
|
||||
int flag;
|
||||
} INTRANGE;
|
||||
#define gistentryinit(e, k, r, pg, o, b, l) \
|
||||
do { (e).key = (k); (e).rel = (r); (e).page = (pg); \
|
||||
(e).offset = (o); (e).bytes = (b); (e).leafkey = (l); } while (0)
|
||||
|
||||
/* gist.c */
|
||||
extern Datum gistbuild(PG_FUNCTION_ARGS);
|
||||
extern Datum gistinsert(PG_FUNCTION_ARGS);
|
||||
extern Datum gistdelete(PG_FUNCTION_ARGS);
|
||||
extern void _gistdump(Relation r);
|
||||
extern void gistfreestack(GISTSTACK *s);
|
||||
extern void initGISTstate(GISTSTATE *giststate, Relation index);
|
||||
extern void gistdentryinit(GISTSTATE *giststate, GISTENTRY *e, char *pr,
|
||||
Relation r, Page pg, OffsetNumber o, int b, bool l);
|
||||
extern void gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e,
|
||||
Datum k, Relation r, Page pg, OffsetNumber o,
|
||||
int b, bool l);
|
||||
extern StrategyNumber RelationGetGISTStrategy(Relation, AttrNumber,
|
||||
RegProcedure);
|
||||
|
||||
|
Reference in New Issue
Block a user