postgresql/src/include/access/gist.h

201 lines
5.5 KiB
C
Raw Normal View History

/*-------------------------------------------------------------------------
*
* gist.h
* common declarations for the GiST access method code.
*
*
2004-08-29 06:13:13 +02:00
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
2004-08-29 07:07:03 +02:00
* $PostgreSQL: pgsql/src/include/access/gist.h,v 1.42 2004/08/29 05:06:55 momjian 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
/*
* amproc indexes for GiST indexes.
*/
#define GIST_CONSISTENT_PROC 1
#define GIST_UNION_PROC 2
#define GIST_COMPRESS_PROC 3
#define GIST_DECOMPRESS_PROC 4
#define GIST_PENALTY_PROC 5
#define GIST_PICKSPLIT_PROC 6
#define GIST_EQUAL_PROC 7
#define GISTNProcs 7
/*
* Page opaque data in a GiST index page.
*/
#define F_LEAF (1 << 0)
typedef struct GISTPageOpaqueData
{
uint32 flags;
} 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.
*/
typedef struct GISTSTACK
{
struct GISTSTACK *gs_parent;
OffsetNumber gs_child;
BlockNumber gs_blk;
} 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
{
struct GISTSTACK *s_stack;
struct GISTSTACK *s_markstk;
uint16 s_flags;
struct GISTSTATE *giststate;
} 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 */
#define GISTP_ROOT 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.
*/
typedef struct GIST_SPLITVEC
{
OffsetNumber *spl_left; /* array of entries that go left */
int spl_nleft; /* size of this array */
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];
bool spl_lisnull[INDEX_MAX_KEYS];
OffsetNumber *spl_right; /* array of entries that go right */
int spl_nright; /* size of the array */
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];
bool spl_risnull[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, 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
{
Datum key;
Relation rel;
Page page;
OffsetNumber offset;
int bytes;
bool leafkey;
} GISTENTRY;
/*
* Vector of GISTENTRY struct's, user-defined
* methods union andpick split takes it as one of args
*/
2004-08-29 07:07:03 +02:00
typedef struct
{
int32 n; /* number of elements */
GISTENTRY vector[1];
} GistEntryVector;
#define GEVHDRSZ ( offsetof(GistEntryVector, vector[0]) )
/*
* macro to initialize a GISTENTRY
*/
#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 gistbulkdelete(PG_FUNCTION_ARGS);
extern void _gistdump(Relation r);
extern void gistfreestack(GISTSTACK *s);
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);
2001-03-22 05:01:46 +01:00
extern void gist_desc(char *buf, uint8 xl_info, char *rec);
/* gistget.c */
extern Datum gistgettuple(PG_FUNCTION_ARGS);
#endif /* GIST_H */