diff options
author | Teodor Sigaev <teodor@sigaev.ru> | 2016-04-07 18:44:18 +0300 |
---|---|---|
committer | Teodor Sigaev <teodor@sigaev.ru> | 2016-04-07 18:44:18 +0300 |
commit | bb140506df605fab58f48926ee1db1f80bdafb59 (patch) | |
tree | 581f9aeb71e3596000af3b4904e0c62a372d77b3 /src/backend/utils/adt/tsquery_op.c | |
parent | 015e88942aa50f0d419ddac00e63bb06d6e62e86 (diff) | |
download | postgresql-bb140506df605fab58f48926ee1db1f80bdafb59.tar.gz postgresql-bb140506df605fab58f48926ee1db1f80bdafb59.zip |
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
Diffstat (limited to 'src/backend/utils/adt/tsquery_op.c')
-rw-r--r-- | src/backend/utils/adt/tsquery_op.c | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/src/backend/utils/adt/tsquery_op.c b/src/backend/utils/adt/tsquery_op.c index 9cdf1fe10b2..30d3faf3e22 100644 --- a/src/backend/utils/adt/tsquery_op.c +++ b/src/backend/utils/adt/tsquery_op.c @@ -27,7 +27,7 @@ tsquery_numnode(PG_FUNCTION_ARGS) } static QTNode * -join_tsqueries(TSQuery a, TSQuery b, int8 operator) +join_tsqueries(TSQuery a, TSQuery b, int8 operator, uint16 distance) { QTNode *res = (QTNode *) palloc0(sizeof(QTNode)); @@ -36,6 +36,8 @@ join_tsqueries(TSQuery a, TSQuery b, int8 operator) res->valnode = (QueryItem *) palloc0(sizeof(QueryItem)); res->valnode->type = QI_OPR; res->valnode->qoperator.oper = operator; + if (operator == OP_PHRASE) + res->valnode->qoperator.distance = distance; res->child = (QTNode **) palloc0(sizeof(QTNode *) * 2); res->child[0] = QT2QTN(GETQUERY(b), GETOPERAND(b)); @@ -64,7 +66,7 @@ tsquery_and(PG_FUNCTION_ARGS) PG_RETURN_POINTER(a); } - res = join_tsqueries(a, b, OP_AND); + res = join_tsqueries(a, b, OP_AND, 0); query = QTN2QT(res); @@ -94,7 +96,7 @@ tsquery_or(PG_FUNCTION_ARGS) PG_RETURN_POINTER(a); } - res = join_tsqueries(a, b, OP_OR); + res = join_tsqueries(a, b, OP_OR, 0); query = QTN2QT(res); @@ -106,6 +108,52 @@ tsquery_or(PG_FUNCTION_ARGS) } Datum +tsquery_phrase_distance(PG_FUNCTION_ARGS) +{ + TSQuery a = PG_GETARG_TSQUERY_COPY(0); + TSQuery b = PG_GETARG_TSQUERY_COPY(1); + QTNode *res; + TSQuery query; + int32 distance = PG_GETARG_INT32(2); + + if (distance < 0 || distance > MAXENTRYPOS) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("distance in phrase operator should be non-negative and less than %d", + MAXENTRYPOS))); + if (a->size == 0) + { + PG_FREE_IF_COPY(a, 1); + PG_RETURN_POINTER(b); + } + else if (b->size == 0) + { + PG_FREE_IF_COPY(b, 1); + PG_RETURN_POINTER(a); + } + + res = join_tsqueries(a, b, OP_PHRASE, (uint16) distance); + + query = QTN2QT(res); + + QTNFree(res); + PG_FREE_IF_COPY(a, 0); + PG_FREE_IF_COPY(b, 1); + + PG_RETURN_POINTER(cleanup_fakeval_and_phrase(query)); +} + +Datum +tsquery_phrase(PG_FUNCTION_ARGS) +{ + PG_RETURN_POINTER(DirectFunctionCall3( + tsquery_phrase_distance, + PG_GETARG_DATUM(0), + PG_GETARG_DATUM(1), + Int32GetDatum(1))); +} + +Datum tsquery_not(PG_FUNCTION_ARGS) { TSQuery a = PG_GETARG_TSQUERY_COPY(0); |