1 /*-------------------------------------------------------------------------
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
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 ScanKey key
= (ScanKey
) PG_GETARG_POINTER(2);
34 scan
= RelationGetIndexScan(r
, nkeys
, key
);
36 PG_RETURN_POINTER(scan
);
40 gistrescan(PG_FUNCTION_ARGS
)
42 IndexScanDesc scan
= (IndexScanDesc
) PG_GETARG_POINTER(0);
43 ScanKey key
= (ScanKey
) PG_GETARG_POINTER(1);
47 so
= (GISTScanOpaque
) scan
->opaque
;
50 /* rescan an existing indexscan --- reset state */
51 gistfreestack(so
->stack
);
53 /* drop pins on buffers -- no locks held */
54 if (BufferIsValid(so
->curbuf
))
56 ReleaseBuffer(so
->curbuf
);
57 so
->curbuf
= InvalidBuffer
;
62 /* initialize opaque data */
63 so
= (GISTScanOpaque
) palloc(sizeof(GISTScanOpaqueData
));
65 so
->tempCxt
= createTempGistContext();
66 so
->curbuf
= InvalidBuffer
;
67 so
->giststate
= (GISTSTATE
*) palloc(sizeof(GISTSTATE
));
68 initGISTstate(so
->giststate
, scan
->indexRelation
);
74 * Clear all the pointers.
76 ItemPointerSetInvalid(&so
->curpos
);
77 so
->nPageData
= so
->curPageData
= 0;
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
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)
113 gistmarkpos(PG_FUNCTION_ARGS
)
115 elog(ERROR
, "GiST does not support mark/restore");
120 gistrestrpos(PG_FUNCTION_ARGS
)
122 elog(ERROR
, "GiST does not support mark/restore");
127 gistendscan(PG_FUNCTION_ARGS
)
129 IndexScanDesc scan
= (IndexScanDesc
) PG_GETARG_POINTER(0);
132 so
= (GISTScanOpaque
) scan
->opaque
;
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
);
150 gistfreestack(GISTSearchStack
*s
)
154 GISTSearchStack
*p
= s
->next
;