Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4eecbb0

Browse files
feodordmpgpro
authored andcommitted
Do not fallback to AND for FTS phrase operator.
If there is no positional information of lexemes then phrase operator will notfallback to AND operator. This change makes needing to modify TS_execute()interface, because somewhere (in indexes, for example) positional informationis unaccesible and in this cases we need to force fallback to AND.Per discussion c19fcfec308e6ccd952cdde9e648b505@mail.gmail.comConflicts:src/backend/utils/adt/tsvector_op.c
1 parentaf01c25 commit4eecbb0

File tree

7 files changed

+55
-29
lines changed

7 files changed

+55
-29
lines changed

‎src/backend/utils/adt/tsginidx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ gin_tsquery_consistent(PG_FUNCTION_ARGS)
307307

308308
res=TS_execute(GETQUERY(query),
309309
&gcv,
310-
true,
310+
TS_EXEC_CALC_NOT |TS_EXEC_PHRASE_AS_AND,
311311
checkcondition_gin);
312312
}
313313

‎src/backend/utils/adt/tsgistidx.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,8 @@ gtsvector_consistent(PG_FUNCTION_ARGS)
362362

363363
PG_RETURN_BOOL(TS_execute(
364364
GETQUERY(query),
365-
(void*)GETSIGN(key), false,
365+
(void*)GETSIGN(key),
366+
TS_EXEC_PHRASE_AS_AND,
366367
checkcondition_bit
367368
));
368369
}
@@ -374,7 +375,8 @@ gtsvector_consistent(PG_FUNCTION_ARGS)
374375
chkval.arre=chkval.arrb+ARRNELEM(key);
375376
PG_RETURN_BOOL(TS_execute(
376377
GETQUERY(query),
377-
(void*)&chkval, true,
378+
(void*)&chkval,
379+
TS_EXEC_PHRASE_AS_AND |TS_EXEC_CALC_NOT,
378380
checkcondition_arr
379381
));
380382
}

‎src/backend/utils/adt/tsrank.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,8 @@ Cover(DocRepresentation *doc, int len, QueryRepresentation *qr, CoverExt *ext)
659659
{
660660
fillQueryRepresentationData(qr,ptr);
661661

662-
if (TS_execute(GETQUERY(qr->query), (void*)qr, false,checkcondition_QueryOperand))
662+
if (TS_execute(GETQUERY(qr->query), (void*)qr,
663+
TS_EXEC_EMPTY,checkcondition_QueryOperand))
663664
{
664665
if (WEP_GETPOS(ptr->pos)>ext->q)
665666
{
@@ -688,7 +689,8 @@ Cover(DocRepresentation *doc, int len, QueryRepresentation *qr, CoverExt *ext)
688689
*/
689690
fillQueryRepresentationData(qr,ptr);
690691

691-
if (TS_execute(GETQUERY(qr->query), (void*)qr, true,checkcondition_QueryOperand))
692+
if (TS_execute(GETQUERY(qr->query), (void*)qr,
693+
TS_EXEC_CALC_NOT,checkcondition_QueryOperand))
692694
{
693695
if (WEP_GETPOS(ptr->pos)<ext->p)
694696
{

‎src/backend/utils/adt/tsvector_op.c

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,7 @@ checkcondition_str(void *checkval, QueryOperand *val, ExecPhraseData *data)
776776
*/
777777
staticbool
778778
TS_phrase_execute(QueryItem*curitem,
779-
void*checkval,boolcalcnot,ExecPhraseData*data,
779+
void*checkval,uint32flags,ExecPhraseData*data,
780780
bool (*chkcond) (void*,QueryOperand*,ExecPhraseData*))
781781
{
782782
/* since this function recurses, it could be driven to stack overflow */
@@ -798,18 +798,19 @@ TS_phrase_execute(QueryItem *curitem,
798798
Assert(curitem->qoperator.oper==OP_PHRASE);
799799

800800
if (!TS_phrase_execute(curitem+curitem->qoperator.left,
801-
checkval,calcnot,&Ldata,chkcond))
801+
checkval,flags,&Ldata,chkcond))
802802
return false;
803803

804-
if (!TS_phrase_execute(curitem+1,checkval,calcnot,&Rdata,chkcond))
804+
if (!TS_phrase_execute(curitem+1,checkval,flags,&Rdata,chkcond))
805805
return false;
806806

807807
/*
808-
* if at least one of the operands has no position
809-
* information, fallback to AND operation.
808+
* if at least one of the operands has no position information,
809+
* then return false. But if TS_EXEC_PHRASE_AS_AND flag is set then
810+
* we return true as it is a AND operation
810811
*/
811812
if (Ldata.npos==0||Rdata.npos==0)
812-
return true;
813+
return(flags&TS_EXEC_PHRASE_AS_AND) ?true : false;
813814

814815
/*
815816
* Result of the operation is a list of the
@@ -912,14 +913,12 @@ TS_phrase_execute(QueryItem *curitem,
912913
* chkcond is a callback function used to evaluate each VAL node in the query.
913914
* checkval can be used to pass information to the callback. TS_execute doesn't
914915
* do anything with it.
915-
* if calcnot is false, NOT expressions are always evaluated to be true. This
916-
* is used in ranking.
917916
* It believes that ordinary operators are always closier to root than phrase
918917
* operator, so, TS_execute() may not take care of lexeme's position at all.
919918
*/
920919
bool
921-
TS_execute(QueryItem*curitem,void*checkval,boolcalcnot,
922-
bool (*chkcond) (void*checkval,QueryOperand*val,ExecPhraseData*data))
920+
TS_execute(QueryItem*curitem,void*checkval,uint32flags,
921+
bool (*chkcond) (void*checkval,QueryOperand*val,ExecPhraseData*data))
923922
{
924923
/* since this function recurses, it could be driven to stack overflow */
925924
check_stack_depth();
@@ -931,25 +930,29 @@ TS_execute(QueryItem *curitem, void *checkval, bool calcnot,
931930
switch (curitem->qoperator.oper)
932931
{
933932
caseOP_NOT:
934-
if (calcnot)
935-
return !TS_execute(curitem+1,checkval,calcnot,chkcond);
933+
if (flags&TS_EXEC_CALC_NOT)
934+
return !TS_execute(curitem+1,checkval,flags,chkcond);
936935
else
937936
return true;
938937

939938
caseOP_AND:
940-
if (TS_execute(curitem+curitem->qoperator.left,checkval,calcnot,chkcond))
941-
returnTS_execute(curitem+1,checkval,calcnot,chkcond);
939+
if (TS_execute(curitem+curitem->qoperator.left,checkval,flags,chkcond))
940+
returnTS_execute(curitem+1,checkval,flags,chkcond);
942941
else
943942
return false;
944943

945944
caseOP_OR:
946-
if (TS_execute(curitem+curitem->qoperator.left,checkval,calcnot,chkcond))
945+
if (TS_execute(curitem+curitem->qoperator.left,checkval,flags,chkcond))
947946
return true;
948947
else
949-
returnTS_execute(curitem+1,checkval,calcnot,chkcond);
948+
returnTS_execute(curitem+1,checkval,flags,chkcond);
950949

951950
caseOP_PHRASE:
952-
returnTS_phrase_execute(curitem,checkval,calcnot,NULL,chkcond);
951+
/*
952+
* do not check TS_EXEC_PHRASE_AS_AND here because chkcond()
953+
* could do something more if it's called from TS_phrase_execute()
954+
*/
955+
returnTS_phrase_execute(curitem,checkval,flags,NULL,chkcond);
953956

954957
default:
955958
elog(ERROR,"unrecognized operator: %d",curitem->qoperator.oper);
@@ -1046,7 +1049,7 @@ ts_match_vq(PG_FUNCTION_ARGS)
10461049
result=TS_execute(
10471050
GETQUERY(query),
10481051
&chkval,
1049-
true,
1052+
TS_EXEC_CALC_NOT,
10501053
checkcondition_str
10511054
);
10521055

‎src/include/tsearch/ts_utils.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,25 @@ typedef struct ExecPhraseData
112112
WordEntryPos*pos;
113113
}ExecPhraseData;
114114

115-
externboolTS_execute(QueryItem*curitem,void*checkval,boolcalcnot,
115+
/*
116+
* Evaluates tsquery, flags are followe below
117+
*/
118+
externboolTS_execute(QueryItem*curitem,void*checkval,uint32flags,
116119
bool (*chkcond) (void*,QueryOperand*,ExecPhraseData*));
120+
121+
#defineTS_EXEC_EMPTY(0x00)
122+
/*
123+
* if TS_EXEC_CALC_NOT is not set then NOT expression evaluated to be true,
124+
* used in cases where NOT cannot be accurately computed (GiST) or
125+
* it isn't important (ranking)
126+
*/
127+
#defineTS_EXEC_CALC_NOT(0x01)
128+
/*
129+
* Treat OP_PHRASE as OP_AND. Used when posiotional information is not
130+
* accessible, like in consistent methods of GIN/GiST indexes
131+
*/
132+
#defineTS_EXEC_PHRASE_AS_AND(0x02)
133+
117134
externbooltsquery_requires_match(QueryItem*curitem);
118135

119136
/*

‎src/test/regress/expected/tsearch.out

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,13 +1453,14 @@ select * from pendtest where 'ipi:*'::tsquery @@ ts;
14531453

14541454
--check OP_PHRASE on index
14551455
create temp table phrase_index_test(fts tsvector);
1456-
insert into phrase_index_test values('A fat cat has just eaten a rat.');
1456+
insert into phrase_index_test values ('A fat cat has just eaten a rat.');
1457+
insert into phrase_index_test values (to_tsvector('english', 'A fat cat has just eaten a rat.'));
14571458
create index phrase_index_test_idx on phrase_index_test using gin(fts);
14581459
set enable_seqscan = off;
14591460
select * from phrase_index_test where fts @@ phraseto_tsquery('english', 'fat cat');
1460-
fts
1461-
-------------------------------------------------
1462-
'A' 'a' 'cat' 'eaten' 'fat' 'has' 'just' 'rat.'
1461+
fts
1462+
-----------------------------------
1463+
'cat':3 'eaten':6 'fat':2 'rat':8
14631464
(1 row)
14641465

14651466
set enable_seqscan = on;

‎src/test/regress/sql/tsearch.sql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,8 @@ select * from pendtest where 'ipi:*'::tsquery @@ ts;
482482

483483
--check OP_PHRASE on index
484484
create temp table phrase_index_test(fts tsvector);
485-
insert into phrase_index_testvalues('A fat cat has just eaten a rat.');
485+
insert into phrase_index_testvalues ('A fat cat has just eaten a rat.');
486+
insert into phrase_index_testvalues (to_tsvector('english','A fat cat has just eaten a rat.'));
486487
createindexphrase_index_test_idxon phrase_index_test using gin(fts);
487488
set enable_seqscan= off;
488489
select*from phrase_index_testwhere fts @@ phraseto_tsquery('english','fat cat');

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp