diff options
Diffstat (limited to 'src/backend/access/index')
| -rw-r--r-- | src/backend/access/index/genam.c | 328 | ||||
| -rw-r--r-- | src/backend/access/index/indexam.c | 474 | ||||
| -rw-r--r-- | src/backend/access/index/istrat.c | 1095 |
3 files changed, 979 insertions, 918 deletions
diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c index 52b7b1473b..da7fc0dc09 100644 --- a/src/backend/access/index/genam.c +++ b/src/backend/access/index/genam.c @@ -1,17 +1,17 @@ /*------------------------------------------------------------------------- * * genam.c-- - * general index access method routines + * general index access method routines * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.7 1997/08/19 21:29:26 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.8 1997/09/07 04:38:17 momjian Exp $ * * NOTES - * many of the old access method routines have been turned into - * macros and moved to genam.h -cim 4/30/91 + * many of the old access method routines have been turned into + * macros and moved to genam.h -cim 4/30/91 * *------------------------------------------------------------------------- */ @@ -29,18 +29,18 @@ * previous, current, next. Note that the case of reverse scans works * identically. * - * State Result - * (1) + + - + 0 0 (if the next item pointer is invalid) - * (2) + X - (otherwise) - * (3) * 0 0 * 0 0 (no change) - * (4) + X 0 X 0 0 (shift) - * (5) * + X + X - (shift, add unknown) + * State Result + * (1) + + - + 0 0 (if the next item pointer is invalid) + * (2) + X - (otherwise) + * (3) * 0 0 * 0 0 (no change) + * (4) + X 0 X 0 0 (shift) + * (5) * + X + X - (shift, add unknown) * * All other states cannot occur. * * Note: *It would be possible to cache the status of the previous and - * next item pointer using the flags. + * next item pointer using the flags. * ---------------------------------------------------------------- */ @@ -51,220 +51,234 @@ #include <storage/bufmgr.h> #ifndef HAVE_MEMMOVE -# include <regex/utils.h> +#include <regex/utils.h> #else -# include <string.h> +#include <string.h> #endif /* ---------------------------------------------------------------- - * general access method routines + * general access method routines * - * All indexed access methods use an identical scan structure. - * We don't know how the various AMs do locking, however, so we don't - * do anything about that here. + * All indexed access methods use an identical scan structure. + * We don't know how the various AMs do locking, however, so we don't + * do anything about that here. * - * The intent is that an AM implementor will define a front-end routine - * that calls this one, to fill in the scan, and then does whatever kind - * of locking he wants. + * The intent is that an AM implementor will define a front-end routine + * that calls this one, to fill in the scan, and then does whatever kind + * of locking he wants. * ---------------------------------------------------------------- */ /* ---------------- - * RelationGetIndexScan -- Create and fill an IndexScanDesc. + * RelationGetIndexScan -- Create and fill an IndexScanDesc. * - * This routine creates an index scan structure and sets its contents - * up correctly. This routine calls AMrescan to set up the scan with - * the passed key. + * This routine creates an index scan structure and sets its contents + * up correctly. This routine calls AMrescan to set up the scan with + * the passed key. * - * Parameters: - * relation -- index relation for scan. - * scanFromEnd -- if true, begin scan at one of the index's - * endpoints. - * numberOfKeys -- count of scan keys (more than one won't - * necessarily do anything useful, yet). - * key -- the ScanKey for the starting position of the scan. + * Parameters: + * relation -- index relation for scan. + * scanFromEnd -- if true, begin scan at one of the index's + * endpoints. + * numberOfKeys -- count of scan keys (more than one won't + * necessarily do anything useful, yet). + * key -- the ScanKey for the starting position of the scan. * - * Returns: - * An initialized IndexScanDesc. + * Returns: + * An initialized IndexScanDesc. + * + * Side Effects: + * Bumps the ref count on the relation to keep it in the cache. * - * Side Effects: - * Bumps the ref count on the relation to keep it in the cache. - * * ---------------- */ IndexScanDesc RelationGetIndexScan(Relation relation, - bool scanFromEnd, - uint16 numberOfKeys, - ScanKey key) + bool scanFromEnd, + uint16 numberOfKeys, + ScanKey key) { - IndexScanDesc scan; - - if (! RelationIsValid(relation)) - elog(WARN, "RelationGetIndexScan: relation invalid"); - - scan = (IndexScanDesc) palloc(sizeof(IndexScanDescData)); - - scan->relation = relation; - scan->opaque = NULL; - scan->numberOfKeys = numberOfKeys; - - ItemPointerSetInvalid(&scan->previousItemData); - ItemPointerSetInvalid(&scan->currentItemData); - ItemPointerSetInvalid(&scan->nextItemData); - ItemPointerSetInvalid(&scan->previousMarkData); - ItemPointerSetInvalid(&scan->currentMarkData); - ItemPointerSetInvalid(&scan->nextMarkData); + IndexScanDesc scan; + + if (!RelationIsValid(relation)) + elog(WARN, "RelationGetIndexScan: relation invalid"); + + scan = (IndexScanDesc) palloc(sizeof(IndexScanDescData)); - if (numberOfKeys > 0) { - scan->keyData = (ScanKey) palloc(sizeof(ScanKeyData) * numberOfKeys); - } else { - scan->keyData = NULL; - } + scan->relation = relation; + scan->opaque = NULL; + scan->numberOfKeys = numberOfKeys; + + ItemPointerSetInvalid(&scan->previousItemData); + ItemPointerSetInvalid(&scan->currentItemData); + ItemPointerSetInvalid(&scan->nextItemData); + ItemPointerSetInvalid(&scan->previousMarkData); + ItemPointerSetInvalid(&scan->currentMarkData); + ItemPointerSetInvalid(&scan->nextMarkData); + + if (numberOfKeys > 0) + { + scan->keyData = (ScanKey) palloc(sizeof(ScanKeyData) * numberOfKeys); + } + else + { + scan->keyData = NULL; + } - index_rescan(scan, scanFromEnd, key); - - return (scan); + index_rescan(scan, scanFromEnd, key); + + return (scan); } #ifdef NOT_USED /* ---------------- - * IndexScanRestart -- Restart an index scan. + * IndexScanRestart -- Restart an index scan. * - * This routine isn't used by any existing access method. It's - * appropriate if relation level locks are what you want. + * This routine isn't used by any existing access method. It's + * appropriate if relation level locks are what you want. * - * Returns: - * None. + * Returns: + * None. * - * Side Effects: - * None. + * Side Effects: + * None. * ---------------- */ void IndexScanRestart(IndexScanDesc scan, - bool scanFromEnd, - ScanKey key) + bool scanFromEnd, + ScanKey key) { - if (! IndexScanIsValid(scan)) - elog(WARN, "IndexScanRestart: invalid scan"); - - ItemPointerSetInvalid(&scan->previousItemData); - ItemPointerSetInvalid(&scan->currentItemData); - ItemPointerSetInvalid(&scan->nextItemData); - - if (RelationGetNumberOfBlocks(scan->relation) == 0) - scan->flags = ScanUnmarked; - else if (scanFromEnd) - scan->flags = ScanUnmarked | ScanUncheckedPrevious; - else - scan->flags = ScanUnmarked | ScanUncheckedNext; - - scan->scanFromEnd = (bool) scanFromEnd; - - if (scan->numberOfKeys > 0) - memmove(scan->keyData, - key, - scan->numberOfKeys * sizeof(ScanKeyData)); + if (!IndexScanIsValid(scan)) + elog(WARN, "IndexScanRestart: invalid scan"); + + ItemPointerSetInvalid(&scan->previousItemData); + ItemPointerSetInvalid(&scan->currentItemData); + ItemPointerSetInvalid(&scan->nextItemData); + + if (RelationGetNumberOfBlocks(scan->relation) == 0) + scan->flags = ScanUnmarked; + else if (scanFromEnd) + scan->flags = ScanUnmarked | ScanUncheckedPrevious; + else + scan->flags = ScanUnmarked | ScanUncheckedNext; + + scan->scanFromEnd = (bool) scanFromEnd; + + if (scan->numberOfKeys > 0) + memmove(scan->keyData, + key, + scan->numberOfKeys * sizeof(ScanKeyData)); } + #endif #ifdef NOT_USED /* ---------------- - * IndexScanEnd -- End and index scan. + * IndexScanEnd -- End and index scan. * - * This routine is not used by any existing access method, but is - * suitable for use if you don't want to do sophisticated locking. + * This routine is not used by any existing access method, but is + * suitable for use if you don't want to do sophisticated locking. * - * Returns: - * None. + * Returns: + * None. * - * Side Effects: - * None. + * Side Effects: + * None. * ---------------- */ void IndexScanEnd(IndexScanDesc scan) { - if (! IndexScanIsValid(scan)) - elog(WARN, "IndexScanEnd: invalid scan"); - - pfree(scan); + if (!IndexScanIsValid(scan)) + elog(WARN, "IndexScanEnd: invalid scan"); + + pfree(scan); } + #endif /* ---------------- - * IndexScanMarkPosition -- Mark current position in a scan. + * IndexScanMarkPosition -- Mark current position in a scan. * - * This routine isn't used by any existing access method, but is the - * one that AM implementors should use, if they don't want to do any - * special locking. If relation-level locking is sufficient, this is - * the routine for you. + * This routine isn't used by any existing access method, but is the + * one that AM implementors should use, if they don't want to do any + * special locking. If relation-level locking is sufficient, this is + * the routine for you. * - * Returns: - * None. + * Returns: + * None. * - * Side Effects: - * None. + * Side Effects: + * None. * ---------------- */ void IndexScanMarkPosition(IndexScanDesc scan) { - RetrieveIndexResult result; - - if (scan->flags & ScanUncheckedPrevious) { - result = - index_getnext(scan, BackwardScanDirection); - - if (result != NULL) { - scan->previousItemData = result->index_iptr; - } else { - ItemPointerSetInvalid(&scan->previousItemData); + RetrieveIndexResult result; + + if (scan->flags & ScanUncheckedPrevious) + { + result = + index_getnext(scan, BackwardScanDirection); + + if (result != NULL) + { + scan->previousItemData = result->index_iptr; + } + else + { + ItemPointerSetInvalid(&scan->previousItemData); + } + } - - } else if (scan->flags & ScanUncheckedNext) { - result = (RetrieveIndexResult) - index_getnext(scan, ForwardScanDirection); - - if (result != NULL) { - scan->nextItemData = result->index_iptr; - } else { - ItemPointerSetInvalid(&scan->nextItemData); + else if (scan->flags & ScanUncheckedNext) + { + result = (RetrieveIndexResult) + index_getnext(scan, ForwardScanDirection); + + if (result != NULL) + { + scan->nextItemData = result->index_iptr; + } + else + { + ItemPointerSetInvalid(&scan->nextItemData); + } } - } - - scan->previousMarkData = scan->previousItemData; - scan->currentMarkData = scan->currentItemData; - scan->nextMarkData = scan->nextItemData; - - scan->flags = 0x0; /* XXX should have a symbolic name */ + + scan->previousMarkData = scan->previousItemData; + scan->currentMarkData = scan->currentItemData; + scan->nextMarkData = scan->nextItemData; + + scan->flags = 0x0; /* XXX should have a symbolic name */ } /* ---------------- - * IndexScanRestorePosition -- Restore position on a marked scan. + * IndexScanRestorePosition -- Restore position on a marked scan. * - * This routine isn't used by any existing access method, but is the - * one that AM implementors should use if they don't want to do any - * special locking. If relation-level locking is sufficient, then - * this is the one you want. + * This routine isn't used by any existing access method, but is the + * one that AM implementors should use if they don't want to do any + * special locking. If relation-level locking is sufficient, then + * this is the one you want. * - * Returns: - * None. + * Returns: + * None. * - * Side Effects: - * None. + * Side Effects: + * None. * ---------------- */ void IndexScanRestorePosition(IndexScanDesc scan) -{ - if (scan->flags & ScanUnmarked) - elog(WARN, "IndexScanRestorePosition: no mark to restore"); - - scan->previousItemData = scan->previousMarkData; - scan->currentItemData = scan->currentMarkData; - scan->nextItemData = scan->nextMarkData; - - scan->flags = 0x0; /* XXX should have a symbolic name */ +{ + if (scan->flags & ScanUnmarked) + elog(WARN, "IndexScanRestorePosition: no mark to restore"); + + scan->previousItemData = scan->previousMarkData; + scan->currentItemData = scan->currentMarkData; + scan->nextItemData = scan->nextMarkData; + + scan->flags = 0x0; /* XXX should have a symbolic name */ } diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c index 3068f7ccee..6841899fa3 100644 --- a/src/backend/access/index/indexam.c +++ b/src/backend/access/index/indexam.c @@ -1,80 +1,80 @@ /*------------------------------------------------------------------------- * * indexam.c-- - * general index access method routines + * general index access method routines * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.13 1997/08/26 23:31:28 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.14 1997/09/07 04:38:26 momjian Exp $ * * INTERFACE ROUTINES - * index_open - open an index relation by relationId - * index_openr - open a index relation by name - * index_close - close a index relation - * index_beginscan - start a scan of an index - * index_rescan - restart a scan of an index - * index_endscan - end a scan - * index_insert - insert an index tuple into a relation - * index_delete - delete an item from an index relation - * index_markpos - mark a scan position - * index_restrpos - restore a scan position - * index_getnext - get the next tuple from a scan - * ** index_fetch - retrieve tuple with tid + * index_open - open an index relation by relationId + * index_openr - open a index relation by name + * index_close - close a index relation + * index_beginscan - start a scan of an index + * index_rescan - restart a scan of an index + * index_endscan - end a scan + * index_insert - insert an index tuple into a relation + * index_delete - delete an item from an index relation + * index_markpos - mark a scan position + * index_restrpos - restore a scan position + * index_getnext - get the next tuple from a scan + * ** index_fetch - retrieve tuple with tid * ** index_replace - replace a tuple * ** index_getattr - get an attribute from an index tuple - * index_getprocid - get a support procedure id from the rel tuple - * - * IndexScanIsValid - check index scan + * index_getprocid - get a support procedure id from the rel tuple + * + * IndexScanIsValid - check index scan * * NOTES - * This file contains the index_ routines which used - * to be a scattered collection of stuff in access/genam. + * This file contains the index_ routines which used + * to be a scattered collection of stuff in access/genam. * - * The ** routines: index_fetch, index_replace, and index_getattr - * have not yet been implemented. They may not be needed. + * The ** routines: index_fetch, index_replace, and index_getattr + * have not yet been implemented. They may not be needed. * * old comments - * Scans are implemented as follows: + * Scans are implemented as follows: * - * `0' represents an invalid item pointer. - * `-' represents an unknown item pointer. - * `X' represents a known item pointers. - * `+' represents known or invalid item pointers. - * `*' represents any item pointers. + * `0' represents an invalid item pointer. + * `-' represents an unknown item pointer. + * `X' represents a known item pointers. + * `+' represents known or invalid item pointers. + * `*' represents any item pointers. * - * State is represented by a triple of these symbols in the order of - * previous, current, next. Note that the case of reverse scans works - * identically. + * State is represented by a triple of these symbols in the order of + * previous, current, next. Note that the case of reverse scans works + * identically. * - * State Result - * (1) + + - + 0 0 (if the next item pointer is invalid) - * (2) + X - (otherwise) - * (3) * 0 0 * 0 0 (no change) - * (4) + X 0 X 0 0 (shift) - * (5) * + X + X - (shift, add unknown) + * State Result + * (1) + + - + 0 0 (if the next item pointer is invalid) + * (2) + X - (otherwise) + * (3) * 0 0 * 0 0 (no change) + * (4) + X 0 X 0 0 (shift) + * (5) * + X + X - (shift, add unknown) * - * All other states cannot occur. + * All other states cannot occur. * - * Note: It would be possible to cache the status of the previous and - * next item pointer using the flags. + * Note: It would be possible to cache the status of the previous and + * next item pointer using the flags. * *------------------------------------------------------------------------- */ #include <postgres.h> - -#include <access/genam.h> + +#include <access/genam.h> #include <utils/relcache.h> #include <fmgr.h> #include <storage/lmgr.h> #include <access/heapam.h> /* ---------------- - * undefine macros we aren't going to use that would otherwise - * get in our way.. delete is defined in c.h and the am's are - * defined in heapam.h + * undefine macros we aren't going to use that would otherwise + * get in our way.. delete is defined in c.h and the am's are + * defined in heapam.h * ---------------- */ #undef delete @@ -88,314 +88,320 @@ #undef amgettuple /* ---------------------------------------------------------------- - * macros used in index_ routines + * macros used in index_ routines * ---------------------------------------------------------------- */ #define RELATION_CHECKS \ Assert(RelationIsValid(relation)); \ - Assert(PointerIsValid(relation->rd_am)) - + Assert(PointerIsValid(relation->rd_am)) + #define SCAN_CHECKS \ - Assert(IndexScanIsValid(scan)); \ - Assert(RelationIsValid(scan->relation)); \ - Assert(PointerIsValid(scan->relation->rd_am)) - + Assert(IndexScanIsValid(scan)); \ + Assert(RelationIsValid(scan->relation)); \ + Assert(PointerIsValid(scan->relation->rd_am)) + #define GET_REL_PROCEDURE(x,y) \ - procedure = relation->rd_am->y; \ - if (! RegProcedureIsValid(procedure)) \ - elog(WARN, "index_%s: invalid %s regproc", \ - CppAsString(x), CppAsString(y)) - + procedure = relation->rd_am->y; \ + if (! RegProcedureIsValid(procedure)) \ + elog(WARN, "index_%s: invalid %s regproc", \ + CppAsString(x), CppAsString(y)) + #define GET_SCAN_PROCEDURE(x,y) \ - procedure = scan->relation->rd_am->y; \ - if (! RegProcedureIsValid(procedure)) \ - elog(WARN, "index_%s: invalid %s regproc", \ - CppAsString(x), CppAsString(y)) - - + procedure = scan->relation->rd_am->y; \ + if (! RegProcedureIsValid(procedure)) \ + elog(WARN, "index_%s: invalid %s regproc", \ + CppAsString(x), CppAsString(y)) + + /* ---------------------------------------------------------------- - * index_ interface functions + * index_ interface functions * ---------------------------------------------------------------- */ /* ---------------- - * index_open - open an index relation by relationId + * index_open - open an index relation by relationId * - * presently the relcache routines do all the work we need - * to open/close index relations. + * presently the relcache routines do all the work we need + * to open/close index relations. * ---------------- */ Relation index_open(Oid relationId) { - return RelationIdGetRelation(relationId); + return RelationIdGetRelation(relationId); } /* ---------------- - * index_openr - open a index relation by name + * index_openr - open a index relation by name * - * presently the relcache routines do all the work we need - * to open/close index relations. + * presently the relcache routines do all the work we need + * to open/close index relations. * ---------------- */ Relation index_openr(char *relationName) { - return RelationNameGetRelation(relationName); + return RelationNameGetRelation(relationName); } /* ---------------- - * index_close - close a index relation + * index_close - close a index relation * - * presently the relcache routines do all the work we need - * to open/close index relations. + * presently the relcache routines do all the work we need + * to open/close index relations. * ---------------- */ void index_close(Relation relation) { - RelationClose(relation); + RelationClose(relation); } /* ---------------- - * index_insert - insert an index tuple into a relation + * index_insert - insert an index tuple into a relation * ---------------- */ InsertIndexResult index_insert(Relation relation, - Datum *datum, - char *nulls, - ItemPointer heap_t_ctid, - Relation heapRel) + Datum * datum, + char *nulls, + ItemPointer heap_t_ctid, + Relation heapRel) { - RegProcedure procedure; - InsertIndexResult specificResult; - - RELATION_CHECKS; - GET_REL_PROCEDURE(insert,aminsert); - - /* ---------------- - * have the am's insert proc do all the work. - * ---------------- - */ - specificResult = (InsertIndexResult) - fmgr(procedure, relation, datum, nulls, heap_t_ctid, heapRel, NULL); - - /* ---------------- - * the insert proc is supposed to return a "specific result" and - * this routine has to return a "general result" so after we get - * something back from the insert proc, we allocate a - * "general result" and copy some crap between the two. - * - * As far as I'm concerned all this result shit is needlessly c - * omplicated and should be eliminated. -cim 1/19/91 - * - * mao concurs. regardless of how we feel here, however, it is - * important to free memory we don't intend to return to anyone. - * 2/28/91 - * - * this "general result" crap is now gone. -ay 3/6/95 - * ---------------- - */ - - return (specificResult); + RegProcedure procedure; + InsertIndexResult specificResult; + + RELATION_CHECKS; + GET_REL_PROCEDURE(insert, aminsert); + + /* ---------------- + * have the am's insert proc do all the work. + * ---------------- + */ + specificResult = (InsertIndexResult) + fmgr(procedure, relation, datum, nulls, heap_t_ctid, heapRel, NULL); + + /* ---------------- + * the insert proc is supposed to return a "specific result" and + * this routine has to return a "general result" so after we get + * something back from the insert proc, we allocate a + * "general result" and copy some crap between the two. + * + * As far as I'm concerned all this result shit is needlessly c + * omplicated and should be eliminated. -cim 1/19/91 + * + * mao concurs. regardless of how we feel here, however, it is + * important to free memory we don't intend to return to anyone. + * 2/28/91 + * + * this "general result" crap is now gone. -ay 3/6/95 + * ---------------- + */ + + return (specificResult); } /* ---------------- - * index_delete - delete an item from an index relation + * index_delete - delete an item from an index relation * ---------------- */ void index_delete(Relation relation, ItemPointer indexItem) { - RegProcedure procedure; - - RELATION_CHECKS; - GET_REL_PROCEDURE(delete,amdelete); - - fmgr(procedure, relation, indexItem); + RegProcedure procedure; + + RELATION_CHECKS; + GET_REL_PROCEDURE(delete, amdelete); + + fmgr(procedure, relation, indexItem); } /* ---------------- - * index_beginscan - start a scan of an index + * index_beginscan - start a scan of an index * ---------------- */ IndexScanDesc index_beginscan(Relation relation, - bool scanFromEnd, - uint16 numberOfKeys, - ScanKey key) + bool scanFromEnd, + uint16 numberOfKeys, + ScanKey key) { - IndexScanDesc scandesc; - RegProcedure procedure; - - RELATION_CHECKS; - GET_REL_PROCEDURE(beginscan,ambeginscan); - - RelationSetRIntentLock(relation); - - scandesc = (IndexScanDesc) - fmgr(procedure, relation, scanFromEnd, numberOfKeys, key); - - return scandesc; + IndexScanDesc scandesc; + RegProcedure procedure; + + RELATION_CHECKS; + GET_REL_PROCEDURE(beginscan, ambeginscan); + + RelationSetRIntentLock(relation); + + scandesc = (IndexScanDesc) + fmgr(procedure, relation, scanFromEnd, numberOfKeys, key); + + return scandesc; } /* ---------------- - * index_rescan - restart a scan of an index + * index_rescan - restart a scan of an index * ---------------- */ void index_rescan(IndexScanDesc scan, bool scanFromEnd, ScanKey key) { - RegProcedure procedure; - - SCAN_CHECKS; - GET_SCAN_PROCEDURE(rescan,amrescan); - - fmgr(procedure, scan, scanFromEnd, key); + RegProcedure procedure; + + SCAN_CHECKS; + GET_SCAN_PROCEDURE(rescan, amrescan); + + fmgr(procedure, scan, scanFromEnd, key); } /* ---------------- - * index_endscan - end a scan + * index_endscan - end a scan * ---------------- */ void index_endscan(IndexScanDesc scan) { - RegProcedure procedure; - - SCAN_CHECKS; - GET_SCAN_PROCEDURE(endscan,amendscan); - - fmgr(procedure, scan); - - RelationUnsetRIntentLock(scan->relation); + RegProcedure procedure; + + SCAN_CHECKS; + GET_SCAN_PROCEDURE(endscan, amendscan); + + fmgr(procedure, scan); + + RelationUnsetRIntentLock(scan->relation); } #ifdef NOT_USED /* ---------------- - * index_markpos - mark a scan position + * index_markpos - mark a scan position * ---------------- */ void index_markpos(IndexScanDesc scan) { - RegProcedure procedure; - - SCAN_CHECKS; - GET_SCAN_PROCEDURE(markpos,ammarkpos); - - fmgr(procedure, scan); + RegProcedure procedure; + + SCAN_CHECKS; + GET_SCAN_PROCEDURE(markpos, ammarkpos); + + fmgr(procedure, scan); } + #endif #ifdef NOT_USED /* ---------------- - * index_restrpos - restore a scan position + * index_restrpos - restore a scan position * ---------------- */ void index_restrpos(IndexScanDesc scan) { - RegProcedure procedure; - - SCAN_CHECKS; - GET_SCAN_PROCEDURE(restrpos,amrestrpos); - - fmgr(procedure, scan); + RegProcedure procedure; + + SCAN_CHECKS; + GET_SCAN_PROCEDURE(restrpos, amrestrpos); + + fmgr(procedure, scan); } + #endif /* ---------------- - * index_getnext - get the next tuple from a scan + * index_getnext - get the next tuple from a scan * - * A RetrieveIndexResult is a index tuple/heap tuple pair + * A RetrieveIndexResult is a index tuple/heap tuple pair * ---------------- */ RetrieveIndexResult index_getnext(IndexScanDesc scan, - ScanDirection direction) + ScanDirection direction) { - RegProcedure procedure; - RetrieveIndexResult result; - - SCAN_CHECKS; - GET_SCAN_PROCEDURE(getnext,amgettuple); - - /* ---------------- - * have the am's gettuple proc do all the work. - * ---------------- - */ - result = (RetrieveIndexResult) - fmgr(procedure, scan, direction); - - return result; + RegProcedure procedure; + RetrieveIndexResult result; + + SCAN_CHECKS; + GET_SCAN_PROCEDURE(getnext, amgettuple); + + /* ---------------- + * have the am's gettuple proc do all the work. + * ---------------- + */ + result = (RetrieveIndexResult) + fmgr(procedure, scan, direction); + + return result; } /* ---------------- - * index_getprocid + * index_getprocid * - * Some indexed access methods may require support routines that are - * not in the operator class/operator model imposed by pg_am. These - * access methods may store the OIDs of registered procedures they - * need in pg_amproc. These registered procedure OIDs are ordered in - * a way that makes sense to the access method, and used only by the - * access method. The general index code doesn't know anything about - * the routines involved; it just builds an ordered list of them for - * each attribute on which an index is defined. + * Some indexed access methods may require support routines that are + * not in the operator class/operator model imposed by pg_am. These + * access methods may store the OIDs of registered procedures they + * need in pg_amproc. These registered procedure OIDs are ordered in + * a way that makes sense to the access method, and used only by the + * access method. The general index code doesn't know anything about + * the routines involved; it just builds an ordered list of them for + * each attribute on which an index is defined. * - * This routine returns the requested procedure OID for a particular - * indexed attribute. + * This routine returns the requested procedure OID for a particular + * indexed attribute. * ---------------- */ RegProcedure index_getprocid(Relation irel, - AttrNumber attnum, - uint16 procnum) + AttrNumber attnum, + uint16 procnum) { - RegProcedure *loc; - int natts; - - natts = irel->rd_rel->relnatts; - - loc = irel->rd_support; - - Assert(loc != NULL); - - return (loc[(natts * (procnum - 1)) + (attnum - 1)]); + RegProcedure *loc; + int natts; + + natts = irel->rd_rel->relnatts; + + loc = irel->rd_support; + + Assert(loc != NULL); + + return (loc[(natts * (procnum - 1)) + (attnum - 1)]); } Datum GetIndexValue(HeapTuple tuple, - TupleDesc hTupDesc, - int attOff, - AttrNumber attrNums[], - FuncIndexInfo *fInfo, - bool *attNull, - Buffer buffer) + TupleDesc hTupDesc, + int attOff, + AttrNumber attrNums[], + FuncIndexInfo * fInfo, + bool * attNull, + Buffer buffer) { - Datum returnVal; - bool isNull; - - if (PointerIsValid(fInfo) && FIgetProcOid(fInfo) != InvalidOid) { - int i; - Datum *attData = (Datum *)palloc(FIgetnArgs(fInfo)*sizeof(Datum)); - - for (i = 0; i < FIgetnArgs(fInfo); i++) { - attData[i] = (Datum) heap_getattr(tuple, - buffer, - attrNums[i], - hTupDesc, - attNull); + Datum returnVal; + bool isNull; + + if (PointerIsValid(fInfo) && FIgetProcOid(fInfo) != InvalidOid) + { + int i; + Datum *attData = (Datum *) palloc(FIgetnArgs(fInfo) * sizeof(Datum)); + + for (i = 0; i < FIgetnArgs(fInfo); i++) + { + attData[i] = (Datum) heap_getattr(tuple, + buffer, + attrNums[i], + hTupDesc, + attNull); + } + returnVal = (Datum) fmgr_array_args(FIgetProcOid(fInfo), + FIgetnArgs(fInfo), + (char **) attData, + &isNull); + pfree(attData); + *attNull = FALSE; + } + else + { + returnVal = (Datum) heap_getattr(tuple, buffer, attrNums[attOff], + hTupDesc, attNull); } - returnVal = (Datum)fmgr_array_args(FIgetProcOid(fInfo), - FIgetnArgs(fInfo), - (char **) attData, - &isNull); - pfree(attData); - *attNull = FALSE; - }else { - returnVal = (Datum) heap_getattr(tuple, buffer, attrNums[attOff], - hTupDesc, attNull); - } - return returnVal; + return returnVal; } diff --git a/src/backend/access/index/istrat.c b/src/backend/access/index/istrat.c index 5c143f0aa5..35158c2217 100644 --- a/src/backend/access/index/istrat.c +++ b/src/backend/access/index/istrat.c @@ -1,689 +1,730 @@ /*------------------------------------------------------------------------- * * istrat.c-- - * index scan strategy manipulation code and index strategy manipulation - * operator code. + * index scan strategy manipulation code and index strategy manipulation + * operator code. * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.9 1997/08/22 16:48:14 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.10 1997/09/07 04:38:32 momjian Exp $ * *------------------------------------------------------------------------- */ #include <postgres.h> - + #include <catalog/pg_proc.h> #include <catalog/pg_operator.h> #include <catalog/catname.h> #include <catalog/pg_index.h> #include <catalog/pg_amop.h> #include <catalog/pg_amproc.h> -#include <utils/memutils.h> /* could have been access/itup.h */ +#include <utils/memutils.h> /* could have been access/itup.h */ #include <access/heapam.h> #include <access/istrat.h> #include <fmgr.h> -#ifndef NO_ASSERT_CHECKING -static bool StrategyEvaluationIsValid(StrategyEvaluation evaluation); -static bool StrategyExpressionIsValid(StrategyExpression expression, - StrategyNumber maxStrategy); -static ScanKey StrategyMapGetScanKeyEntry(StrategyMap map, - StrategyNumber strategyNumber); -static bool StrategyOperatorIsValid(StrategyOperator operator, - StrategyNumber maxStrategy); -static bool StrategyTermIsValid(StrategyTerm term, - StrategyNumber maxStrategy); +#ifndef NO_ASSERT_CHECKING +static bool StrategyEvaluationIsValid(StrategyEvaluation evaluation); +static bool +StrategyExpressionIsValid(StrategyExpression expression, + StrategyNumber maxStrategy); +static ScanKey +StrategyMapGetScanKeyEntry(StrategyMap map, + StrategyNumber strategyNumber); +static bool +StrategyOperatorIsValid(StrategyOperator operator, + StrategyNumber maxStrategy); +static bool +StrategyTermIsValid(StrategyTerm term, + StrategyNumber maxStrategy); + #endif /* ---------------------------------------------------------------- - * misc strategy support routines + * misc strategy support routines * ---------------------------------------------------------------- */ - -/* - * StrategyNumberIsValid - * StrategyNumberIsInBounds - * StrategyMapIsValid - * StrategyTransformMapIsValid - * IndexStrategyIsValid + +/* + * StrategyNumberIsValid + * StrategyNumberIsInBounds + * StrategyMapIsValid + * StrategyTransformMapIsValid + * IndexStrategyIsValid * - * ... are now macros in istrat.h -cim 4/27/91 + * ... are now macros in istrat.h -cim 4/27/91 */ - + /* * StrategyMapGetScanKeyEntry -- - * Returns a scan key entry of a index strategy mapping member. + * 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. + * Assumes that the index strategy mapping is valid. + * Assumes that the index strategy number is valid. + * Bounds checking should be done outside this routine. */ -static ScanKey +static ScanKey StrategyMapGetScanKeyEntry(StrategyMap map, - StrategyNumber strategyNumber) + StrategyNumber strategyNumber) { - Assert(StrategyMapIsValid(map)); - Assert(StrategyNumberIsValid(strategyNumber)); - return (&map->entry[strategyNumber - 1]); + Assert(StrategyMapIsValid(map)); + Assert(StrategyNumberIsValid(strategyNumber)); + return (&map->entry[strategyNumber - 1]); } /* * IndexStrategyGetStrategyMap -- - * Returns an index strategy mapping of an index strategy. + * 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. + * 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) + StrategyNumber maxStrategyNum, + AttrNumber attrNum) { - Assert(IndexStrategyIsValid(indexStrategy)); - Assert(StrategyNumberIsValid(maxStrategyNum)); - Assert(AttributeNumberIsValid(attrNum)); - - maxStrategyNum = AMStrategies(maxStrategyNum); /* XXX */ - return - &indexStrategy->strategyMapData[maxStrategyNum * (attrNum - 1)]; + 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. + * Computes the size of an index strategy. */ Size AttributeNumberGetIndexStrategySize(AttrNumber maxAttributeNumber, - StrategyNumber maxStrategyNumber) + StrategyNumber maxStrategyNumber) { - maxStrategyNumber = AMStrategies(maxStrategyNumber); /* XXX */ - return - maxAttributeNumber * maxStrategyNumber * sizeof (ScanKeyData); + maxStrategyNumber = AMStrategies(maxStrategyNumber); /* XXX */ + return + maxAttributeNumber * maxStrategyNumber * sizeof(ScanKeyData); } -#ifndef NO_ASSERT_CHECKING -/* +#ifndef NO_ASSERT_CHECKING +/* * StrategyTransformMapIsValid is now a macro in istrat.h -cim 4/27/91 */ /* ---------------- - * StrategyOperatorIsValid + * StrategyOperatorIsValid * ---------------- */ -static bool +static bool StrategyOperatorIsValid(StrategyOperator operator, - StrategyNumber maxStrategy) + StrategyNumber maxStrategy) { - return (bool) + return (bool) (PointerIsValid(operator) && StrategyNumberIsInBounds(operator->strategy, maxStrategy) && !(operator->flags & ~(SK_NEGATE | SK_COMMUTE))); } /* ---------------- - * StrategyTermIsValid + * StrategyTermIsValid * ---------------- */ -static bool +static bool StrategyTermIsValid(StrategyTerm term, - StrategyNumber maxStrategy) + 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; + 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; + + return true; } /* ---------------- - * StrategyExpressionIsValid + * StrategyExpressionIsValid * ---------------- */ -static bool +static bool StrategyExpressionIsValid(StrategyExpression expression, - StrategyNumber maxStrategy) + 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)); + 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 + * StrategyEvaluationIsValid * ---------------- */ -static bool +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; + Index index; + + if (!PointerIsValid(evaluation) || + !StrategyNumberIsValid(evaluation->maxStrategy) || + !StrategyTransformMapIsValid(evaluation->negateTransform) || + !StrategyTransformMapIsValid(evaluation->commuteTransform) || + !StrategyTransformMapIsValid(evaluation->negateCommuteTransform)) + { + + return false; } - } - return true; + + for (index = 0; index < evaluation->maxStrategy; index += 1) + { + if (!StrategyExpressionIsValid(evaluation->expression[index], + evaluation->maxStrategy)) + { + + return false; + } + } + return true; } + #endif /* ---------------- - * StrategyTermEvaluate + * StrategyTermEvaluate * ---------------- */ -static bool +static bool StrategyTermEvaluate(StrategyTerm term, - StrategyMap map, - Datum left, - Datum right) + StrategyMap map, + Datum left, + Datum right) { - Index index; - long tmpres = 0; - bool result = 0; - StrategyOperator operator; - ScanKey entry; - - for (index = 0, operator = &term->operatorData[0]; - index < term->degree; index += 1, operator += 1) { - - entry = &map->entry[operator->strategy - 1]; - - Assert(RegProcedureIsValid(entry->sk_procedure)); - - switch (operator->flags ^ entry->sk_flags) { - case 0x0: - tmpres = (long) FMGR_PTR2(entry->sk_func, entry->sk_procedure, - left, right); - break; - - case SK_NEGATE: - tmpres = (long) !FMGR_PTR2(entry->sk_func, entry->sk_procedure, - left, right); - break; - - case SK_COMMUTE: - tmpres = (long) FMGR_PTR2(entry->sk_func, entry->sk_procedure, - right, left); - break; - - case SK_NEGATE | SK_COMMUTE: - tmpres = (long) !FMGR_PTR2(entry->sk_func, entry->sk_procedure, - right, left); - break; - - default: - elog(FATAL, "StrategyTermEvaluate: impossible case %d", - operator->flags ^ entry->sk_flags); + Index index; + long tmpres = 0; + bool result = 0; + StrategyOperator operator; + ScanKey entry; + + for (index = 0, operator = &term->operatorData[0]; + index < term->degree; index += 1, operator += 1) + { + + entry = &map->entry[operator->strategy - 1]; + + Assert(RegProcedureIsValid(entry->sk_procedure)); + + switch (operator->flags ^ entry->sk_flags) + { + case 0x0: + tmpres = (long) FMGR_PTR2(entry->sk_func, entry->sk_procedure, + left, right); + break; + + case SK_NEGATE: + tmpres = (long) !FMGR_PTR2(entry->sk_func, entry->sk_procedure, + left, right); + break; + + case SK_COMMUTE: + tmpres = (long) FMGR_PTR2(entry->sk_func, entry->sk_procedure, + right, left); + break; + + case SK_NEGATE | SK_COMMUTE: + tmpres = (long) !FMGR_PTR2(entry->sk_func, entry->sk_procedure, + right, left); + break; + + default: + elog(FATAL, "StrategyTermEvaluate: impossible case %d", + operator->flags ^ entry->sk_flags); + } + + result = (bool) tmpres; + if (!result) + return result; } - - result = (bool) tmpres; - if (!result) - return result; - } - - return result; + + return result; } /* ---------------- - * RelationGetStrategy + * RelationGetStrategy * ---------------- */ StrategyNumber RelationGetStrategy(Relation relation, - AttrNumber attributeNumber, - StrategyEvaluation evaluation, - RegProcedure procedure) + 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(AttributeNumberIsValid(attributeNumber)); - Assert( (attributeNumber >= 1) && (attributeNumber < 1 + 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; + 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(AttributeNumberIsValid(attributeNumber)); + Assert((attributeNumber >= 1) && (attributeNumber < 1 + 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(FATAL, "RelationGetStrategy: impossible case %d", entry->sk_flags); - } - - - if (! StrategyNumberIsInBounds(strategy, evaluation->maxStrategy)) { - if (! StrategyNumberIsValid(strategy)) { - elog(WARN, "RelationGetStrategy: corrupted evaluation"); + + 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(FATAL, "RelationGetStrategy: impossible case %d", entry->sk_flags); } - } - - return strategy; + + + if (!StrategyNumberIsInBounds(strategy, evaluation->maxStrategy)) + { + if (!StrategyNumberIsValid(strategy)) + { + elog(WARN, "RelationGetStrategy: corrupted evaluation"); + } + } + + return strategy; } /* ---------------- - * RelationInvokeStrategy + * RelationInvokeStrategy * ---------------- */ -bool /* XXX someday, this may return Datum */ +bool /* XXX someday, this may return Datum */ RelationInvokeStrategy(Relation relation, - StrategyEvaluation evaluation, - AttrNumber attributeNumber, - StrategyNumber strategy, - Datum left, - Datum right) + 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); + 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->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->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->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); + + 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); + } } - } - - 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; + + 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 (index == (*termP)->degree) { - return - StrategyTermEvaluate(*termP, strategyMap, left, right); - } - - termP += 1; } - } - - elog(WARN, "RelationInvokeStrategy: cannot evaluate strategy %d", - strategy); - /* not reached, just to make compiler happy */ - return FALSE; + 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(WARN, "RelationInvokeStrategy: cannot evaluate strategy %d", + strategy); + + /* not reached, just to make compiler happy */ + return FALSE; } /* ---------------- - * OperatorRelationFillScanKeyEntry + * OperatorRelationFillScanKeyEntry * ---------------- */ static void OperatorRelationFillScanKeyEntry(Relation operatorRelation, - Oid operatorObjectId, - ScanKey entry) + Oid operatorObjectId, + ScanKey entry) { - HeapScanDesc scan; - ScanKeyData scanKeyData; - HeapTuple tuple; - - ScanKeyEntryInitialize(&scanKeyData, 0, - ObjectIdAttributeNumber, - ObjectIdEqualRegProcedure, - ObjectIdGetDatum(operatorObjectId)); - - scan = heap_beginscan(operatorRelation, false, NowTimeQual, - 1, &scanKeyData); - - tuple = heap_getnext(scan, false, (Buffer *)NULL); - if (! HeapTupleIsValid(tuple)) { - elog(WARN, "OperatorObjectIdFillScanKeyEntry: unknown operator %lu", - (uint32) operatorObjectId); - } - - entry->sk_flags = 0; - entry->sk_procedure = - ((OperatorTupleForm) GETSTRUCT(tuple))->oprcode; - fmgr_info(entry->sk_procedure, &entry->sk_func, &entry->sk_nargs); - - if (! RegProcedureIsValid(entry->sk_procedure)) { - elog(WARN, - "OperatorObjectIdFillScanKeyEntry: no procedure for operator %lu", - (uint32) operatorObjectId); - } - - heap_endscan(scan); + HeapScanDesc scan; + ScanKeyData scanKeyData; + HeapTuple tuple; + + ScanKeyEntryInitialize(&scanKeyData, 0, + ObjectIdAttributeNumber, + ObjectIdEqualRegProcedure, + ObjectIdGetDatum(operatorObjectId)); + + scan = heap_beginscan(operatorRelation, false, NowTimeQual, + 1, &scanKeyData); + + tuple = heap_getnext(scan, false, (Buffer *) NULL); + if (!HeapTupleIsValid(tuple)) + { + elog(WARN, "OperatorObjectIdFillScanKeyEntry: unknown operator %lu", + (uint32) operatorObjectId); + } + + entry->sk_flags = 0; + entry->sk_procedure = + ((OperatorTupleForm) GETSTRUCT(tuple))->oprcode; + fmgr_info(entry->sk_procedure, &entry->sk_func, &entry->sk_nargs); + + if (!RegProcedureIsValid(entry->sk_procedure)) + { + elog(WARN, + "OperatorObjectIdFillScanKeyEntry: no procedure for operator %lu", + (uint32) operatorObjectId); + } + + heap_endscan(scan); } /* * IndexSupportInitialize -- - * Initializes an index strategy and associated support procedures. + * Initializes an index strategy and associated support procedures. */ void IndexSupportInitialize(IndexStrategy indexStrategy, - RegProcedure *indexSupport, - Oid indexObjectId, - Oid accessMethodObjectId, - StrategyNumber maxStrategyNumber, - StrategyNumber maxSupportNumber, - AttrNumber maxAttributeNumber) + RegProcedure * indexSupport, + Oid indexObjectId, + Oid accessMethodObjectId, + StrategyNumber maxStrategyNumber, + StrategyNumber maxSupportNumber, + AttrNumber maxAttributeNumber) { - Relation relation; - Relation operatorRelation; - HeapScanDesc scan; - HeapTuple tuple; - ScanKeyData entry[2]; - StrategyMap map; - AttrNumber attributeNumber; - int attributeIndex; - Oid operatorClassObjectId[ MaxIndexAttributeNumber ]; - - maxStrategyNumber = AMStrategies(maxStrategyNumber); - - ScanKeyEntryInitialize(&entry[0], 0, Anum_pg_index_indexrelid, - ObjectIdEqualRegProcedure, - ObjectIdGetDatum(indexObjectId)); - - relation = heap_openr(IndexRelationName); - scan = heap_beginscan(relation, false, NowTimeQual, 1, entry); - tuple = heap_getnext(scan, 0, (Buffer *)NULL); - if (! HeapTupleIsValid(tuple)) - elog(WARN, "IndexSupportInitialize: corrupted catalogs"); - - /* - * XXX note that the following assumes the INDEX tuple is well formed and - * that the key[] and class[] are 0 terminated. - */ - for (attributeIndex=0; attributeIndex<maxAttributeNumber; attributeIndex++) + Relation relation; + Relation operatorRelation; + HeapScanDesc scan; + HeapTuple tuple; + ScanKeyData entry[2]; + StrategyMap map; + AttrNumber attributeNumber; + int attributeIndex; + Oid operatorClassObjectId[MaxIndexAttributeNumber]; + + maxStrategyNumber = AMStrategies(maxStrategyNumber); + + ScanKeyEntryInitialize(&entry[0], 0, Anum_pg_index_indexrelid, + ObjectIdEqualRegProcedure, + ObjectIdGetDatum(indexObjectId)); + + relation = heap_openr(IndexRelationName); + scan = heap_beginscan(relation, false, NowTimeQual, 1, entry); + tuple = heap_getnext(scan, 0, (Buffer *) NULL); + if (!HeapTupleIsValid(tuple)) + elog(WARN, "IndexSupportInitialize: corrupted catalogs"); + + /* + * XXX note that the following assumes the INDEX tuple is well formed + * and that the key[] and class[] are 0 terminated. + */ + for (attributeIndex = 0; attributeIndex < maxAttributeNumber; attributeIndex++) { - IndexTupleForm iform; - - iform = (IndexTupleForm) GETSTRUCT(tuple); - - if (!OidIsValid(iform->indkey[attributeIndex])) { - if (attributeIndex == 0) { - elog(WARN, "IndexSupportInitialize: no pg_index tuple"); + IndexTupleForm iform; + + iform = (IndexTupleForm) GETSTRUCT(tuple); + + if (!OidIsValid(iform->indkey[attributeIndex])) + { + if (attributeIndex == 0) + { + elog(WARN, "IndexSupportInitialize: no pg_index tuple"); + } + break; } - break; - } - - operatorClassObjectId[attributeIndex] - = iform->indclass[attributeIndex]; + + operatorClassObjectId[attributeIndex] + = iform->indclass[attributeIndex]; } - - heap_endscan(scan); - heap_close(relation); - - /* if support routines exist for this access method, load them */ - if (maxSupportNumber > 0) { - - ScanKeyEntryInitialize(&entry[0], 0, Anum_pg_amproc_amid, - ObjectIdEqualRegProcedure, - ObjectIdGetDatum(accessMethodObjectId)); - - ScanKeyEntryInitialize(&entry[1], 0, Anum_pg_amproc_amopclaid, - ObjectIdEqualRegProcedure, 0); - -/* relation = heap_openr(Name_pg_amproc); */ - relation = heap_openr(AccessMethodProcedureRelationName); - - + + heap_endscan(scan); + heap_close(relation); + + /* if support routines exist for this access method, load them */ + if (maxSupportNumber > 0) + { + + ScanKeyEntryInitialize(&entry[0], 0, Anum_pg_amproc_amid, + ObjectIdEqualRegProcedure, + ObjectIdGetDatum(accessMethodObjectId)); + + ScanKeyEntryInitialize(&entry[1], 0, Anum_pg_amproc_amopclaid, + ObjectIdEqualRegProcedure, 0); + +/* relation = heap_openr(Name_pg_amproc); */ + relation = heap_openr(AccessMethodProcedureRelationName); + + + for (attributeNumber = maxAttributeNumber; attributeNumber > 0; + attributeNumber--) + { + + int16 support; + Form_pg_amproc form; + RegProcedure *loc; + + loc = &indexSupport[((attributeNumber - 1) * maxSupportNumber)]; + + for (support = maxSupportNumber; --support >= 0;) + { + loc[support] = InvalidOid; + } + + entry[1].sk_argument = + ObjectIdGetDatum(operatorClassObjectId[attributeNumber - 1]); + + scan = heap_beginscan(relation, false, NowTimeQual, 2, entry); + + while (tuple = heap_getnext(scan, 0, (Buffer *) NULL), + HeapTupleIsValid(tuple)) + { + + form = (Form_pg_amproc) GETSTRUCT(tuple); + loc[(form->amprocnum - 1)] = form->amproc; + } + + heap_endscan(scan); + } + heap_close(relation); + } + + ScanKeyEntryInitialize(&entry[0], 0, + Anum_pg_amop_amopid, + ObjectIdEqualRegProcedure, + ObjectIdGetDatum(accessMethodObjectId)); + + ScanKeyEntryInitialize(&entry[1], 0, + Anum_pg_amop_amopclaid, + ObjectIdEqualRegProcedure, 0); + + relation = heap_openr(AccessMethodOperatorRelationName); + operatorRelation = heap_openr(OperatorRelationName); + for (attributeNumber = maxAttributeNumber; attributeNumber > 0; - attributeNumber--) { - - int16 support; - Form_pg_amproc form; - RegProcedure *loc; - - loc = &indexSupport[((attributeNumber - 1) * maxSupportNumber)]; - - for (support = maxSupportNumber; --support >= 0; ) { - loc[support] = InvalidOid; - } - - entry[1].sk_argument = - ObjectIdGetDatum(operatorClassObjectId[attributeNumber - 1]); - - scan = heap_beginscan(relation, false, NowTimeQual, 2, entry); - - while (tuple = heap_getnext(scan, 0, (Buffer *)NULL), - HeapTupleIsValid(tuple)) { - - form = (Form_pg_amproc) GETSTRUCT(tuple); - loc[(form->amprocnum - 1)] = form->amproc; - } - - heap_endscan(scan); + attributeNumber--) + { + + StrategyNumber strategy; + + entry[1].sk_argument = + ObjectIdGetDatum(operatorClassObjectId[attributeNumber - 1]); + + map = IndexStrategyGetStrategyMap(indexStrategy, + maxStrategyNumber, + attributeNumber); + + for (strategy = 1; strategy <= maxStrategyNumber; strategy++) + ScanKeyEntrySetIllegal(StrategyMapGetScanKeyEntry(map, strategy)); + + scan = heap_beginscan(relation, false, NowTimeQual, 2, entry); + + while (tuple = heap_getnext(scan, 0, (Buffer *) NULL), + HeapTupleIsValid(tuple)) + { + Form_pg_amop form; + + form = (Form_pg_amop) GETSTRUCT(tuple); + + OperatorRelationFillScanKeyEntry(operatorRelation, + form->amopopr, + StrategyMapGetScanKeyEntry(map, form->amopstrategy)); + } + + heap_endscan(scan); } + + heap_close(operatorRelation); heap_close(relation); - } - - ScanKeyEntryInitialize(&entry[0], 0, - Anum_pg_amop_amopid, - ObjectIdEqualRegProcedure, - ObjectIdGetDatum(accessMethodObjectId)); - - ScanKeyEntryInitialize(&entry[1], 0, - Anum_pg_amop_amopclaid, - ObjectIdEqualRegProcedure, 0); - - relation = heap_openr(AccessMethodOperatorRelationName); - operatorRelation = heap_openr(OperatorRelationName); - - for (attributeNumber = maxAttributeNumber; attributeNumber > 0; - attributeNumber--) { - - StrategyNumber strategy; - - entry[1].sk_argument = - ObjectIdGetDatum(operatorClassObjectId[attributeNumber - 1]); - - map = IndexStrategyGetStrategyMap(indexStrategy, - maxStrategyNumber, - attributeNumber); - - for (strategy = 1; strategy <= maxStrategyNumber; strategy++) - ScanKeyEntrySetIllegal(StrategyMapGetScanKeyEntry(map, strategy)); - - scan = heap_beginscan(relation, false, NowTimeQual, 2, entry); - - while (tuple = heap_getnext(scan, 0, (Buffer *)NULL), - HeapTupleIsValid(tuple)) { - Form_pg_amop form; - - form = (Form_pg_amop) GETSTRUCT(tuple); - - OperatorRelationFillScanKeyEntry(operatorRelation, - form->amopopr, - StrategyMapGetScanKeyEntry(map, form->amopstrategy)); - } - - heap_endscan(scan); - } - - heap_close(operatorRelation); - heap_close(relation); } /* ---------------- - * IndexStrategyDisplay + * IndexStrategyDisplay * ---------------- */ #ifdef ISTRATDEBUG int IndexStrategyDisplay(IndexStrategy indexStrategy, - StrategyNumber numberOfStrategies, - int numberOfAttributes) + 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); + 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) */ - +#endif /* defined(ISTRATDEBUG) */ |
