1 /*-------------------------------------------------------------------------
4 * routines to manage scans on GiST index relations
7 * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/backend/access/gist/gistscan.c
13 *-------------------------------------------------------------------------
17 #include "access/genam.h"
18 #include "access/gist_private.h"
19 #include "access/gistscan.h"
20 #include "access/relscan.h"
21 #include "storage/bufmgr.h"
22 #include "utils/memutils.h"
24 static void gistfreestack(GISTSearchStack *s);
27 gistbeginscan(PG_FUNCTION_ARGS)
29 Relation r = (Relation) PG_GETARG_POINTER(0);
30 int nkeys = PG_GETARG_INT32(1);
31 int norderbys = PG_GETARG_INT32(2);
35 /* no order by operators allowed */
36 Assert(norderbys == 0);
38 scan = RelationGetIndexScan(r, nkeys, norderbys);
40 /* initialize opaque data */
41 so = (GISTScanOpaque) palloc(sizeof(GISTScanOpaqueData));
43 so->tempCxt = createTempGistContext();
44 so->curbuf = InvalidBuffer;
45 so->giststate = (GISTSTATE *) palloc(sizeof(GISTSTATE));
46 initGISTstate(so->giststate, scan->indexRelation);
50 PG_RETURN_POINTER(scan);
54 gistrescan(PG_FUNCTION_ARGS)
56 IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
57 ScanKey key = (ScanKey) PG_GETARG_POINTER(1);
58 /* remaining arguments are ignored */
59 GISTScanOpaque so = (GISTScanOpaque) scan->opaque;
62 /* rescan an existing indexscan --- reset state */
63 gistfreestack(so->stack);
65 /* drop pins on buffers -- no locks held */
66 if (BufferIsValid(so->curbuf))
68 ReleaseBuffer(so->curbuf);
69 so->curbuf = InvalidBuffer;
73 * Clear all the pointers.
75 ItemPointerSetInvalid(&so->curpos);
76 so->nPageData = so->curPageData = 0;
80 /* Update scan key, if a new one is given */
81 if (key && scan->numberOfKeys > 0)
83 memmove(scan->keyData, key,
84 scan->numberOfKeys * sizeof(ScanKeyData));
87 * Modify the scan key so that all the Consistent method is called for
88 * all comparisons. The original operator is passed to the Consistent
89 * function in the form of its strategy number, which is available
90 * from the sk_strategy field, and its subtype from the sk_subtype
93 * Next, if any of keys is a NULL and that key is not marked with
94 * SK_SEARCHNULL/SK_SEARCHNOTNULL then nothing can be found (ie, we
95 * assume all indexable operators are strict).
97 for (i = 0; i < scan->numberOfKeys; i++)
99 ScanKey skey = &(scan->keyData[i]);
101 skey->sk_func = so->giststate->consistentFn[skey->sk_attno - 1];
103 if (skey->sk_flags & SK_ISNULL)
105 if (!(skey->sk_flags & (SK_SEARCHNULL | SK_SEARCHNOTNULL)))
115 gistmarkpos(PG_FUNCTION_ARGS)
117 elog(ERROR, "GiST does not support mark/restore");
122 gistrestrpos(PG_FUNCTION_ARGS)
124 elog(ERROR, "GiST does not support mark/restore");
129 gistendscan(PG_FUNCTION_ARGS)
131 IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
132 GISTScanOpaque so = (GISTScanOpaque) scan->opaque;
134 gistfreestack(so->stack);
135 if (so->giststate != NULL)
136 freeGISTstate(so->giststate);
137 /* drop pins on buffers -- we aren't holding any locks */
138 if (BufferIsValid(so->curbuf))
139 ReleaseBuffer(so->curbuf);
140 MemoryContextDelete(so->tempCxt);
147 gistfreestack(GISTSearchStack *s)
151 GISTSearchStack *p = s->next;