* interface routines for the postgres GiST index access method.
*
*
+ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.76 2001/05/15 14:14:49 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.77 2001/05/30 19:53:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
-
#include "postgres.h"
#include "access/genam.h"
#include "executor/executor.h"
#include "miscadmin.h"
#include "utils/syscache.h"
-
#include "access/xlogutils.h"
+
/* result's status */
#define INSERTED 0x01
#define SPLITED 0x02
OffsetNumber o, int b, bool l);
#undef GISTDEBUG
+
#ifdef GISTDEBUG
static void gist_dumptree(Relation r, int level, BlockNumber blk, OffsetNumber coff);
-
#endif
/*
* fetch tuples from a GiST scan.
*
*
+ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * /usr/local/devel/pglite/cvs/src/backend/access/gisr/gistget.c,v 1.9.1 1996/11/21 01:00:00 vadim Exp
+ * $Header: /cvsroot/pgsql/src/backend/access/gist/gistget.c,v 1.27 2001/05/30 19:53:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
-
#include "postgres.h"
#include "access/gist.h"
#include "executor/execdebug.h"
-
static OffsetNumber gistfindnext(IndexScanDesc s, Page p, OffsetNumber n,
ScanDirection dir);
static RetrieveIndexResult gistscancache(IndexScanDesc s, ScanDirection dir);
/*-------------------------------------------------------------------------
*
* gistscan.c
- * routines to manage scans on index relations
+ * routines to manage scans on GiST index relations
*
*
+ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
* IDENTIFICATION
- * /usr/local/devel/pglite/cvs/src/backend/access/gist/gistscan.c,v 1.7 1995/06/14 00:10:05 jolly Exp
+ * $Header: /cvsroot/pgsql/src/backend/access/gist/gistscan.c,v 1.34 2001/05/30 19:53:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
-
#include "postgres.h"
#include "access/genam.h"
* giststrat.c
* strategy map data for GiSTs.
*
+ *
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- *
* IDENTIFICATION
- * /usr/local/devel/pglite/cvs/src/backend/access/gist/giststrat.c,v 1.4 1995/06/14 00:10:05 jolly Exp
+ * $Header: /cvsroot/pgsql/src/backend/access/gist/Attic/giststrat.c,v 1.17 2001/05/30 19:53:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
-
#include "postgres.h"
#include "access/gist.h"
#include "access/istrat.h"
+
/*
* Note: negate, commute, and negatecommute all assume that operators are
* ordered as follows in the strategy map:
* TermData) -- such logic must be encoded in the user's Consistent function.
*/
+static StrategyExpression GISTEvaluationExpressions[GISTNStrategies] = {
+ NULL,
+ NULL,
+ NULL
+};
+
/*
* If you were sufficiently attentive to detail, you would go through
* the ExpressionData pain above for every one of the strategies
(StrategyTransformMap) GISTNegate, /* how to do (not qual) */
(StrategyTransformMap) GISTCommute, /* how to swap operands */
(StrategyTransformMap) GISTNegateCommute, /* how to do both */
- {NULL}
+ GISTEvaluationExpressions
};
+
StrategyNumber
RelationGetGISTStrategy(Relation r,
AttrNumber attnum,
/*-------------------------------------------------------------------------
*
- * btstrat.c
- * Srategy map entries for the btree indexed access method
+ * hashstrat.c
+ * Srategy map entries for the hash indexed access method
*
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/hash/Attic/hashstrat.c,v 1.17 2001/01/24 19:42:47 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/hash/Attic/hashstrat.c,v 1.18 2001/05/30 19:53:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
-
#include "postgres.h"
+#include "access/hash.h"
+
/*
* only one valid strategy for hash tables: equality.
*/
#ifdef NOT_USED
-static StrategyNumber HTNegate[1] = {
+
+static StrategyNumber HTNegate[HTMaxStrategyNumber] = {
InvalidStrategy
};
-static StrategyNumber HTCommute[1] = {
+static StrategyNumber HTCommute[HTMaxStrategyNumber] = {
HTEqualStrategyNumber
};
-static StrategyNumber HTNegateCommute[1] = {
+static StrategyNumber HTNegateCommute[HTMaxStrategyNumber] = {
InvalidStrategy
};
-static StrategyEvaluationData HTEvaluationData = {
- /* XXX static for simplicity */
+static StrategyExpression HTEvaluationExpressions[HTMaxStrategyNumber] = {
+ NULL
+};
+static StrategyEvaluationData HTEvaluationData = {
HTMaxStrategyNumber,
(StrategyTransformMap) HTNegate,
(StrategyTransformMap) HTCommute,
(StrategyTransformMap) HTNegateCommute,
- {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
+ HTEvaluationExpressions
};
#endif
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.49 2001/03/22 03:59:13 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.50 2001/05/30 19:53:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
-
#include "postgres.h"
#include "access/heapam.h"
StrategyNumber maxStrategy);
static bool StrategyTermIsValid(StrategyTerm term,
StrategyNumber maxStrategy);
-
#endif
!StrategyTransformMapIsValid(evaluation->negateTransform) ||
!StrategyTransformMapIsValid(evaluation->commuteTransform) ||
!StrategyTransformMapIsValid(evaluation->negateCommuteTransform))
- {
-
return false;
- }
for (index = 0; index < evaluation->maxStrategy; index += 1)
{
if (!StrategyExpressionIsValid(evaluation->expression[index],
evaluation->maxStrategy))
- {
-
return false;
- }
}
return true;
}
/* ----------------
* RelationGetStrategy
+ *
+ * Identify strategy number that describes given procedure, if there is one.
* ----------------
*/
StrategyNumber
numattrs = RelationGetNumberOfAttributes(relation);
Assert(relation->rd_rel->relkind == RELKIND_INDEX); /* XXX use accessor */
- Assert(AttributeNumberIsValid(attributeNumber));
- Assert((attributeNumber >= 1) && (attributeNumber < 1 + numattrs));
+ Assert((attributeNumber >= 1) && (attributeNumber <= numattrs));
Assert(StrategyEvaluationIsValid(evaluation));
Assert(RegProcedureIsValid(procedure));
elog(FATAL, "RelationGetStrategy: impossible case %d", entry->sk_flags);
}
-
if (!StrategyNumberIsInBounds(strategy, evaluation->maxStrategy))
{
if (!StrategyNumberIsValid(strategy))
newStrategy = evaluation->negateTransform->strategy[strategy - 1];
if (newStrategy != strategy && StrategyNumberIsValid(newStrategy))
{
-
entry = StrategyMapGetScanKeyEntry(strategyMap, newStrategy);
if (RegProcedureIsValid(entry->sk_procedure))
newStrategy = evaluation->commuteTransform->strategy[strategy - 1];
if (newStrategy != strategy && StrategyNumberIsValid(newStrategy))
{
-
entry = StrategyMapGetScanKeyEntry(strategyMap, newStrategy);
if (RegProcedureIsValid(entry->sk_procedure))
newStrategy = evaluation->negateCommuteTransform->strategy[strategy - 1];
if (newStrategy != strategy && StrategyNumberIsValid(newStrategy))
{
-
entry = StrategyMapGetScanKeyEntry(strategyMap, newStrategy);
if (RegProcedureIsValid(entry->sk_procedure))
/* not reached, just to make compiler happy */
return FALSE;
-
-
}
#endif
ObjectIdGetDatum(accessMethodObjectId));
ScanKeyEntryInitialize(&entry[1], 0, Anum_pg_amproc_amopclaid,
- F_OIDEQ, 0);
+ F_OIDEQ,
+ InvalidOid); /* will set below */
relation = heap_openr(AccessMethodProcedureRelationName,
AccessShareLock);
for (attNumber = 1; attNumber <= maxAttributeNumber; attNumber++)
{
- int16 support;
- Form_pg_amproc aform;
RegProcedure *loc;
+ StrategyNumber support;
loc = &indexSupport[((attNumber - 1) * maxSupportNumber)];
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
{
+ Form_pg_amproc aform;
+
aform = (Form_pg_amproc) GETSTRUCT(tuple);
- loc[(aform->amprocnum - 1)] = aform->amproc;
+ support = aform->amprocnum;
+ Assert(support > 0 && support <= maxSupportNumber);
+ loc[support - 1] = aform->amproc;
}
heap_endscan(scan);
for (attributeNumber = 1; attributeNumber <= numberOfAttributes;
attributeNumber += 1)
{
-
strategyMap = IndexStrategyGetStrategyMap(indexStrategy,
numberOfStrategies,
attributeNumber);
strategyNumber <= AMStrategies(numberOfStrategies);
strategyNumber += 1)
{
-
printf(":att %d\t:str %d\t:opr 0x%x(%d)\n",
attributeNumber, strategyNumber,
strategyMap->entry[strategyNumber - 1].sk_procedure,
/*-------------------------------------------------------------------------
*
- * btstrat.c
- * Srategy map entries for the btree indexed access method
+ * nbtstrat.c
+ * Strategy map entries for the btree indexed access method
*
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtstrat.c,v 1.13 2001/01/24 19:42:49 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtstrat.c,v 1.14 2001/05/30 19:53:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* StrategyNegate, StrategyCommute, and StrategyNegateCommute
* assume <, <=, ==, >=, > ordering.
*/
-static StrategyNumber BTNegate[5] = {
+static StrategyNumber BTNegate[BTMaxStrategyNumber] = {
BTGreaterEqualStrategyNumber,
BTGreaterStrategyNumber,
InvalidStrategy,
BTLessEqualStrategyNumber
};
-static StrategyNumber BTCommute[5] = {
+static StrategyNumber BTCommute[BTMaxStrategyNumber] = {
BTGreaterStrategyNumber,
BTGreaterEqualStrategyNumber,
InvalidStrategy,
BTLessStrategyNumber
};
-static StrategyNumber BTNegateCommute[5] = {
+static StrategyNumber BTNegateCommute[BTMaxStrategyNumber] = {
BTLessEqualStrategyNumber,
BTLessStrategyNumber,
InvalidStrategy,
NULL
};
-static StrategyEvaluationData BTEvaluationData = {
- /* XXX static for simplicity */
+static StrategyExpression BTEvaluationExpressions[BTMaxStrategyNumber] = {
+ NULL,
+ NULL,
+ (StrategyExpression) BTEqualExpressionData,
+ NULL,
+ NULL
+};
+static StrategyEvaluationData BTEvaluationData = {
BTMaxStrategyNumber,
- (StrategyTransformMap) BTNegate, /* XXX */
- (StrategyTransformMap) BTCommute, /* XXX */
- (StrategyTransformMap) BTNegateCommute, /* XXX */
-
- {NULL, NULL, (StrategyExpression) BTEqualExpressionData, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL}
+ (StrategyTransformMap) BTNegate,
+ (StrategyTransformMap) BTCommute,
+ (StrategyTransformMap) BTNegateCommute,
+ BTEvaluationExpressions
};
/* ----------------------------------------------------------------
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtstrat.c,v 1.16 2001/01/24 19:42:50 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtstrat.c,v 1.17 2001/05/30 19:53:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* Early in the development of the POSTGRES access methods, it was believed
* that writing functions was harder than writing arrays. This is wrong;
* TermData is hard to understand and hard to get right. In general, when
- * someone populates a new operator class, the populate it completely. If
+ * someone populates a new operator class, they populate it completely. If
* Mike Hirohama had forced Cimarron Taylor to populate the strategy map
* for btree int2_ops completely in 1988, you wouldn't have to deal with
* all this now. Too bad for you.
* in the access methods just isn't worth the trouble, though.
*/
+static StrategyExpression RTEvaluationExpressions[RTNStrategies] = {
+ NULL, /* express left */
+ NULL, /* express overleft */
+ NULL, /* express overlap */
+ NULL, /* express overright */
+ NULL, /* express right */
+ (StrategyExpression) RTEqualExpressionData, /* express same */
+ NULL, /* express contains */
+ NULL /* express contained-by */
+};
+
static StrategyEvaluationData RTEvaluationData = {
RTNStrategies, /* # of strategies */
(StrategyTransformMap) RTNegate, /* how to do (not qual) */
(StrategyTransformMap) RTCommute, /* how to swap operands */
(StrategyTransformMap) RTNegateCommute, /* how to do both */
- {
- NULL, /* express left */
- NULL, /* express overleft */
- NULL, /* express over */
- NULL, /* express overright */
- NULL, /* express right */
- (StrategyExpression) RTEqualExpressionData, /* express same */
- NULL, /* express contains */
- NULL, /* express contained-by */
- NULL,
- NULL,
- NULL
- }
+ RTEvaluationExpressions
};
/*
* common declarations for the GiST access method code.
*
*
+ * 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 $
*
*-------------------------------------------------------------------------
*/
#include "access/xlog.h"
/*
-** You can have as many strategies as you please in GiSTs, as
-** long as your consistent method can handle them
-**
-** But strat.h->StrategyEvaluationData->StrategyExpression expression[12]
-** - so 12 is real max # of strategies, or StrategyEvaluationIsValid
-** crashes backend... - vadim 05/21/97
-
+ * 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
-*/
-#define GISTNStrategies 12
-
/*
-** Helper routines
-*/
-#define GISTNProcs 8
+ * amproc indexes for GiST indexes.
+ */
#define GIST_CONSISTENT_PROC 1
#define GIST_UNION_PROC 2
#define GIST_COMPRESS_PROC 3
#define GIST_PENALTY_PROC 5
#define GIST_PICKSPLIT_PROC 6
#define GIST_EQUAL_PROC 7
-#define GIST_INFO_PROC 8
+#define GISTNProcs 7
+
+/*
+ * Page opaque data in a GiST index page.
+ */
#define F_LEAF (1 << 0)
typedef struct GISTPageOpaqueData
/*
* When we descend a tree, we keep a stack of parent pointers.
*/
-
typedef struct GISTSTACK
{
struct GISTSTACK *gs_parent;
/*
-** When we're doing a scan, we need to keep track of the parent stack
-** for the marked and current items.
-*/
-
+ * 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;
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.
-*/
-
+ * 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))
#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.
-*/
-
+ * 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.
-*/
+ * 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 */
} GIST_SPLITVEC;
/*
-** An entry on a GiST node. Contains the key (pred), 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
-** tell us if the entry is in a leaf node.
-*/
+ * An entry on a GiST node. Contains the key (pred), 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
+ * tell us if the entry is in a leaf node.
+ */
typedef struct GISTENTRY
{
char *pred;
} GISTENTRY;
/*
-** macro to initialize a 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)
+ 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))
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 vl_len;
int32 flag;
char bytes[2];
} TXTRANGE;
{
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.
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 StrategyNumber RelationGetGISTStrategy(Relation, AttrNumber, RegProcedure);
+extern StrategyNumber RelationGetGISTStrategy(Relation, AttrNumber,
+ RegProcedure);
extern void gist_redo(XLogRecPtr lsn, XLogRecord *record);
extern void gist_undo(XLogRecPtr lsn, XLogRecord *record);
/*-------------------------------------------------------------------------
*
* gistscan.h
- * routines defined in access/gisr/gistscan.c
+ * routines defined in access/gist/gistscan.c
*
*
+ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
*
- * rtscan.h,v 1.2 1995/06/14 00:06:58 jolly Exp
+ * $Id: gistscan.h,v 1.15 2001/05/30 19:53:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: rtree.h,v 1.22 2001/03/22 04:00:30 momjian Exp $
+ * $Id: rtree.h,v 1.23 2001/05/30 19:53:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
/*
* RTree code.
- * Defined in access/index-rtree/
+ * Defined in access/rtree/
*/
extern Datum rtinsert(PG_FUNCTION_ARGS);
extern Datum rtdelete(PG_FUNCTION_ARGS);
extern void rtadjscans(Relation r, int op, BlockNumber blkno,
OffsetNumber offnum);
-/* rtstrat.h */
+/* rtstrat.c */
extern RegProcedure RTMapOperator(Relation r, AttrNumber attnum,
RegProcedure proc);
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: strat.h,v 1.21 2001/03/22 06:16:20 momjian Exp $
+ * $Id: strat.h,v 1.22 2001/05/30 19:53:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "access/skey.h"
+
typedef uint16 StrategyNumber;
#define InvalidStrategy 0
typedef struct StrategyTransformMapData
{
StrategyNumber strategy[1]; /* VARIABLE LENGTH ARRAY */
-} StrategyTransformMapData; /* VARIABLE LENGTH
-
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- * STRUCTURE */
+} StrategyTransformMapData; /* VARIABLE LENGTH STRUCTURE */
typedef StrategyTransformMapData *StrategyTransformMap;
typedef struct StrategyOperatorData
{
StrategyNumber strategy;
- bits16 flags; /* scan qualification flags h/skey.h */
+ bits16 flags; /* scan qualification flags, see skey.h */
} StrategyOperatorData;
typedef StrategyOperatorData *StrategyOperator;
typedef struct StrategyTermData
{ /* conjunctive term */
uint16 degree;
- StrategyOperatorData operatorData[1]; /* VARIABLE LENGTH */
+ StrategyOperatorData operatorData[1]; /* VARIABLE LENGTH ARRAY */
} StrategyTermData; /* VARIABLE LENGTH STRUCTURE */
typedef StrategyTermData *StrategyTerm;
typedef struct StrategyEvaluationData
{
StrategyNumber maxStrategy;
+ /* each of these must point to an array of maxStrategy elements: */
StrategyTransformMap negateTransform;
StrategyTransformMap commuteTransform;
StrategyTransformMap negateCommuteTransform;
- StrategyExpression expression[12]; /* XXX VARIABLE LENGTH */
-} StrategyEvaluationData; /* VARIABLE LENGTH STRUCTURE */
+ StrategyExpression *expression;
+} StrategyEvaluationData;
typedef StrategyEvaluationData *StrategyEvaluation;