mirror of
https://github.com/postgres/postgres.git
synced 2025-11-21 00:42:43 +03:00
Phrase full text search.
Patch introduces new text search operator (<-> or <DISTANCE>) into tsquery. On-disk and binary in/out format of tsquery are backward compatible. It has two side effect: - change order for tsquery, so, users, who has a btree index over tsquery, should reindex it - less number of parenthesis in tsquery output, and tsquery becomes more readable Authors: Teodor Sigaev, Oleg Bartunov, Dmitry Ivanov Reviewers: Alexander Korotkov, Artur Zakirov
This commit is contained in:
@@ -179,14 +179,16 @@ typedef struct
|
||||
} GinChkVal;
|
||||
|
||||
static GinTernaryValue
|
||||
checkcondition_gin(void *checkval, QueryOperand *val)
|
||||
checkcondition_gin_internal(GinChkVal *gcv, QueryOperand *val, ExecPhraseData *data)
|
||||
{
|
||||
GinChkVal *gcv = (GinChkVal *) checkval;
|
||||
int j;
|
||||
|
||||
/* if any val requiring a weight is used, set recheck flag */
|
||||
if (val->weight != 0)
|
||||
*(gcv->need_recheck) = true;
|
||||
/*
|
||||
* if any val requiring a weight is used or caller
|
||||
* needs position information then set recheck flag
|
||||
*/
|
||||
if (val->weight != 0 || data != NULL)
|
||||
*gcv->need_recheck = true;
|
||||
|
||||
/* convert item's number to corresponding entry's (operand's) number */
|
||||
j = gcv->map_item_operand[((QueryItem *) val) - gcv->first_item];
|
||||
@@ -195,16 +197,22 @@ checkcondition_gin(void *checkval, QueryOperand *val)
|
||||
return gcv->check[j];
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper of check condition function for TS_execute.
|
||||
*/
|
||||
static bool
|
||||
checkcondition_gin(void *checkval, QueryOperand *val, ExecPhraseData *data)
|
||||
{
|
||||
return checkcondition_gin_internal((GinChkVal *) checkval,
|
||||
val,
|
||||
data) != GIN_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Evaluate tsquery boolean expression using ternary logic.
|
||||
*
|
||||
* chkcond is a callback function used to evaluate each VAL node in the query.
|
||||
* checkval can be used to pass information to the callback. TS_execute doesn't
|
||||
* do anything with it.
|
||||
*/
|
||||
static GinTernaryValue
|
||||
TS_execute_ternary(QueryItem *curitem, void *checkval,
|
||||
GinTernaryValue (*chkcond) (void *checkval, QueryOperand *val))
|
||||
TS_execute_ternary(GinChkVal *gcv, QueryItem *curitem)
|
||||
{
|
||||
GinTernaryValue val1,
|
||||
val2,
|
||||
@@ -214,22 +222,30 @@ TS_execute_ternary(QueryItem *curitem, void *checkval,
|
||||
check_stack_depth();
|
||||
|
||||
if (curitem->type == QI_VAL)
|
||||
return chkcond(checkval, (QueryOperand *) curitem);
|
||||
return checkcondition_gin_internal(gcv,
|
||||
(QueryOperand *) curitem,
|
||||
NULL /* don't have any position info */);
|
||||
|
||||
switch (curitem->qoperator.oper)
|
||||
{
|
||||
case OP_NOT:
|
||||
result = TS_execute_ternary(curitem + 1, checkval, chkcond);
|
||||
result = TS_execute_ternary(gcv, curitem + 1);
|
||||
if (result == GIN_MAYBE)
|
||||
return result;
|
||||
return !result;
|
||||
|
||||
case OP_PHRASE:
|
||||
/*
|
||||
* GIN doesn't contain any information about positions,
|
||||
* treat OP_PHRASE as OP_AND with recheck requirement
|
||||
*/
|
||||
*gcv->need_recheck = true;
|
||||
|
||||
case OP_AND:
|
||||
val1 = TS_execute_ternary(curitem + curitem->qoperator.left,
|
||||
checkval, chkcond);
|
||||
val1 = TS_execute_ternary(gcv, curitem + curitem->qoperator.left);
|
||||
if (val1 == GIN_FALSE)
|
||||
return GIN_FALSE;
|
||||
val2 = TS_execute_ternary(curitem + 1, checkval, chkcond);
|
||||
val2 = TS_execute_ternary(gcv, curitem + 1);
|
||||
if (val2 == GIN_FALSE)
|
||||
return GIN_FALSE;
|
||||
if (val1 == GIN_TRUE && val2 == GIN_TRUE)
|
||||
@@ -238,11 +254,10 @@ TS_execute_ternary(QueryItem *curitem, void *checkval,
|
||||
return GIN_MAYBE;
|
||||
|
||||
case OP_OR:
|
||||
val1 = TS_execute_ternary(curitem + curitem->qoperator.left,
|
||||
checkval, chkcond);
|
||||
val1 = TS_execute_ternary(gcv, curitem + curitem->qoperator.left);
|
||||
if (val1 == GIN_TRUE)
|
||||
return GIN_TRUE;
|
||||
val2 = TS_execute_ternary(curitem + 1, checkval, chkcond);
|
||||
val2 = TS_execute_ternary(gcv, curitem + 1);
|
||||
if (val2 == GIN_TRUE)
|
||||
return GIN_TRUE;
|
||||
if (val1 == GIN_FALSE && val2 == GIN_FALSE)
|
||||
@@ -327,9 +342,7 @@ gin_tsquery_triconsistent(PG_FUNCTION_ARGS)
|
||||
gcv.map_item_operand = (int *) (extra_data[0]);
|
||||
gcv.need_recheck = &recheck;
|
||||
|
||||
res = TS_execute_ternary(GETQUERY(query),
|
||||
&gcv,
|
||||
checkcondition_gin);
|
||||
res = TS_execute_ternary(&gcv, GETQUERY(query));
|
||||
|
||||
if (res == GIN_TRUE && recheck)
|
||||
res = GIN_MAYBE;
|
||||
|
||||
Reference in New Issue
Block a user