diff --git a/src/backend/tsearch/to_tsany.c b/src/backend/tsearch/to_tsany.c index e7cd6264db2..f5aae2da385 100644 --- a/src/backend/tsearch/to_tsany.c +++ b/src/backend/tsearch/to_tsany.c @@ -19,11 +19,13 @@ #include "utils/builtins.h" #include "utils/jsonfuncs.h" +typedef int (*QOperatorCallback) (TSQueryParserState state); typedef struct MorphOpaque { Oid cfg_id; int qoperator; /* query operator */ + QOperatorCallback qoperator_callback; } MorphOpaque; typedef struct TSVectorBuildState @@ -511,7 +513,12 @@ pushval_morph(Datum opaque, TSQueryParserState state, char *strval, int lenval, /* put placeholders for each missing stop word */ pushStop(state); if (cntpos) - pushOperator(state, data->qoperator, 1); + { + if (data->qoperator != 0) + pushOperator(state, data->qoperator, 1); + else + pushOperator(state, data->qoperator_callback(state), 1); + } cntpos++; pos++; } @@ -552,7 +559,10 @@ pushval_morph(Datum opaque, TSQueryParserState state, char *strval, int lenval, if (cntpos) { /* distance may be useful */ - pushOperator(state, data->qoperator, 1); + if (data->qoperator != 0) + pushOperator(state, data->qoperator, 1); + else + pushOperator(state, data->qoperator_callback(state), 1); } cntpos++; @@ -665,7 +675,8 @@ websearch_to_tsquery_byid(PG_FUNCTION_ARGS) data.cfg_id = PG_GETARG_OID(0); - data.qoperator = OP_AND; + data.qoperator = 0; + data.qoperator_callback = websearch_qoperator_callback; query = parse_tsquery(text_to_cstring(in), pushval_morph, diff --git a/src/backend/utils/adt/tsquery.c b/src/backend/utils/adt/tsquery.c index 092e8a130bf..eae76f9b2e1 100644 --- a/src/backend/utils/adt/tsquery.c +++ b/src/backend/utils/adt/tsquery.c @@ -520,6 +520,12 @@ gettoken_query_websearch(TSQueryParserState state, int8 *operator, } } +int +websearch_qoperator_callback(TSQueryParserState state) +{ + return state->in_quotes ? OP_PHRASE : OP_AND; +} + static ts_tokentype gettoken_query_plain(TSQueryParserState state, int8 *operator, int *lenval, char **strval, diff --git a/src/include/tsearch/ts_utils.h b/src/include/tsearch/ts_utils.h index 400ba330014..be7b6b592f7 100644 --- a/src/include/tsearch/ts_utils.h +++ b/src/include/tsearch/ts_utils.h @@ -66,6 +66,8 @@ extern TSQuery parse_tsquery(char *buf, Datum opaque, int flags); +extern int websearch_qoperator_callback(TSQueryParserState state); + /* Functions for use by PushFunction implementations */ extern void pushValue(TSQueryParserState state, char *strval, int lenval, int16 weight, bool prefix); diff --git a/src/test/regress/expected/tsearch.out b/src/test/regress/expected/tsearch.out index 0110b4d2e0d..a158286454e 100644 --- a/src/test/regress/expected/tsearch.out +++ b/src/test/regress/expected/tsearch.out @@ -2690,33 +2690,33 @@ select websearch_to_tsquery('english', 'pg_class pg"'); (1 row) select websearch_to_tsquery('english', '"pg_class pg"'); - websearch_to_tsquery ------------------------------ - ( 'pg' & 'class' ) <-> 'pg' + websearch_to_tsquery +--------------------------- + 'pg' <-> 'class' <-> 'pg' (1 row) select websearch_to_tsquery('english', 'abc "pg_class pg"'); - websearch_to_tsquery -------------------------------------- - 'abc' & ( 'pg' & 'class' ) <-> 'pg' + websearch_to_tsquery +----------------------------------- + 'abc' & 'pg' <-> 'class' <-> 'pg' (1 row) select websearch_to_tsquery('english', '"pg_class pg" def'); - websearch_to_tsquery -------------------------------------- - ( 'pg' & 'class' ) <-> 'pg' & 'def' + websearch_to_tsquery +----------------------------------- + 'pg' <-> 'class' <-> 'pg' & 'def' (1 row) select websearch_to_tsquery('english', 'abc "pg pg_class pg" def'); - websearch_to_tsquery ------------------------------------------------------- - 'abc' & 'pg' <-> ( 'pg' & 'class' ) <-> 'pg' & 'def' + websearch_to_tsquery +-------------------------------------------------------- + 'abc' & 'pg' <-> ( 'pg' <-> 'class' ) <-> 'pg' & 'def' (1 row) select websearch_to_tsquery('english', ' or "pg pg_class pg" or '); - websearch_to_tsquery --------------------------------------- - 'pg' <-> ( 'pg' & 'class' ) <-> 'pg' + websearch_to_tsquery +---------------------------------------- + 'pg' <-> ( 'pg' <-> 'class' ) <-> 'pg' (1 row) select websearch_to_tsquery('english', '""pg pg_class pg""');