Fix xslt_process() to ensure that it inserts a NULL terminator after the
[PostgreSQL.git] / src / backend / access / gist / gistscan.c
blobcc6bf21d501043c34267e6eb5dccaa57158ce86c
1 /*-------------------------------------------------------------------------
3 * gistscan.c
4 * routines to manage scans on GiST index relations
7 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
8 * Portions Copyright (c) 1994, Regents of the University of California
10 * IDENTIFICATION
11 * $PostgreSQL$
13 *-------------------------------------------------------------------------
15 #include "postgres.h"
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);
26 Datum
27 gistbeginscan(PG_FUNCTION_ARGS)
29 Relation r = (Relation) PG_GETARG_POINTER(0);
30 int nkeys = PG_GETARG_INT32(1);
31 ScanKey key = (ScanKey) PG_GETARG_POINTER(2);
32 IndexScanDesc scan;
34 scan = RelationGetIndexScan(r, nkeys, key);
36 PG_RETURN_POINTER(scan);
39 Datum
40 gistrescan(PG_FUNCTION_ARGS)
42 IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
43 ScanKey key = (ScanKey) PG_GETARG_POINTER(1);
44 GISTScanOpaque so;
45 int i;
47 so = (GISTScanOpaque) scan->opaque;
48 if (so != NULL)
50 /* rescan an existing indexscan --- reset state */
51 gistfreestack(so->stack);
52 so->stack = NULL;
53 /* drop pins on buffers -- no locks held */
54 if (BufferIsValid(so->curbuf))
56 ReleaseBuffer(so->curbuf);
57 so->curbuf = InvalidBuffer;
60 else
62 /* initialize opaque data */
63 so = (GISTScanOpaque) palloc(sizeof(GISTScanOpaqueData));
64 so->stack = NULL;
65 so->tempCxt = createTempGistContext();
66 so->curbuf = InvalidBuffer;
67 so->giststate = (GISTSTATE *) palloc(sizeof(GISTSTATE));
68 initGISTstate(so->giststate, scan->indexRelation);
70 scan->opaque = so;
74 * Clear all the pointers.
76 ItemPointerSetInvalid(&so->curpos);
77 so->nPageData = so->curPageData = 0;
79 so->qual_ok = true;
81 /* Update scan key, if a new one is given */
82 if (key && scan->numberOfKeys > 0)
84 memmove(scan->keyData, key,
85 scan->numberOfKeys * sizeof(ScanKeyData));
88 * Modify the scan key so that all the Consistent method is called for
89 * all comparisons. The original operator is passed to the Consistent
90 * function in the form of its strategy number, which is available
91 * from the sk_strategy field, and its subtype from the sk_subtype
92 * field.
94 * Next, if any of keys is a NULL and that key is not marked with
95 * SK_SEARCHNULL then nothing can be found.
97 for (i = 0; i < scan->numberOfKeys; i++)
99 scan->keyData[i].sk_func = so->giststate->consistentFn[scan->keyData[i].sk_attno - 1];
101 if (scan->keyData[i].sk_flags & SK_ISNULL)
103 if ((scan->keyData[i].sk_flags & SK_SEARCHNULL) == 0)
104 so->qual_ok = false;
109 PG_RETURN_VOID();
112 Datum
113 gistmarkpos(PG_FUNCTION_ARGS)
115 elog(ERROR, "GiST does not support mark/restore");
116 PG_RETURN_VOID();
119 Datum
120 gistrestrpos(PG_FUNCTION_ARGS)
122 elog(ERROR, "GiST does not support mark/restore");
123 PG_RETURN_VOID();
126 Datum
127 gistendscan(PG_FUNCTION_ARGS)
129 IndexScanDesc scan = (IndexScanDesc) PG_GETARG_POINTER(0);
130 GISTScanOpaque so;
132 so = (GISTScanOpaque) scan->opaque;
134 if (so != NULL)
136 gistfreestack(so->stack);
137 if (so->giststate != NULL)
138 freeGISTstate(so->giststate);
139 /* drop pins on buffers -- we aren't holding any locks */
140 if (BufferIsValid(so->curbuf))
141 ReleaseBuffer(so->curbuf);
142 MemoryContextDelete(so->tempCxt);
143 pfree(scan->opaque);
146 PG_RETURN_VOID();
149 static void
150 gistfreestack(GISTSearchStack *s)
152 while (s != NULL)
154 GISTSearchStack *p = s->next;
156 pfree(s);
157 s = p;