From c1d62bfd00f4d1ea0647e12947ca1de9fea39b33 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 9 Nov 2003 21:30:38 +0000 Subject: [PATCH] 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. --- contrib/dblink/dblink.c | 6 +- contrib/miscutil/misc_utils.c | 5 +- src/backend/access/common/indexvalid.c | 9 +- src/backend/access/common/scankey.c | 77 ++-- src/backend/access/gist/Makefile | 4 +- src/backend/access/gist/gistget.c | 22 +- src/backend/access/gist/gistscan.c | 14 +- src/backend/access/gist/giststrat.c | 125 ------ src/backend/access/hash/Makefile | 4 +- src/backend/access/hash/hashstrat.c | 84 ---- src/backend/access/heap/tuptoaster.c | 51 ++- src/backend/access/index/Makefile | 4 +- src/backend/access/index/istrat.c | 479 --------------------- src/backend/access/nbtree/Makefile | 4 +- src/backend/access/nbtree/nbtinsert.c | 4 +- src/backend/access/nbtree/nbtsearch.c | 13 +- src/backend/access/nbtree/nbtstrat.c | 138 ------ src/backend/access/nbtree/nbtutils.c | 148 +++---- src/backend/access/rtree/rtscan.c | 26 +- src/backend/access/rtree/rtstrat.c | 203 +-------- src/backend/bootstrap/bootparse.y | 3 +- src/backend/bootstrap/bootscanner.l | 3 +- src/backend/catalog/aclchk.c | 21 +- src/backend/catalog/dependency.c | 110 +++-- src/backend/catalog/heap.c | 63 +-- src/backend/catalog/index.c | 11 +- src/backend/catalog/pg_constraint.c | 37 +- src/backend/catalog/pg_conversion.c | 10 +- src/backend/catalog/pg_depend.c | 31 +- src/backend/catalog/pg_largeobject.c | 19 +- src/backend/commands/async.c | 11 +- src/backend/commands/cluster.c | 7 +- src/backend/commands/comment.c | 81 ++-- src/backend/commands/dbcommands.c | 68 +-- src/backend/commands/functioncmds.c | 8 +- src/backend/commands/opclasscmds.c | 20 +- src/backend/commands/tablecmds.c | 14 +- src/backend/commands/trigger.c | 61 +-- src/backend/commands/typecmds.c | 30 +- src/backend/commands/user.c | 9 +- src/backend/commands/vacuum.c | 16 +- src/backend/executor/nodeIndexscan.c | 164 ++----- src/backend/nodes/copyfuncs.c | 13 +- src/backend/nodes/outfuncs.c | 12 +- src/backend/optimizer/plan/createplan.c | 70 ++- src/backend/optimizer/util/plancat.c | 12 +- src/backend/parser/parse_func.c | 9 +- src/backend/rewrite/rewriteRemove.c | 10 +- src/backend/storage/large_object/inv_api.c | 48 +-- src/backend/utils/adt/regproc.c | 34 +- src/backend/utils/adt/ruleutils.c | 16 +- src/backend/utils/cache/catcache.c | 11 +- src/backend/utils/cache/lsyscache.c | 20 +- src/backend/utils/cache/relcache.c | 251 ++++------- src/backend/utils/cache/typcache.c | 9 +- src/backend/utils/init/postinit.c | 9 +- src/backend/utils/sort/tuplesort.c | 18 +- src/include/access/gist.h | 4 +- src/include/access/istrat.h | 61 --- src/include/access/nbtree.h | 18 +- src/include/access/relscan.h | 3 +- src/include/access/rtree.h | 5 +- src/include/access/skey.h | 79 +++- src/include/access/strat.h | 90 ---- src/include/access/valid.h | 20 +- src/include/commands/sequence.h | 4 +- src/include/nodes/plannodes.h | 14 +- src/include/pg_config_manual.h | 3 +- src/include/storage/smgr.h | 3 +- src/include/utils/catcache.h | 3 +- src/include/utils/lsyscache.h | 5 +- src/include/utils/rel.h | 26 +- 72 files changed, 950 insertions(+), 2147 deletions(-) delete mode 100644 src/backend/access/gist/giststrat.c delete mode 100644 src/backend/access/hash/hashstrat.c delete mode 100644 src/backend/access/index/istrat.c delete mode 100644 src/backend/access/nbtree/nbtstrat.c delete mode 100644 src/include/access/istrat.h delete mode 100644 src/include/access/strat.h diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c index dd0059fe77c..5728682ccc8 100644 --- a/contrib/dblink/dblink.c +++ b/contrib/dblink/dblink.c @@ -1357,8 +1357,10 @@ get_pkey_attnames(Oid relid, int16 *numatts) /* use relid to get all related indexes */ indexRelation = heap_openr(IndexRelationName, AccessShareLock); - ScanKeyEntryInitialize(&entry, 0, Anum_pg_index_indrelid, - F_OIDEQ, ObjectIdGetDatum(relid)); + ScanKeyEntryInitialize(&entry, 0, + Anum_pg_index_indrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(relid), OIDOID); scan = heap_beginscan(indexRelation, SnapshotNow, 1, &entry); while ((indexTuple = heap_getnext(scan, ForwardScanDirection)) != NULL) diff --git a/contrib/miscutil/misc_utils.c b/contrib/miscutil/misc_utils.c index 705e89ee0d7..bf84f3b3c2e 100644 --- a/contrib/miscutil/misc_utils.c +++ b/contrib/miscutil/misc_utils.c @@ -21,6 +21,7 @@ #include "access/tupdesc.h" #include "catalog/catname.h" #include "catalog/pg_listener.h" +#include "catalog/pg_type.h" #include "commands/async.h" #include "fmgr.h" #include "storage/lmgr.h" @@ -88,8 +89,8 @@ active_listeners(text *relname) memcpy(listen_name, VARDATA(relname), len); ScanKeyEntryInitialize(&key, 0, Anum_pg_listener_relname, - F_NAMEEQ, - PointerGetDatum(listen_name)); + BTEqualStrategyNumber, F_NAMEEQ, + PointerGetDatum(listen_name), NAMEOID); sRel = heap_beginscan(lRel, SnapshotNow, 1, &key); } else diff --git a/src/backend/access/common/indexvalid.c b/src/backend/access/common/indexvalid.c index 6b316362758..e2ca5a7563c 100644 --- a/src/backend/access/common/indexvalid.c +++ b/src/backend/access/common/indexvalid.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/common/Attic/indexvalid.c,v 1.29 2003/08/04 02:39:56 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/common/Attic/indexvalid.c,v 1.30 2003/11/09 21:30:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -57,12 +57,9 @@ index_keytest(IndexTuple tuple, if (key->sk_flags & SK_ISNULL) return false; - if (key->sk_flags & SK_COMMUTE) - test = FunctionCall2(&key->sk_func, key->sk_argument, datum); - else - test = FunctionCall2(&key->sk_func, datum, key->sk_argument); + test = FunctionCall2(&key->sk_func, datum, key->sk_argument); - if (DatumGetBool(test) == !!(key->sk_flags & SK_NEGATE)) + if (!DatumGetBool(test)) return false; key++; diff --git a/src/backend/access/common/scankey.c b/src/backend/access/common/scankey.c index f79b2c71432..93741cbb849 100644 --- a/src/backend/access/common/scankey.c +++ b/src/backend/access/common/scankey.c @@ -1,73 +1,46 @@ /*------------------------------------------------------------------------- * - * scan.c - * scan direction and key code + * scankey.c + * scan key support code * * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/common/scankey.c,v 1.22 2003/08/04 02:39:56 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/common/scankey.c,v 1.23 2003/11/09 21:30:35 tgl Exp $ * *------------------------------------------------------------------------- */ - #include "postgres.h" #include "access/skey.h" -/* - * ScanKeyEntryIsLegal - * True iff the scan key entry is legal. - */ -#define ScanKeyEntryIsLegal(entry) \ -( \ - AssertMacro(PointerIsValid(entry)), \ - AttributeNumberIsValid((entry)->sk_attno) \ -) - -/* - * ScanKeyEntrySetIllegal - * Marks a scan key entry as illegal. - */ -void -ScanKeyEntrySetIllegal(ScanKey entry) -{ - - Assert(PointerIsValid(entry)); - - entry->sk_flags = 0; /* just in case... */ - entry->sk_attno = InvalidAttrNumber; - entry->sk_procedure = 0; /* should be InvalidRegProcedure */ - entry->sk_func.fn_oid = InvalidOid; - entry->sk_argument = (Datum) 0; -} /* * ScanKeyEntryInitialize - * Initializes a scan key entry. + * Initializes a scan key entry given all the field values. + * The target procedure is specified by OID. * - * Note: - * Assumes the scan key entry is valid. - * Assumes the intialized scan key entry will be legal. + * Note: CurrentMemoryContext at call should be as long-lived as the ScanKey + * itself, because that's what will be used for any subsidiary info attached + * to the ScanKey's FmgrInfo record. */ void ScanKeyEntryInitialize(ScanKey entry, - bits16 flags, + int flags, AttrNumber attributeNumber, + StrategyNumber strategy, RegProcedure procedure, - Datum argument) + Datum argument, + Oid argtype) { - Assert(PointerIsValid(entry)); - entry->sk_flags = flags; entry->sk_attno = attributeNumber; - entry->sk_procedure = procedure; + entry->sk_strategy = strategy; entry->sk_argument = argument; + entry->sk_argtype = argtype; fmgr_info(procedure, &entry->sk_func); - - Assert(ScanKeyEntryIsLegal(entry)); } /* @@ -75,25 +48,23 @@ ScanKeyEntryInitialize(ScanKey entry, * Initializes a scan key entry using an already-completed FmgrInfo * function lookup record. * - * mcxt is the memory context holding the scan key; it'll be used for - * any subsidiary info attached to the scankey's FmgrInfo record. + * Note: CurrentMemoryContext at call should be as long-lived as the ScanKey + * itself, because that's what will be used for any subsidiary info attached + * to the ScanKey's FmgrInfo record. */ void ScanKeyEntryInitializeWithInfo(ScanKey entry, - bits16 flags, + int flags, AttrNumber attributeNumber, + StrategyNumber strategy, FmgrInfo *finfo, - MemoryContext mcxt, - Datum argument) + Datum argument, + Oid argtype) { - Assert(PointerIsValid(entry)); - Assert(RegProcedureIsValid(finfo->fn_oid)); - entry->sk_flags = flags; entry->sk_attno = attributeNumber; - entry->sk_procedure = finfo->fn_oid; + entry->sk_strategy = strategy; entry->sk_argument = argument; - fmgr_info_copy(&entry->sk_func, finfo, mcxt); - - Assert(ScanKeyEntryIsLegal(entry)); + entry->sk_argtype = argtype; + fmgr_info_copy(&entry->sk_func, finfo, CurrentMemoryContext); } diff --git a/src/backend/access/gist/Makefile b/src/backend/access/gist/Makefile index 7f982d0dfd8..f2c7ddf3a7c 100644 --- a/src/backend/access/gist/Makefile +++ b/src/backend/access/gist/Makefile @@ -4,7 +4,7 @@ # Makefile for access/gist # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/access/gist/Makefile,v 1.10 2000/08/31 16:09:31 petere Exp $ +# $Header: /cvsroot/pgsql/src/backend/access/gist/Makefile,v 1.11 2003/11/09 21:30:35 tgl Exp $ # #------------------------------------------------------------------------- @@ -12,7 +12,7 @@ subdir = src/backend/access/gist top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global -OBJS = gist.o gistget.o gistscan.o giststrat.o +OBJS = gist.o gistget.o gistscan.o all: SUBSYS.o diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c index bfa557bb9c6..24168c99269 100644 --- a/src/backend/access/gist/gistget.c +++ b/src/backend/access/gist/gistget.c @@ -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.36 2003/08/04 02:39:57 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/gist/gistget.c,v 1.37 2003/11/09 21:30:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -249,26 +249,16 @@ gistindex_keytest(IndexTuple tuple, IndexTupleSize(tuple) - sizeof(IndexTupleData), FALSE, isNull); - if (key[0].sk_flags & SK_COMMUTE) - { - test = FunctionCall3(&key[0].sk_func, - key[0].sk_argument, - PointerGetDatum(&de), - ObjectIdGetDatum(key[0].sk_procedure)); - } - else - { - test = FunctionCall3(&key[0].sk_func, - PointerGetDatum(&de), - key[0].sk_argument, - ObjectIdGetDatum(key[0].sk_procedure)); - } + test = FunctionCall3(&key[0].sk_func, + PointerGetDatum(&de), + key[0].sk_argument, + Int32GetDatum(key[0].sk_strategy)); if (de.key != datum && !isAttByVal(giststate, key[0].sk_attno - 1)) if (DatumGetPointer(de.key) != NULL) pfree(DatumGetPointer(de.key)); - if (DatumGetBool(test) == !!(key[0].sk_flags & SK_NEGATE)) + if (!DatumGetBool(test)) return false; scanKeySize--; diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c index 790048aef38..960d1c2f25b 100644 --- a/src/backend/access/gist/gistscan.c +++ b/src/backend/access/gist/gistscan.c @@ -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.47 2003/08/04 02:39:57 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/gist/gistscan.c,v 1.48 2003/11/09 21:30:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -106,17 +106,13 @@ gistrescan(PG_FUNCTION_ARGS) s->numberOfKeys * sizeof(ScanKeyData)); /* - * Play games here with the scan key to use the Consistent - * function for all comparisons: 1) the sk_procedure field will - * now be used to hold the strategy number 2) the sk_func field - * will point to the Consistent function + * Modify the scan key so that the Consistent function is called + * for all comparisons. The original operator is passed to the + * Consistent function in the form of its strategy number, which + * is available from the sk_strategy field. */ for (i = 0; i < s->numberOfKeys; i++) { - s->keyData[i].sk_procedure = - RelationGetGISTStrategy(s->indexRelation, - s->keyData[i].sk_attno, - s->keyData[i].sk_procedure); s->keyData[i].sk_func = p->giststate->consistentFn[s->keyData[i].sk_attno - 1]; } } diff --git a/src/backend/access/gist/giststrat.c b/src/backend/access/gist/giststrat.c deleted file mode 100644 index fe83b5ac799..00000000000 --- a/src/backend/access/gist/giststrat.c +++ /dev/null @@ -1,125 +0,0 @@ -/*------------------------------------------------------------------------- - * - * giststrat.c - * strategy map data for GiSTs. - * - * - * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/gist/Attic/giststrat.c,v 1.21 2003/08/04 02:39:57 momjian 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: - * - * contains, contained-by - * - * The negate, commute, and negatecommute arrays are used by the planner - * to plan indexed scans over data that appears in the qualificiation in - * a boolean negation, or whose operands appear in the wrong order. For - * example, if the operator "<%" means "contains", and the user says - * - * where not rel.box <% "(10,10,20,20)"::box - * - * the planner can plan an index scan by noting that GiST indices have - * an operator in their operator class for negating <%. - * - * Similarly, if the user says something like - * - * where "(10,10,20,20)"::box <% rel.box - * - * the planner can see that the GiST index on rel.box has an operator in - * its opclass for commuting <%, and plan the scan using that operator. - * This added complexity in the access methods makes the planner a lot easier - * to write. - */ - -/* if a op b, what operator tells us if (not a op b)? */ -static StrategyNumber GISTNegate[GISTNStrategies] = { - InvalidStrategy, - InvalidStrategy, - InvalidStrategy -}; - -/* if a op_1 b, what is the operator op_2 such that b op_2 a? */ -static StrategyNumber GISTCommute[GISTNStrategies] = { - InvalidStrategy, - InvalidStrategy, - InvalidStrategy -}; - -/* if a op_1 b, what is the operator op_2 such that (b !op_2 a)? */ -static StrategyNumber GISTNegateCommute[GISTNStrategies] = { - InvalidStrategy, - InvalidStrategy, - InvalidStrategy -}; - -/* - * GiSTs do not currently support TermData (see rtree/rtstrat.c for - * discussion of - * 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 - * we defined. I am not. Now we declare the StrategyEvaluationData - * structure that gets shipped around to help the planner and the access - * method decide what sort of scan it should do, based on (a) what the - * user asked for, (b) what operators are defined for a particular opclass, - * and (c) the reams of information we supplied above. - * - * The idea of all of this initialized data is to make life easier on the - * user when he defines a new operator class to use this access method. - * By filling in all the data, we let him get away with leaving holes in his - * operator class, and still let him use the index. The added complexity - * in the access methods just isn't worth the trouble, though. - */ - -static StrategyEvaluationData GISTEvaluationData = { - GISTNStrategies, /* # of strategies */ - (StrategyTransformMap) GISTNegate, /* how to do (not qual) */ - (StrategyTransformMap) GISTCommute, /* how to swap operands */ - (StrategyTransformMap) GISTNegateCommute, /* how to do both */ - GISTEvaluationExpressions -}; - - -StrategyNumber -RelationGetGISTStrategy(Relation r, - AttrNumber attnum, - RegProcedure proc) -{ - return RelationGetStrategy(r, attnum, &GISTEvaluationData, proc); -} - -#ifdef NOT_USED -bool -RelationInvokeGISTStrategy(Relation r, - AttrNumber attnum, - StrategyNumber s, - Datum left, - Datum right) -{ - return (RelationInvokeStrategy(r, &GISTEvaluationData, attnum, s, - left, right)); -} - -#endif diff --git a/src/backend/access/hash/Makefile b/src/backend/access/hash/Makefile index 5e4f56a80cc..5203db34b1d 100644 --- a/src/backend/access/hash/Makefile +++ b/src/backend/access/hash/Makefile @@ -4,7 +4,7 @@ # Makefile for access/hash # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/access/hash/Makefile,v 1.10 2000/08/31 16:09:33 petere Exp $ +# $Header: /cvsroot/pgsql/src/backend/access/hash/Makefile,v 1.11 2003/11/09 21:30:35 tgl Exp $ # #------------------------------------------------------------------------- @@ -13,7 +13,7 @@ top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global OBJS = hash.o hashfunc.o hashinsert.o hashovfl.o hashpage.o hashscan.o \ - hashsearch.o hashstrat.o hashutil.o + hashsearch.o hashutil.o all: SUBSYS.o diff --git a/src/backend/access/hash/hashstrat.c b/src/backend/access/hash/hashstrat.c deleted file mode 100644 index d72ad08ee17..00000000000 --- a/src/backend/access/hash/hashstrat.c +++ /dev/null @@ -1,84 +0,0 @@ -/*------------------------------------------------------------------------- - * - * hashstrat.c - * Strategy map entries for the hash indexed access method - * - * Portions Copyright (c) 1996-2003, 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.23 2003/08/04 02:39:57 momjian Exp $ - * - *------------------------------------------------------------------------- - */ -#include "postgres.h" - -#include "access/hash.h" - - -/* - * only one valid strategy for hash tables: equality. - */ - -#ifdef NOT_USED - -static StrategyNumber HTNegate[HTMaxStrategyNumber] = { - InvalidStrategy -}; - -static StrategyNumber HTCommute[HTMaxStrategyNumber] = { - HTEqualStrategyNumber -}; - -static StrategyNumber HTNegateCommute[HTMaxStrategyNumber] = { - InvalidStrategy -}; - -static StrategyExpression HTEvaluationExpressions[HTMaxStrategyNumber] = { - NULL -}; - -static StrategyEvaluationData HTEvaluationData = { - HTMaxStrategyNumber, - (StrategyTransformMap) HTNegate, - (StrategyTransformMap) HTCommute, - (StrategyTransformMap) HTNegateCommute, - HTEvaluationExpressions -}; -#endif - -/* ---------------------------------------------------------------- - * RelationGetHashStrategy - * ---------------------------------------------------------------- - */ - -#ifdef NOT_USED -static StrategyNumber -_hash_getstrat(Relation rel, - AttrNumber attno, - RegProcedure proc) -{ - StrategyNumber strat; - - strat = RelationGetStrategy(rel, attno, &HTEvaluationData, proc); - - Assert(StrategyNumberIsValid(strat)); - - return strat; -} -#endif - -#ifdef NOT_USED -static bool -_hash_invokestrat(Relation rel, - AttrNumber attno, - StrategyNumber strat, - Datum left, - Datum right) -{ - return (RelationInvokeStrategy(rel, &HTEvaluationData, attno, strat, - left, right)); -} - -#endif diff --git a/src/backend/access/heap/tuptoaster.c b/src/backend/access/heap/tuptoaster.c index 1840e0d1d77..0bfe3c01b8f 100644 --- a/src/backend/access/heap/tuptoaster.c +++ b/src/backend/access/heap/tuptoaster.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.38 2003/08/04 23:59:37 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.39 2003/11/09 21:30:35 tgl Exp $ * * * INTERFACE ROUTINES @@ -31,6 +31,7 @@ #include "access/genam.h" #include "access/tuptoaster.h" #include "catalog/catalog.h" +#include "catalog/pg_type.h" #include "utils/rel.h" #include "utils/builtins.h" #include "utils/fmgroids.h" @@ -967,11 +968,11 @@ toast_delete_datum(Relation rel, Datum value) * Setup a scan key to fetch from the index by va_valueid (we don't * particularly care whether we see them in sequence or not) */ - ScanKeyEntryInitialize(&toastkey, - (bits16) 0, + ScanKeyEntryInitialize(&toastkey, 0, (AttrNumber) 1, - (RegProcedure) F_OIDEQ, - ObjectIdGetDatum(attr->va_content.va_external.va_valueid)); + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(attr->va_content.va_external.va_valueid), + OIDOID); /* * Find the chunks by index @@ -1039,11 +1040,11 @@ toast_fetch_datum(varattrib *attr) /* * Setup a scan key to fetch from the index by va_valueid */ - ScanKeyEntryInitialize(&toastkey, - (bits16) 0, + ScanKeyEntryInitialize(&toastkey, 0, (AttrNumber) 1, - (RegProcedure) F_OIDEQ, - ObjectIdGetDatum(attr->va_content.va_external.va_valueid)); + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(attr->va_content.va_external.va_valueid), + OIDOID); /* * Read the chunks by index @@ -1194,37 +1195,33 @@ toast_fetch_datum_slice(varattrib *attr, int32 sliceoffset, int32 length) * Setup a scan key to fetch from the index. This is either two keys * or three depending on the number of chunks. */ - ScanKeyEntryInitialize(&toastkey[0], - (bits16) 0, + ScanKeyEntryInitialize(&toastkey[0], 0, (AttrNumber) 1, - (RegProcedure) F_OIDEQ, - ObjectIdGetDatum(attr->va_content.va_external.va_valueid)); + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(attr->va_content.va_external.va_valueid), + OIDOID); /* - * Now dependent on number of chunks: + * Use equality condition for one chunk, a range condition otherwise: */ - if (numchunks == 1) { - ScanKeyEntryInitialize(&toastkey[1], - (bits16) 0, + ScanKeyEntryInitialize(&toastkey[1], 0, (AttrNumber) 2, - (RegProcedure) F_INT4EQ, - Int32GetDatum(startchunk)); + BTEqualStrategyNumber, F_INT4EQ, + Int32GetDatum(startchunk), INT4OID); nscankeys = 2; } else { - ScanKeyEntryInitialize(&toastkey[1], - (bits16) 0, + ScanKeyEntryInitialize(&toastkey[1], 0, (AttrNumber) 2, - (RegProcedure) F_INT4GE, - Int32GetDatum(startchunk)); - ScanKeyEntryInitialize(&toastkey[2], - (bits16) 0, + BTGreaterEqualStrategyNumber, F_INT4GE, + Int32GetDatum(startchunk), INT4OID); + ScanKeyEntryInitialize(&toastkey[2], 0, (AttrNumber) 2, - (RegProcedure) F_INT4LE, - Int32GetDatum(endchunk)); + BTLessEqualStrategyNumber, F_INT4LE, + Int32GetDatum(endchunk), INT4OID); nscankeys = 3; } diff --git a/src/backend/access/index/Makefile b/src/backend/access/index/Makefile index dcae193bffe..cc3d2ee1384 100644 --- a/src/backend/access/index/Makefile +++ b/src/backend/access/index/Makefile @@ -4,7 +4,7 @@ # Makefile for access/index # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/access/index/Makefile,v 1.10 2000/08/31 16:09:36 petere Exp $ +# $Header: /cvsroot/pgsql/src/backend/access/index/Makefile,v 1.11 2003/11/09 21:30:35 tgl Exp $ # #------------------------------------------------------------------------- @@ -12,7 +12,7 @@ subdir = src/backend/access/index top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global -OBJS = genam.o indexam.o istrat.o +OBJS = genam.o indexam.o all: SUBSYS.o diff --git a/src/backend/access/index/istrat.c b/src/backend/access/index/istrat.c deleted file mode 100644 index 1298420d4fd..00000000000 --- a/src/backend/access/index/istrat.c +++ /dev/null @@ -1,479 +0,0 @@ -/*------------------------------------------------------------------------- - * - * istrat.c - * index scan strategy manipulation code and index strategy manipulation - * operator code. - * - * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.60 2003/08/04 02:39:57 momjian Exp $ - * - *------------------------------------------------------------------------- - */ -#include "postgres.h" - -#include "access/istrat.h" - - -#ifdef USE_ASSERT_CHECKING -static bool StrategyEvaluationIsValid(StrategyEvaluation evaluation); -static bool StrategyExpressionIsValid(StrategyExpression expression, - StrategyNumber maxStrategy); -static bool StrategyOperatorIsValid(StrategyOperator operator, - StrategyNumber maxStrategy); -static bool StrategyTermIsValid(StrategyTerm term, - StrategyNumber maxStrategy); -#endif - - -/* ---------------------------------------------------------------- - * misc strategy support routines - * ---------------------------------------------------------------- - */ - -/* - * StrategyNumberIsValid - * StrategyNumberIsInBounds - * StrategyMapIsValid - * StrategyTransformMapIsValid - * IndexStrategyIsValid - * - * ... are now macros in istrat.h -cim 4/27/91 - */ - -/* - * StrategyMapGetScanKeyEntry - * Returns a scan key entry of a index strategy mapping member. - * - * Note: - * Assumes that the index strategy mapping is valid. - * Assumes that the index strategy number is valid. - * Bounds checking should be done outside this routine. - */ -ScanKey -StrategyMapGetScanKeyEntry(StrategyMap map, - StrategyNumber strategyNumber) -{ - Assert(StrategyMapIsValid(map)); - Assert(StrategyNumberIsValid(strategyNumber)); - return &map->entry[strategyNumber - 1]; -} - -/* - * IndexStrategyGetStrategyMap - * Returns an index strategy mapping of an index strategy. - * - * Note: - * Assumes that the index strategy is valid. - * Assumes that the number of index strategies is valid. - * Bounds checking should be done outside this routine. - */ -StrategyMap -IndexStrategyGetStrategyMap(IndexStrategy indexStrategy, - StrategyNumber maxStrategyNum, - AttrNumber attrNum) -{ - Assert(IndexStrategyIsValid(indexStrategy)); - Assert(StrategyNumberIsValid(maxStrategyNum)); - Assert(AttributeNumberIsValid(attrNum)); - - maxStrategyNum = AMStrategies(maxStrategyNum); /* XXX */ - return &indexStrategy->strategyMapData[maxStrategyNum * (attrNum - 1)]; -} - -/* - * AttributeNumberGetIndexStrategySize - * Computes the size of an index strategy. - */ -Size -AttributeNumberGetIndexStrategySize(AttrNumber maxAttributeNumber, - StrategyNumber maxStrategyNumber) -{ - maxStrategyNumber = AMStrategies(maxStrategyNumber); /* XXX */ - return maxAttributeNumber * maxStrategyNumber * sizeof(ScanKeyData); -} - -#ifdef USE_ASSERT_CHECKING -/* - * StrategyTransformMapIsValid is now a macro in istrat.h -cim 4/27/91 - */ - -/* ---------------- - * StrategyOperatorIsValid - * ---------------- - */ -static bool -StrategyOperatorIsValid(StrategyOperator operator, - StrategyNumber maxStrategy) -{ - return (bool) - (PointerIsValid(operator) && - StrategyNumberIsInBounds(operator->strategy, maxStrategy) && - !(operator->flags & ~(SK_NEGATE | SK_COMMUTE))); -} - -/* ---------------- - * StrategyTermIsValid - * ---------------- - */ -static bool -StrategyTermIsValid(StrategyTerm term, - StrategyNumber maxStrategy) -{ - Index index; - - if (!PointerIsValid(term) || term->degree == 0) - return false; - - for (index = 0; index < term->degree; index += 1) - { - if (!StrategyOperatorIsValid(&term->operatorData[index], - maxStrategy)) - return false; - } - - return true; -} - -/* ---------------- - * StrategyExpressionIsValid - * ---------------- - */ -static bool -StrategyExpressionIsValid(StrategyExpression expression, - StrategyNumber maxStrategy) -{ - StrategyTerm *termP; - - if (!PointerIsValid(expression)) - return true; - - if (!StrategyTermIsValid(expression->term[0], maxStrategy)) - return false; - - termP = &expression->term[1]; - while (StrategyTermIsValid(*termP, maxStrategy)) - termP += 1; - - return (bool) - (!PointerIsValid(*termP)); -} - -/* ---------------- - * StrategyEvaluationIsValid - * ---------------- - */ -static bool -StrategyEvaluationIsValid(StrategyEvaluation evaluation) -{ - Index index; - - if (!PointerIsValid(evaluation) || - !StrategyNumberIsValid(evaluation->maxStrategy) || - !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; -} -#endif - -#ifdef NOT_USED -/* ---------------- - * StrategyTermEvaluate - * ---------------- - */ -static bool -StrategyTermEvaluate(StrategyTerm term, - StrategyMap map, - Datum left, - Datum right) -{ - bool result = false; - Index index; - StrategyOperator operator; - - for (index = 0, operator = &term->operatorData[0]; - index < term->degree; index += 1, operator += 1) - { - ScanKey entry; - - entry = &map->entry[operator->strategy - 1]; - - Assert(RegProcedureIsValid(entry->sk_procedure)); - - switch (operator->flags ^ entry->sk_flags) - { - case 0x0: - result = DatumGetBool(FunctionCall2(&entry->sk_func, - left, right)); - break; - - case SK_NEGATE: - result = !DatumGetBool(FunctionCall2(&entry->sk_func, - left, right)); - break; - - case SK_COMMUTE: - result = DatumGetBool(FunctionCall2(&entry->sk_func, - right, left)); - break; - - case SK_NEGATE | SK_COMMUTE: - result = !DatumGetBool(FunctionCall2(&entry->sk_func, - right, left)); - break; - - default: - elog(ERROR, "impossible strategy case: %d", - operator->flags ^ entry->sk_flags); - } - if (!result) - return result; - } - - return result; -} -#endif - -/* ---------------- - * RelationGetStrategy - * - * Identify strategy number that describes given procedure, if there is one. - * ---------------- - */ -StrategyNumber -RelationGetStrategy(Relation relation, - AttrNumber attributeNumber, - StrategyEvaluation evaluation, - RegProcedure procedure) -{ - StrategyNumber strategy; - StrategyMap strategyMap; - ScanKey entry; - Index index; - int numattrs; - - Assert(RelationIsValid(relation)); - numattrs = RelationGetNumberOfAttributes(relation); - - Assert(relation->rd_rel->relkind == RELKIND_INDEX); /* XXX use accessor */ - Assert((attributeNumber >= 1) && (attributeNumber <= numattrs)); - - Assert(StrategyEvaluationIsValid(evaluation)); - Assert(RegProcedureIsValid(procedure)); - - strategyMap = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation), - evaluation->maxStrategy, - attributeNumber); - - /* get a strategy number for the procedure ignoring flags for now */ - for (index = 0; index < evaluation->maxStrategy; index += 1) - { - if (strategyMap->entry[index].sk_procedure == procedure) - break; - } - - if (index == evaluation->maxStrategy) - return InvalidStrategy; - - strategy = 1 + index; - entry = StrategyMapGetScanKeyEntry(strategyMap, strategy); - - Assert(!(entry->sk_flags & ~(SK_NEGATE | SK_COMMUTE))); - - switch (entry->sk_flags & (SK_NEGATE | SK_COMMUTE)) - { - case 0x0: - return strategy; - - case SK_NEGATE: - strategy = evaluation->negateTransform->strategy[strategy - 1]; - break; - - case SK_COMMUTE: - strategy = evaluation->commuteTransform->strategy[strategy - 1]; - break; - - case SK_NEGATE | SK_COMMUTE: - strategy = evaluation->negateCommuteTransform->strategy[strategy - 1]; - break; - - default: - elog(ERROR, "impossible strategy case: %d", - entry->sk_flags); - } - - if (!StrategyNumberIsInBounds(strategy, evaluation->maxStrategy)) - { - if (!StrategyNumberIsValid(strategy)) - elog(ERROR, "corrupted strategy evaluation"); - } - - return strategy; -} - -#ifdef NOT_USED -/* ---------------- - * RelationInvokeStrategy - * ---------------- - */ -bool /* XXX someday, this may return Datum */ -RelationInvokeStrategy(Relation relation, - StrategyEvaluation evaluation, - AttrNumber attributeNumber, - StrategyNumber strategy, - Datum left, - Datum right) -{ - StrategyNumber newStrategy; - StrategyMap strategyMap; - ScanKey entry; - StrategyTermData termData; - int numattrs; - - Assert(RelationIsValid(relation)); - Assert(relation->rd_rel->relkind == RELKIND_INDEX); /* XXX use accessor */ - numattrs = RelationGetNumberOfAttributes(relation); - - Assert(StrategyEvaluationIsValid(evaluation)); - Assert(AttributeNumberIsValid(attributeNumber)); - Assert((attributeNumber >= 1) && (attributeNumber < 1 + numattrs)); - - Assert(StrategyNumberIsInBounds(strategy, evaluation->maxStrategy)); - - termData.degree = 1; - - strategyMap = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation), - evaluation->maxStrategy, - attributeNumber); - - entry = StrategyMapGetScanKeyEntry(strategyMap, strategy); - - if (RegProcedureIsValid(entry->sk_procedure)) - { - termData.operatorData[0].strategy = strategy; - termData.operatorData[0].flags = 0x0; - - return StrategyTermEvaluate(&termData, strategyMap, left, right); - } - - - newStrategy = evaluation->negateTransform->strategy[strategy - 1]; - if (newStrategy != strategy && StrategyNumberIsValid(newStrategy)) - { - entry = StrategyMapGetScanKeyEntry(strategyMap, newStrategy); - - if (RegProcedureIsValid(entry->sk_procedure)) - { - termData.operatorData[0].strategy = newStrategy; - termData.operatorData[0].flags = SK_NEGATE; - - return StrategyTermEvaluate(&termData, strategyMap, left, right); - } - } - - newStrategy = evaluation->commuteTransform->strategy[strategy - 1]; - if (newStrategy != strategy && StrategyNumberIsValid(newStrategy)) - { - entry = StrategyMapGetScanKeyEntry(strategyMap, newStrategy); - - if (RegProcedureIsValid(entry->sk_procedure)) - { - termData.operatorData[0].strategy = newStrategy; - termData.operatorData[0].flags = SK_COMMUTE; - - return StrategyTermEvaluate(&termData, strategyMap, left, right); - } - } - - newStrategy = evaluation->negateCommuteTransform->strategy[strategy - 1]; - if (newStrategy != strategy && StrategyNumberIsValid(newStrategy)) - { - entry = StrategyMapGetScanKeyEntry(strategyMap, newStrategy); - - if (RegProcedureIsValid(entry->sk_procedure)) - { - termData.operatorData[0].strategy = newStrategy; - termData.operatorData[0].flags = SK_NEGATE | SK_COMMUTE; - - return StrategyTermEvaluate(&termData, strategyMap, left, right); - } - } - - if (PointerIsValid(evaluation->expression[strategy - 1])) - { - StrategyTerm *termP; - - termP = &evaluation->expression[strategy - 1]->term[0]; - while (PointerIsValid(*termP)) - { - Index index; - - for (index = 0; index < (*termP)->degree; index += 1) - { - entry = StrategyMapGetScanKeyEntry(strategyMap, - (*termP)->operatorData[index].strategy); - - if (!RegProcedureIsValid(entry->sk_procedure)) - break; - } - - if (index == (*termP)->degree) - return StrategyTermEvaluate(*termP, strategyMap, left, right); - - termP += 1; - } - } - - elog(ERROR, "cannot evaluate strategy %d", strategy); - - /* not reached, just to make compiler happy */ - return FALSE; -} -#endif - -/* ---------------- - * IndexStrategyDisplay - * ---------------- - */ -#ifdef ISTRATDEBUG -int -IndexStrategyDisplay(IndexStrategy indexStrategy, - StrategyNumber numberOfStrategies, - int numberOfAttributes) -{ - StrategyMap strategyMap; - AttrNumber attributeNumber; - StrategyNumber strategyNumber; - - for (attributeNumber = 1; attributeNumber <= numberOfAttributes; - attributeNumber += 1) - { - strategyMap = IndexStrategyGetStrategyMap(indexStrategy, - numberOfStrategies, - attributeNumber); - - for (strategyNumber = 1; - 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, - strategyMap->entry[strategyNumber - 1].sk_procedure); - } - } -} - -#endif /* defined(ISTRATDEBUG) */ diff --git a/src/backend/access/nbtree/Makefile b/src/backend/access/nbtree/Makefile index cf525f9f1f9..487c0a94442 100644 --- a/src/backend/access/nbtree/Makefile +++ b/src/backend/access/nbtree/Makefile @@ -4,7 +4,7 @@ # Makefile for access/nbtree # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/access/nbtree/Makefile,v 1.12 2003/02/21 00:06:21 tgl Exp $ +# $Header: /cvsroot/pgsql/src/backend/access/nbtree/Makefile,v 1.13 2003/11/09 21:30:35 tgl Exp $ # #------------------------------------------------------------------------- @@ -13,7 +13,7 @@ top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global OBJS = nbtcompare.o nbtinsert.o nbtpage.o nbtree.o nbtsearch.o \ - nbtstrat.o nbtutils.o nbtsort.o nbtxlog.o + nbtutils.o nbtsort.o nbtxlog.o all: SUBSYS.o diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c index 27c833408d6..98f3abb511f 100644 --- a/src/backend/access/nbtree/nbtinsert.c +++ b/src/backend/access/nbtree/nbtinsert.c @@ -1,6 +1,6 @@ /*------------------------------------------------------------------------- * - * btinsert.c + * nbtinsert.c * Item insertion in Lehman and Yao btrees for Postgres. * * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.106 2003/09/25 06:57:57 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.107 2003/11/09 21:30:35 tgl Exp $ * *------------------------------------------------------------------------- */ diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c index d27af61c5cd..432a1ab0c2a 100644 --- a/src/backend/access/nbtree/nbtsearch.c +++ b/src/backend/access/nbtree/nbtsearch.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.80 2003/08/08 21:41:27 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.81 2003/11/09 21:30:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -488,8 +488,6 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) /* if we didn't find a boundary for the preceding attr, quit */ if (attno > keysCount + 1) break; - strat = _bt_getstrat(rel, attno, - so->keyData[i].sk_procedure); /* * Can we use this key as a starting boundary for this attr? @@ -497,6 +495,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) * We can use multiple keys if they look like, say, = >= = but we * have to stop after accepting a > or < boundary. */ + strat = so->keyData[i].sk_strategy; if (strat == strat_total || strat == BTEqualStrategyNumber) nKeyIs[keysCount++] = i; @@ -555,13 +554,17 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) elog(ERROR, "btree doesn't support is(not)null, yet"); return false; } + /* + * XXX what if sk_argtype is not same as index? + */ procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC); ScanKeyEntryInitializeWithInfo(scankeys + i, so->keyData[j].sk_flags, i + 1, + InvalidStrategy, procinfo, - CurrentMemoryContext, - so->keyData[j].sk_argument); + so->keyData[j].sk_argument, + so->keyData[j].sk_argtype); } if (nKeyIs) pfree(nKeyIs); diff --git a/src/backend/access/nbtree/nbtstrat.c b/src/backend/access/nbtree/nbtstrat.c deleted file mode 100644 index 15544d47572..00000000000 --- a/src/backend/access/nbtree/nbtstrat.c +++ /dev/null @@ -1,138 +0,0 @@ -/*------------------------------------------------------------------------- - * - * nbtstrat.c - * Strategy map entries for the btree indexed access method - * - * Portions Copyright (c) 1996-2003, 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.18 2003/08/04 02:39:57 momjian Exp $ - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" - -#include "access/istrat.h" -#include "access/nbtree.h" - -/* - * Note: - * StrategyNegate, StrategyCommute, and StrategyNegateCommute - * assume <, <=, ==, >=, > ordering. - */ -static StrategyNumber BTNegate[BTMaxStrategyNumber] = { - BTGreaterEqualStrategyNumber, - BTGreaterStrategyNumber, - InvalidStrategy, - BTLessStrategyNumber, - BTLessEqualStrategyNumber -}; - -static StrategyNumber BTCommute[BTMaxStrategyNumber] = { - BTGreaterStrategyNumber, - BTGreaterEqualStrategyNumber, - InvalidStrategy, - BTLessEqualStrategyNumber, - BTLessStrategyNumber -}; - -static StrategyNumber BTNegateCommute[BTMaxStrategyNumber] = { - BTLessEqualStrategyNumber, - BTLessStrategyNumber, - InvalidStrategy, - BTGreaterStrategyNumber, - BTGreaterEqualStrategyNumber -}; - -static uint16 BTLessTermData[] = { /* XXX type clash */ - 2, - BTLessStrategyNumber, - SK_NEGATE, - BTLessStrategyNumber, - SK_NEGATE | SK_COMMUTE -}; - -static uint16 BTLessEqualTermData[] = { /* XXX type clash */ - 2, - BTLessEqualStrategyNumber, - 0x0, - BTLessEqualStrategyNumber, - SK_COMMUTE -}; - -static uint16 BTGreaterEqualTermData[] = { /* XXX type clash */ - 2, - BTGreaterEqualStrategyNumber, - 0x0, - BTGreaterEqualStrategyNumber, - SK_COMMUTE -}; - -static uint16 BTGreaterTermData[] = { /* XXX type clash */ - 2, - BTGreaterStrategyNumber, - SK_NEGATE, - BTGreaterStrategyNumber, - SK_NEGATE | SK_COMMUTE -}; - -static StrategyTerm BTEqualExpressionData[] = { - (StrategyTerm) BTLessTermData, /* XXX */ - (StrategyTerm) BTLessEqualTermData, /* XXX */ - (StrategyTerm) BTGreaterEqualTermData, /* XXX */ - (StrategyTerm) BTGreaterTermData, /* XXX */ - NULL -}; - -static StrategyExpression BTEvaluationExpressions[BTMaxStrategyNumber] = { - NULL, - NULL, - (StrategyExpression) BTEqualExpressionData, - NULL, - NULL -}; - -static StrategyEvaluationData BTEvaluationData = { - BTMaxStrategyNumber, - (StrategyTransformMap) BTNegate, - (StrategyTransformMap) BTCommute, - (StrategyTransformMap) BTNegateCommute, - BTEvaluationExpressions -}; - -/* ---------------------------------------------------------------- - * RelationGetBTStrategy - * ---------------------------------------------------------------- - */ - -StrategyNumber -_bt_getstrat(Relation rel, - AttrNumber attno, - RegProcedure proc) -{ - StrategyNumber strat; - - strat = RelationGetStrategy(rel, attno, &BTEvaluationData, proc); - - Assert(StrategyNumberIsValid(strat)); - - return strat; -} - -#ifdef NOT_USED - -bool -_bt_invokestrat(Relation rel, - AttrNumber attno, - StrategyNumber strat, - Datum left, - Datum right) -{ - return (RelationInvokeStrategy(rel, &BTEvaluationData, attno, strat, - left, right)); -} - -#endif diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c index 44980588a8c..54cd7c8cd01 100644 --- a/src/backend/access/nbtree/nbtutils.c +++ b/src/backend/access/nbtree/nbtutils.c @@ -1,6 +1,6 @@ /*------------------------------------------------------------------------- * - * btutils.c + * nbtutils.c * Utility code for Postgres btree implementation. * * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.54 2003/08/04 02:39:57 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.55 2003/11/09 21:30:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -16,13 +16,10 @@ #include "postgres.h" #include "access/genam.h" -#include "access/istrat.h" #include "access/nbtree.h" #include "catalog/catalog.h" #include "executor/execdebug.h" - - -static int _bt_getstrategynumber(RegProcedure sk_procedure, StrategyMap map); +#include "utils/lsyscache.h" /* @@ -39,10 +36,6 @@ _bt_mkscankey(Relation rel, IndexTuple itup) TupleDesc itupdesc; int natts; int i; - FmgrInfo *procinfo; - Datum arg; - bool null; - bits16 flag; itupdesc = RelationGetDescr(rel); natts = RelationGetNumberOfAttributes(rel); @@ -51,15 +44,23 @@ _bt_mkscankey(Relation rel, IndexTuple itup) for (i = 0; i < natts; i++) { + FmgrInfo *procinfo; + Datum arg; + bool null; + + /* + * We can use the cached support procs since no cross-type comparison + * can be needed. + */ procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC); arg = index_getattr(itup, i + 1, itupdesc, &null); - flag = null ? SK_ISNULL : 0x0; ScanKeyEntryInitializeWithInfo(&skey[i], - flag, + null ? SK_ISNULL : 0, (AttrNumber) (i + 1), + InvalidStrategy, procinfo, - CurrentMemoryContext, - arg); + arg, + itupdesc->attrs[i]->atttypid); } return skey; @@ -68,33 +69,42 @@ _bt_mkscankey(Relation rel, IndexTuple itup) /* * _bt_mkscankey_nodata * Build a scan key that contains comparator routines appropriate to - * the key datatypes, but no comparison data. + * the key datatypes, but no comparison data. The comparison data + * ultimately used must match the key datatypes. * * The result cannot be used with _bt_compare(). Currently this - * routine is only called by utils/sort/tuplesort.c, which has its - * own comparison routine. + * routine is only called by nbtsort.c and tuplesort.c, which have + * their own comparison routines. */ ScanKey _bt_mkscankey_nodata(Relation rel) { ScanKey skey; + TupleDesc itupdesc; int natts; int i; - FmgrInfo *procinfo; + itupdesc = RelationGetDescr(rel); natts = RelationGetNumberOfAttributes(rel); skey = (ScanKey) palloc(natts * sizeof(ScanKeyData)); for (i = 0; i < natts; i++) { + FmgrInfo *procinfo; + + /* + * We can use the cached support procs since no cross-type comparison + * can be needed. + */ procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC); ScanKeyEntryInitializeWithInfo(&skey[i], SK_ISNULL, (AttrNumber) (i + 1), + InvalidStrategy, procinfo, - CurrentMemoryContext, - (Datum) 0); + (Datum) 0, + itupdesc->attrs[i]->atttypid); } return skey; @@ -185,17 +195,6 @@ _bt_formitem(IndexTuple itup) * The initial ordering of the keys is expected to be by attribute already * (see group_clauses_by_indexkey() in indxpath.c). The task here is to * standardize the appearance of multiple keys for the same attribute. - * - * XXX this routine is one of many places that fail to handle SK_COMMUTE - * scankeys properly. Currently, the planner is careful never to generate - * any indexquals that would require SK_COMMUTE to be set. Someday we ought - * to try to fix this, though it's not real critical as long as indexable - * operators all have commutators... - * - * Note: this routine invokes comparison operators via OidFunctionCallN, - * ie, without caching function lookups. No point in trying to be smarter, - * since these comparisons are executed only when the user expresses a - * hokey qualification, and happen only once per scan anyway. *---------- */ void @@ -208,7 +207,6 @@ _bt_orderkeys(IndexScanDesc scan) int numberOfKeys = so->numberOfKeys; ScanKey key; ScanKey cur; - StrategyMap map; Datum test; int i, j; @@ -229,6 +227,32 @@ _bt_orderkeys(IndexScanDesc scan) if (cur->sk_attno != 1) elog(ERROR, "key(s) for attribute 1 missed"); +#if 0 + /* XXX verify that operator strategy info is correct */ + /* XXX this is temporary for debugging; it's pretty expensive */ + /* XXX can't do it during bootstrap, else will recurse infinitely */ + { + extern bool criticalRelcachesBuilt; + static bool inRecursion = false; + + if (criticalRelcachesBuilt && !inRecursion) + { + inRecursion = true; + for (i = 0; i < numberOfKeys; i++) + { + AttrNumber attno = key[i].sk_attno; + Oid opclass; + Oid chk_oper; + + opclass = relation->rd_index->indclass[attno-1]; + chk_oper = get_opclass_member(opclass, key[i].sk_strategy); + Assert(key[i].sk_func.fn_oid == get_opcode(chk_oper)); + } + inRecursion = false; + } + } +#endif + /* We can short-circuit most of the work if there's just one key */ if (numberOfKeys == 1) { @@ -243,11 +267,7 @@ _bt_orderkeys(IndexScanDesc scan) relation->rd_rel->relnatts == 1) { /* it's a unique index, do we have an equality qual? */ - map = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation), - BTMaxStrategyNumber, - 1); - j = _bt_getstrategynumber(cur->sk_procedure, map); - if (j == (BTEqualStrategyNumber - 1)) + if (cur->sk_strategy == BTEqualStrategyNumber) scan->keys_are_unique = true; } so->numberOfRequiredKeys = 1; @@ -267,9 +287,6 @@ _bt_orderkeys(IndexScanDesc scan) * any; init[i] is TRUE if we have found such a key for this attr. */ attno = 1; - map = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation), - BTMaxStrategyNumber, - attno); MemSet(xform, 0, sizeof(xform)); /* not really necessary */ MemSet(init, 0, sizeof(init)); @@ -324,9 +341,9 @@ _bt_orderkeys(IndexScanDesc scan) j == (BTEqualStrategyNumber - 1)) continue; chk = &xform[j]; - test = OidFunctionCall2(chk->sk_procedure, - eq->sk_argument, - chk->sk_argument); + test = FunctionCall2(&chk->sk_func, + eq->sk_argument, + chk->sk_argument); if (!DatumGetBool(test)) so->qual_ok = false; } @@ -350,9 +367,9 @@ _bt_orderkeys(IndexScanDesc scan) ScanKeyData *lt = &xform[BTLessStrategyNumber - 1]; ScanKeyData *le = &xform[BTLessEqualStrategyNumber - 1]; - test = OidFunctionCall2(le->sk_procedure, - lt->sk_argument, - le->sk_argument); + test = FunctionCall2(&le->sk_func, + lt->sk_argument, + le->sk_argument); if (DatumGetBool(test)) init[BTLessEqualStrategyNumber - 1] = false; else @@ -366,9 +383,9 @@ _bt_orderkeys(IndexScanDesc scan) ScanKeyData *gt = &xform[BTGreaterStrategyNumber - 1]; ScanKeyData *ge = &xform[BTGreaterEqualStrategyNumber - 1]; - test = OidFunctionCall2(ge->sk_procedure, - gt->sk_argument, - ge->sk_argument); + test = FunctionCall2(&ge->sk_func, + gt->sk_argument, + ge->sk_argument); if (DatumGetBool(test)) init[BTGreaterEqualStrategyNumber - 1] = false; else @@ -404,15 +421,12 @@ _bt_orderkeys(IndexScanDesc scan) /* Re-initialize for new attno */ attno = cur->sk_attno; - map = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation), - BTMaxStrategyNumber, - attno); MemSet(xform, 0, sizeof(xform)); /* not really necessary */ MemSet(init, 0, sizeof(init)); } /* figure out which strategy this key's operator corresponds to */ - j = _bt_getstrategynumber(cur->sk_procedure, map); + j = cur->sk_strategy - 1; /* have we seen one of these before? */ if (init[j]) @@ -446,25 +460,6 @@ _bt_orderkeys(IndexScanDesc scan) scan->keys_are_unique = true; } -/* - * Determine which btree strategy an operator procedure matches. - * - * Result is strategy number minus 1. - */ -static int -_bt_getstrategynumber(RegProcedure sk_procedure, StrategyMap map) -{ - int j; - - for (j = BTMaxStrategyNumber; --j >= 0;) - { - if (sk_procedure == map->entry[j].sk_procedure) - return j; - } - elog(ERROR, "could not identify operator %u", sk_procedure); - return -1; /* keep compiler quiet */ -} - /* * Test whether an indextuple satisfies all the scankey conditions. * @@ -533,14 +528,9 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple, return false; } - if (key->sk_flags & SK_COMMUTE) - test = FunctionCall2(&key->sk_func, - key->sk_argument, datum); - else - test = FunctionCall2(&key->sk_func, - datum, key->sk_argument); + test = FunctionCall2(&key->sk_func, datum, key->sk_argument); - if (DatumGetBool(test) == !!(key->sk_flags & SK_NEGATE)) + if (!DatumGetBool(test)) { /* * Tuple fails this qual. If it's a required qual, then we diff --git a/src/backend/access/rtree/rtscan.c b/src/backend/access/rtree/rtscan.c index f3329448d93..263fff4bf26 100644 --- a/src/backend/access/rtree/rtscan.c +++ b/src/backend/access/rtree/rtscan.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.47 2003/08/04 02:39:57 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.48 2003/11/09 21:30:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -17,7 +17,7 @@ #include "access/genam.h" #include "access/rtree.h" - +#include "utils/lsyscache.h" /* routines defined and used here */ @@ -71,7 +71,6 @@ rtrescan(PG_FUNCTION_ARGS) IndexScanDesc s = (IndexScanDesc) PG_GETARG_POINTER(0); ScanKey key = (ScanKey) PG_GETARG_POINTER(1); RTreeScanOpaque p; - RegProcedure internal_proc; int i; /* @@ -116,14 +115,23 @@ rtrescan(PG_FUNCTION_ARGS) */ for (i = 0; i < s->numberOfKeys; i++) { - internal_proc = RTMapOperator(s->indexRelation, - s->keyData[i].sk_attno, - s->keyData[i].sk_procedure); + AttrNumber attno = s->keyData[i].sk_attno; + Oid opclass; + StrategyNumber int_strategy; + Oid int_oper; + RegProcedure int_proc; + + opclass = s->indexRelation->rd_index->indclass[attno-1]; + int_strategy = RTMapToInternalOperator(s->keyData[i].sk_strategy); + int_oper = get_opclass_member(opclass, int_strategy); + int_proc = get_opcode(int_oper); ScanKeyEntryInitialize(&(p->s_internalKey[i]), s->keyData[i].sk_flags, - s->keyData[i].sk_attno, - internal_proc, - s->keyData[i].sk_argument); + attno, + int_strategy, + int_proc, + s->keyData[i].sk_argument, + s->keyData[i].sk_argtype); } } diff --git a/src/backend/access/rtree/rtstrat.c b/src/backend/access/rtree/rtstrat.c index f7253a48e14..7d9097c8ea4 100644 --- a/src/backend/access/rtree/rtstrat.c +++ b/src/backend/access/rtree/rtstrat.c @@ -8,176 +8,18 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtstrat.c,v 1.21 2003/08/04 02:39:57 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtstrat.c,v 1.22 2003/11/09 21:30:35 tgl Exp $ * *------------------------------------------------------------------------- */ #include "postgres.h" -#include "access/istrat.h" #include "access/rtree.h" -static StrategyNumber RelationGetRTStrategy(Relation r, - AttrNumber attnum, RegProcedure proc); /* - * Note: negate, commute, and negatecommute all assume that operators are - * ordered as follows in the strategy map: - * - * left, left-or-overlap, overlap, right-or-overlap, right, same, - * contains, contained-by - * - * The negate, commute, and negatecommute arrays are used by the planner - * to plan indexed scans over data that appears in the qualificiation in - * a boolean negation, or whose operands appear in the wrong order. For - * example, if the operator "<%" means "contains", and the user says - * - * where not rel.box <% "(10,10,20,20)"::box - * - * the planner can plan an index scan by noting that rtree indices have - * an operator in their operator class for negating <%. - * - * Similarly, if the user says something like - * - * where "(10,10,20,20)"::box <% rel.box - * - * the planner can see that the rtree index on rel.box has an operator in - * its opclass for commuting <%, and plan the scan using that operator. - * This added complexity in the access methods makes the planner a lot easier - * to write. - */ - -/* if a op b, what operator tells us if (not a op b)? */ -static StrategyNumber RTNegate[RTNStrategies] = { - InvalidStrategy, - InvalidStrategy, - InvalidStrategy, - InvalidStrategy, - InvalidStrategy, - InvalidStrategy, - InvalidStrategy, - InvalidStrategy -}; - -/* if a op_1 b, what is the operator op_2 such that b op_2 a? */ -static StrategyNumber RTCommute[RTNStrategies] = { - InvalidStrategy, - InvalidStrategy, - InvalidStrategy, - InvalidStrategy, - InvalidStrategy, - InvalidStrategy, - InvalidStrategy, - InvalidStrategy -}; - -/* if a op_1 b, what is the operator op_2 such that (b !op_2 a)? */ -static StrategyNumber RTNegateCommute[RTNStrategies] = { - InvalidStrategy, - InvalidStrategy, - InvalidStrategy, - InvalidStrategy, - InvalidStrategy, - InvalidStrategy, - InvalidStrategy, - InvalidStrategy -}; - -/* - * Now do the TermData arrays. These exist in case the user doesn't give - * us a full set of operators for a particular operator class. The idea - * is that by making multiple comparisons using any one of the supplied - * operators, we can decide whether two n-dimensional polygons are equal. - * For example, if a contains b and b contains a, we may conclude that - * a and b are equal. - * - * The presence of the TermData arrays in all this is a historical accident. - * 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, 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. - * - * Since you can't necessarily do this in all cases (for example, you can't - * do it given only "intersects" or "disjoint"), TermData arrays for some - * operators don't appear below. - * - * Note that if you DO supply all the operators required in a given opclass - * by inserting them into the pg_opclass system catalog, you can get away - * without doing all this TermData stuff. Since the rtree code is intended - * to be a reference for access method implementors, I'm doing TermData - * correctly here. - * - * Note on style: these are all actually of type StrategyTermData, but - * since those have variable-length data at the end of the struct we can't - * properly initialize them if we declare them to be what they are. - */ - -/* if you only have "contained-by", how do you determine equality? */ -static uint16 RTContainedByTermData[] = { - 2, /* make two comparisons */ - RTContainedByStrategyNumber, /* use "a contained-by b" */ - 0x0, /* without any magic */ - RTContainedByStrategyNumber, /* then use contained-by, */ - SK_COMMUTE /* swapping a and b */ -}; - -/* if you only have "contains", how do you determine equality? */ -static uint16 RTContainsTermData[] = { - 2, /* make two comparisons */ - RTContainsStrategyNumber, /* use "a contains b" */ - 0x0, /* without any magic */ - RTContainsStrategyNumber, /* then use contains again, */ - SK_COMMUTE /* swapping a and b */ -}; - -/* now put all that together in one place for the planner */ -static StrategyTerm RTEqualExpressionData[] = { - (StrategyTerm) RTContainedByTermData, - (StrategyTerm) RTContainsTermData, - NULL -}; - -/* - * If you were sufficiently attentive to detail, you would go through - * the ExpressionData pain above for every one of the seven strategies - * we defined. I am not. Now we declare the StrategyEvaluationData - * structure that gets shipped around to help the planner and the access - * method decide what sort of scan it should do, based on (a) what the - * user asked for, (b) what operators are defined for a particular opclass, - * and (c) the reams of information we supplied above. - * - * The idea of all of this initialized data is to make life easier on the - * user when he defines a new operator class to use this access method. - * By filling in all the data, we let him get away with leaving holes in his - * operator class, and still let him use the index. The added complexity - * 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 */ - RTEvaluationExpressions -}; - -/* - * Okay, now something peculiar to rtrees that doesn't apply to most other + * Here's something peculiar to rtrees that doesn't apply to most other * indexing structures: When we're searching a tree for a given value, we * can't do the same sorts of comparisons on internal node entries as we * do at leaves. The reason is that if we're looking for (say) all boxes @@ -191,7 +33,7 @@ static StrategyEvaluationData RTEvaluationData = { * left, left-or-overlap, overlap, right-or-overlap, right, same, * contains, contained-by */ -static StrategyNumber RTOperMap[RTNStrategies] = { +static const StrategyNumber RTOperMap[RTNStrategies] = { RTOverLeftStrategyNumber, RTOverLeftStrategyNumber, RTOverlapStrategyNumber, @@ -202,39 +44,10 @@ static StrategyNumber RTOperMap[RTNStrategies] = { RTOverlapStrategyNumber }; -static StrategyNumber -RelationGetRTStrategy(Relation r, - AttrNumber attnum, - RegProcedure proc) + +StrategyNumber +RTMapToInternalOperator(StrategyNumber strat) { - return RelationGetStrategy(r, attnum, &RTEvaluationData, proc); -} - -#ifdef NOT_USED -bool -RelationInvokeRTStrategy(Relation r, - AttrNumber attnum, - StrategyNumber s, - Datum left, - Datum right) -{ - return (RelationInvokeStrategy(r, &RTEvaluationData, attnum, s, - left, right)); -} -#endif - -RegProcedure -RTMapOperator(Relation r, - AttrNumber attnum, - RegProcedure proc) -{ - StrategyNumber procstrat; - StrategyMap strategyMap; - - procstrat = RelationGetRTStrategy(r, attnum, proc); - strategyMap = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(r), - RTNStrategies, - attnum); - - return strategyMap->entry[RTOperMap[procstrat - 1] - 1].sk_procedure; + Assert(strat > 0 && strat <= RTNStrategies); + return RTOperMap[strat - 1]; } diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y index f23bbed7520..8a5bc945133 100644 --- a/src/backend/bootstrap/bootparse.y +++ b/src/backend/bootstrap/bootparse.y @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.60 2003/08/04 02:39:57 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.61 2003/11/09 21:30:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -23,7 +23,6 @@ #include "access/htup.h" #include "access/itup.h" #include "access/skey.h" -#include "access/strat.h" #include "access/tupdesc.h" #include "access/xact.h" #include "bootstrap/bootstrap.h" diff --git a/src/backend/bootstrap/bootscanner.l b/src/backend/bootstrap/bootscanner.l index af74121c3d8..23d8bd9e02d 100644 --- a/src/backend/bootstrap/bootscanner.l +++ b/src/backend/bootstrap/bootscanner.l @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootscanner.l,v 1.30 2003/08/04 02:39:57 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootscanner.l,v 1.31 2003/11/09 21:30:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -21,7 +21,6 @@ #include "access/htup.h" #include "access/itup.h" #include "access/skey.h" -#include "access/strat.h" #include "access/tupdesc.h" #include "bootstrap/bootstrap.h" #include "catalog/pg_am.h" diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index bf43769d706..a1b697bee85 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.91 2003/10/31 20:00:49 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.92 2003/11/09 21:30:35 tgl Exp $ * * NOTES * See acl.h. @@ -367,8 +367,9 @@ ExecuteGrantStmt_Database(GrantStmt *stmt) relation = heap_openr(DatabaseRelationName, RowExclusiveLock); ScanKeyEntryInitialize(&entry[0], 0, - Anum_pg_database_datname, F_NAMEEQ, - CStringGetDatum(dbname)); + Anum_pg_database_datname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(dbname), NAMEOID); scan = heap_beginscan(relation, SnapshotNow, 1, entry); tuple = heap_getnext(scan, ForwardScanDirection); if (!HeapTupleIsValid(tuple)) @@ -1130,9 +1131,10 @@ pg_database_aclcheck(Oid db_oid, AclId userid, AclMode mode) * There's no syscache for pg_database, so must look the hard way */ pg_database = heap_openr(DatabaseRelationName, AccessShareLock); - ScanKeyEntryInitialize(&entry[0], 0x0, - ObjectIdAttributeNumber, F_OIDEQ, - ObjectIdGetDatum(db_oid)); + ScanKeyEntryInitialize(&entry[0], 0, + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(db_oid), OIDOID); scan = heap_beginscan(pg_database, SnapshotNow, 1, entry); tuple = heap_getnext(scan, ForwardScanDirection); if (!HeapTupleIsValid(tuple)) @@ -1529,9 +1531,10 @@ pg_database_ownercheck(Oid db_oid, AclId userid) /* There's no syscache for pg_database, so must look the hard way */ pg_database = heap_openr(DatabaseRelationName, AccessShareLock); - ScanKeyEntryInitialize(&entry[0], 0x0, - ObjectIdAttributeNumber, F_OIDEQ, - ObjectIdGetDatum(db_oid)); + ScanKeyEntryInitialize(&entry[0], 0, + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(db_oid), OIDOID); scan = heap_beginscan(pg_database, SnapshotNow, 1, entry); dbtuple = heap_getnext(scan, ForwardScanDirection); diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index 8155f4fff3f..b0e17652c74 100644 --- a/src/backend/catalog/dependency.c +++ b/src/backend/catalog/dependency.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.31 2003/08/11 23:04:49 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.32 2003/11/09 21:30:35 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -31,6 +31,7 @@ #include "catalog/pg_opclass.h" #include "catalog/pg_rewrite.h" #include "catalog/pg_trigger.h" +#include "catalog/pg_type.h" #include "commands/comment.h" #include "commands/defrem.h" #include "commands/proclang.h" @@ -282,17 +283,20 @@ findAutoDeletableObjects(const ObjectAddress *object, * When dropping a whole object (subId = 0), find pg_depend records for * its sub-objects too. */ - ScanKeyEntryInitialize(&key[0], 0x0, - Anum_pg_depend_refclassid, F_OIDEQ, - ObjectIdGetDatum(object->classId)); - ScanKeyEntryInitialize(&key[1], 0x0, - Anum_pg_depend_refobjid, F_OIDEQ, - ObjectIdGetDatum(object->objectId)); + ScanKeyEntryInitialize(&key[0], 0, + Anum_pg_depend_refclassid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(object->classId), OIDOID); + ScanKeyEntryInitialize(&key[1], 0, + Anum_pg_depend_refobjid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(object->objectId), OIDOID); if (object->objectSubId != 0) { - ScanKeyEntryInitialize(&key[2], 0x0, - Anum_pg_depend_refobjsubid, F_INT4EQ, - Int32GetDatum(object->objectSubId)); + ScanKeyEntryInitialize(&key[2], 0, + Anum_pg_depend_refobjsubid, + BTEqualStrategyNumber, F_INT4EQ, + Int32GetDatum(object->objectSubId), INT4OID); nkeys = 3; } else @@ -414,17 +418,20 @@ recursiveDeletion(const ObjectAddress *object, * When dropping a whole object (subId = 0), remove all pg_depend records * for its sub-objects too. */ - ScanKeyEntryInitialize(&key[0], 0x0, - Anum_pg_depend_classid, F_OIDEQ, - ObjectIdGetDatum(object->classId)); - ScanKeyEntryInitialize(&key[1], 0x0, - Anum_pg_depend_objid, F_OIDEQ, - ObjectIdGetDatum(object->objectId)); + ScanKeyEntryInitialize(&key[0], 0, + Anum_pg_depend_classid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(object->classId), OIDOID); + ScanKeyEntryInitialize(&key[1], 0, + Anum_pg_depend_objid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(object->objectId), OIDOID); if (object->objectSubId != 0) { - ScanKeyEntryInitialize(&key[2], 0x0, - Anum_pg_depend_objsubid, F_INT4EQ, - Int32GetDatum(object->objectSubId)); + ScanKeyEntryInitialize(&key[2], 0, + Anum_pg_depend_objsubid, + BTEqualStrategyNumber, F_INT4EQ, + Int32GetDatum(object->objectSubId), INT4OID); nkeys = 3; } else @@ -644,17 +651,20 @@ deleteDependentObjects(const ObjectAddress *object, HeapTuple tup; ObjectAddress otherObject; - ScanKeyEntryInitialize(&key[0], 0x0, - Anum_pg_depend_refclassid, F_OIDEQ, - ObjectIdGetDatum(object->classId)); - ScanKeyEntryInitialize(&key[1], 0x0, - Anum_pg_depend_refobjid, F_OIDEQ, - ObjectIdGetDatum(object->objectId)); + ScanKeyEntryInitialize(&key[0], 0, + Anum_pg_depend_refclassid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(object->classId), OIDOID); + ScanKeyEntryInitialize(&key[1], 0, + Anum_pg_depend_refobjid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(object->objectId), OIDOID); if (object->objectSubId != 0) { - ScanKeyEntryInitialize(&key[2], 0x0, - Anum_pg_depend_refobjsubid, F_INT4EQ, - Int32GetDatum(object->objectSubId)); + ScanKeyEntryInitialize(&key[2], 0, + Anum_pg_depend_refobjsubid, + BTEqualStrategyNumber, F_INT4EQ, + Int32GetDatum(object->objectSubId), INT4OID); nkeys = 3; } else @@ -1463,9 +1473,11 @@ getObjectDescription(const ObjectAddress *object) castDesc = heap_openr(CastRelationName, AccessShareLock); - ScanKeyEntryInitialize(&skey[0], 0x0, - ObjectIdAttributeNumber, F_OIDEQ, - ObjectIdGetDatum(object->objectId)); + ScanKeyEntryInitialize(&skey[0], 0, + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(object->objectId), + OIDOID); rcscan = systable_beginscan(castDesc, CastOidIndex, true, SnapshotNow, 1, skey); @@ -1497,9 +1509,11 @@ getObjectDescription(const ObjectAddress *object) conDesc = heap_openr(ConstraintRelationName, AccessShareLock); - ScanKeyEntryInitialize(&skey[0], 0x0, - ObjectIdAttributeNumber, F_OIDEQ, - ObjectIdGetDatum(object->objectId)); + ScanKeyEntryInitialize(&skey[0], 0, + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(object->objectId), + OIDOID); rcscan = systable_beginscan(conDesc, ConstraintOidIndex, true, SnapshotNow, 1, skey); @@ -1556,12 +1570,14 @@ getObjectDescription(const ObjectAddress *object) attrdefDesc = heap_openr(AttrDefaultRelationName, AccessShareLock); - ScanKeyEntryInitialize(&skey[0], 0x0, - ObjectIdAttributeNumber, F_OIDEQ, - ObjectIdGetDatum(object->objectId)); + ScanKeyEntryInitialize(&skey[0], 0, + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(object->objectId), + OIDOID); - adscan = systable_beginscan(attrdefDesc, AttrDefaultOidIndex, true, - SnapshotNow, 1, skey); + adscan = systable_beginscan(attrdefDesc, AttrDefaultOidIndex, + true, SnapshotNow, 1, skey); tup = systable_getnext(adscan); @@ -1656,9 +1672,11 @@ getObjectDescription(const ObjectAddress *object) ruleDesc = heap_openr(RewriteRelationName, AccessShareLock); - ScanKeyEntryInitialize(&skey[0], 0x0, - ObjectIdAttributeNumber, F_OIDEQ, - ObjectIdGetDatum(object->objectId)); + ScanKeyEntryInitialize(&skey[0], 0, + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(object->objectId), + OIDOID); rcscan = systable_beginscan(ruleDesc, RewriteOidIndex, true, SnapshotNow, 1, skey); @@ -1690,9 +1708,11 @@ getObjectDescription(const ObjectAddress *object) trigDesc = heap_openr(TriggerRelationName, AccessShareLock); - ScanKeyEntryInitialize(&skey[0], 0x0, - ObjectIdAttributeNumber, F_OIDEQ, - ObjectIdGetDatum(object->objectId)); + ScanKeyEntryInitialize(&skey[0], 0, + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(object->objectId), + OIDOID); tgscan = systable_beginscan(trigDesc, TriggerOidIndex, true, SnapshotNow, 1, skey); diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index ada1d23f51e..75445334ec7 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.253 2003/09/25 06:57:57 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.254 2003/11/09 21:30:36 tgl Exp $ * * * INTERFACE ROUTINES @@ -853,9 +853,11 @@ RelationRemoveInheritance(Relation relation) catalogRelation = heap_openr(InheritsRelationName, RowExclusiveLock); - ScanKeyEntryInitialize(&key, 0x0, - Anum_pg_inherits_inhrelid, F_OIDEQ, - ObjectIdGetDatum(RelationGetRelid(relation))); + ScanKeyEntryInitialize(&key, 0, + Anum_pg_inherits_inhrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(relation)), + OIDOID); scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndex, true, SnapshotNow, 1, &key); @@ -918,9 +920,10 @@ DeleteAttributeTuples(Oid relid) attrel = heap_openr(AttributeRelationName, RowExclusiveLock); /* Use the index to scan only attributes of the target relation */ - ScanKeyEntryInitialize(&key[0], 0x0, - Anum_pg_attribute_attrelid, F_OIDEQ, - ObjectIdGetDatum(relid)); + ScanKeyEntryInitialize(&key[0], 0, + Anum_pg_attribute_attrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(relid), OIDOID); scan = systable_beginscan(attrel, AttributeRelidNumIndex, true, SnapshotNow, 1, key); @@ -1032,12 +1035,14 @@ RemoveAttrDefault(Oid relid, AttrNumber attnum, attrdef_rel = heap_openr(AttrDefaultRelationName, RowExclusiveLock); - ScanKeyEntryInitialize(&scankeys[0], 0x0, - Anum_pg_attrdef_adrelid, F_OIDEQ, - ObjectIdGetDatum(relid)); - ScanKeyEntryInitialize(&scankeys[1], 0x0, - Anum_pg_attrdef_adnum, F_INT2EQ, - Int16GetDatum(attnum)); + ScanKeyEntryInitialize(&scankeys[0], 0, + Anum_pg_attrdef_adrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(relid), OIDOID); + ScanKeyEntryInitialize(&scankeys[1], 0, + Anum_pg_attrdef_adnum, + BTEqualStrategyNumber, F_INT2EQ, + Int16GetDatum(attnum), INT2OID); scan = systable_beginscan(attrdef_rel, AttrDefaultIndex, true, SnapshotNow, 2, scankeys); @@ -1087,9 +1092,10 @@ RemoveAttrDefaultById(Oid attrdefId) attrdef_rel = heap_openr(AttrDefaultRelationName, RowExclusiveLock); /* Find the pg_attrdef tuple */ - ScanKeyEntryInitialize(&scankeys[0], 0x0, - ObjectIdAttributeNumber, F_OIDEQ, - ObjectIdGetDatum(attrdefId)); + ScanKeyEntryInitialize(&scankeys[0], 0, + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(attrdefId), OIDOID); scan = systable_beginscan(attrdef_rel, AttrDefaultOidIndex, true, SnapshotNow, 1, scankeys); @@ -1823,9 +1829,10 @@ RemoveRelConstraints(Relation rel, const char *constrName, conrel = heap_openr(ConstraintRelationName, RowExclusiveLock); /* Use the index to scan only constraints of the target relation */ - ScanKeyEntryInitialize(&key[0], 0x0, - Anum_pg_constraint_conrelid, F_OIDEQ, - ObjectIdGetDatum(RelationGetRelid(rel))); + ScanKeyEntryInitialize(&key[0], 0, + Anum_pg_constraint_conrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(rel)), OIDOID); conscan = systable_beginscan(conrel, ConstraintRelidIndex, true, SnapshotNow, 1, key); @@ -1876,17 +1883,19 @@ RemoveStatistics(Relation rel, AttrNumber attnum) pgstatistic = heap_openr(StatisticRelationName, RowExclusiveLock); - ScanKeyEntryInitialize(&key[0], 0x0, - Anum_pg_statistic_starelid, F_OIDEQ, - ObjectIdGetDatum(RelationGetRelid(rel))); + ScanKeyEntryInitialize(&key[0], 0, + Anum_pg_statistic_starelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(rel)), OIDOID); if (attnum == 0) nkeys = 1; else { - ScanKeyEntryInitialize(&key[1], 0x0, - Anum_pg_statistic_staattnum, F_INT2EQ, - Int16GetDatum(attnum)); + ScanKeyEntryInitialize(&key[1], 0, + Anum_pg_statistic_staattnum, + BTEqualStrategyNumber, F_INT2EQ, + Int16GetDatum(attnum), INT2OID); nkeys = 2; } @@ -2043,8 +2052,8 @@ heap_truncate_check_FKs(Relation rel) ScanKeyEntryInitialize(&key, 0, Anum_pg_constraint_confrelid, - F_OIDEQ, - ObjectIdGetDatum(relid)); + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(relid), OIDOID); fkeyScan = systable_beginscan(fkeyRel, NULL, false, SnapshotNow, 1, &key); diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index ccf52248260..67f970c55d7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.219 2003/09/29 00:05:24 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.220 2003/11/09 21:30:36 tgl Exp $ * * * INTERFACE ROUTINES @@ -25,7 +25,6 @@ #include "access/genam.h" #include "access/heapam.h" -#include "access/istrat.h" #include "bootstrap/bootstrap.h" #include "catalog/catalog.h" #include "catalog/catname.h" @@ -995,8 +994,8 @@ setRelhasindex(Oid relid, bool hasindex, bool isprimary, Oid reltoastidxid) ScanKeyEntryInitialize(&key[0], 0, ObjectIdAttributeNumber, - F_OIDEQ, - ObjectIdGetDatum(relid)); + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(relid), OIDOID); pg_class_scan = heap_beginscan(pg_class, SnapshotNow, 1, key); tuple = heap_getnext(pg_class_scan, ForwardScanDirection); @@ -1198,8 +1197,8 @@ UpdateStats(Oid relid, double reltuples) ScanKeyEntryInitialize(&key[0], 0, ObjectIdAttributeNumber, - F_OIDEQ, - ObjectIdGetDatum(relid)); + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(relid), OIDOID); pg_class_scan = heap_beginscan(pg_class, SnapshotNow, 1, key); tuple = heap_getnext(pg_class_scan, ForwardScanDirection); diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c index a985dfcd927..0fa665a568d 100644 --- a/src/backend/catalog/pg_constraint.c +++ b/src/backend/catalog/pg_constraint.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/pg_constraint.c,v 1.16 2003/08/04 02:39:58 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/pg_constraint.c,v 1.17 2003/11/09 21:30:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -281,13 +281,15 @@ ConstraintNameIsUsed(CONSTRAINTCATEGORY conCat, Oid objId, Oid objNamespace, con found = false; - ScanKeyEntryInitialize(&skey[0], 0x0, - Anum_pg_constraint_conname, F_NAMEEQ, - CStringGetDatum(cname)); + ScanKeyEntryInitialize(&skey[0], 0, + Anum_pg_constraint_conname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(cname), NAMEOID); - ScanKeyEntryInitialize(&skey[1], 0x0, - Anum_pg_constraint_connamespace, F_OIDEQ, - ObjectIdGetDatum(objNamespace)); + ScanKeyEntryInitialize(&skey[1], 0, + Anum_pg_constraint_connamespace, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(objNamespace), OIDOID); conscan = systable_beginscan(conDesc, ConstraintNameNspIndex, true, SnapshotNow, 2, skey); @@ -353,13 +355,15 @@ GenerateConstraintName(CONSTRAINTCATEGORY conCat, Oid objId, Oid objNamespace, i */ found = false; - ScanKeyEntryInitialize(&skey[0], 0x0, - Anum_pg_constraint_conname, F_NAMEEQ, - CStringGetDatum(cname)); + ScanKeyEntryInitialize(&skey[0], 0, + Anum_pg_constraint_conname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(cname), NAMEOID); - ScanKeyEntryInitialize(&skey[1], 0x0, - Anum_pg_constraint_connamespace, F_OIDEQ, - ObjectIdGetDatum(objNamespace)); + ScanKeyEntryInitialize(&skey[1], 0, + Anum_pg_constraint_connamespace, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(objNamespace), OIDOID); conscan = systable_beginscan(conDesc, ConstraintNameNspIndex, true, SnapshotNow, 2, skey); @@ -418,9 +422,10 @@ RemoveConstraintById(Oid conId) conDesc = heap_openr(ConstraintRelationName, RowExclusiveLock); - ScanKeyEntryInitialize(&skey[0], 0x0, - ObjectIdAttributeNumber, F_OIDEQ, - ObjectIdGetDatum(conId)); + ScanKeyEntryInitialize(&skey[0], 0, + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(conId), OIDOID); conscan = systable_beginscan(conDesc, ConstraintOidIndex, true, SnapshotNow, 1, skey); diff --git a/src/backend/catalog/pg_conversion.c b/src/backend/catalog/pg_conversion.c index b059b429be0..709f50f2a5d 100644 --- a/src/backend/catalog/pg_conversion.c +++ b/src/backend/catalog/pg_conversion.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/pg_conversion.c,v 1.15 2003/08/04 02:39:58 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/pg_conversion.c,v 1.16 2003/11/09 21:30:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -21,6 +21,7 @@ #include "catalog/pg_class.h" #include "catalog/pg_conversion.h" #include "catalog/namespace.h" +#include "catalog/pg_type.h" #include "utils/builtins.h" #include "utils/lsyscache.h" #include "utils/syscache.h" @@ -176,11 +177,10 @@ RemoveConversionById(Oid conversionOid) HeapScanDesc scan; ScanKeyData scanKeyData; - ScanKeyEntryInitialize(&scanKeyData, - 0, + ScanKeyEntryInitialize(&scanKeyData, 0, ObjectIdAttributeNumber, - F_OIDEQ, - ObjectIdGetDatum(conversionOid)); + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(conversionOid), OIDOID); /* open pg_conversion */ rel = heap_openr(ConversionRelationName, RowExclusiveLock); diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c index 84f54fcfabb..21eeb3e6543 100644 --- a/src/backend/catalog/pg_depend.c +++ b/src/backend/catalog/pg_depend.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/pg_depend.c,v 1.7 2003/08/04 02:39:58 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/pg_depend.c,v 1.8 2003/11/09 21:30:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -20,6 +20,7 @@ #include "catalog/indexing.h" #include "catalog/dependency.h" #include "catalog/pg_depend.h" +#include "catalog/pg_type.h" #include "miscadmin.h" #include "utils/fmgroids.h" @@ -138,12 +139,14 @@ deleteDependencyRecordsFor(Oid classId, Oid objectId) depRel = heap_openr(DependRelationName, RowExclusiveLock); - ScanKeyEntryInitialize(&key[0], 0x0, - Anum_pg_depend_classid, F_OIDEQ, - ObjectIdGetDatum(classId)); - ScanKeyEntryInitialize(&key[1], 0x0, - Anum_pg_depend_objid, F_OIDEQ, - ObjectIdGetDatum(objectId)); + ScanKeyEntryInitialize(&key[0], 0, + Anum_pg_depend_classid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(classId), OIDOID); + ScanKeyEntryInitialize(&key[1], 0, + Anum_pg_depend_objid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(objectId), OIDOID); scan = systable_beginscan(depRel, DependDependerIndex, true, SnapshotNow, 2, key); @@ -178,13 +181,15 @@ isObjectPinned(const ObjectAddress *object, Relation rel) HeapTuple tup; ScanKeyData key[2]; - ScanKeyEntryInitialize(&key[0], 0x0, - Anum_pg_depend_refclassid, F_OIDEQ, - ObjectIdGetDatum(object->classId)); + ScanKeyEntryInitialize(&key[0], 0, + Anum_pg_depend_refclassid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(object->classId), OIDOID); - ScanKeyEntryInitialize(&key[1], 0x0, - Anum_pg_depend_refobjid, F_OIDEQ, - ObjectIdGetDatum(object->objectId)); + ScanKeyEntryInitialize(&key[1], 0, + Anum_pg_depend_refobjid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(object->objectId), OIDOID); scan = systable_beginscan(rel, DependReferenceIndex, true, SnapshotNow, 2, key); diff --git a/src/backend/catalog/pg_largeobject.c b/src/backend/catalog/pg_largeobject.c index 85025671699..96f73056cf2 100644 --- a/src/backend/catalog/pg_largeobject.c +++ b/src/backend/catalog/pg_largeobject.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/pg_largeobject.c,v 1.17 2003/09/24 18:54:01 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/pg_largeobject.c,v 1.18 2003/11/09 21:30:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -19,6 +19,7 @@ #include "catalog/catname.h" #include "catalog/indexing.h" #include "catalog/pg_largeobject.h" +#include "catalog/pg_type.h" #include "miscadmin.h" #include "utils/builtins.h" #include "utils/fmgroids.h" @@ -81,10 +82,10 @@ LargeObjectDrop(Oid loid) SysScanDesc sd; HeapTuple tuple; - ScanKeyEntryInitialize(&skey[0], 0x0, - (AttrNumber) Anum_pg_largeobject_loid, - (RegProcedure) F_OIDEQ, - ObjectIdGetDatum(loid)); + ScanKeyEntryInitialize(&skey[0], 0, + Anum_pg_largeobject_loid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(loid), OIDOID); pg_largeobject = heap_openr(LargeObjectRelationName, RowExclusiveLock); @@ -119,10 +120,10 @@ LargeObjectExists(Oid loid) /* * See if we can find any tuples belonging to the specified LO */ - ScanKeyEntryInitialize(&skey[0], 0x0, - (AttrNumber) Anum_pg_largeobject_loid, - (RegProcedure) F_OIDEQ, - ObjectIdGetDatum(loid)); + ScanKeyEntryInitialize(&skey[0], 0, + Anum_pg_largeobject_loid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(loid), OIDOID); pg_largeobject = heap_openr(LargeObjectRelationName, AccessShareLock); diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index f0dde27bb17..2cda1f94a97 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.102 2003/10/16 16:50:41 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.103 2003/11/09 21:30:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -80,6 +80,7 @@ #include "access/heapam.h" #include "catalog/catname.h" #include "catalog/pg_listener.h" +#include "catalog/pg_type.h" #include "commands/async.h" #include "libpq/libpq.h" #include "libpq/pqformat.h" @@ -354,8 +355,8 @@ Async_UnlistenAll(void) /* Find and delete all entries with my listenerPID */ ScanKeyEntryInitialize(&key[0], 0, Anum_pg_listener_pid, - F_INT4EQ, - Int32GetDatum(MyProcPid)); + BTEqualStrategyNumber, F_INT4EQ, + Int32GetDatum(MyProcPid), INT4OID); scan = heap_beginscan(lRel, SnapshotNow, 1, key); while ((lTuple = heap_getnext(scan, ForwardScanDirection)) != NULL) @@ -818,8 +819,8 @@ ProcessIncomingNotify(void) /* Scan only entries with my listenerPID */ ScanKeyEntryInitialize(&key[0], 0, Anum_pg_listener_pid, - F_INT4EQ, - Int32GetDatum(MyProcPid)); + BTEqualStrategyNumber, F_INT4EQ, + Int32GetDatum(MyProcPid), INT4OID); scan = heap_beginscan(lRel, SnapshotNow, 1, key); /* Prepare data for rewriting 0 into notification field */ diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index a3f9ae8aac7..780a60f7966 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.116 2003/09/25 06:57:58 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.117 2003/11/09 21:30:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -26,6 +26,7 @@ #include "catalog/index.h" #include "catalog/indexing.h" #include "catalog/namespace.h" +#include "catalog/pg_type.h" #include "commands/cluster.h" #include "commands/tablecmds.h" #include "miscadmin.h" @@ -880,8 +881,8 @@ get_tables_to_cluster(MemoryContext cluster_context) indRelation = relation_openr(IndexRelationName, AccessShareLock); ScanKeyEntryInitialize(&entry, 0, Anum_pg_index_indisclustered, - F_BOOLEQ, - BoolGetDatum(true)); + BTEqualStrategyNumber, F_BOOLEQ, + BoolGetDatum(true), BOOLOID); scan = heap_beginscan(indRelation, SnapshotNow, 1, &entry); while ((indexTuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c index e133ef5dd28..fbce38ca577 100644 --- a/src/backend/commands/comment.c +++ b/src/backend/commands/comment.c @@ -7,7 +7,7 @@ * Copyright (c) 1996-2003, PostgreSQL Global Development Group * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.71 2003/09/25 06:57:58 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.72 2003/11/09 21:30:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -156,23 +156,18 @@ CreateComments(Oid oid, Oid classoid, int32 subid, char *comment) /* Use the index to search for a matching old tuple */ - ScanKeyEntryInitialize(&skey[0], - (bits16) 0x0, - (AttrNumber) 1, - (RegProcedure) F_OIDEQ, - ObjectIdGetDatum(oid)); - - ScanKeyEntryInitialize(&skey[1], - (bits16) 0x0, - (AttrNumber) 2, - (RegProcedure) F_OIDEQ, - ObjectIdGetDatum(classoid)); - - ScanKeyEntryInitialize(&skey[2], - (bits16) 0x0, - (AttrNumber) 3, - (RegProcedure) F_INT4EQ, - Int32GetDatum(subid)); + ScanKeyEntryInitialize(&skey[0], 0, + Anum_pg_description_objoid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(oid), OIDOID); + ScanKeyEntryInitialize(&skey[1], 0, + Anum_pg_description_classoid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(classoid), OIDOID); + ScanKeyEntryInitialize(&skey[2], 0, + Anum_pg_description_objsubid, + BTEqualStrategyNumber, F_INT4EQ, + Int32GetDatum(subid), INT4OID); description = heap_openr(DescriptionRelationName, RowExclusiveLock); @@ -236,19 +231,21 @@ DeleteComments(Oid oid, Oid classoid, int32 subid) /* Use the index to search for all matching old tuples */ - ScanKeyEntryInitialize(&skey[0], 0x0, - Anum_pg_description_objoid, F_OIDEQ, - ObjectIdGetDatum(oid)); - - ScanKeyEntryInitialize(&skey[1], 0x0, - Anum_pg_description_classoid, F_OIDEQ, - ObjectIdGetDatum(classoid)); + ScanKeyEntryInitialize(&skey[0], 0, + Anum_pg_description_objoid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(oid), OIDOID); + ScanKeyEntryInitialize(&skey[1], 0, + Anum_pg_description_classoid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(classoid), OIDOID); if (subid != 0) { - ScanKeyEntryInitialize(&skey[2], 0x0, - Anum_pg_description_objsubid, F_INT4EQ, - Int32GetDatum(subid)); + ScanKeyEntryInitialize(&skey[2], 0, + Anum_pg_description_objsubid, + BTEqualStrategyNumber, F_INT4EQ, + Int32GetDatum(subid), INT4OID); nkeys = 3; } else @@ -541,11 +538,10 @@ CommentRule(List *qualname, char *comment) rulename = strVal(lfirst(qualname)); /* Search pg_rewrite for such a rule */ - ScanKeyEntryInitialize(&scanKeyData, - 0, + ScanKeyEntryInitialize(&scanKeyData, 0, Anum_pg_rewrite_rulename, - F_NAMEEQ, - PointerGetDatum(rulename)); + BTEqualStrategyNumber, F_NAMEEQ, + PointerGetDatum(rulename), NAMEOID); RewriteRelation = heap_openr(RewriteRelationName, AccessShareLock); scanDesc = heap_beginscan(RewriteRelation, SnapshotNow, @@ -795,14 +791,15 @@ CommentTrigger(List *qualname, char *comment) * because of the unique index. */ pg_trigger = heap_openr(TriggerRelationName, AccessShareLock); - ScanKeyEntryInitialize(&entry[0], 0x0, + ScanKeyEntryInitialize(&entry[0], 0, Anum_pg_trigger_tgrelid, - F_OIDEQ, - ObjectIdGetDatum(RelationGetRelid(relation))); - ScanKeyEntryInitialize(&entry[1], 0x0, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(relation)), + OIDOID); + ScanKeyEntryInitialize(&entry[1], 0, Anum_pg_trigger_tgname, - F_NAMEEQ, - CStringGetDatum(trigname)); + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(trigname), NAMEOID); scan = systable_beginscan(pg_trigger, TriggerRelidNameIndex, true, SnapshotNow, 2, entry); triggertuple = systable_getnext(scan); @@ -875,9 +872,11 @@ CommentConstraint(List *qualname, char *comment) */ pg_constraint = heap_openr(ConstraintRelationName, AccessShareLock); - ScanKeyEntryInitialize(&skey[0], 0x0, - Anum_pg_constraint_conrelid, F_OIDEQ, - ObjectIdGetDatum(RelationGetRelid(relation))); + ScanKeyEntryInitialize(&skey[0], 0, + Anum_pg_constraint_conrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(relation)), + OIDOID); scan = systable_beginscan(pg_constraint, ConstraintRelidIndex, true, SnapshotNow, 1, skey); diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index bc34adfcf37..5ac51bc84d3 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.124 2003/09/29 00:05:24 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.125 2003/11/09 21:30:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -27,6 +27,7 @@ #include "catalog/pg_database.h" #include "catalog/pg_shadow.h" #include "catalog/indexing.h" +#include "catalog/pg_type.h" #include "commands/comment.h" #include "commands/dbcommands.h" #include "miscadmin.h" @@ -530,10 +531,13 @@ dropdb(const char *dbname) /* * Find the database's tuple by OID (should be unique). */ - ScanKeyEntryInitialize(&key, 0, ObjectIdAttributeNumber, - F_OIDEQ, ObjectIdGetDatum(db_id)); + ScanKeyEntryInitialize(&key, 0, + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(db_id), OIDOID); - pgdbscan = systable_beginscan(pgdbrel, DatabaseOidIndex, true, SnapshotNow, 1, &key); + pgdbscan = systable_beginscan(pgdbrel, DatabaseOidIndex, true, + SnapshotNow, 1, &key); tup = systable_getnext(pgdbscan); if (!HeapTupleIsValid(tup)) @@ -612,9 +616,12 @@ RenameDatabase(const char *oldname, const char *newname) */ rel = heap_openr(DatabaseRelationName, AccessExclusiveLock); - ScanKeyEntryInitialize(&key, 0, Anum_pg_database_datname, - F_NAMEEQ, NameGetDatum(oldname)); - scan = systable_beginscan(rel, DatabaseNameIndex, true, SnapshotNow, 1, &key); + ScanKeyEntryInitialize(&key, 0, + Anum_pg_database_datname, + BTEqualStrategyNumber, F_NAMEEQ, + NameGetDatum(oldname), NAMEOID); + scan = systable_beginscan(rel, DatabaseNameIndex, true, + SnapshotNow, 1, &key); tup = systable_getnext(scan); if (!HeapTupleIsValid(tup)) @@ -644,9 +651,12 @@ RenameDatabase(const char *oldname, const char *newname) oldname))); /* make sure the new name doesn't exist */ - ScanKeyEntryInitialize(&key2, 0, Anum_pg_database_datname, - F_NAMEEQ, NameGetDatum(newname)); - scan2 = systable_beginscan(rel, DatabaseNameIndex, true, SnapshotNow, 1, &key2); + ScanKeyEntryInitialize(&key2, 0, + Anum_pg_database_datname, + BTEqualStrategyNumber, F_NAMEEQ, + NameGetDatum(newname), NAMEOID); + scan2 = systable_beginscan(rel, DatabaseNameIndex, true, + SnapshotNow, 1, &key2); if (HeapTupleIsValid(systable_getnext(scan2))) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_DATABASE), @@ -702,9 +712,12 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt) valuestr = flatten_set_variable_args(stmt->variable, stmt->value); rel = heap_openr(DatabaseRelationName, RowExclusiveLock); - ScanKeyEntryInitialize(&scankey, 0, Anum_pg_database_datname, - F_NAMEEQ, NameGetDatum(stmt->dbname)); - scan = systable_beginscan(rel, DatabaseNameIndex, true, SnapshotNow, 1, &scankey); + ScanKeyEntryInitialize(&scankey, 0, + Anum_pg_database_datname, + BTEqualStrategyNumber, F_NAMEEQ, + NameGetDatum(stmt->dbname), NAMEOID); + scan = systable_beginscan(rel, DatabaseNameIndex, true, + SnapshotNow, 1, &scankey); tuple = systable_getnext(scan); if (!HeapTupleIsValid(tuple)) ereport(ERROR, @@ -782,10 +795,13 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP, /* Caller may wish to grab a better lock on pg_database beforehand... */ relation = heap_openr(DatabaseRelationName, AccessShareLock); - ScanKeyEntryInitialize(&scanKey, 0, Anum_pg_database_datname, - F_NAMEEQ, NameGetDatum(name)); + ScanKeyEntryInitialize(&scanKey, 0, + Anum_pg_database_datname, + BTEqualStrategyNumber, F_NAMEEQ, + NameGetDatum(name), NAMEOID); - scan = systable_beginscan(relation, DatabaseNameIndex, true, SnapshotNow, 1, &scanKey); + scan = systable_beginscan(relation, DatabaseNameIndex, true, + SnapshotNow, 1, &scanKey); tuple = systable_getnext(scan); @@ -985,10 +1001,12 @@ get_database_oid(const char *dbname) /* There's no syscache for pg_database, so must look the hard way */ pg_database = heap_openr(DatabaseRelationName, AccessShareLock); - ScanKeyEntryInitialize(&entry[0], 0x0, - Anum_pg_database_datname, F_NAMEEQ, - CStringGetDatum(dbname)); - scan = systable_beginscan(pg_database, DatabaseNameIndex, true, SnapshotNow, 1, entry); + ScanKeyEntryInitialize(&entry[0], 0, + Anum_pg_database_datname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(dbname), NAMEOID); + scan = systable_beginscan(pg_database, DatabaseNameIndex, true, + SnapshotNow, 1, entry); dbtuple = systable_getnext(scan); @@ -1023,10 +1041,12 @@ get_database_name(Oid dbid) /* There's no syscache for pg_database, so must look the hard way */ pg_database = heap_openr(DatabaseRelationName, AccessShareLock); - ScanKeyEntryInitialize(&entry[0], 0x0, - ObjectIdAttributeNumber, F_OIDEQ, - ObjectIdGetDatum(dbid)); - scan = systable_beginscan(pg_database, DatabaseOidIndex, true, SnapshotNow, 1, entry); + ScanKeyEntryInitialize(&entry[0], 0, + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(dbid), OIDOID); + scan = systable_beginscan(pg_database, DatabaseOidIndex, true, + SnapshotNow, 1, entry); dbtuple = systable_getnext(scan); diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index 35ab80c09a7..9e1e0746f55 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.38 2003/10/02 06:34:03 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.39 2003/11/09 21:30:36 tgl Exp $ * * DESCRIPTION * These routines take the parse tree and pick out the @@ -1097,10 +1097,10 @@ DropCastById(Oid castOid) relation = heap_openr(CastRelationName, RowExclusiveLock); - ScanKeyEntryInitialize(&scankey, 0x0, + ScanKeyEntryInitialize(&scankey, 0, ObjectIdAttributeNumber, - F_OIDEQ, - ObjectIdGetDatum(castOid)); + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(castOid), OIDOID); scan = systable_beginscan(relation, CastOidIndex, true, SnapshotNow, 1, &scankey); diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c index c183d7ad5bc..599d2eb8259 100644 --- a/src/backend/commands/opclasscmds.c +++ b/src/backend/commands/opclasscmds.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/opclasscmds.c,v 1.21 2003/09/26 15:27:31 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/opclasscmds.c,v 1.22 2003/11/09 21:30:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -25,6 +25,7 @@ #include "catalog/pg_amop.h" #include "catalog/pg_amproc.h" #include "catalog/pg_opclass.h" +#include "catalog/pg_type.h" #include "commands/defrem.h" #include "miscadmin.h" #include "parser/parse_func.h" @@ -270,9 +271,10 @@ DefineOpClass(CreateOpClassStmt *stmt) ScanKeyData skey[1]; SysScanDesc scan; - ScanKeyEntryInitialize(&skey[0], 0x0, - Anum_pg_opclass_opcamid, F_OIDEQ, - ObjectIdGetDatum(amoid)); + ScanKeyEntryInitialize(&skey[0], 0, + Anum_pg_opclass_opcamid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(amoid), OIDOID); scan = systable_beginscan(rel, OpclassAmNameNspIndex, true, SnapshotNow, 1, skey); @@ -589,8 +591,9 @@ RemoveOpClassById(Oid opclassOid) * Remove associated entries in pg_amop. */ ScanKeyEntryInitialize(&skey[0], 0, - Anum_pg_amop_amopclaid, F_OIDEQ, - ObjectIdGetDatum(opclassOid)); + Anum_pg_amop_amopclaid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(opclassOid), OIDOID); rel = heap_openr(AccessMethodOperatorRelationName, RowExclusiveLock); @@ -607,8 +610,9 @@ RemoveOpClassById(Oid opclassOid) * Remove associated entries in pg_amproc. */ ScanKeyEntryInitialize(&skey[0], 0, - Anum_pg_amproc_amopclaid, F_OIDEQ, - ObjectIdGetDatum(opclassOid)); + Anum_pg_amproc_amopclaid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(opclassOid), OIDOID); rel = heap_openr(AccessMethodProcedureRelationName, RowExclusiveLock); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index b77faed0d3e..df441ca476c 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.91 2003/10/13 22:47:15 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.92 2003/11/09 21:30:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1393,20 +1393,20 @@ update_ri_trigger_args(Oid relid, tgrel = heap_openr(TriggerRelationName, RowExclusiveLock); if (fk_scan) { - ScanKeyEntryInitialize(&skey[0], 0x0, + ScanKeyEntryInitialize(&skey[0], 0, Anum_pg_trigger_tgconstrrelid, - F_OIDEQ, - ObjectIdGetDatum(relid)); + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(relid), OIDOID); trigscan = systable_beginscan(tgrel, TriggerConstrRelidIndex, true, SnapshotNow, 1, skey); } else { - ScanKeyEntryInitialize(&skey[0], 0x0, + ScanKeyEntryInitialize(&skey[0], 0, Anum_pg_trigger_tgrelid, - F_OIDEQ, - ObjectIdGetDatum(relid)); + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(relid), OIDOID); trigscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true, SnapshotNow, 1, skey); diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 9a603a6f042..80225f8f25f 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.160 2003/11/06 22:08:14 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.161 2003/11/09 21:30:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -255,8 +255,8 @@ CreateTrigger(CreateTrigStmt *stmt, bool forConstraint) tgrel = heap_openr(TriggerRelationName, RowExclusiveLock); ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgrelid, - F_OIDEQ, - ObjectIdGetDatum(RelationGetRelid(rel))); + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(rel)), OIDOID); tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true, SnapshotNow, 1, &key); while (HeapTupleIsValid(tuple = systable_getnext(tgscan))) @@ -465,13 +465,15 @@ DropTrigger(Oid relid, const char *trigname, DropBehavior behavior) */ tgrel = heap_openr(TriggerRelationName, AccessShareLock); - ScanKeyEntryInitialize(&skey[0], 0x0, - Anum_pg_trigger_tgrelid, F_OIDEQ, - ObjectIdGetDatum(relid)); + ScanKeyEntryInitialize(&skey[0], 0, + Anum_pg_trigger_tgrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(relid), OIDOID); - ScanKeyEntryInitialize(&skey[1], 0x0, - Anum_pg_trigger_tgname, F_NAMEEQ, - CStringGetDatum(trigname)); + ScanKeyEntryInitialize(&skey[1], 0, + Anum_pg_trigger_tgname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(trigname), NAMEOID); tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true, SnapshotNow, 2, skey); @@ -522,9 +524,10 @@ RemoveTriggerById(Oid trigOid) /* * Find the trigger to delete. */ - ScanKeyEntryInitialize(&skey[0], 0x0, - ObjectIdAttributeNumber, F_OIDEQ, - ObjectIdGetDatum(trigOid)); + ScanKeyEntryInitialize(&skey[0], 0, + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(trigOid), OIDOID); tgscan = systable_beginscan(tgrel, TriggerOidIndex, true, SnapshotNow, 1, skey); @@ -640,12 +643,12 @@ renametrig(Oid relid, */ ScanKeyEntryInitialize(&key[0], 0, Anum_pg_trigger_tgrelid, - F_OIDEQ, - ObjectIdGetDatum(relid)); + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(relid), OIDOID); ScanKeyEntryInitialize(&key[1], 0, Anum_pg_trigger_tgname, - F_NAMEEQ, - PointerGetDatum(newname)); + BTEqualStrategyNumber, F_NAMEEQ, + PointerGetDatum(newname), NAMEOID); tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true, SnapshotNow, 2, key); if (HeapTupleIsValid(tuple = systable_getnext(tgscan))) @@ -660,12 +663,12 @@ renametrig(Oid relid, */ ScanKeyEntryInitialize(&key[0], 0, Anum_pg_trigger_tgrelid, - F_OIDEQ, - ObjectIdGetDatum(relid)); + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(relid), OIDOID); ScanKeyEntryInitialize(&key[1], 0, Anum_pg_trigger_tgname, - F_NAMEEQ, - PointerGetDatum(oldname)); + BTEqualStrategyNumber, F_NAMEEQ, + PointerGetDatum(oldname), NAMEOID); tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true, SnapshotNow, 2, key); if (HeapTupleIsValid(tuple = systable_getnext(tgscan))) @@ -741,11 +744,11 @@ RelationBuildTriggers(Relation relation) * emergency-recovery operations (ie, IsIgnoringSystemIndexes). This * in turn ensures that triggers will be fired in name order. */ - ScanKeyEntryInitialize(&skey, - (bits16) 0x0, - (AttrNumber) Anum_pg_trigger_tgrelid, - (RegProcedure) F_OIDEQ, - ObjectIdGetDatum(RelationGetRelid(relation))); + ScanKeyEntryInitialize(&skey, 0, + Anum_pg_trigger_tgrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(relation)), + OIDOID); tgrel = heap_openr(TriggerRelationName, AccessShareLock); tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true, @@ -2259,10 +2262,10 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt) /* * Setup to scan pg_trigger by tgconstrname ... */ - ScanKeyEntryInitialize(&skey, (bits16) 0x0, - (AttrNumber) Anum_pg_trigger_tgconstrname, - (RegProcedure) F_NAMEEQ, - PointerGetDatum(cname)); + ScanKeyEntryInitialize(&skey, 0, + Anum_pg_trigger_tgconstrname, + BTEqualStrategyNumber, F_NAMEEQ, + PointerGetDatum(cname), NAMEOID); tgscan = systable_beginscan(tgrel, TriggerConstrNameIndex, true, SnapshotNow, 1, &skey); diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index e6d1b5c50b2..17b4df92179 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.48 2003/10/02 06:34:03 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.49 2003/11/09 21:30:36 tgl Exp $ * * DESCRIPTION * The "DefineFoo" routines take the parse tree and pick out the @@ -1362,9 +1362,10 @@ AlterDomainDropConstraint(List *names, const char *constrName, DropBehavior beha conrel = heap_openr(ConstraintRelationName, RowExclusiveLock); /* Use the index to scan only constraints of the target relation */ - ScanKeyEntryInitialize(&key[0], 0x0, - Anum_pg_constraint_contypid, F_OIDEQ, - ObjectIdGetDatum(HeapTupleGetOid(tup))); + ScanKeyEntryInitialize(&key[0], 0, + Anum_pg_constraint_contypid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(HeapTupleGetOid(tup)), OIDOID); conscan = systable_beginscan(conrel, ConstraintTypidIndex, true, SnapshotNow, 1, key); @@ -1614,12 +1615,14 @@ get_rels_with_domain(Oid domainOid, LOCKMODE lockmode) */ depRel = relation_openr(DependRelationName, AccessShareLock); - ScanKeyEntryInitialize(&key[0], 0x0, - Anum_pg_depend_refclassid, F_OIDEQ, - ObjectIdGetDatum(RelOid_pg_type)); - ScanKeyEntryInitialize(&key[1], 0x0, - Anum_pg_depend_refobjid, F_OIDEQ, - ObjectIdGetDatum(domainOid)); + ScanKeyEntryInitialize(&key[0], 0, + Anum_pg_depend_refclassid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelOid_pg_type), OIDOID); + ScanKeyEntryInitialize(&key[1], 0, + Anum_pg_depend_refobjid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(domainOid), OIDOID); depScan = systable_beginscan(depRel, DependReferenceIndex, true, SnapshotNow, 2, key); @@ -1898,9 +1901,10 @@ GetDomainConstraints(Oid typeOid) notNull = true; /* Look for CHECK Constraints on this domain */ - ScanKeyEntryInitialize(&key[0], 0x0, - Anum_pg_constraint_contypid, F_OIDEQ, - ObjectIdGetDatum(typeOid)); + ScanKeyEntryInitialize(&key[0], 0, + Anum_pg_constraint_contypid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(typeOid), OIDOID); scan = systable_beginscan(conRel, ConstraintTypidIndex, true, SnapshotNow, 1, key); diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index 13e80283ff2..4fad67f43a3 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.128 2003/10/02 06:36:37 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.129 2003/11/09 21:30:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1074,9 +1074,10 @@ DropUser(DropUserStmt *stmt) pg_rel = heap_openr(DatabaseRelationName, AccessShareLock); pg_dsc = RelationGetDescr(pg_rel); - ScanKeyEntryInitialize(&scankey, 0x0, - Anum_pg_database_datdba, F_INT4EQ, - Int32GetDatum(usesysid)); + ScanKeyEntryInitialize(&scankey, 0, + Anum_pg_database_datdba, + BTEqualStrategyNumber, F_INT4EQ, + Int32GetDatum(usesysid), INT4OID); scan = heap_beginscan(pg_rel, SnapshotNow, 1, &scankey); diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 8011567f66a..a4d6de2282c 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -13,7 +13,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.263 2003/10/02 23:19:44 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.264 2003/11/09 21:30:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -30,6 +30,7 @@ #include "catalog/namespace.h" #include "catalog/pg_database.h" #include "catalog/pg_index.h" +#include "catalog/pg_type.h" #include "commands/vacuum.h" #include "executor/executor.h" #include "miscadmin.h" @@ -399,10 +400,10 @@ getrels(const RangeVar *vacrel, const char *stmttype) HeapTuple tuple; ScanKeyData key; - ScanKeyEntryInitialize(&key, 0x0, + ScanKeyEntryInitialize(&key, 0, Anum_pg_class_relkind, - F_CHAREQ, - CharGetDatum(RELKIND_RELATION)); + BTEqualStrategyNumber, F_CHAREQ, + CharGetDatum(RELKIND_RELATION), CHAROID); pgclass = heap_openr(RelationRelationName, AccessShareLock); @@ -582,9 +583,10 @@ vac_update_dbstats(Oid dbid, relation = heap_openr(DatabaseRelationName, RowExclusiveLock); /* Must use a heap scan, since there's no syscache for pg_database */ - ScanKeyEntryInitialize(&entry[0], 0x0, - ObjectIdAttributeNumber, F_OIDEQ, - ObjectIdGetDatum(dbid)); + ScanKeyEntryInitialize(&entry[0], 0, + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(dbid), OIDOID); scan = heap_beginscan(relation, SnapshotNow, 1, entry); diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c index 6ab2f0a47bd..54114ad9245 100644 --- a/src/backend/executor/nodeIndexscan.c +++ b/src/backend/executor/nodeIndexscan.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.84 2003/09/24 18:54:01 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.85 2003/11/09 21:30:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -31,13 +31,10 @@ #include "miscadmin.h" #include "nodes/nodeFuncs.h" #include "optimizer/clauses.h" +#include "parser/parse_expr.h" #include "parser/parsetree.h" -#define NO_OP 0 -#define LEFT_OP 1 -#define RIGHT_OP 2 - /* * In a multiple-index plan, we must take care to return any given tuple * only once, even if it matches conditions of several index scans. Our @@ -617,8 +614,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate) { IndexScanState *indexstate; List *indxqual; + List *indxstrategy; List *indxid; - List *listscan; int i; int numIndices; int indexPtr; @@ -713,46 +710,49 @@ ExecInitIndexScan(IndexScan *node, EState *estate) * build the index scan keys from the index qualification */ indxqual = node->indxqual; + indxstrategy = node->indxstrategy; for (i = 0; i < numIndices; i++) { - int j; - List *qual; + List *quals; + List *strategies; int n_keys; ScanKey scan_keys; ExprState **run_keys; + int j; - qual = lfirst(indxqual); + quals = lfirst(indxqual); indxqual = lnext(indxqual); - n_keys = length(qual); + strategies = lfirst(indxstrategy); + indxstrategy = lnext(indxstrategy); + n_keys = length(quals); scan_keys = (n_keys <= 0) ? (ScanKey) NULL : (ScanKey) palloc(n_keys * sizeof(ScanKeyData)); run_keys = (n_keys <= 0) ? (ExprState **) NULL : (ExprState **) palloc(n_keys * sizeof(ExprState *)); - CXT1_printf("ExecInitIndexScan: context is %d\n", CurrentMemoryContext); - /* * for each opclause in the given qual, convert each qual's * opclause into a single scan key */ - listscan = qual; for (j = 0; j < n_keys; j++) { - OpExpr *clause; /* one clause of index qual */ - Expr *leftop; /* expr on lhs of operator */ - Expr *rightop; /* expr on rhs ... */ - bits16 flags = 0; - - int scanvar; /* which var identifies varattno */ - AttrNumber varattno = 0; /* att number used in scan */ - Oid opfuncid; /* operator id used in scan */ - Datum scanvalue = 0; /* value used in scan (if const) */ + OpExpr *clause; /* one clause of index qual */ + Expr *leftop; /* expr on lhs of operator */ + Expr *rightop; /* expr on rhs ... */ + int flags = 0; + AttrNumber varattno; /* att number used in scan */ + StrategyNumber strategy; /* op's strategy number */ + RegProcedure opfuncid; /* operator proc id used in scan */ + Datum scanvalue; /* value used in scan (if const) */ + Oid rhstype; /* datatype of comparison value */ /* * extract clause information from the qualification */ - clause = (OpExpr *) lfirst(listscan); - listscan = lnext(listscan); + clause = (OpExpr *) lfirst(quals); + quals = lnext(quals); + strategy = lfirsti(strategies); + strategies = lnext(strategies); if (!IsA(clause, OpExpr)) elog(ERROR, "indxqual is not an OpExpr"); @@ -761,40 +761,17 @@ ExecInitIndexScan(IndexScan *node, EState *estate) /* * Here we figure out the contents of the index qual. The - * usual case is (var op const) or (const op var) which means - * we form a scan key for the attribute listed in the var node - * and use the value of the const. + * usual case is (var op const) which means we form a scan key + * for the attribute listed in the var node and use the value of + * the const as comparison data. * - * If we don't have a const node, then it means that one of the - * var nodes refers to the "scan" tuple and is used to - * determine which attribute to scan, and the other expression - * is used to calculate the value used in scanning the index. - * - * This means our index scan's scan key is a function of - * information obtained during the execution of the plan in - * which case we need to recalculate the index scan key at run - * time. - * - * Hence, we set have_runtime_keys to true and place the - * appropriate subexpression in run_keys. The corresponding + * If we don't have a const node, it means our scan key is a + * function of information obtained during the execution of the + * plan, in which case we need to recalculate the index scan key + * at run time. Hence, we set have_runtime_keys to true and place + * the appropriate subexpression in run_keys. The corresponding * scan key values are recomputed at run time. - * - * XXX Although this code *thinks* it can handle an indexqual - * with the indexkey on either side, in fact it cannot. - * Indexscans only work with quals that have the indexkey on - * the left (the planner/optimizer makes sure it never passes - * anything else). The reason: the scankey machinery has no - * provision for distinguishing which side of the operator is - * the indexed attribute and which is the compared-to - * constant. It just assumes that the attribute is on the left - * :-( - * - * I am leaving this code able to support both ways, even though - * half of it is dead code, on the off chance that someone - * will fix the scankey machinery someday --- tgl 8/11/99. */ - - scanvar = NO_OP; run_keys[j] = NULL; /* @@ -807,67 +784,25 @@ ExecInitIndexScan(IndexScan *node, EState *estate) Assert(leftop != NULL); - if (IsA(leftop, Var) && - var_is_rel((Var *) leftop)) - { - /* - * if the leftop is a "rel-var", then it means that it is - * a var node which tells us which attribute to use for - * our scan key. - */ - varattno = ((Var *) leftop)->varattno; - scanvar = LEFT_OP; - } - else if (IsA(leftop, Const)) - { - /* - * if the leftop is a const node then it means it - * identifies the value to place in our scan key. - */ - scanvalue = ((Const *) leftop)->constvalue; - if (((Const *) leftop)->constisnull) - flags |= SK_ISNULL; - } - else - { - /* - * otherwise, the leftop contains an expression evaluable - * at runtime to figure out the value to place in our scan - * key. - */ - have_runtime_keys = true; - run_keys[j] = ExecInitExpr(leftop, (PlanState *) indexstate); - } + if (!(IsA(leftop, Var) && + var_is_rel((Var *) leftop))) + elog(ERROR, "indxqual doesn't have key on left side"); + + varattno = ((Var *) leftop)->varattno; /* * now determine information in rightop */ rightop = (Expr *) get_rightop((Expr *) clause); + rhstype = exprType((Node *) rightop); + if (rightop && IsA(rightop, RelabelType)) rightop = ((RelabelType *) rightop)->arg; Assert(rightop != NULL); - if (IsA(rightop, Var) && - var_is_rel((Var *) rightop)) - { - /* - * here we make sure only one op identifies the - * scan-attribute... - */ - if (scanvar == LEFT_OP) - elog(ERROR, "both left and right operands are rel-vars"); - - /* - * if the rightop is a "rel-var", then it means that it is - * a var node which tells us which attribute to use for - * our scan key. - */ - varattno = ((Var *) rightop)->varattno; - scanvar = RIGHT_OP; - } - else if (IsA(rightop, Const)) + if (IsA(rightop, Const)) { /* * if the rightop is a const node then it means it @@ -886,15 +821,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate) */ have_runtime_keys = true; run_keys[j] = ExecInitExpr(rightop, (PlanState *) indexstate); + scanvalue = (Datum) 0; } - /* - * now check that at least one op tells us the scan - * attribute... - */ - if (scanvar == NO_OP) - elog(ERROR, "neither left nor right operand refer to scan relation"); - /* * initialize the scan key's fields appropriately */ @@ -902,8 +831,10 @@ ExecInitIndexScan(IndexScan *node, EState *estate) flags, varattno, /* attribute number to * scan */ + strategy, /* op's strategy */ opfuncid, /* reg proc to use */ - scanvalue); /* constant */ + scanvalue, /* constant */ + rhstype); /* constant's type */ } /* @@ -922,7 +853,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate) indexstate->iss_NumScanKeys = numScanKeys; /* - * If all of our keys have the form (op var const) , then we have no + * If all of our keys have the form (var op const), then we have no * runtime keys so we store NULL in the runtime key info. Otherwise * runtime key info contains an array of pointers (one for each index) * to arrays of flags (one for each key) which indicate that the qual @@ -978,10 +909,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate) * does its own locks and unlocks. (We rely on having AccessShareLock * on the parent table to ensure the index won't go away!) */ - listscan = indxid; for (i = 0; i < numIndices; i++) { - Oid indexOid = lfirsto(listscan); + Oid indexOid = lfirsto(indxid); indexDescs[i] = index_open(indexOid); scanDescs[i] = index_beginscan(currentRelation, @@ -989,7 +919,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate) estate->es_snapshot, numScanKeys[i], scanKeys[i]); - listscan = lnext(listscan); + indxid = lnext(indxid); } indexstate->iss_RelationDescs = indexDescs; diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 17b32cd4ab8..c02270fa2e7 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.265 2003/08/17 23:43:25 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.266 2003/11/09 21:30:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -262,6 +262,17 @@ _copyIndexScan(IndexScan *from) COPY_OIDLIST_FIELD(indxid); COPY_NODE_FIELD(indxqual); COPY_NODE_FIELD(indxqualorig); + /* this can become COPY_NODE_FIELD when intlists are normal objects: */ + { + List *newstrat = NIL; + List *tmp; + + foreach(tmp, from->indxstrategy) + { + newstrat = lappend(newstrat, listCopy(lfirst(tmp))); + } + newnode->indxstrategy = newstrat; + } COPY_SCALAR_FIELD(indxorderdir); return newnode; diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 97d9aed2407..b2fa96bd5d2 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.218 2003/08/17 23:43:26 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.219 2003/11/09 21:30:36 tgl Exp $ * * NOTES * Every node type that can appear in stored rules' parsetrees *must* @@ -336,6 +336,16 @@ _outIndexScan(StringInfo str, IndexScan *node) WRITE_OIDLIST_FIELD(indxid); WRITE_NODE_FIELD(indxqual); WRITE_NODE_FIELD(indxqualorig); + /* this can become WRITE_NODE_FIELD when intlists are normal objects: */ + { + List *tmp; + + appendStringInfo(str, " :indxstrategy "); + foreach(tmp, node->indxstrategy) + { + _outIntList(str, lfirst(tmp)); + } + } WRITE_ENUM_FIELD(indxorderdir, ScanDirection); } diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index e3ad5bc6554..37478d7de0a 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.157 2003/08/27 12:44:12 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.158 2003/11/09 21:30:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -62,11 +62,14 @@ static HashJoin *create_hashjoin_plan(Query *root, HashPath *best_path, Plan *outer_plan, Plan *inner_plan); static void fix_indxqual_references(List *indexquals, IndexPath *index_path, List **fixed_indexquals, - List **recheck_indexquals); + List **recheck_indexquals, + List **indxstrategy); static void fix_indxqual_sublist(List *indexqual, Relids baserelids, int baserelid, IndexOptInfo *index, - List **fixed_quals, List **recheck_quals); + List **fixed_quals, + List **recheck_quals, + List **strategy); static Node *fix_indxqual_operand(Node *node, int baserelid, IndexOptInfo *index, Oid *opclass); @@ -77,7 +80,7 @@ static void copy_plan_costsize(Plan *dest, Plan *src); static SeqScan *make_seqscan(List *qptlist, List *qpqual, Index scanrelid); static IndexScan *make_indexscan(List *qptlist, List *qpqual, Index scanrelid, List *indxid, List *indxqual, - List *indxqualorig, + List *indxqualorig, List *indxstrategy, ScanDirection indexscandir); static TidScan *make_tidscan(List *qptlist, List *qpqual, Index scanrelid, List *tideval); @@ -700,6 +703,7 @@ create_indexscan_plan(Query *root, Expr *indxqual_or_expr = NULL; List *fixed_indxqual; List *recheck_indxqual; + List *indxstrategy; FastList indexids; List *ixinfo; IndexScan *scan_plan; @@ -766,7 +770,8 @@ create_indexscan_plan(Query *root, * pass also looks for "lossy" operators. */ fix_indxqual_references(indxqual, best_path, - &fixed_indxqual, &recheck_indxqual); + &fixed_indxqual, &recheck_indxqual, + &indxstrategy); /* * If there were any "lossy" operators, need to add back the @@ -798,6 +803,7 @@ create_indexscan_plan(Query *root, FastListValue(&indexids), fixed_indxqual, indxqual, + indxstrategy, best_path->indexscandir); copy_path_costsize(&scan_plan->scan.plan, &best_path->path); @@ -1134,7 +1140,7 @@ create_hashjoin_plan(Query *root, * Adjust indexqual clauses to the form the executor's indexqual * machinery needs, and check for recheckable (lossy) index conditions. * - * We have three tasks here: + * We have four tasks here: * * Index keys must be represented by Var nodes with varattno set to the * index's attribute number, not the attribute number in the original rel. * * If the index key is on the right, commute the clause to put it on the @@ -1145,9 +1151,8 @@ create_hashjoin_plan(Query *root, * must add (the original form of) the indexqual clause to the "qpquals" * of the indexscan node, where the operator will be re-evaluated to * ensure it passes. - * - * This code used to be entirely bogus for multi-index scans. Now it keeps - * track of which index applies to each subgroup of index qual clauses... + * * We must construct a list of operator strategy numbers corresponding + * to the top-level operators of each index clause. * * Both the input list and the output lists have the form of lists of sublists * of qual clauses --- the top-level list has one entry for each indexscan @@ -1160,10 +1165,13 @@ create_hashjoin_plan(Query *root, * * recheck_indexquals similarly receives a full copy of whichever clauses * need rechecking. + * + * indxstrategy receives a list of integer sublists of strategy numbers. */ static void fix_indxqual_references(List *indexquals, IndexPath *index_path, - List **fixed_indexquals, List **recheck_indexquals) + List **fixed_indexquals, List **recheck_indexquals, + List **indxstrategy) { FastList fixed_quals; FastList recheck_quals; @@ -1174,18 +1182,21 @@ fix_indxqual_references(List *indexquals, IndexPath *index_path, FastListInit(&fixed_quals); FastListInit(&recheck_quals); + *indxstrategy = NIL; foreach(i, indexquals) { List *indexqual = lfirst(i); IndexOptInfo *index = (IndexOptInfo *) lfirst(ixinfo); List *fixed_qual; List *recheck_qual; + List *strategy; fix_indxqual_sublist(indexqual, baserelids, baserelid, index, - &fixed_qual, &recheck_qual); + &fixed_qual, &recheck_qual, &strategy); FastAppend(&fixed_quals, fixed_qual); if (recheck_qual != NIL) FastAppend(&recheck_quals, recheck_qual); + *indxstrategy = lappend(*indxstrategy, strategy); ixinfo = lnext(ixinfo); } @@ -1199,18 +1210,21 @@ fix_indxqual_references(List *indexquals, IndexPath *index_path, * * For each qual clause, commute if needed to put the indexkey operand on the * left, and then fix its varattno. (We do not need to change the other side - * of the clause.) Also change the operator if necessary, and check for - * lossy index behavior. + * of the clause.) Also change the operator if necessary, check for + * lossy index behavior, and determine the operator's strategy number. * - * Returns two lists: the list of fixed indexquals, and the list (usually + * Returns three lists: the list of fixed indexquals, the list (usually * empty) of original clauses that must be rechecked as qpquals because - * the index is lossy for this operator type. + * the index is lossy for this operator type, and the integer list of + * strategy numbers. */ static void fix_indxqual_sublist(List *indexqual, Relids baserelids, int baserelid, IndexOptInfo *index, - List **fixed_quals, List **recheck_quals) + List **fixed_quals, + List **recheck_quals, + List **strategy) { FastList fixed_qual; FastList recheck_qual; @@ -1218,14 +1232,18 @@ fix_indxqual_sublist(List *indexqual, FastListInit(&fixed_qual); FastListInit(&recheck_qual); + *strategy = NIL; foreach(i, indexqual) { OpExpr *clause = (OpExpr *) lfirst(i); OpExpr *newclause; Relids leftvarnos; Oid opclass; + int stratno; + bool recheck; - if (!IsA(clause, OpExpr) ||length(clause->args) != 2) + if (!IsA(clause, OpExpr) || + length(clause->args) != 2) elog(ERROR, "indexqual clause is not binary opclause"); /* @@ -1259,10 +1277,20 @@ fix_indxqual_sublist(List *indexqual, FastAppend(&fixed_qual, newclause); /* - * Finally, check to see if index is lossy for this operator. If - * so, add (a copy of) original form of clause to recheck list. + * Look up the operator in the operator class to get its strategy + * number and the recheck indicator. This also double-checks that + * we found an operator matching the index. */ - if (op_requires_recheck(newclause->opno, opclass)) + get_op_opclass_properties(newclause->opno, opclass, + &stratno, &recheck); + + *strategy = lappendi(*strategy, stratno); + + /* + * If index is lossy for this operator, add (a copy of) original form + * of clause to recheck list. + */ + if (recheck) FastAppend(&recheck_qual, copyObject((Node *) clause)); } @@ -1511,6 +1539,7 @@ make_indexscan(List *qptlist, List *indxid, List *indxqual, List *indxqualorig, + List *indxstrategy, ScanDirection indexscandir) { IndexScan *node = makeNode(IndexScan); @@ -1525,6 +1554,7 @@ make_indexscan(List *qptlist, node->indxid = indxid; node->indxqual = indxqual; node->indxqualorig = indxqualorig; + node->indxstrategy = indxstrategy; node->indxorderdir = indexscandir; return node; diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 48dc3a6cf36..8e621dd063a 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.87 2003/08/04 02:40:01 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.88 2003/11/09 21:30:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -23,6 +23,7 @@ #include "catalog/pg_amop.h" #include "catalog/pg_inherits.h" #include "catalog/pg_index.h" +#include "catalog/pg_type.h" #include "nodes/makefuncs.h" #include "optimizer/clauses.h" #include "optimizer/plancat.h" @@ -328,11 +329,10 @@ find_inheritance_children(Oid inhparent) if (!has_subclass(inhparent)) return NIL; - ScanKeyEntryInitialize(&key[0], - (bits16) 0x0, - (AttrNumber) Anum_pg_inherits_inhparent, - (RegProcedure) F_OIDEQ, - ObjectIdGetDatum(inhparent)); + ScanKeyEntryInitialize(&key[0], 0, + Anum_pg_inherits_inhparent, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(inhparent), OIDOID); relation = heap_openr(InheritsRelationName, AccessShareLock); scan = heap_beginscan(relation, SnapshotNow, 1, key); while ((inheritsTuple = heap_getnext(scan, ForwardScanDirection)) != NULL) diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index a922f5599e9..95b5dc37cc6 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.161 2003/09/29 00:05:25 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.162 2003/11/09 21:30:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1039,9 +1039,10 @@ find_inheritors(Oid relid, Oid **supervec) { /* find all types this relid inherits from, and add them to queue */ - ScanKeyEntryInitialize(&skey, 0x0, Anum_pg_inherits_inhrelid, - F_OIDEQ, - ObjectIdGetDatum(relid)); + ScanKeyEntryInitialize(&skey, 0, + Anum_pg_inherits_inhrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(relid), OIDOID); inhscan = heap_beginscan(inhrel, SnapshotNow, 1, &skey); diff --git a/src/backend/rewrite/rewriteRemove.c b/src/backend/rewrite/rewriteRemove.c index c7de8ead12c..53f94137e16 100644 --- a/src/backend/rewrite/rewriteRemove.c +++ b/src/backend/rewrite/rewriteRemove.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.56 2003/08/04 02:40:03 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.57 2003/11/09 21:30:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -20,6 +20,7 @@ #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/pg_rewrite.h" +#include "catalog/pg_type.h" #include "miscadmin.h" #include "rewrite/rewriteRemove.h" #include "rewrite/rewriteSupport.h" @@ -104,9 +105,10 @@ RemoveRewriteRuleById(Oid ruleOid) /* * Find the tuple for the target rule. */ - ScanKeyEntryInitialize(&skey[0], 0x0, - ObjectIdAttributeNumber, F_OIDEQ, - ObjectIdGetDatum(ruleOid)); + ScanKeyEntryInitialize(&skey[0], 0, + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(ruleOid), OIDOID); rcscan = systable_beginscan(RewriteRelation, RewriteOidIndex, true, SnapshotNow, 1, skey); diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c index c02437c7ebb..33e40109d3e 100644 --- a/src/backend/storage/large_object/inv_api.c +++ b/src/backend/storage/large_object/inv_api.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.98 2003/08/04 02:40:03 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.99 2003/11/09 21:30:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -22,7 +22,6 @@ #include "access/genam.h" #include "access/heapam.h" #include "access/htup.h" -#include "access/nbtree.h" #include "access/tuptoaster.h" #include "catalog/catalog.h" #include "catalog/catname.h" @@ -203,11 +202,10 @@ inv_getsize(LargeObjectDesc *obj_desc) Assert(PointerIsValid(obj_desc)); - ScanKeyEntryInitialize(&skey[0], - (bits16) 0x0, - (AttrNumber) 1, - (RegProcedure) F_OIDEQ, - ObjectIdGetDatum(obj_desc->id)); + ScanKeyEntryInitialize(&skey[0], 0, + Anum_pg_largeobject_loid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(obj_desc->id), OIDOID); sd = index_beginscan(obj_desc->heap_r, obj_desc->index_r, SnapshotNow, 1, skey); @@ -308,17 +306,15 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes) if (nbytes <= 0) return 0; - ScanKeyEntryInitialize(&skey[0], - (bits16) 0x0, - (AttrNumber) 1, - (RegProcedure) F_OIDEQ, - ObjectIdGetDatum(obj_desc->id)); + ScanKeyEntryInitialize(&skey[0], 0, + Anum_pg_largeobject_loid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(obj_desc->id), OIDOID); - ScanKeyEntryInitialize(&skey[1], - (bits16) 0x0, - (AttrNumber) 2, - (RegProcedure) F_INT4GE, - Int32GetDatum(pageno)); + ScanKeyEntryInitialize(&skey[1], 0, + Anum_pg_largeobject_pageno, + BTGreaterEqualStrategyNumber, F_INT4GE, + Int32GetDatum(pageno), INT4OID); sd = index_beginscan(obj_desc->heap_r, obj_desc->index_r, SnapshotNow, 2, skey); @@ -417,17 +413,15 @@ inv_write(LargeObjectDesc *obj_desc, char *buf, int nbytes) indstate = CatalogOpenIndexes(obj_desc->heap_r); - ScanKeyEntryInitialize(&skey[0], - (bits16) 0x0, - (AttrNumber) 1, - (RegProcedure) F_OIDEQ, - ObjectIdGetDatum(obj_desc->id)); + ScanKeyEntryInitialize(&skey[0], 0, + Anum_pg_largeobject_loid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(obj_desc->id), OIDOID); - ScanKeyEntryInitialize(&skey[1], - (bits16) 0x0, - (AttrNumber) 2, - (RegProcedure) F_INT4GE, - Int32GetDatum(pageno)); + ScanKeyEntryInitialize(&skey[1], 0, + Anum_pg_largeobject_pageno, + BTGreaterEqualStrategyNumber, F_INT4GE, + Int32GetDatum(pageno), INT4OID); sd = index_beginscan(obj_desc->heap_r, obj_desc->index_r, SnapshotNow, 2, skey); diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c index 8efaa30fe59..211549afeaf 100644 --- a/src/backend/utils/adt/regproc.c +++ b/src/backend/utils/adt/regproc.c @@ -13,7 +13,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.82 2003/09/25 06:58:04 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.83 2003/11/09 21:30:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -92,10 +92,10 @@ regprocin(PG_FUNCTION_ARGS) SysScanDesc sysscan; HeapTuple tuple; - ScanKeyEntryInitialize(&skey[0], 0x0, - (AttrNumber) Anum_pg_proc_proname, - (RegProcedure) F_NAMEEQ, - CStringGetDatum(pro_name_or_oid)); + ScanKeyEntryInitialize(&skey[0], 0, + Anum_pg_proc_proname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(pro_name_or_oid), NAMEOID); hdesc = heap_openr(ProcedureRelationName, AccessShareLock); sysscan = systable_beginscan(hdesc, ProcedureNameNspIndex, true, @@ -442,10 +442,10 @@ regoperin(PG_FUNCTION_ARGS) SysScanDesc sysscan; HeapTuple tuple; - ScanKeyEntryInitialize(&skey[0], 0x0, - (AttrNumber) Anum_pg_operator_oprname, - (RegProcedure) F_NAMEEQ, - CStringGetDatum(opr_name_or_oid)); + ScanKeyEntryInitialize(&skey[0], 0, + Anum_pg_operator_oprname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(opr_name_or_oid), NAMEOID); hdesc = heap_openr(OperatorRelationName, AccessShareLock); sysscan = systable_beginscan(hdesc, OperatorNameNspIndex, true, @@ -820,10 +820,10 @@ regclassin(PG_FUNCTION_ARGS) SysScanDesc sysscan; HeapTuple tuple; - ScanKeyEntryInitialize(&skey[0], 0x0, - (AttrNumber) Anum_pg_class_relname, - (RegProcedure) F_NAMEEQ, - CStringGetDatum(class_name_or_oid)); + ScanKeyEntryInitialize(&skey[0], 0, + Anum_pg_class_relname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(class_name_or_oid), NAMEOID); hdesc = heap_openr(RelationRelationName, AccessShareLock); sysscan = systable_beginscan(hdesc, ClassNameNspIndex, true, @@ -986,10 +986,10 @@ regtypein(PG_FUNCTION_ARGS) SysScanDesc sysscan; HeapTuple tuple; - ScanKeyEntryInitialize(&skey[0], 0x0, - (AttrNumber) Anum_pg_type_typname, - (RegProcedure) F_NAMEEQ, - CStringGetDatum(typ_name_or_oid)); + ScanKeyEntryInitialize(&skey[0], 0, + Anum_pg_type_typname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(typ_name_or_oid), NAMEOID); hdesc = heap_openr(TypeRelationName, AccessShareLock); sysscan = systable_beginscan(hdesc, TypeNameNspIndex, true, diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index d3269e11067..fe749cc9b12 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -3,7 +3,7 @@ * back to source text * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.157 2003/10/04 18:22:59 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.158 2003/11/09 21:30:37 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -488,9 +488,10 @@ pg_get_triggerdef(PG_FUNCTION_ARGS) */ tgrel = heap_openr(TriggerRelationName, AccessShareLock); - ScanKeyEntryInitialize(&skey[0], 0x0, - ObjectIdAttributeNumber, F_OIDEQ, - ObjectIdGetDatum(trigid)); + ScanKeyEntryInitialize(&skey[0], 0, + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(trigid), OIDOID); tgscan = systable_beginscan(tgrel, TriggerOidIndex, true, SnapshotNow, 1, skey); @@ -885,9 +886,10 @@ pg_get_constraintdef_worker(Oid constraintId, int prettyFlags) */ conDesc = heap_openr(ConstraintRelationName, AccessShareLock); - ScanKeyEntryInitialize(&skey[0], 0x0, - ObjectIdAttributeNumber, F_OIDEQ, - ObjectIdGetDatum(constraintId)); + ScanKeyEntryInitialize(&skey[0], 0, + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(constraintId), OIDOID); conscan = systable_beginscan(conDesc, ConstraintOidIndex, true, SnapshotNow, 1, skey); diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index f8363265de9..640629c3a04 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.108 2003/08/04 02:40:06 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.109 2003/11/09 21:30:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -937,6 +937,7 @@ CatalogCacheInitializeCache(CatCache *cache) for (i = 0; i < cache->cc_nkeys; ++i) { Oid keytype; + RegProcedure eqfunc; CatalogCacheInitializeCache_DEBUG2; @@ -951,7 +952,7 @@ CatalogCacheInitializeCache(CatCache *cache) GetCCHashEqFuncs(keytype, &cache->cc_hashfunc[i], - &cache->cc_skey[i].sk_procedure); + &eqfunc); cache->cc_isname[i] = (keytype == NAMEOID); @@ -959,13 +960,17 @@ CatalogCacheInitializeCache(CatCache *cache) * Do equality-function lookup (we assume this won't need a * catalog lookup for any supported type) */ - fmgr_info_cxt(cache->cc_skey[i].sk_procedure, + fmgr_info_cxt(eqfunc, &cache->cc_skey[i].sk_func, CacheMemoryContext); /* Initialize sk_attno suitably for HeapKeyTest() and heap scans */ cache->cc_skey[i].sk_attno = cache->cc_key[i]; + /* Fill in sk_strategy and sk_argtype correctly as well */ + cache->cc_skey[i].sk_strategy = BTEqualStrategyNumber; + cache->cc_skey[i].sk_argtype = keytype; + CACHE4_elog(DEBUG2, "CatalogCacheInit %s %d %p", cache->cc_relname, i, diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c index 992be3ca4e3..bed4fcdbce6 100644 --- a/src/backend/utils/cache/lsyscache.c +++ b/src/backend/utils/cache/lsyscache.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.108 2003/10/04 18:22:59 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.109 2003/11/09 21:30:37 tgl Exp $ * * NOTES * Eventually, the index information should go through here, too. @@ -53,21 +53,20 @@ op_in_opclass(Oid opno, Oid opclass) } /* - * op_requires_recheck + * get_op_opclass_properties * - * Return t if operator 'opno' requires a recheck when used as a - * member of opclass 'opclass' (ie, this opclass is lossy for this - * operator). + * Get the operator's strategy number and recheck (lossy) flag + * within the specified opclass. * * Caller should already have verified that opno is a member of opclass, * therefore we raise an error if the tuple is not found. */ -bool -op_requires_recheck(Oid opno, Oid opclass) +void +get_op_opclass_properties(Oid opno, Oid opclass, + int *strategy, bool *recheck) { HeapTuple tp; Form_pg_amop amop_tup; - bool result; tp = SearchSysCache(AMOPOPID, ObjectIdGetDatum(opno), @@ -77,10 +76,9 @@ op_requires_recheck(Oid opno, Oid opclass) elog(ERROR, "operator %u is not a member of opclass %u", opno, opclass); amop_tup = (Form_pg_amop) GETSTRUCT(tp); - - result = amop_tup->amopreqcheck; + *strategy = amop_tup->amopstrategy; + *recheck = amop_tup->amopreqcheck; ReleaseSysCache(tp); - return result; } /* diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index d28875b1da9..88c8cbb1418 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.190 2003/09/25 06:58:05 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.191 2003/11/09 21:30:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -34,7 +34,6 @@ #include "access/genam.h" #include "access/heapam.h" -#include "access/istrat.h" #include "catalog/catalog.h" #include "catalog/catname.h" #include "catalog/indexing.h" @@ -69,6 +68,8 @@ */ #define RELCACHE_INIT_FILENAME "pg_internal.init" +#define RELCACHE_INIT_FILEMAGIC 0x573261 /* version ID value */ + /* * hardcoded tuple descriptors. see include/catalog/pg_attribute.h */ @@ -260,6 +261,8 @@ do { \ /* * Special cache for opclass-related information + * + * Note: only non-cross-type operators and support procs get cached */ typedef struct opclasscacheent { @@ -268,7 +271,6 @@ typedef struct opclasscacheent StrategyNumber numStrats; /* max # of strategies (from pg_am) */ StrategyNumber numSupport; /* max # of support procs (from pg_am) */ Oid *operatorOids; /* strategy operators' OIDs */ - RegProcedure *operatorProcs; /* strategy operators' procs */ RegProcedure *supportProcs; /* support procs */ } OpClassCacheEnt; @@ -298,7 +300,6 @@ static void AttrDefaultFetch(Relation relation); static void CheckConstraintFetch(Relation relation); static List *insert_ordered_oid(List *list, Oid datum); static void IndexSupportInitialize(Form_pg_index iform, - IndexStrategy indexStrategy, Oid *indexOperator, RegProcedure *indexSupport, StrategyNumber maxStrategyNumber, @@ -337,8 +338,9 @@ ScanPgRelation(RelationBuildDescInfo buildinfo, bool indexOK) case INFO_RELID: ScanKeyEntryInitialize(&key[0], 0, ObjectIdAttributeNumber, - F_OIDEQ, - ObjectIdGetDatum(buildinfo.i.info_id)); + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(buildinfo.i.info_id), + OIDOID); nkeys = 1; indexRelname = ClassOidIndex; break; @@ -346,12 +348,14 @@ ScanPgRelation(RelationBuildDescInfo buildinfo, bool indexOK) case INFO_RELNAME: ScanKeyEntryInitialize(&key[0], 0, Anum_pg_class_relname, - F_NAMEEQ, - NameGetDatum(buildinfo.i.info_name)); + BTEqualStrategyNumber, F_NAMEEQ, + NameGetDatum(buildinfo.i.info_name), + NAMEOID); ScanKeyEntryInitialize(&key[1], 0, Anum_pg_class_relnamespace, - F_OIDEQ, - ObjectIdGetDatum(PG_CATALOG_NAMESPACE)); + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(PG_CATALOG_NAMESPACE), + OIDOID); nkeys = 2; indexRelname = ClassNameNspIndex; break; @@ -481,12 +485,13 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo, */ ScanKeyEntryInitialize(&skey[0], 0, Anum_pg_attribute_attrelid, - F_OIDEQ, - ObjectIdGetDatum(RelationGetRelid(relation))); + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(relation)), + OIDOID); ScanKeyEntryInitialize(&skey[1], 0, Anum_pg_attribute_attnum, - F_INT2GT, - Int16GetDatum(0)); + BTGreaterStrategyNumber, F_INT2GT, + Int16GetDatum(0), INT2OID); /* * Open pg_attribute and begin a scan. Force heap scan if we haven't @@ -531,14 +536,10 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo, if (attp->atthasdef) { if (attrdef == NULL) - { attrdef = (AttrDefault *) - MemoryContextAlloc(CacheMemoryContext, - relation->rd_rel->relnatts * - sizeof(AttrDefault)); - MemSet(attrdef, 0, - relation->rd_rel->relnatts * sizeof(AttrDefault)); - } + MemoryContextAllocZero(CacheMemoryContext, + relation->rd_rel->relnatts * + sizeof(AttrDefault)); attrdef[ndef].adnum = attp->attnum; attrdef[ndef].adbin = NULL; ndef++; @@ -605,9 +606,8 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo, { constr->num_check = relation->rd_rel->relchecks; constr->check = (ConstrCheck *) - MemoryContextAlloc(CacheMemoryContext, - constr->num_check * sizeof(ConstrCheck)); - MemSet(constr->check, 0, constr->num_check * sizeof(ConstrCheck)); + MemoryContextAllocZero(CacheMemoryContext, + constr->num_check * sizeof(ConstrCheck)); CheckConstraintFetch(relation); } else @@ -675,8 +675,9 @@ RelationBuildRuleLock(Relation relation) */ ScanKeyEntryInitialize(&key, 0, Anum_pg_rewrite_ev_class, - F_OIDEQ, - ObjectIdGetDatum(RelationGetRelid(relation))); + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(relation)), + OIDOID); /* * open pg_rewrite and begin a scan @@ -950,7 +951,6 @@ RelationInitIndexAccessInfo(Relation relation) Form_pg_am aform; MemoryContext indexcxt; MemoryContext oldcontext; - IndexStrategy strategy; Oid *operator; RegProcedure *support; FmgrInfo *supportinfo; @@ -1016,33 +1016,20 @@ RelationInitIndexAccessInfo(Relation relation) * Allocate arrays to hold data */ if (amstrategies > 0) - { - int noperators = natts * amstrategies; - Size stratSize; - - stratSize = AttributeNumberGetIndexStrategySize(natts, amstrategies); - strategy = (IndexStrategy) MemoryContextAlloc(indexcxt, stratSize); - MemSet(strategy, 0, stratSize); operator = (Oid *) - MemoryContextAlloc(indexcxt, noperators * sizeof(Oid)); - MemSet(operator, 0, noperators * sizeof(Oid)); - } + MemoryContextAllocZero(indexcxt, + natts * amstrategies * sizeof(Oid)); else - { - strategy = NULL; operator = NULL; - } if (amsupport > 0) { int nsupport = natts * amsupport; support = (RegProcedure *) - MemoryContextAlloc(indexcxt, nsupport * sizeof(RegProcedure)); - MemSet(support, 0, nsupport * sizeof(RegProcedure)); + MemoryContextAllocZero(indexcxt, nsupport * sizeof(RegProcedure)); supportinfo = (FmgrInfo *) - MemoryContextAlloc(indexcxt, nsupport * sizeof(FmgrInfo)); - MemSet(supportinfo, 0, nsupport * sizeof(FmgrInfo)); + MemoryContextAllocZero(indexcxt, nsupport * sizeof(FmgrInfo)); } else { @@ -1050,17 +1037,16 @@ RelationInitIndexAccessInfo(Relation relation) supportinfo = NULL; } - relation->rd_istrat = strategy; relation->rd_operator = operator; relation->rd_support = support; relation->rd_supportinfo = supportinfo; /* - * Fill the strategy map and the support RegProcedure arrays. + * Fill the operator and support procedure OID arrays. * (supportinfo is left as zeroes, and is filled on-the-fly when used) */ IndexSupportInitialize(relation->rd_index, - strategy, operator, support, + operator, support, amstrategies, amsupport, natts); /* @@ -1072,11 +1058,11 @@ RelationInitIndexAccessInfo(Relation relation) /* * IndexSupportInitialize - * Initializes an index strategy and associated support procedures, + * Initializes an index's cached lists of operators and support procs, * given the index's pg_index tuple. * - * Data is returned into *indexStrategy, *indexOperator, and *indexSupport, - * all of which are objects allocated by the caller. + * Data is returned into *indexOperator and *indexSupport, which are arrays + * allocated by the caller. * * The caller also passes maxStrategyNumber, maxSupportNumber, and * maxAttributeNumber, since these indicate the size of the arrays @@ -1086,7 +1072,6 @@ RelationInitIndexAccessInfo(Relation relation) */ static void IndexSupportInitialize(Form_pg_index iform, - IndexStrategy indexStrategy, Oid *indexOperator, RegProcedure *indexSupport, StrategyNumber maxStrategyNumber, @@ -1095,8 +1080,6 @@ IndexSupportInitialize(Form_pg_index iform, { int attIndex; - maxStrategyNumber = AMStrategies(maxStrategyNumber); - /* * XXX note that the following assumes the INDEX tuple is well formed * and that the *key and *class are 0 terminated. @@ -1113,52 +1096,15 @@ IndexSupportInitialize(Form_pg_index iform, maxStrategyNumber, maxSupportNumber); - /* load the strategy information for the index operators */ + /* copy cached data into relcache entry */ if (maxStrategyNumber > 0) - { - StrategyMap map; - Oid *opers; - StrategyNumber strategy; - - map = IndexStrategyGetStrategyMap(indexStrategy, - maxStrategyNumber, - attIndex + 1); - opers = &indexOperator[attIndex * maxStrategyNumber]; - - for (strategy = 0; strategy < maxStrategyNumber; strategy++) - { - ScanKey mapentry; - - mapentry = StrategyMapGetScanKeyEntry(map, strategy + 1); - if (RegProcedureIsValid(opcentry->operatorProcs[strategy])) - { - MemSet(mapentry, 0, sizeof(*mapentry)); - mapentry->sk_flags = 0; - mapentry->sk_procedure = opcentry->operatorProcs[strategy]; - - /* - * Mark mapentry->sk_func invalid, until and unless - * someone sets it up. - */ - mapentry->sk_func.fn_oid = InvalidOid; - } - else - ScanKeyEntrySetIllegal(mapentry); - opers[strategy] = opcentry->operatorOids[strategy]; - } - } - - /* if support routines exist for this access method, load them */ + memcpy(&indexOperator[attIndex * maxStrategyNumber], + opcentry->operatorOids, + maxStrategyNumber * sizeof(Oid)); if (maxSupportNumber > 0) - { - RegProcedure *procs; - StrategyNumber support; - - procs = &indexSupport[attIndex * maxSupportNumber]; - - for (support = 0; support < maxSupportNumber; ++support) - procs[support] = opcentry->supportProcs[support]; - } + memcpy(&indexSupport[attIndex * maxSupportNumber], + opcentry->supportProcs, + maxSupportNumber * sizeof(RegProcedure)); } } @@ -1231,29 +1177,16 @@ LookupOpclassInfo(Oid operatorClassOid, opcentry->numSupport = numSupport; if (numStrats > 0) - { opcentry->operatorOids = (Oid *) - MemoryContextAlloc(CacheMemoryContext, - numStrats * sizeof(Oid)); - MemSet(opcentry->operatorOids, 0, numStrats * sizeof(Oid)); - opcentry->operatorProcs = (RegProcedure *) - MemoryContextAlloc(CacheMemoryContext, - numStrats * sizeof(RegProcedure)); - MemSet(opcentry->operatorProcs, 0, numStrats * sizeof(RegProcedure)); - } + MemoryContextAllocZero(CacheMemoryContext, + numStrats * sizeof(Oid)); else - { opcentry->operatorOids = NULL; - opcentry->operatorProcs = NULL; - } if (numSupport > 0) - { opcentry->supportProcs = (RegProcedure *) - MemoryContextAlloc(CacheMemoryContext, - numSupport * sizeof(RegProcedure)); - MemSet(opcentry->supportProcs, 0, numSupport * sizeof(RegProcedure)); - } + MemoryContextAllocZero(CacheMemoryContext, + numSupport * sizeof(RegProcedure)); else opcentry->supportProcs = NULL; @@ -1273,8 +1206,9 @@ LookupOpclassInfo(Oid operatorClassOid, { ScanKeyEntryInitialize(&key, 0, Anum_pg_amop_amopclaid, - F_OIDEQ, - ObjectIdGetDatum(operatorClassOid)); + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(operatorClassOid), + OIDOID); pg_amop_desc = heap_openr(AccessMethodOperatorRelationName, AccessShareLock); pg_amop_scan = systable_beginscan(pg_amop_desc, @@ -1293,8 +1227,6 @@ LookupOpclassInfo(Oid operatorClassOid, amopform->amopstrategy, operatorClassOid); opcentry->operatorOids[amopform->amopstrategy - 1] = amopform->amopopr; - opcentry->operatorProcs[amopform->amopstrategy - 1] = - get_opcode(amopform->amopopr); } systable_endscan(pg_amop_scan); @@ -1308,8 +1240,9 @@ LookupOpclassInfo(Oid operatorClassOid, { ScanKeyEntryInitialize(&key, 0, Anum_pg_amproc_amopclaid, - F_OIDEQ, - ObjectIdGetDatum(operatorClassOid)); + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(operatorClassOid), + OIDOID); pg_amproc_desc = heap_openr(AccessMethodProcedureRelationName, AccessShareLock); pg_amproc_scan = systable_beginscan(pg_amproc_desc, @@ -2550,11 +2483,11 @@ AttrDefaultFetch(Relation relation) int found; int i; - ScanKeyEntryInitialize(&skey, - (bits16) 0x0, - (AttrNumber) Anum_pg_attrdef_adrelid, - (RegProcedure) F_OIDEQ, - ObjectIdGetDatum(RelationGetRelid(relation))); + ScanKeyEntryInitialize(&skey, 0, + Anum_pg_attrdef_adrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(relation)), + OIDOID); adrel = heap_openr(AttrDefaultRelationName, AccessShareLock); adscan = systable_beginscan(adrel, AttrDefaultIndex, true, @@ -2617,9 +2550,11 @@ CheckConstraintFetch(Relation relation) bool isnull; int found = 0; - ScanKeyEntryInitialize(&skey[0], 0x0, - Anum_pg_constraint_conrelid, F_OIDEQ, - ObjectIdGetDatum(RelationGetRelid(relation))); + ScanKeyEntryInitialize(&skey[0], 0, + Anum_pg_constraint_conrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(relation)), + OIDOID); conrel = heap_openr(ConstraintRelationName, AccessShareLock); conscan = systable_beginscan(conrel, ConstraintRelidIndex, true, @@ -2707,11 +2642,11 @@ RelationGetIndexList(Relation relation) result = NIL; /* Prepare to scan pg_index for entries having indrelid = this rel. */ - ScanKeyEntryInitialize(&skey, - (bits16) 0x0, - (AttrNumber) Anum_pg_index_indrelid, - (RegProcedure) F_OIDEQ, - ObjectIdGetDatum(RelationGetRelid(relation))); + ScanKeyEntryInitialize(&skey, 0, + Anum_pg_index_indrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(relation)), + OIDOID); indrel = heap_openr(IndexRelationName, AccessShareLock); indscan = systable_beginscan(indrel, IndexIndrelidIndex, true, @@ -2988,7 +2923,8 @@ load_relcache_init_file(void) num_rels, max_rels, nailed_rels, - nailed_indexes; + nailed_indexes, + magic; int i; snprintf(initfilename, sizeof(initfilename), "%s/%s", @@ -3012,6 +2948,12 @@ load_relcache_init_file(void) nailed_rels = nailed_indexes = 0; initFileRelationIds = NIL; + /* check for correct magic number (compatible version) */ + if (fread(&magic, 1, sizeof(magic), fp) != sizeof(magic)) + goto read_failed; + if (magic != RELCACHE_INIT_FILEMAGIC) + goto read_failed; + for (relno = 0;; relno++) { Size len; @@ -3088,11 +3030,9 @@ load_relcache_init_file(void) { Form_pg_am am; MemoryContext indexcxt; - IndexStrategy strat; Oid *operator; RegProcedure *support; - int nstrategies, - nsupport; + int nsupport; /* Count nailed indexes to ensure we have 'em all */ if (rel->rd_isnailed) @@ -3131,21 +3071,6 @@ load_relcache_init_file(void) ALLOCSET_SMALL_MAXSIZE); rel->rd_indexcxt = indexcxt; - /* next, read the index strategy map */ - if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len)) - goto read_failed; - - strat = (IndexStrategy) MemoryContextAlloc(indexcxt, len); - if ((nread = fread(strat, 1, len, fp)) != len) - goto read_failed; - - /* have to invalidate any FmgrInfo data in the strategy maps */ - nstrategies = am->amstrategies * relform->relnatts; - for (i = 0; i < nstrategies; i++) - strat->strategyMapData[i].entry[0].sk_func.fn_oid = InvalidOid; - - rel->rd_istrat = strat; - /* next, read the vector of operator OIDs */ if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len)) goto read_failed; @@ -3168,8 +3093,7 @@ load_relcache_init_file(void) /* add a zeroed support-fmgr-info vector */ nsupport = relform->relnatts * am->amsupport; rel->rd_supportinfo = (FmgrInfo *) - MemoryContextAlloc(indexcxt, nsupport * sizeof(FmgrInfo)); - MemSet(rel->rd_supportinfo, 0, nsupport * sizeof(FmgrInfo)); + MemoryContextAllocZero(indexcxt, nsupport * sizeof(FmgrInfo)); } else { @@ -3181,7 +3105,6 @@ load_relcache_init_file(void) Assert(rel->rd_indextuple == NULL); Assert(rel->rd_am == NULL); Assert(rel->rd_indexcxt == NULL); - Assert(rel->rd_istrat == NULL); Assert(rel->rd_operator == NULL); Assert(rel->rd_support == NULL); Assert(rel->rd_supportinfo == NULL); @@ -3277,6 +3200,7 @@ write_relcache_init_file(void) FILE *fp; char tempfilename[MAXPGPATH]; char finalfilename[MAXPGPATH]; + int magic; HASH_SEQ_STATUS status; RelIdCacheEnt *idhentry; MemoryContext oldcxt; @@ -3309,6 +3233,14 @@ write_relcache_init_file(void) return; } + /* + * Write a magic number to serve as a file version identifier. We can + * change the magic number whenever the relcache layout changes. + */ + magic = RELCACHE_INIT_FILEMAGIC; + if (fwrite(&magic, 1, sizeof(magic), fp) != sizeof(magic)) + elog(FATAL, "could not write init file"); + /* * Write all the reldescs (in no particular order). */ @@ -3375,15 +3307,6 @@ write_relcache_init_file(void) if (fwrite(am, 1, len, fp) != len) elog(FATAL, "could not write init file"); - /* next, write the index strategy map */ - len = AttributeNumberGetIndexStrategySize(relform->relnatts, - am->amstrategies); - if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len)) - elog(FATAL, "could not write init file"); - - if (fwrite(rel->rd_istrat, 1, len, fp) != len) - elog(FATAL, "could not write init file"); - /* next, write the vector of operator OIDs */ len = relform->relnatts * (am->amstrategies * sizeof(Oid)); if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len)) diff --git a/src/backend/utils/cache/typcache.c b/src/backend/utils/cache/typcache.c index 3ae5a1d17b1..9b7620b0f0a 100644 --- a/src/backend/utils/cache/typcache.c +++ b/src/backend/utils/cache/typcache.c @@ -33,7 +33,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/cache/typcache.c,v 1.1 2003/08/17 19:58:06 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/cache/typcache.c,v 1.2 2003/11/09 21:30:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -248,9 +248,10 @@ lookup_default_opclass(Oid type_id, Oid am_id) */ rel = heap_openr(OperatorClassRelationName, AccessShareLock); - ScanKeyEntryInitialize(&skey[0], 0x0, - Anum_pg_opclass_opcamid, F_OIDEQ, - ObjectIdGetDatum(am_id)); + ScanKeyEntryInitialize(&skey[0], 0, + Anum_pg_opclass_opcamid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(am_id), OIDOID); scan = systable_beginscan(rel, OpclassAmNameNspIndex, true, SnapshotNow, 1, skey); diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index 85bfc93c8bc..21e2efdda75 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.127 2003/09/25 06:58:05 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.128 2003/11/09 21:30:37 tgl Exp $ * * *------------------------------------------------------------------------- @@ -26,6 +26,7 @@ #include "catalog/namespace.h" #include "catalog/pg_database.h" #include "catalog/pg_shadow.h" +#include "catalog/pg_type.h" #include "commands/trigger.h" #include "mb/pg_wchar.h" #include "miscadmin.h" @@ -91,8 +92,10 @@ ReverifyMyDatabase(const char *name) */ pgdbrel = heap_openr(DatabaseRelationName, AccessShareLock); - ScanKeyEntryInitialize(&key, 0, Anum_pg_database_datname, - F_NAMEEQ, NameGetDatum(name)); + ScanKeyEntryInitialize(&key, 0, + Anum_pg_database_datname, + BTEqualStrategyNumber, F_NAMEEQ, + NameGetDatum(name), NAMEOID); pgdbscan = heap_beginscan(pgdbrel, SnapshotNow, 1, &key); diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index 983296086be..9b3c0bb4075 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -78,7 +78,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/sort/tuplesort.c,v 1.37 2003/08/17 19:58:06 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/sort/tuplesort.c,v 1.38 2003/11/09 21:30:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -471,11 +471,16 @@ tuplesort_begin_heap(TupleDesc tupDesc, SelectSortFunction(sortOperators[i], &sortFunction, &state->sortFnKinds[i]); - ScanKeyEntryInitialize(&state->scanKeys[i], - 0x0, + /* + * We needn't fill in sk_strategy or sk_argtype since these scankeys + * will never be passed to an index. + */ + ScanKeyEntryInitialize(&state->scanKeys[i], 0, attNums[i], + InvalidStrategy, sortFunction, - (Datum) 0); + (Datum) 0, + InvalidOid); } return state; @@ -1929,12 +1934,7 @@ comparetup_heap(Tuplesortstate *state, const void *a, const void *b) datum1, isnull1, datum2, isnull2); if (compare != 0) - { - /* dead code? SK_COMMUTE can't actually be set here, can it? */ - if (scanKey->sk_flags & SK_COMMUTE) - compare = -compare; return compare; - } } return 0; diff --git a/src/include/access/gist.h b/src/include/access/gist.h index fbe3e5a9f20..9aa6991a0d5 100644 --- a/src/include/access/gist.h +++ b/src/include/access/gist.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: 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); diff --git a/src/include/access/istrat.h b/src/include/access/istrat.h deleted file mode 100644 index b538d2aae09..00000000000 --- a/src/include/access/istrat.h +++ /dev/null @@ -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 */ diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h index a852fa24925..80d412a52e5 100644 --- a/src/include/access/nbtree.h +++ b/src/include/access/nbtree.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 */ diff --git a/src/include/access/relscan.h b/src/include/access/relscan.h index 63c6bcc56bc..d56b2ac958b 100644 --- a/src/include/access/relscan.h +++ b/src/include/access/relscan.h @@ -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" diff --git a/src/include/access/rtree.h b/src/include/access/rtree.h index ed8dd6cf2e1..846090204aa 100644 --- a/src/include/access/rtree.h +++ b/src/include/access/rtree.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 */ diff --git a/src/include/access/skey.h b/src/include/access/skey.h index 2e66cfd894a..b7373dd6410 100644 --- a/src/include/access/skey.h +++ b/src/include/access/skey.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 */ diff --git a/src/include/access/strat.h b/src/include/access/strat.h deleted file mode 100644 index f697f79e4ee..00000000000 --- a/src/include/access/strat.h +++ /dev/null @@ -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 */ diff --git a/src/include/access/valid.h b/src/include/access/valid.h index 3109d3e7e4d..e16a392a243 100644 --- a/src/include/access/valid.h +++ b/src/include/access/valid.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; \ } \ diff --git a/src/include/commands/sequence.h b/src/include/commands/sequence.h index 531e30bb6ce..8c83fec3cc7 100644 --- a/src/include/commands/sequence.h +++ b/src/include/commands/sequence.h @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: sequence.h,v 1.26 2003/08/08 21:42:41 momjian Exp $ + * $Id: sequence.h,v 1.27 2003/11/09 21:30:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -15,6 +15,8 @@ #include "nodes/parsenodes.h" #include "access/xlog.h" +#include "fmgr.h" + /* * On a machine with no 64-bit-int C datatype, sizeof(int64) will not be 8, diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h index f56dc4653de..2312c0562e3 100644 --- a/src/include/nodes/plannodes.h +++ b/src/include/nodes/plannodes.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: plannodes.h,v 1.68 2003/08/08 21:42:48 momjian Exp $ + * $Id: plannodes.h,v 1.69 2003/11/09 21:30:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -153,15 +153,19 @@ typedef Scan SeqScan; /* ---------------- * index scan node + * + * Note: this can actually represent N indexscans, all on the same table + * but potentially using different indexes, put together with OR semantics. * ---------------- */ typedef struct IndexScan { Scan scan; - List *indxid; - List *indxqual; - List *indxqualorig; - ScanDirection indxorderdir; + List *indxid; /* list of index OIDs (1 per scan) */ + List *indxqual; /* list of sublists of index quals */ + List *indxqualorig; /* the same in original form */ + List *indxstrategy; /* list of sublists of strategy numbers */ + ScanDirection indxorderdir; /* forward or backward or don't care */ } IndexScan; /* ---------------- diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h index 98d357760dc..eed5c5ee9f3 100644 --- a/src/include/pg_config_manual.h +++ b/src/include/pg_config_manual.h @@ -6,7 +6,7 @@ * for developers. If you edit any of these, be sure to do a *full* * rebuild (and an initdb if noted). * - * $Id: pg_config_manual.h,v 1.6 2003/09/21 17:57:21 tgl Exp $ + * $Id: pg_config_manual.h,v 1.7 2003/11/09 21:30:37 tgl Exp $ *------------------------------------------------------------------------ */ @@ -229,7 +229,6 @@ */ /* #define IPORTAL_DEBUG */ /* #define HEAPDEBUGALL */ -/* #define ISTRATDEBUG */ /* #define ACLDEBUG */ /* #define RTDEBUG */ /* #define GISTDEBUG */ diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h index 67b1d4b6ccf..a4d3097dffc 100644 --- a/src/include/storage/smgr.h +++ b/src/include/storage/smgr.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: smgr.h,v 1.37 2003/08/04 02:40:15 momjian Exp $ + * $Id: smgr.h,v 1.38 2003/11/09 21:30:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -15,6 +15,7 @@ #define SMGR_H #include "access/xlog.h" +#include "fmgr.h" #include "storage/relfilenode.h" #include "storage/block.h" #include "utils/rel.h" diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h index d61b58a2cd4..df42020c04d 100644 --- a/src/include/utils/catcache.h +++ b/src/include/utils/catcache.h @@ -13,7 +13,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: catcache.h,v 1.46 2003/08/04 02:40:15 momjian Exp $ + * $Id: catcache.h,v 1.47 2003/11/09 21:30:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -21,6 +21,7 @@ #define CATCACHE_H #include "access/htup.h" +#include "access/skey.h" #include "lib/dllist.h" /* diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h index d6aaf2c1c25..36146f23d11 100644 --- a/src/include/utils/lsyscache.h +++ b/src/include/utils/lsyscache.h @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: lsyscache.h,v 1.82 2003/10/04 18:22:59 tgl Exp $ + * $Id: lsyscache.h,v 1.83 2003/11/09 21:30:38 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -25,7 +25,8 @@ typedef enum IOFuncSelector } IOFuncSelector; extern bool op_in_opclass(Oid opno, Oid opclass); -extern bool op_requires_recheck(Oid opno, Oid opclass); +extern void get_op_opclass_properties(Oid opno, Oid opclass, + int *strategy, bool *recheck); extern Oid get_opclass_member(Oid opclass, int16 strategy); extern Oid get_op_hash_function(Oid opno); extern Oid get_opclass_proc(Oid opclass, int16 procnum); diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index 377822afc69..f08d6c0f1f8 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -7,14 +7,13 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: rel.h,v 1.68 2003/09/24 18:54:01 tgl Exp $ + * $Id: rel.h,v 1.69 2003/11/09 21:30:38 tgl Exp $ * *------------------------------------------------------------------------- */ #ifndef REL_H #define REL_H -#include "access/strat.h" #include "access/tupdesc.h" #include "catalog/pg_am.h" #include "catalog/pg_class.h" @@ -88,9 +87,8 @@ typedef struct TriggerDesc } TriggerDesc; -/* ---------- +/* * Same for the statistics collector data in Relation and scan data. - * ---------- */ typedef struct PgStat_Info { @@ -138,9 +136,15 @@ typedef struct RelationData /* "struct HeapTupleData *" avoids need to include htup.h here */ Form_pg_am rd_am; /* pg_am tuple for index's AM */ - /* index access support info (used only for an index relation) */ + /* + * index access support info (used only for an index relation) + * + * Note: only operators and support procs for the index's own datatype + * are cached, not any cross-type operators. The arrays are indexed by + * strategy or support number, which is a sufficient identifier given + * that restriction. + */ MemoryContext rd_indexcxt; /* private memory cxt for this stuff */ - IndexStrategy rd_istrat; /* operator strategy map */ Oid *rd_operator; /* OIDs of index operators */ RegProcedure *rd_support; /* OIDs of support procedures */ struct FmgrInfo *rd_supportinfo; /* lookup info for support @@ -241,16 +245,6 @@ typedef Relation *RelationPtr; */ #define RelationGetDescr(relation) ((relation)->rd_att) -/* - * RelationGetIndexStrategy - * Returns index strategy for a relation. - * - * Note: - * Assumes relation descriptor is valid. - * Assumes relation descriptor is for an index relation. - */ -#define RelationGetIndexStrategy(relation) ((relation)->rd_istrat) - /* * RelationGetRelationName *