summaryrefslogtreecommitdiff
path: root/src/backend/access/gin
diff options
context:
space:
mode:
authorTeodor Sigaev <teodor@sigaev.ru>2007-01-31 15:09:45 +0000
committerTeodor Sigaev <teodor@sigaev.ru>2007-01-31 15:09:45 +0000
commitd4c6da152782b580b24cd8b4054eb1b7fb72c5a0 (patch)
tree23db426588b5ff2a39981393a3cc4b48397b4294 /src/backend/access/gin
parent147a3ce149088c913b152e7d37bb92f61bb068dd (diff)
downloadpostgresql-d4c6da152782b580b24cd8b4054eb1b7fb72c5a0.tar.gz
Allow GIN's extractQuery method to signal that nothing can satisfy the query.
In this case extractQuery should returns -1 as nentries. This changes prototype of extractQuery method to use int32* instead of uint32* for nentries argument. Based on that gincostestimate may see two corner cases: nothing will be found or seqscan should be used. Per proposal at http://archives.postgresql.org/pgsql-hackers/2007-01/msg01581.php PS tsearch_core patch should be sightly modified to support changes, but I'm waiting a verdict about reviewing of tsearch_core patch.
Diffstat (limited to 'src/backend/access/gin')
-rw-r--r--src/backend/access/gin/ginarrayproc.c19
-rw-r--r--src/backend/access/gin/ginbulk.c6
-rw-r--r--src/backend/access/gin/ginget.c13
-rw-r--r--src/backend/access/gin/gininsert.c6
-rw-r--r--src/backend/access/gin/ginscan.c17
-rw-r--r--src/backend/access/gin/ginutil.c6
6 files changed, 50 insertions, 17 deletions
diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c
index fd505333bc..a46def63c5 100644
--- a/src/backend/access/gin/ginarrayproc.c
+++ b/src/backend/access/gin/ginarrayproc.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/gin/ginarrayproc.c,v 1.8 2007/01/05 22:19:21 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gin/ginarrayproc.c,v 1.9 2007/01/31 15:09:45 teodor Exp $
*-------------------------------------------------------------------------
*/
#include "postgres.h"
@@ -38,7 +38,7 @@ Datum
ginarrayextract(PG_FUNCTION_ARGS)
{
ArrayType *array;
- uint32 *nentries = (uint32 *) PG_GETARG_POINTER(1);
+ int32 *nentries = (int32 *) PG_GETARG_POINTER(1);
Datum *entries = NULL;
int16 elmlen;
bool elmbyval;
@@ -60,6 +60,21 @@ ginarrayextract(PG_FUNCTION_ARGS)
elmlen, elmbyval, elmalign,
&entries, NULL, (int *) nentries);
+ if ( *nentries == 0 && PG_NARGS() == 3 )
+ {
+ switch( PG_GETARG_UINT16(2) )
+ {
+ case GinOverlapStrategy:
+ *nentries = -1; /* nobody can be found */
+ break;
+ case GinContainsStrategy:
+ case GinContainedStrategy:
+ case GinEqualStrategy:
+ default: /* require fullscan: GIN can't find void arrays */
+ break;
+ }
+ }
+
/* we should not free array, entries[i] points into it */
PG_RETURN_POINTER(entries);
}
diff --git a/src/backend/access/gin/ginbulk.c b/src/backend/access/gin/ginbulk.c
index f45d5b6395..d3b6f0bceb 100644
--- a/src/backend/access/gin/ginbulk.c
+++ b/src/backend/access/gin/ginbulk.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/gin/ginbulk.c,v 1.7 2007/01/05 22:19:21 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gin/ginbulk.c,v 1.8 2007/01/31 15:09:45 teodor Exp $
*-------------------------------------------------------------------------
*/
@@ -191,13 +191,13 @@ ginChooseElem(BuildAccumulator *accum, ItemPointer heapptr, Datum *entries, uint
* next middle on left part and middle of right part.
*/
void
-ginInsertRecordBA(BuildAccumulator *accum, ItemPointer heapptr, Datum *entries, uint32 nentry)
+ginInsertRecordBA(BuildAccumulator *accum, ItemPointer heapptr, Datum *entries, int32 nentry)
{
uint32 i,
nbit = 0,
offset;
- if (nentry == 0)
+ if (nentry <= 0)
return;
i = nentry - 1;
diff --git a/src/backend/access/gin/ginget.c b/src/backend/access/gin/ginget.c
index 11f034bb21..2366f3f727 100644
--- a/src/backend/access/gin/ginget.c
+++ b/src/backend/access/gin/ginget.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/gin/ginget.c,v 1.5 2007/01/05 22:19:21 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gin/ginget.c,v 1.6 2007/01/31 15:09:45 teodor Exp $
*-------------------------------------------------------------------------
*/
@@ -420,6 +420,7 @@ scanGetItem(IndexScanDesc scan, ItemPointerData *item)
}
#define GinIsNewKey(s) ( ((GinScanOpaque) scan->opaque)->keys == NULL )
+#define GinIsVoidRes(s) ( ((GinScanOpaque) scan->opaque)->isVoidRes == true )
Datum
gingetmulti(PG_FUNCTION_ARGS)
@@ -432,10 +433,13 @@ gingetmulti(PG_FUNCTION_ARGS)
if (GinIsNewKey(scan))
newScanKey(scan);
- startScan(scan);
-
*returned_tids = 0;
+ if (GinIsVoidRes(scan))
+ PG_RETURN_BOOL(false);
+
+ startScan(scan);
+
do
{
if (scanGetItem(scan, tids + *returned_tids))
@@ -462,6 +466,9 @@ gingettuple(PG_FUNCTION_ARGS)
if (GinIsNewKey(scan))
newScanKey(scan);
+ if (GinIsVoidRes(scan))
+ PG_RETURN_BOOL(false);
+
startScan(scan);
res = scanGetItem(scan, &scan->xs_ctup.t_self);
stopScan(scan);
diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c
index a7ded0c47f..3a17233ba8 100644
--- a/src/backend/access/gin/gininsert.c
+++ b/src/backend/access/gin/gininsert.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/gin/gininsert.c,v 1.6 2007/01/05 22:19:21 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gin/gininsert.c,v 1.7 2007/01/31 15:09:45 teodor Exp $
*-------------------------------------------------------------------------
*/
@@ -203,7 +203,7 @@ static uint32
ginHeapTupleBulkInsert(GinBuildState *buildstate, Datum value, ItemPointer heapptr)
{
Datum *entries;
- uint32 nentries;
+ int32 nentries;
MemoryContext oldCtx;
oldCtx = MemoryContextSwitchTo(buildstate->funcCtx);
@@ -356,7 +356,7 @@ static uint32
ginHeapTupleInsert(Relation index, GinState *ginstate, Datum value, ItemPointer item)
{
Datum *entries;
- uint32 i,
+ int32 i,
nentries;
entries = extractEntriesSU(ginstate, value, &nentries);
diff --git a/src/backend/access/gin/ginscan.c b/src/backend/access/gin/ginscan.c
index bc8c5595f9..22896bc5d7 100644
--- a/src/backend/access/gin/ginscan.c
+++ b/src/backend/access/gin/ginscan.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/gin/ginscan.c,v 1.8 2007/01/05 22:19:21 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gin/ginscan.c,v 1.9 2007/01/31 15:09:45 teodor Exp $
*-------------------------------------------------------------------------
*/
@@ -145,10 +145,12 @@ newScanKey(IndexScanDesc scan)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("GIN indexes do not support whole-index scans")));
+ so->isVoidRes = false;
+
for (i = 0; i < scan->numberOfKeys; i++)
{
Datum *entryValues;
- uint32 nEntryValues;
+ int32 nEntryValues;
if (scankey[i].sk_flags & SK_ISNULL)
elog(ERROR, "Gin doesn't support NULL as scan key");
@@ -162,6 +164,15 @@ newScanKey(IndexScanDesc scan)
UInt16GetDatum(scankey[i].sk_strategy)
)
);
+ if ( nEntryValues < 0 )
+ {
+ /*
+ * extractQueryFn signals that nothing will be found,
+ * so we can just set isVoidRes flag...
+ */
+ so->isVoidRes = true;
+ break;
+ }
if (entryValues == NULL || nEntryValues == 0)
/* full scan... */
continue;
@@ -173,7 +184,7 @@ newScanKey(IndexScanDesc scan)
so->nkeys = nkeys;
- if (so->nkeys == 0)
+ if (so->nkeys == 0 && !so->isVoidRes)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("GIN index does not support search with void query")));
diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c
index a14900e56c..e704e8051e 100644
--- a/src/backend/access/gin/ginutil.c
+++ b/src/backend/access/gin/ginutil.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/gin/ginutil.c,v 1.9 2007/01/05 22:19:21 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/gin/ginutil.c,v 1.10 2007/01/31 15:09:45 teodor Exp $
*-------------------------------------------------------------------------
*/
@@ -148,7 +148,7 @@ cmpEntries(const Datum *a, const Datum *b, cmpEntriesData *arg)
}
Datum *
-extractEntriesS(GinState *ginstate, Datum value, uint32 *nentries,
+extractEntriesS(GinState *ginstate, Datum value, int32 *nentries,
bool *needUnique)
{
Datum *entries;
@@ -178,7 +178,7 @@ extractEntriesS(GinState *ginstate, Datum value, uint32 *nentries,
Datum *
-extractEntriesSU(GinState *ginstate, Datum value, uint32 *nentries)
+extractEntriesSU(GinState *ginstate, Datum value, int32 *nentries)
{
bool needUnique;
Datum *entries = extractEntriesS(ginstate, value, nentries,