diff options
Diffstat (limited to 'src/backend/access')
-rw-r--r-- | src/backend/access/gin/ginscan.c | 55 | ||||
-rw-r--r-- | src/backend/access/gist/gistscan.c | 74 | ||||
-rw-r--r-- | src/backend/access/hash/hash.c | 44 | ||||
-rw-r--r-- | src/backend/access/index/genam.c | 33 | ||||
-rw-r--r-- | src/backend/access/index/indexam.c | 42 | ||||
-rw-r--r-- | src/backend/access/nbtree/nbtree.c | 39 |
6 files changed, 144 insertions, 143 deletions
diff --git a/src/backend/access/gin/ginscan.c b/src/backend/access/gin/ginscan.c index a6604c4c934..3a5e52dc383 100644 --- a/src/backend/access/gin/ginscan.c +++ b/src/backend/access/gin/ginscan.c @@ -26,11 +26,28 @@ Datum ginbeginscan(PG_FUNCTION_ARGS) { Relation rel = (Relation) PG_GETARG_POINTER(0); - int keysz = PG_GETARG_INT32(1); - ScanKey scankey = (ScanKey) PG_GETARG_POINTER(2); + int nkeys = PG_GETARG_INT32(1); + int norderbys = PG_GETARG_INT32(2); IndexScanDesc scan; + GinScanOpaque so; + + /* no order by operators allowed */ + Assert(norderbys == 0); + + scan = RelationGetIndexScan(rel, nkeys, norderbys); + + /* allocate private workspace */ + so = (GinScanOpaque) palloc(sizeof(GinScanOpaqueData)); + so->keys = NULL; + so->nkeys = 0; + so->tempCtx = AllocSetContextCreate(CurrentMemoryContext, + "Gin scan temporary context", + ALLOCSET_DEFAULT_MINSIZE, + ALLOCSET_DEFAULT_INITSIZE, + ALLOCSET_DEFAULT_MAXSIZE); + initGinState(&so->ginstate, scan->indexRelation); - scan = RelationGetIndexScan(rel, keysz, scankey); + scan->opaque = so; PG_RETURN_POINTER(scan); } @@ -241,27 +258,10 @@ ginrescan(PG_FUNCTION_ARGS) { IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0); ScanKey scankey = (ScanKey) PG_GETARG_POINTER(1); - GinScanOpaque so; - - so = (GinScanOpaque) scan->opaque; - - if (so == NULL) - { - /* if called from ginbeginscan */ - so = (GinScanOpaque) palloc(sizeof(GinScanOpaqueData)); - so->tempCtx = AllocSetContextCreate(CurrentMemoryContext, - "Gin scan temporary context", - ALLOCSET_DEFAULT_MINSIZE, - ALLOCSET_DEFAULT_INITSIZE, - ALLOCSET_DEFAULT_MAXSIZE); - initGinState(&so->ginstate, scan->indexRelation); - scan->opaque = so; - } - else - { - freeScanKeys(so->keys, so->nkeys); - } + /* remaining arguments are ignored */ + GinScanOpaque so = (GinScanOpaque) scan->opaque; + freeScanKeys(so->keys, so->nkeys); so->keys = NULL; if (scankey && scan->numberOfKeys > 0) @@ -280,14 +280,11 @@ ginendscan(PG_FUNCTION_ARGS) IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0); GinScanOpaque so = (GinScanOpaque) scan->opaque; - if (so != NULL) - { - freeScanKeys(so->keys, so->nkeys); + freeScanKeys(so->keys, so->nkeys); - MemoryContextDelete(so->tempCtx); + MemoryContextDelete(so->tempCtx); - pfree(so); - } + pfree(so); PG_RETURN_VOID(); } diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c index 21f4ea54b7d..106714511a8 100644 --- a/src/backend/access/gist/gistscan.c +++ b/src/backend/access/gist/gistscan.c @@ -28,10 +28,24 @@ gistbeginscan(PG_FUNCTION_ARGS) { Relation r = (Relation) PG_GETARG_POINTER(0); int nkeys = PG_GETARG_INT32(1); - ScanKey key = (ScanKey) PG_GETARG_POINTER(2); + int norderbys = PG_GETARG_INT32(2); IndexScanDesc scan; + GISTScanOpaque so; + + /* no order by operators allowed */ + Assert(norderbys == 0); + + scan = RelationGetIndexScan(r, nkeys, norderbys); + + /* initialize opaque data */ + so = (GISTScanOpaque) palloc(sizeof(GISTScanOpaqueData)); + so->stack = NULL; + so->tempCxt = createTempGistContext(); + so->curbuf = InvalidBuffer; + so->giststate = (GISTSTATE *) palloc(sizeof(GISTSTATE)); + initGISTstate(so->giststate, scan->indexRelation); - scan = RelationGetIndexScan(r, nkeys, key); + scan->opaque = so; PG_RETURN_POINTER(scan); } @@ -41,33 +55,18 @@ gistrescan(PG_FUNCTION_ARGS) { IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0); ScanKey key = (ScanKey) PG_GETARG_POINTER(1); - GISTScanOpaque so; + /* remaining arguments are ignored */ + GISTScanOpaque so = (GISTScanOpaque) scan->opaque; int i; - so = (GISTScanOpaque) scan->opaque; - if (so != NULL) + /* rescan an existing indexscan --- reset state */ + gistfreestack(so->stack); + so->stack = NULL; + /* drop pins on buffers -- no locks held */ + if (BufferIsValid(so->curbuf)) { - /* rescan an existing indexscan --- reset state */ - gistfreestack(so->stack); - so->stack = NULL; - /* drop pins on buffers -- no locks held */ - if (BufferIsValid(so->curbuf)) - { - ReleaseBuffer(so->curbuf); - so->curbuf = InvalidBuffer; - } - } - else - { - /* initialize opaque data */ - so = (GISTScanOpaque) palloc(sizeof(GISTScanOpaqueData)); - so->stack = NULL; - so->tempCxt = createTempGistContext(); + ReleaseBuffer(so->curbuf); so->curbuf = InvalidBuffer; - so->giststate = (GISTSTATE *) palloc(sizeof(GISTSTATE)); - initGISTstate(so->giststate, scan->indexRelation); - - scan->opaque = so; } /* @@ -130,21 +129,16 @@ Datum gistendscan(PG_FUNCTION_ARGS) { IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0); - GISTScanOpaque so; - - so = (GISTScanOpaque) scan->opaque; - - if (so != NULL) - { - gistfreestack(so->stack); - if (so->giststate != NULL) - freeGISTstate(so->giststate); - /* drop pins on buffers -- we aren't holding any locks */ - if (BufferIsValid(so->curbuf)) - ReleaseBuffer(so->curbuf); - MemoryContextDelete(so->tempCxt); - pfree(scan->opaque); - } + GISTScanOpaque so = (GISTScanOpaque) scan->opaque; + + gistfreestack(so->stack); + if (so->giststate != NULL) + freeGISTstate(so->giststate); + /* drop pins on buffers -- we aren't holding any locks */ + if (BufferIsValid(so->curbuf)) + ReleaseBuffer(so->curbuf); + MemoryContextDelete(so->tempCxt); + pfree(so); PG_RETURN_VOID(); } diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c index bb46446d713..e53ec3d5eaa 100644 --- a/src/backend/access/hash/hash.c +++ b/src/backend/access/hash/hash.c @@ -366,12 +366,16 @@ Datum hashbeginscan(PG_FUNCTION_ARGS) { Relation rel = (Relation) PG_GETARG_POINTER(0); - int keysz = PG_GETARG_INT32(1); - ScanKey scankey = (ScanKey) PG_GETARG_POINTER(2); + int nkeys = PG_GETARG_INT32(1); + int norderbys = PG_GETARG_INT32(2); IndexScanDesc scan; HashScanOpaque so; - scan = RelationGetIndexScan(rel, keysz, scankey); + /* no order by operators allowed */ + Assert(norderbys == 0); + + scan = RelationGetIndexScan(rel, nkeys, norderbys); + so = (HashScanOpaque) palloc(sizeof(HashScanOpaqueData)); so->hashso_bucket_valid = false; so->hashso_bucket_blkno = 0; @@ -396,26 +400,23 @@ hashrescan(PG_FUNCTION_ARGS) { IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0); ScanKey scankey = (ScanKey) PG_GETARG_POINTER(1); + /* remaining arguments are ignored */ HashScanOpaque so = (HashScanOpaque) scan->opaque; Relation rel = scan->indexRelation; - /* if we are called from beginscan, so is still NULL */ - if (so) - { - /* release any pin we still hold */ - if (BufferIsValid(so->hashso_curbuf)) - _hash_dropbuf(rel, so->hashso_curbuf); - so->hashso_curbuf = InvalidBuffer; - - /* release lock on bucket, too */ - if (so->hashso_bucket_blkno) - _hash_droplock(rel, so->hashso_bucket_blkno, HASH_SHARE); - so->hashso_bucket_blkno = 0; - - /* set position invalid (this will cause _hash_first call) */ - ItemPointerSetInvalid(&(so->hashso_curpos)); - ItemPointerSetInvalid(&(so->hashso_heappos)); - } + /* release any pin we still hold */ + if (BufferIsValid(so->hashso_curbuf)) + _hash_dropbuf(rel, so->hashso_curbuf); + so->hashso_curbuf = InvalidBuffer; + + /* release lock on bucket, too */ + if (so->hashso_bucket_blkno) + _hash_droplock(rel, so->hashso_bucket_blkno, HASH_SHARE); + so->hashso_bucket_blkno = 0; + + /* set position invalid (this will cause _hash_first call) */ + ItemPointerSetInvalid(&(so->hashso_curpos)); + ItemPointerSetInvalid(&(so->hashso_heappos)); /* Update scan key, if a new one is given */ if (scankey && scan->numberOfKeys > 0) @@ -423,8 +424,7 @@ hashrescan(PG_FUNCTION_ARGS) memmove(scan->keyData, scankey, scan->numberOfKeys * sizeof(ScanKeyData)); - if (so) - so->hashso_bucket_valid = false; + so->hashso_bucket_valid = false; } PG_RETURN_VOID(); diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c index cd0212aa94d..d0eaa36b3b5 100644 --- a/src/backend/access/index/genam.c +++ b/src/backend/access/index/genam.c @@ -57,22 +57,20 @@ /* ---------------- * 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 up initial + * contents for it. * * Parameters: * indexRelation -- index relation for scan. - * nkeys -- count of scan keys. - * key -- array of scan keys to restrict the index scan. + * nkeys -- count of scan keys (index qual conditions). + * norderbys -- count of index order-by operators. * * Returns: * An initialized IndexScanDesc. * ---------------- */ IndexScanDesc -RelationGetIndexScan(Relation indexRelation, - int nkeys, ScanKey key) +RelationGetIndexScan(Relation indexRelation, int nkeys, int norderbys) { IndexScanDesc scan; @@ -82,15 +80,19 @@ RelationGetIndexScan(Relation indexRelation, scan->indexRelation = indexRelation; scan->xs_snapshot = SnapshotNow; /* may be set later */ scan->numberOfKeys = nkeys; + scan->numberOfOrderBys = norderbys; /* - * We allocate the key space here, but the AM is responsible for actually - * filling it from the passed key array. + * We allocate key workspace here, but it won't get filled until amrescan. */ if (nkeys > 0) scan->keyData = (ScanKey) palloc(sizeof(ScanKeyData) * nkeys); else scan->keyData = NULL; + if (norderbys > 0) + scan->orderByData = (ScanKey) palloc(sizeof(ScanKeyData) * norderbys); + else + scan->orderByData = NULL; /* * During recovery we ignore killed tuples and don't bother to kill them @@ -115,11 +117,6 @@ RelationGetIndexScan(Relation indexRelation, scan->xs_next_hot = InvalidOffsetNumber; scan->xs_prev_xmax = InvalidTransactionId; - /* - * Let the AM fill in the key and any opaque data it wants. - */ - index_rescan(scan, key); - return scan; } @@ -140,6 +137,8 @@ IndexScanEnd(IndexScanDesc scan) { if (scan->keyData != NULL) pfree(scan->keyData); + if (scan->orderByData != NULL) + pfree(scan->orderByData); pfree(scan); } @@ -286,7 +285,8 @@ systable_beginscan(Relation heapRelation, } sysscan->iscan = index_beginscan(heapRelation, irel, - snapshot, nkeys, key); + snapshot, nkeys, 0); + index_rescan(sysscan->iscan, key, nkeys, NULL, 0); sysscan->scan = NULL; } else @@ -450,7 +450,8 @@ systable_beginscan_ordered(Relation heapRelation, } sysscan->iscan = index_beginscan(heapRelation, indexRelation, - snapshot, nkeys, key); + snapshot, nkeys, 0); + index_rescan(sysscan->iscan, key, nkeys, NULL, 0); sysscan->scan = NULL; return sysscan; diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c index d151ffda8c0..8c79c6149b6 100644 --- a/src/backend/access/index/indexam.c +++ b/src/backend/access/index/indexam.c @@ -114,7 +114,7 @@ do { \ } while(0) static IndexScanDesc index_beginscan_internal(Relation indexRelation, - int nkeys, ScanKey key); + int nkeys, int norderbys); /* ---------------------------------------------------------------- @@ -213,11 +213,11 @@ IndexScanDesc index_beginscan(Relation heapRelation, Relation indexRelation, Snapshot snapshot, - int nkeys, ScanKey key) + int nkeys, int norderbys) { IndexScanDesc scan; - scan = index_beginscan_internal(indexRelation, nkeys, key); + scan = index_beginscan_internal(indexRelation, nkeys, norderbys); /* * Save additional parameters into the scandesc. Everything else was set @@ -238,11 +238,11 @@ index_beginscan(Relation heapRelation, IndexScanDesc index_beginscan_bitmap(Relation indexRelation, Snapshot snapshot, - int nkeys, ScanKey key) + int nkeys) { IndexScanDesc scan; - scan = index_beginscan_internal(indexRelation, nkeys, key); + scan = index_beginscan_internal(indexRelation, nkeys, 0); /* * Save additional parameters into the scandesc. Everything else was set @@ -258,7 +258,7 @@ index_beginscan_bitmap(Relation indexRelation, */ static IndexScanDesc index_beginscan_internal(Relation indexRelation, - int nkeys, ScanKey key) + int nkeys, int norderbys) { IndexScanDesc scan; FmgrInfo *procedure; @@ -278,7 +278,7 @@ index_beginscan_internal(Relation indexRelation, DatumGetPointer(FunctionCall3(procedure, PointerGetDatum(indexRelation), Int32GetDatum(nkeys), - PointerGetDatum(key))); + Int32GetDatum(norderbys))); return scan; } @@ -286,23 +286,28 @@ index_beginscan_internal(Relation indexRelation, /* ---------------- * index_rescan - (re)start a scan of an index * - * The caller may specify a new set of scankeys (but the number of keys - * cannot change). To restart the scan without changing keys, pass NULL - * for the key array. - * - * Note that this is also called when first starting an indexscan; - * see RelationGetIndexScan. Keys *must* be passed in that case, - * unless scan->numberOfKeys is zero. + * During a restart, the caller may specify a new set of scankeys and/or + * orderbykeys; but the number of keys cannot differ from what index_beginscan + * was told. (Later we might relax that to "must not exceed", but currently + * the index AMs tend to assume that scan->numberOfKeys is what to believe.) + * To restart the scan without changing keys, pass NULL for the key arrays. + * (Of course, keys *must* be passed on the first call, unless + * scan->numberOfKeys is zero.) * ---------------- */ void -index_rescan(IndexScanDesc scan, ScanKey key) +index_rescan(IndexScanDesc scan, + ScanKey keys, int nkeys, + ScanKey orderbys, int norderbys) { FmgrInfo *procedure; SCAN_CHECKS; GET_SCAN_PROCEDURE(amrescan); + Assert(nkeys == scan->numberOfKeys); + Assert(norderbys == scan->numberOfOrderBys); + /* Release any held pin on a heap page */ if (BufferIsValid(scan->xs_cbuf)) { @@ -314,9 +319,12 @@ index_rescan(IndexScanDesc scan, ScanKey key) scan->kill_prior_tuple = false; /* for safety */ - FunctionCall2(procedure, + FunctionCall5(procedure, PointerGetDatum(scan), - PointerGetDatum(key)); + PointerGetDatum(keys), + Int32GetDatum(nkeys), + PointerGetDatum(orderbys), + Int32GetDatum(norderbys)); } /* ---------------- diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index 46aeb9e6adb..655a40090e9 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -337,12 +337,27 @@ Datum btbeginscan(PG_FUNCTION_ARGS) { Relation rel = (Relation) PG_GETARG_POINTER(0); - int keysz = PG_GETARG_INT32(1); - ScanKey scankey = (ScanKey) PG_GETARG_POINTER(2); + int nkeys = PG_GETARG_INT32(1); + int norderbys = PG_GETARG_INT32(2); IndexScanDesc scan; + BTScanOpaque so; + + /* no order by operators allowed */ + Assert(norderbys == 0); /* get the scan */ - scan = RelationGetIndexScan(rel, keysz, scankey); + scan = RelationGetIndexScan(rel, nkeys, norderbys); + + /* allocate private workspace */ + so = (BTScanOpaque) palloc(sizeof(BTScanOpaqueData)); + so->currPos.buf = so->markPos.buf = InvalidBuffer; + if (scan->numberOfKeys > 0) + so->keyData = (ScanKey) palloc(scan->numberOfKeys * sizeof(ScanKeyData)); + else + so->keyData = NULL; + so->killedItems = NULL; /* until needed */ + so->numKilled = 0; + scan->opaque = so; PG_RETURN_POINTER(scan); } @@ -355,22 +370,8 @@ btrescan(PG_FUNCTION_ARGS) { IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0); ScanKey scankey = (ScanKey) PG_GETARG_POINTER(1); - BTScanOpaque so; - - so = (BTScanOpaque) scan->opaque; - - if (so == NULL) /* if called from btbeginscan */ - { - so = (BTScanOpaque) palloc(sizeof(BTScanOpaqueData)); - so->currPos.buf = so->markPos.buf = InvalidBuffer; - if (scan->numberOfKeys > 0) - so->keyData = (ScanKey) palloc(scan->numberOfKeys * sizeof(ScanKeyData)); - else - so->keyData = NULL; - so->killedItems = NULL; /* until needed */ - so->numKilled = 0; - scan->opaque = so; - } + /* remaining arguments are ignored */ + BTScanOpaque so = (BTScanOpaque) scan->opaque; /* we aren't holding any read locks, but gotta drop the pins */ if (BTScanPosIsValid(so->currPos)) |