mirror of
https://github.com/postgres/postgres.git
synced 2025-10-25 13:17:41 +03:00
Add operator strategy and comparison-value datatype fields to ScanKey.
Remove the 'strategy map' code, which was a large amount of mechanism that no longer had any use except reverse-mapping from procedure OID to strategy number. Passing the strategy number to the index AM in the first place is simpler and faster. This is a preliminary step in planned support for cross-datatype index operations. I'm committing it now since the ScanKeyEntryInitialize() API change touches quite a lot of files, and I want to commit those changes before the tree drifts under me.
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: gist.h,v 1.37 2003/08/04 02:40:10 momjian Exp $
|
||||
* $Id: gist.h,v 1.38 2003/11/09 21:30:37 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -175,8 +175,6 @@ 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 StrategyNumber RelationGetGISTStrategy(Relation, AttrNumber,
|
||||
RegProcedure);
|
||||
|
||||
extern void gist_redo(XLogRecPtr lsn, XLogRecord *record);
|
||||
extern void gist_undo(XLogRecPtr lsn, XLogRecord *record);
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* istrat.h
|
||||
* POSTGRES index strategy definitions.
|
||||
*
|
||||
*
|
||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: istrat.h,v 1.27 2003/08/04 02:40:10 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef ISTRAT_H
|
||||
#define ISTRAT_H
|
||||
|
||||
#include "utils/rel.h"
|
||||
|
||||
/*
|
||||
* StrategyNumberIsValid
|
||||
* True iff the strategy number is valid.
|
||||
*/
|
||||
#define StrategyNumberIsValid(strategyNumber) \
|
||||
((bool) ((strategyNumber) != InvalidStrategy))
|
||||
|
||||
/*
|
||||
* StrategyNumberIsInBounds
|
||||
* True iff strategy number is within given bounds.
|
||||
*
|
||||
* Note:
|
||||
* Assumes StrategyNumber is an unsigned type.
|
||||
* Assumes the bounded interval to be (0,max].
|
||||
*/
|
||||
#define StrategyNumberIsInBounds(strategyNumber, maxStrategyNumber) \
|
||||
((bool)(InvalidStrategy < (strategyNumber) && \
|
||||
(strategyNumber) <= (maxStrategyNumber)))
|
||||
|
||||
/*
|
||||
* StrategyMapIsValid
|
||||
* True iff the index strategy mapping is valid.
|
||||
*/
|
||||
#define StrategyMapIsValid(map) PointerIsValid(map)
|
||||
|
||||
/*
|
||||
* IndexStrategyIsValid
|
||||
* True iff the index strategy is valid.
|
||||
*/
|
||||
#define IndexStrategyIsValid(s) PointerIsValid(s)
|
||||
|
||||
extern ScanKey StrategyMapGetScanKeyEntry(StrategyMap map,
|
||||
StrategyNumber strategyNumber);
|
||||
extern StrategyMap IndexStrategyGetStrategyMap(IndexStrategy indexStrategy,
|
||||
StrategyNumber maxStrategyNum, AttrNumber attrNum);
|
||||
|
||||
extern Size AttributeNumberGetIndexStrategySize(AttrNumber maxAttributeNumber,
|
||||
StrategyNumber maxStrategyNumber);
|
||||
extern StrategyNumber RelationGetStrategy(Relation relation,
|
||||
AttrNumber attributeNumber, StrategyEvaluation evaluation,
|
||||
RegProcedure procedure);
|
||||
|
||||
#endif /* ISTRAT_H */
|
||||
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: nbtree.h,v 1.71 2003/09/29 23:40:26 tgl Exp $
|
||||
* $Id: nbtree.h,v 1.72 2003/11/09 21:30:37 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -340,16 +340,10 @@ typedef struct xl_btree_newpage
|
||||
|
||||
|
||||
/*
|
||||
* Operator strategy numbers -- ordering of these is <, <=, =, >=, >
|
||||
* Operator strategy numbers for B-tree have been moved to access/skey.h,
|
||||
* because many places need to use them in ScanKeyEntryInitialize() calls.
|
||||
*/
|
||||
|
||||
#define BTLessStrategyNumber 1
|
||||
#define BTLessEqualStrategyNumber 2
|
||||
#define BTEqualStrategyNumber 3
|
||||
#define BTGreaterEqualStrategyNumber 4
|
||||
#define BTGreaterStrategyNumber 5
|
||||
#define BTMaxStrategyNumber 5
|
||||
|
||||
/*
|
||||
* When a new operator class is declared, we require that the user
|
||||
* supply us with an amproc procedure for determining whether, for
|
||||
@@ -479,12 +473,6 @@ extern bool _bt_first(IndexScanDesc scan, ScanDirection dir);
|
||||
extern bool _bt_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir);
|
||||
extern Buffer _bt_get_endpoint(Relation rel, uint32 level, bool rightmost);
|
||||
|
||||
/*
|
||||
* prototypes for functions in nbtstrat.c
|
||||
*/
|
||||
extern StrategyNumber _bt_getstrat(Relation rel, AttrNumber attno,
|
||||
RegProcedure proc);
|
||||
|
||||
/*
|
||||
* prototypes for functions in nbtutils.c
|
||||
*/
|
||||
|
||||
@@ -7,13 +7,14 @@
|
||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: relscan.h,v 1.32 2003/08/04 02:40:10 momjian Exp $
|
||||
* $Id: relscan.h,v 1.33 2003/11/09 21:30:37 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef RELSCAN_H
|
||||
#define RELSCAN_H
|
||||
|
||||
#include "access/skey.h"
|
||||
#include "utils/tqual.h"
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: rtree.h,v 1.30 2003/08/04 02:40:10 momjian Exp $
|
||||
* $Id: rtree.h,v 1.31 2003/11/09 21:30:37 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -132,7 +132,6 @@ extern void rtadjscans(Relation r, int op, BlockNumber blkno,
|
||||
extern void AtEOXact_rtree(void);
|
||||
|
||||
/* rtstrat.c */
|
||||
extern RegProcedure RTMapOperator(Relation r, AttrNumber attnum,
|
||||
RegProcedure proc);
|
||||
extern StrategyNumber RTMapToInternalOperator(StrategyNumber strat);
|
||||
|
||||
#endif /* RTREE_H */
|
||||
|
||||
@@ -7,10 +7,8 @@
|
||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: skey.h,v 1.22 2003/08/04 02:40:10 momjian Exp $
|
||||
* $Id: skey.h,v 1.23 2003/11/09 21:30:37 tgl Exp $
|
||||
*
|
||||
* Note:
|
||||
* Needs more accessor/assignment routines.
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef SKEY_H
|
||||
@@ -20,32 +18,77 @@
|
||||
#include "fmgr.h"
|
||||
|
||||
|
||||
/*
|
||||
* Strategy numbers identify the semantics that particular operators have
|
||||
* with respect to particular operator classes.
|
||||
*/
|
||||
typedef uint16 StrategyNumber;
|
||||
|
||||
#define InvalidStrategy ((StrategyNumber) 0)
|
||||
|
||||
/*
|
||||
* We define the strategy numbers for B-tree indexes here, to avoid having
|
||||
* to import access/nbtree.h into a lot of places that shouldn't need it.
|
||||
*/
|
||||
#define BTLessStrategyNumber 1
|
||||
#define BTLessEqualStrategyNumber 2
|
||||
#define BTEqualStrategyNumber 3
|
||||
#define BTGreaterEqualStrategyNumber 4
|
||||
#define BTGreaterStrategyNumber 5
|
||||
|
||||
#define BTMaxStrategyNumber 5
|
||||
|
||||
|
||||
/*
|
||||
* A ScanKey represents the application of a comparison operator between
|
||||
* a table or index column and a constant. When it's part of an array of
|
||||
* ScanKeys, the comparison conditions are implicitly ANDed. The index
|
||||
* column is the left argument of the operator, if it's a binary operator.
|
||||
* (The data structure can support unary indexable operators too; in that
|
||||
* case sk_argument would go unused. This is not currently implemented.)
|
||||
*
|
||||
* For an index scan, sk_strategy must be set correctly for the operator.
|
||||
* When using a ScanKey in a heap scan, sk_strategy is not used and may be
|
||||
* set to InvalidStrategy.
|
||||
*
|
||||
* Note: in some places, ScanKeys are used as a convenient representation
|
||||
* for the invocation of an access method support procedure. In this case
|
||||
* sk_strategy is not meaningful, and sk_func may refer to a function that
|
||||
* returns something other than boolean.
|
||||
*/
|
||||
typedef struct ScanKeyData
|
||||
{
|
||||
bits16 sk_flags; /* flags */
|
||||
AttrNumber sk_attno; /* domain number */
|
||||
RegProcedure sk_procedure; /* procedure OID */
|
||||
FmgrInfo sk_func; /* fmgr call info for procedure */
|
||||
int sk_flags; /* flags, see below */
|
||||
AttrNumber sk_attno; /* table or index column number */
|
||||
StrategyNumber sk_strategy; /* operator strategy number */
|
||||
FmgrInfo sk_func; /* lookup info for function to call */
|
||||
Datum sk_argument; /* data to compare */
|
||||
Oid sk_argtype; /* datatype of sk_argument */
|
||||
} ScanKeyData;
|
||||
|
||||
typedef ScanKeyData *ScanKey;
|
||||
|
||||
/* ScanKeyData flags */
|
||||
#define SK_ISNULL 0x1 /* sk_argument is NULL */
|
||||
#define SK_UNARY 0x2 /* unary function (currently unsupported) */
|
||||
#define SK_NEGATE 0x4 /* negate function result */
|
||||
#define SK_COMMUTE 0x8 /* commute function (not fully supported) */
|
||||
/* ScanKeyData sk_flags */
|
||||
#define SK_ISNULL 0x0001 /* sk_argument is NULL */
|
||||
#define SK_UNARY 0x0002 /* unary operator (currently unsupported) */
|
||||
|
||||
|
||||
/*
|
||||
* prototypes for functions in access/common/scankey.c
|
||||
*/
|
||||
extern void ScanKeyEntrySetIllegal(ScanKey entry);
|
||||
extern void ScanKeyEntryInitialize(ScanKey entry, bits16 flags,
|
||||
AttrNumber attributeNumber, RegProcedure procedure, Datum argument);
|
||||
extern void ScanKeyEntryInitializeWithInfo(ScanKey entry, bits16 flags,
|
||||
AttrNumber attributeNumber, FmgrInfo *finfo,
|
||||
MemoryContext mcxt, Datum argument);
|
||||
extern void ScanKeyEntryInitialize(ScanKey entry,
|
||||
int flags,
|
||||
AttrNumber attributeNumber,
|
||||
StrategyNumber strategy,
|
||||
RegProcedure procedure,
|
||||
Datum argument,
|
||||
Oid argtype);
|
||||
extern void ScanKeyEntryInitializeWithInfo(ScanKey entry,
|
||||
int flags,
|
||||
AttrNumber attributeNumber,
|
||||
StrategyNumber strategy,
|
||||
FmgrInfo *finfo,
|
||||
Datum argument,
|
||||
Oid argtype);
|
||||
|
||||
#endif /* SKEY_H */
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* strat.h
|
||||
* index strategy type definitions
|
||||
* (separated out from original istrat.h to avoid circular refs)
|
||||
*
|
||||
*
|
||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: strat.h,v 1.27 2003/08/04 02:40:10 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef STRAT_H
|
||||
#define STRAT_H
|
||||
|
||||
#include "access/skey.h"
|
||||
|
||||
|
||||
typedef uint16 StrategyNumber;
|
||||
|
||||
#define InvalidStrategy 0
|
||||
|
||||
typedef struct StrategyTransformMapData
|
||||
{
|
||||
StrategyNumber strategy[1]; /* VARIABLE LENGTH ARRAY */
|
||||
} StrategyTransformMapData; /* VARIABLE LENGTH STRUCTURE */
|
||||
|
||||
typedef StrategyTransformMapData *StrategyTransformMap;
|
||||
|
||||
typedef struct StrategyOperatorData
|
||||
{
|
||||
StrategyNumber strategy;
|
||||
bits16 flags; /* scan qualification flags, see skey.h */
|
||||
} StrategyOperatorData;
|
||||
|
||||
typedef StrategyOperatorData *StrategyOperator;
|
||||
|
||||
typedef struct StrategyTermData
|
||||
{ /* conjunctive term */
|
||||
uint16 degree;
|
||||
StrategyOperatorData operatorData[1]; /* VARIABLE LENGTH ARRAY */
|
||||
} StrategyTermData; /* VARIABLE LENGTH STRUCTURE */
|
||||
|
||||
typedef StrategyTermData *StrategyTerm;
|
||||
|
||||
typedef struct StrategyExpressionData
|
||||
{ /* disjunctive normal form */
|
||||
StrategyTerm term[1]; /* VARIABLE LENGTH ARRAY */
|
||||
} StrategyExpressionData; /* VARIABLE LENGTH STRUCTURE */
|
||||
|
||||
typedef StrategyExpressionData *StrategyExpression;
|
||||
|
||||
typedef struct StrategyEvaluationData
|
||||
{
|
||||
StrategyNumber maxStrategy;
|
||||
/* each of these must point to an array of maxStrategy elements: */
|
||||
StrategyTransformMap negateTransform;
|
||||
StrategyTransformMap commuteTransform;
|
||||
StrategyTransformMap negateCommuteTransform;
|
||||
StrategyExpression *expression;
|
||||
} StrategyEvaluationData;
|
||||
|
||||
typedef StrategyEvaluationData *StrategyEvaluation;
|
||||
|
||||
/*
|
||||
* StrategyTransformMapIsValid
|
||||
* Returns true iff strategy transformation map is valid.
|
||||
*/
|
||||
#define StrategyTransformMapIsValid(transform) PointerIsValid(transform)
|
||||
|
||||
|
||||
#define AMStrategies(foo) (foo)
|
||||
|
||||
typedef struct StrategyMapData
|
||||
{
|
||||
ScanKeyData entry[1]; /* VARIABLE LENGTH ARRAY */
|
||||
} StrategyMapData; /* VARIABLE LENGTH STRUCTURE */
|
||||
|
||||
typedef StrategyMapData *StrategyMap;
|
||||
|
||||
typedef struct IndexStrategyData
|
||||
{
|
||||
StrategyMapData strategyMapData[1]; /* VARIABLE LENGTH ARRAY */
|
||||
} IndexStrategyData; /* VARIABLE LENGTH STRUCTURE */
|
||||
|
||||
typedef IndexStrategyData *IndexStrategy;
|
||||
|
||||
#endif /* STRAT_H */
|
||||
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: valid.h,v 1.31 2003/09/25 18:58:35 tgl Exp $
|
||||
* $Id: valid.h,v 1.32 2003/11/09 21:30:37 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -31,15 +31,16 @@ do \
|
||||
/* We use underscores to protect the variable passed in as parameters */ \
|
||||
/* We use two underscore here because this macro is included in the \
|
||||
macro below */ \
|
||||
bool __isnull; \
|
||||
Datum __atp; \
|
||||
Datum __test; \
|
||||
int __cur_nkeys = (nkeys); \
|
||||
ScanKey __cur_keys = (keys); \
|
||||
\
|
||||
(result) = true; /* may change */ \
|
||||
for (; __cur_nkeys--; __cur_keys++) \
|
||||
{ \
|
||||
Datum __atp; \
|
||||
bool __isnull; \
|
||||
Datum __test; \
|
||||
\
|
||||
__atp = heap_getattr((tuple), \
|
||||
__cur_keys->sk_attno, \
|
||||
(tupdesc), \
|
||||
@@ -58,16 +59,11 @@ do \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
if (__cur_keys->sk_flags & SK_COMMUTE) \
|
||||
__test = FunctionCall2(&__cur_keys->sk_func, \
|
||||
__cur_keys->sk_argument, __atp); \
|
||||
else \
|
||||
__test = FunctionCall2(&__cur_keys->sk_func, \
|
||||
__atp, __cur_keys->sk_argument); \
|
||||
__test = FunctionCall2(&__cur_keys->sk_func, \
|
||||
__atp, __cur_keys->sk_argument); \
|
||||
\
|
||||
if (DatumGetBool(__test) == !!(__cur_keys->sk_flags & SK_NEGATE)) \
|
||||
if (!DatumGetBool(__test)) \
|
||||
{ \
|
||||
/* XXX eventually should check if SK_ISNULL */ \
|
||||
(result) = false; \
|
||||
break; \
|
||||
} \
|
||||
|
||||
Reference in New Issue
Block a user