websearch_fix_p2.patch
application/octet-stream
Filename: websearch_fix_p2.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/tsearch/to_tsany.c | 14 | 3 |
| src/backend/utils/adt/tsquery.c | 6 | 0 |
| src/include/tsearch/ts_utils.h | 2 | 0 |
| src/test/regress/expected/tsearch.out | 15 | 15 |
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""');