aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access')
-rw-r--r--src/backend/access/gin/ginscan.c55
-rw-r--r--src/backend/access/gist/gistscan.c74
-rw-r--r--src/backend/access/hash/hash.c44
-rw-r--r--src/backend/access/index/genam.c33
-rw-r--r--src/backend/access/index/indexam.c42
-rw-r--r--src/backend/access/nbtree/nbtree.c39
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))