aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/tsgistidx.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2020-07-24 15:26:51 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2020-07-24 15:26:51 -0400
commit2f2007fbb255be178aca586780967f43885203a7 (patch)
treef8b550822ccb33b1a63acc292556c7ee2ae90683 /src/backend/utils/adt/tsgistidx.c
parent25244b8972a34b838c4033fe9efc1d31cba9d0e3 (diff)
downloadpostgresql-2f2007fbb255be178aca586780967f43885203a7.tar.gz
postgresql-2f2007fbb255be178aca586780967f43885203a7.zip
Fix assorted bugs by changing TS_execute's callback API to ternary logic.
Text search sometimes failed to find valid matches, for instance '!crew:A'::tsquery might fail to locate 'crew:1B'::tsvector during an index search. The root of the issue is that TS_execute's callback functions were not changed to use ternary (yes/no/maybe) reporting when we made the search logic itself do so. It's somewhat annoying to break that API, but on the other hand we now see that any code using plain boolean logic is almost certainly broken since the addition of phrase search. There seem to be very few outside callers of this code anyway, so we'll just break them intentionally to get them to adapt. This allows removal of tsginidx.c's private re-implementation of TS_execute, since that's now entirely duplicative. It's also no longer necessary to avoid use of CALC_NOT in tsgistidx.c, since the underlying callbacks can now do something reasonable. Back-patch into v13. We can't change this in stable branches, but it seems not quite too late to fix it in v13. Tom Lane and Pavel Borisov Discussion: https://postgr.es/m/CALT9ZEE-aLotzBg-pOp2GFTesGWVYzXA3=mZKzRDa_OKnLF7Mg@mail.gmail.com
Diffstat (limited to 'src/backend/utils/adt/tsgistidx.c')
-rw-r--r--src/backend/utils/adt/tsgistidx.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/src/backend/utils/adt/tsgistidx.c b/src/backend/utils/adt/tsgistidx.c
index c3f25800e7b..927aed91564 100644
--- a/src/backend/utils/adt/tsgistidx.c
+++ b/src/backend/utils/adt/tsgistidx.c
@@ -273,9 +273,9 @@ typedef struct
} CHKVAL;
/*
- * is there value 'val' in array or not ?
+ * TS_execute callback for matching a tsquery operand to GIST leaf-page data
*/
-static bool
+static TSTernaryValue
checkcondition_arr(void *checkval, QueryOperand *val, ExecPhraseData *data)
{
int32 *StopLow = ((CHKVAL *) checkval)->arrb;
@@ -288,23 +288,26 @@ checkcondition_arr(void *checkval, QueryOperand *val, ExecPhraseData *data)
* we are not able to find a prefix by hash value
*/
if (val->prefix)
- return true;
+ return TS_MAYBE;
while (StopLow < StopHigh)
{
StopMiddle = StopLow + (StopHigh - StopLow) / 2;
if (*StopMiddle == val->valcrc)
- return true;
+ return TS_MAYBE;
else if (*StopMiddle < val->valcrc)
StopLow = StopMiddle + 1;
else
StopHigh = StopMiddle;
}
- return false;
+ return TS_NO;
}
-static bool
+/*
+ * TS_execute callback for matching a tsquery operand to GIST non-leaf data
+ */
+static TSTernaryValue
checkcondition_bit(void *checkval, QueryOperand *val, ExecPhraseData *data)
{
void *key = (SignTSVector *) checkval;
@@ -313,8 +316,12 @@ checkcondition_bit(void *checkval, QueryOperand *val, ExecPhraseData *data)
* we are not able to find a prefix in signature tree
*/
if (val->prefix)
- return true;
- return GETBIT(GETSIGN(key), HASHVAL(val->valcrc, GETSIGLEN(key)));
+ return TS_MAYBE;
+
+ if (GETBIT(GETSIGN(key), HASHVAL(val->valcrc, GETSIGLEN(key))))
+ return TS_MAYBE;
+ else
+ return TS_NO;
}
Datum
@@ -339,10 +346,9 @@ gtsvector_consistent(PG_FUNCTION_ARGS)
if (ISALLTRUE(key))
PG_RETURN_BOOL(true);
- /* since signature is lossy, cannot specify CALC_NOT here */
PG_RETURN_BOOL(TS_execute(GETQUERY(query),
key,
- TS_EXEC_PHRASE_NO_POS,
+ TS_EXEC_PHRASE_NO_POS | TS_EXEC_CALC_NOT,
checkcondition_bit));
}
else