diff --git a/contrib/cube/cube.c b/contrib/cube/cube.c index 6b61d9e3f6..658536ac4d 100644 --- a/contrib/cube/cube.c +++ b/contrib/cube/cube.c @@ -6,6 +6,7 @@ #include "postgres.h" +#include #include #include "access/gist.h" diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c index 66d4347fbb..fd160670ce 100644 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@ -8,14 +8,14 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.116 2005/05/17 00:59:30 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.117 2005/05/17 03:34:18 neilc Exp $ * *------------------------------------------------------------------------- */ #include "postgres.h" #include "access/genam.h" -#include "access/gist.h" +#include "access/gist_private.h" #include "access/gistscan.h" #include "access/heapam.h" #include "catalog/index.h" @@ -26,10 +26,10 @@ #undef GIST_PAGEADDITEM -#define ATTSIZE(datum, TupDesc, i, isnull) \ +#define ATTSIZE(datum, tupdesc, i, isnull) \ ( \ (isnull) ? 0 : \ - att_addlength(0, (TupDesc)->attrs[(i)-1]->attlen, (datum)) \ + att_addlength(0, (tupdesc)->attrs[(i)-1]->attlen, (datum)) \ ) /* result's status */ diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c index d2b0f75fc1..e5f77b6792 100644 --- a/src/backend/access/gist/gistget.c +++ b/src/backend/access/gist/gistget.c @@ -8,13 +8,14 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/gist/gistget.c,v 1.46 2005/05/17 00:59:30 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/access/gist/gistget.c,v 1.47 2005/05/17 03:34:18 neilc Exp $ * *------------------------------------------------------------------------- */ #include "postgres.h" -#include "access/gist.h" +#include "access/gist_private.h" +#include "access/itup.h" #include "executor/execdebug.h" #include "utils/memutils.h" diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c index 7b449892f1..34a8de1829 100644 --- a/src/backend/access/gist/gistscan.c +++ b/src/backend/access/gist/gistscan.c @@ -8,14 +8,14 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/gist/gistscan.c,v 1.57 2005/05/17 00:59:30 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/access/gist/gistscan.c,v 1.58 2005/05/17 03:34:18 neilc Exp $ * *------------------------------------------------------------------------- */ #include "postgres.h" #include "access/genam.h" -#include "access/gist.h" +#include "access/gist_private.h" #include "access/gistscan.h" #include "utils/memutils.h" #include "utils/resowner.h" diff --git a/src/backend/access/transam/rmgr.c b/src/backend/access/transam/rmgr.c index db51f36a00..93e5c3eba7 100644 --- a/src/backend/access/transam/rmgr.c +++ b/src/backend/access/transam/rmgr.c @@ -3,12 +3,12 @@ * * Resource managers definition * - * $PostgreSQL: pgsql/src/backend/access/transam/rmgr.c,v 1.16 2004/08/29 21:08:47 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/transam/rmgr.c,v 1.17 2005/05/17 03:34:18 neilc Exp $ */ #include "postgres.h" #include "access/clog.h" -#include "access/gist.h" +#include "access/gist_private.h" #include "access/hash.h" #include "access/heapam.h" #include "access/nbtree.h" diff --git a/src/include/access/gist.h b/src/include/access/gist.h index 3cca22954c..33110b71b6 100644 --- a/src/include/access/gist.h +++ b/src/include/access/gist.h @@ -1,30 +1,24 @@ /*------------------------------------------------------------------------- * * gist.h - * common declarations for the GiST access method code. + * The public API for GiST indexes. This API is exposed to + * individuals implementing GiST indexes, so backward-incompatible + * changes should be made with care. * * * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/access/gist.h,v 1.45 2005/05/17 00:59:30 neilc Exp $ + * $PostgreSQL: pgsql/src/include/access/gist.h,v 1.46 2005/05/17 03:34:18 neilc Exp $ * *------------------------------------------------------------------------- */ #ifndef GIST_H #define GIST_H -#include "access/itup.h" -#include "access/relscan.h" -#include "access/sdir.h" -#include "access/xlog.h" - -/* - * You can have as many strategies as you please in GiSTs, - * as long as your consistent method can handle them. - * The system doesn't really care what they are. - */ -#define GISTNStrategies 100 +#include "storage/bufpage.h" +#include "storage/off.h" +#include "utils/rel.h" /* * amproc indexes for GiST indexes. @@ -38,7 +32,6 @@ #define GIST_EQUAL_PROC 7 #define GISTNProcs 7 - /* * Page opaque data in a GiST index page. */ @@ -51,81 +44,6 @@ typedef struct GISTPageOpaqueData typedef GISTPageOpaqueData *GISTPageOpaque; -#define GIST_LEAF(entry) (((GISTPageOpaque) PageGetSpecialPointer((entry)->page))->flags & F_LEAF) - -/* - * When we descend a tree, we keep a stack of parent pointers. This - * allows us to follow a chain of internal node points until we reach - * a leaf node, and then back up the stack to re-examine the internal - * nodes. - * - * 'parent' is the previous stack entry -- i.e. the node we arrived - * from. 'block' is the node's block number. 'offset' is the offset in - * the node's page that we stopped at (i.e. we followed the child - * pointer located at the specified offset). - */ -typedef struct GISTSTACK -{ - struct GISTSTACK *parent; - OffsetNumber offset; - BlockNumber block; -} GISTSTACK; - -typedef struct GISTSTATE -{ - 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]; - - TupleDesc tupdesc; -} GISTSTATE; - -#define isAttByVal( gs, anum ) (gs)->tupdesc->attrs[anum]->attbyval - -/* - * When we're doing a scan, we need to keep track of the parent stack - * for the marked and current items. - */ -typedef struct GISTScanOpaqueData -{ - GISTSTACK *stack; - GISTSTACK *markstk; - uint16 flags; - GISTSTATE *giststate; - MemoryContext tempCxt; - Buffer curbuf; - Buffer markbuf; -} GISTScanOpaqueData; - -typedef GISTScanOpaqueData *GISTScanOpaque; - -/* - * When we're doing a scan and updating a tree at the same time, the - * updates may affect the scan. We use the flags entry of the scan's - * opaque space to record our actual position in response to updates - * that we can't handle simply by adjusting pointers. - */ -#define GS_CURBEFORE ((uint16) (1 << 0)) -#define GS_MRKBEFORE ((uint16) (1 << 1)) - -/* root page of a gist index */ -#define GIST_ROOT_BLKNO 0 - -/* - * When we update a relation on which we're doing a scan, we need to - * check the scan and fix it if the update affected any of the pages it - * touches. Otherwise, we can miss records that we should see. The only - * times we need to do this are for deletions and splits. See the code in - * gistscan.c for how the scan is fixed. These two constants tell us what sort - * of operation changed the index. - */ -#define GISTOP_DEL 0 -#define GISTOP_SPLIT 1 - /* * This is the Split Vector to be returned by the PickSplit method. */ @@ -153,10 +71,10 @@ typedef struct GIST_SPLITVEC } GIST_SPLITVEC; /* - * 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 key is in bytes, and leafkey is a flag to - * tell us if the entry is in a leaf node. + * 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 key is in bytes, and leafkey is a flag to tell us + * if the entry is in a leaf node. */ typedef struct GISTENTRY { @@ -168,19 +86,19 @@ typedef struct GISTENTRY bool leafkey; } GISTENTRY; +#define GIST_LEAF(entry) (((GISTPageOpaque) PageGetSpecialPointer((entry)->page))->flags & F_LEAF) /* - * Vector of GISTENTRY struct's, user-defined - * methods union andpick split takes it as one of args + * Vector of GISTENTRY structs; user-defined methods union and pick + * split takes it as one of their arguments */ - typedef struct { int32 n; /* number of elements */ GISTENTRY vector[1]; } GistEntryVector; -#define GEVHDRSZ ( offsetof(GistEntryVector, vector[0]) ) +#define GEVHDRSZ (offsetof(GistEntryVector, vector[0])) /* * macro to initialize a GISTENTRY @@ -189,24 +107,4 @@ typedef struct 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 gistbulkdelete(PG_FUNCTION_ARGS); -extern void _gistdump(Relation r); -extern void initGISTstate(GISTSTATE *giststate, Relation index); -extern void freeGISTstate(GISTSTATE *giststate); -extern void gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e, - Datum k, Relation r, Page pg, OffsetNumber o, - int b, bool l, bool isNull); - -extern void gist_redo(XLogRecPtr lsn, XLogRecord *record); -extern void gist_undo(XLogRecPtr lsn, XLogRecord *record); -extern void gist_desc(char *buf, uint8 xl_info, char *rec); -extern MemoryContext createTempGistContext(void); - -/* gistget.c */ -extern Datum gistgettuple(PG_FUNCTION_ARGS); -extern Datum gistgetmulti(PG_FUNCTION_ARGS); - #endif /* GIST_H */ diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h new file mode 100644 index 0000000000..a34e29d0e0 --- /dev/null +++ b/src/include/access/gist_private.h @@ -0,0 +1,110 @@ +/*------------------------------------------------------------------------- + * + * gist_private.h + * private declarations for GiST -- declarations related to the + * internal implementation of GiST, not the public API + * + * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.1 2005/05/17 03:34:18 neilc Exp $ + * + *------------------------------------------------------------------------- + */ +#ifndef GIST_PRIVATE_H +#define GIST_PRIVATE_H + +#include "access/gist.h" +#include "access/xlog.h" +#include "fmgr.h" + +/* + * When we descend a tree, we keep a stack of parent pointers. This + * allows us to follow a chain of internal node points until we reach + * a leaf node, and then back up the stack to re-examine the internal + * nodes. + * + * 'parent' is the previous stack entry -- i.e. the node we arrived + * from. 'block' is the node's block number. 'offset' is the offset in + * the node's page that we stopped at (i.e. we followed the child + * pointer located at the specified offset). + */ +typedef struct GISTSTACK +{ + struct GISTSTACK *parent; + OffsetNumber offset; + BlockNumber block; +} GISTSTACK; + +typedef struct GISTSTATE +{ + 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]; + + TupleDesc tupdesc; +} GISTSTATE; + +/* + * When we're doing a scan, we need to keep track of the parent stack + * for the marked and current items. + */ +typedef struct GISTScanOpaqueData +{ + GISTSTACK *stack; + GISTSTACK *markstk; + uint16 flags; + GISTSTATE *giststate; + MemoryContext tempCxt; + Buffer curbuf; + Buffer markbuf; +} GISTScanOpaqueData; + +typedef GISTScanOpaqueData *GISTScanOpaque; + +/* + * When we're doing a scan and updating a tree at the same time, the + * updates may affect the scan. We use the flags entry of the scan's + * opaque space to record our actual position in response to updates + * that we can't handle simply by adjusting pointers. + */ +#define GS_CURBEFORE ((uint16) (1 << 0)) +#define GS_MRKBEFORE ((uint16) (1 << 1)) + +/* root page of a gist index */ +#define GIST_ROOT_BLKNO 0 + +/* + * When we update a relation on which we're doing a scan, we need to + * check the scan and fix it if the update affected any of the pages + * it touches. Otherwise, we can miss records that we should see. + * The only times we need to do this are for deletions and splits. See + * the code in gistscan.c for how the scan is fixed. These two + * constants tell us what sort of operation changed the index. + */ +#define GISTOP_DEL 0 +#define GISTOP_SPLIT 1 + +/* gist.c */ +extern Datum gistbuild(PG_FUNCTION_ARGS); +extern Datum gistinsert(PG_FUNCTION_ARGS); +extern Datum gistbulkdelete(PG_FUNCTION_ARGS); +extern MemoryContext createTempGistContext(void); +extern void initGISTstate(GISTSTATE *giststate, Relation index); +extern void freeGISTstate(GISTSTATE *giststate); +extern void gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e, + Datum k, Relation r, Page pg, OffsetNumber o, + int b, bool l, bool isNull); +extern void gist_redo(XLogRecPtr lsn, XLogRecord *record); +extern void gist_undo(XLogRecPtr lsn, XLogRecord *record); +extern void gist_desc(char *buf, uint8 xl_info, char *rec); + +/* gistget.c */ +extern Datum gistgettuple(PG_FUNCTION_ARGS); +extern Datum gistgetmulti(PG_FUNCTION_ARGS); + +#endif /* GIST_PRIVATE_H */