Kouhei Sutou
null+****@clear*****
Thu Apr 7 22:51:39 JST 2016
Kouhei Sutou 2016-04-07 22:51:39 +0900 (Thu, 07 Apr 2016) New Revision: a28a3dd6c352829d3ad55770c6838a3de9228eba https://github.com/pgroonga/pgroonga/commit/a28a3dd6c352829d3ad55770c6838a3de9228eba Message: Support prefix search by '&^' with prefix_search_ops_v2 Added files: expected/prefix/text/prefix/bitmapscan.out expected/prefix/text/prefix/indexscan.out expected/prefix/text/prefix/seqscan.out sql/prefix/text/prefix/bitmapscan.sql sql/prefix/text/prefix/indexscan.sql sql/prefix/text/prefix/seqscan.sql Modified files: pgroonga.sql src/pgrn_create.c src/pgrn_create.h src/pgroonga.c src/pgroonga.h Added: expected/prefix/text/prefix/bitmapscan.out (+22 -0) 100644 =================================================================== --- /dev/null +++ expected/prefix/text/prefix/bitmapscan.out 2016-04-07 22:51:39 +0900 (1178bc2) @@ -0,0 +1,22 @@ +CREATE TABLE tags ( + name text +); +INSERT INTO tags VALUES ('PostgreSQL'); +INSERT INTO tags VALUES ('Groonga'); +INSERT INTO tags VALUES ('PGroonga'); +INSERT INTO tags VALUES ('pglogical'); +CREATE INDEX pgrn_index ON tags + USING pgroonga (name pgroonga.prefix_search_ops_v2); +SET enable_seqscan = off; +SET enable_indexscan = off; +SET enable_bitmapscan = on; +SELECT name + FROM tags + WHERE name &^ 'pG'; + name +----------- + PGroonga + pglogical +(2 rows) + +DROP TABLE tags; Added: expected/prefix/text/prefix/indexscan.out (+22 -0) 100644 =================================================================== --- /dev/null +++ expected/prefix/text/prefix/indexscan.out 2016-04-07 22:51:39 +0900 (5e6f3a5) @@ -0,0 +1,22 @@ +CREATE TABLE tags ( + name text +); +INSERT INTO tags VALUES ('PostgreSQL'); +INSERT INTO tags VALUES ('Groonga'); +INSERT INTO tags VALUES ('PGroonga'); +INSERT INTO tags VALUES ('pglogical'); +CREATE INDEX pgrn_index ON tags + USING pgroonga (name pgroonga.prefix_search_ops_v2); +SET enable_seqscan = off; +SET enable_indexscan = on; +SET enable_bitmapscan = off; +SELECT name + FROM tags + WHERE name &^ 'pG'; + name +----------- + PGroonga + pglogical +(2 rows) + +DROP TABLE tags; Added: expected/prefix/text/prefix/seqscan.out (+22 -0) 100644 =================================================================== --- /dev/null +++ expected/prefix/text/prefix/seqscan.out 2016-04-07 22:51:39 +0900 (68b1fdc) @@ -0,0 +1,22 @@ +CREATE TABLE tags ( + name text +); +INSERT INTO tags VALUES ('PostgreSQL'); +INSERT INTO tags VALUES ('Groonga'); +INSERT INTO tags VALUES ('PGroonga'); +INSERT INTO tags VALUES ('pglogical'); +CREATE INDEX pgrn_index ON tags + USING pgroonga (name pgroonga.prefix_search_ops_v2); +SET enable_seqscan = on; +SET enable_indexscan = off; +SET enable_bitmapscan = off; +SELECT name + FROM tags + WHERE name &^ 'pG'; + name +----------- + PGroonga + pglogical +(2 rows) + +DROP TABLE tags; Modified: pgroonga.sql (+21 -4) =================================================================== --- pgroonga.sql 2016-03-29 00:06:02 +0900 (3bda70a) +++ pgroonga.sql 2016-04-07 22:51:39 +0900 (aaef1fb) @@ -206,7 +206,7 @@ CREATE FUNCTION pgroonga.options(internal) DELETE FROM pg_catalog.pg_am WHERE amname = 'pgroonga'; INSERT INTO pg_catalog.pg_am VALUES( 'pgroonga', -- amname - 17, -- amstrategies + 18, -- amstrategies 0, -- amsupport true, -- amcanorder true, -- amcanorderbyop @@ -414,6 +414,19 @@ CREATE OPERATOR &~? ( RIGHTARG = text ); +CREATE FUNCTION pgroonga.prefix_text(text, text) + RETURNS bool + AS 'MODULE_PATHNAME', 'pgroonga_prefix_text' + LANGUAGE C + IMMUTABLE + STRICT; + +CREATE OPERATOR &^ ( + PROCEDURE = pgroonga.prefix_text, + LEFTARG = text, + RIGHTARG = text +); + CREATE FUNCTION pgroonga.script_text(text, text) RETURNS bool AS 'MODULE_PATHNAME', 'pgroonga_script_text' @@ -460,6 +473,10 @@ CREATE OPERATOR CLASS pgroonga.text_full_text_search_ops_v2 FOR TYPE text OPERATOR 12 &@, OPERATOR 13 &?, OPERATOR 14 &~?, - OPERATOR 15 &`, - OPERATOR 16 &@> (text, text[]), - OPERATOR 17 &?> (text, text[]); + OPERATOR 16 &`, + OPERATOR 17 &@> (text, text[]), + OPERATOR 18 &?> (text, text[]); + +CREATE OPERATOR CLASS pgroonga.prefix_search_ops_v2 FOR TYPE text + USING pgroonga AS + OPERATOR 15 &^; Added: sql/prefix/text/prefix/bitmapscan.sql (+21 -0) 100644 =================================================================== --- /dev/null +++ sql/prefix/text/prefix/bitmapscan.sql 2016-04-07 22:51:39 +0900 (614c7bd) @@ -0,0 +1,21 @@ +CREATE TABLE tags ( + name text +); + +INSERT INTO tags VALUES ('PostgreSQL'); +INSERT INTO tags VALUES ('Groonga'); +INSERT INTO tags VALUES ('PGroonga'); +INSERT INTO tags VALUES ('pglogical'); + +CREATE INDEX pgrn_index ON tags + USING pgroonga (name pgroonga.prefix_search_ops_v2); + +SET enable_seqscan = off; +SET enable_indexscan = off; +SET enable_bitmapscan = on; + +SELECT name + FROM tags + WHERE name &^ 'pG'; + +DROP TABLE tags; Added: sql/prefix/text/prefix/indexscan.sql (+21 -0) 100644 =================================================================== --- /dev/null +++ sql/prefix/text/prefix/indexscan.sql 2016-04-07 22:51:39 +0900 (19da79f) @@ -0,0 +1,21 @@ +CREATE TABLE tags ( + name text +); + +INSERT INTO tags VALUES ('PostgreSQL'); +INSERT INTO tags VALUES ('Groonga'); +INSERT INTO tags VALUES ('PGroonga'); +INSERT INTO tags VALUES ('pglogical'); + +CREATE INDEX pgrn_index ON tags + USING pgroonga (name pgroonga.prefix_search_ops_v2); + +SET enable_seqscan = off; +SET enable_indexscan = on; +SET enable_bitmapscan = off; + +SELECT name + FROM tags + WHERE name &^ 'pG'; + +DROP TABLE tags; Added: sql/prefix/text/prefix/seqscan.sql (+21 -0) 100644 =================================================================== --- /dev/null +++ sql/prefix/text/prefix/seqscan.sql 2016-04-07 22:51:39 +0900 (d302e63) @@ -0,0 +1,21 @@ +CREATE TABLE tags ( + name text +); + +INSERT INTO tags VALUES ('PostgreSQL'); +INSERT INTO tags VALUES ('Groonga'); +INSERT INTO tags VALUES ('PGroonga'); +INSERT INTO tags VALUES ('pglogical'); + +CREATE INDEX pgrn_index ON tags + USING pgroonga (name pgroonga.prefix_search_ops_v2); + +SET enable_seqscan = on; +SET enable_indexscan = off; +SET enable_bitmapscan = off; + +SELECT name + FROM tags + WHERE name &^ 'pG'; + +DROP TABLE tags; Modified: src/pgrn_create.c (+10 -4) =================================================================== --- src/pgrn_create.c 2016-03-29 00:06:02 +0900 (1de8de3) +++ src/pgrn_create.c 2016-04-07 22:51:39 +0900 (69637ca) @@ -94,7 +94,9 @@ PGrnCreateIndexColumn(PGrnCreateData *data) grn_ctx_at(ctx, typeID)); GRN_PTR_PUT(ctx, data->lexicons, lexicon); - if (data->forFullTextSearch || data->forRegexpSearch) + if (data->forFullTextSearch || + data->forRegexpSearch || + data->forPrefixSearch) { const char *tokenizerName; const char *normalizerName = PGRN_DEFAULT_NORMALIZER; @@ -107,11 +109,15 @@ PGrnCreateIndexColumn(PGrnCreateData *data) PGrnApplyOptionValues(data->index, &tokenizerName, &normalizerName); - if (!PGrnIsNoneValue(tokenizerName)) + if (data->forFullTextSearch || data->forRegexpSearch) { - grn_obj_set_info(ctx, lexicon, GRN_INFO_DEFAULT_TOKENIZER, - PGrnLookup(tokenizerName, ERROR)); + if (!PGrnIsNoneValue(tokenizerName)) + { + grn_obj_set_info(ctx, lexicon, GRN_INFO_DEFAULT_TOKENIZER, + PGrnLookup(tokenizerName, ERROR)); + } } + if (!PGrnIsNoneValue(normalizerName)) { grn_obj_set_info(ctx, lexicon, GRN_INFO_NORMALIZER, Modified: src/pgrn_create.h (+1 -0) =================================================================== --- src/pgrn_create.h 2016-03-29 00:06:02 +0900 (79e6e07) +++ src/pgrn_create.h 2016-04-07 22:51:39 +0900 (a909560) @@ -17,6 +17,7 @@ typedef struct PGrnCreateData Oid relNode; bool forFullTextSearch; bool forRegexpSearch; + bool forPrefixSearch; grn_id attributeTypeID; unsigned char attributeFlags; } PGrnCreateData; Modified: src/pgroonga.c (+61 -0) =================================================================== --- src/pgroonga.c 2016-03-29 00:06:02 +0900 (1aebaae) +++ src/pgroonga.c 2016-04-07 22:51:39 +0900 (0804195) @@ -143,6 +143,7 @@ PG_FUNCTION_INFO_V1(pgroonga_match_regexp_varchar); PG_FUNCTION_INFO_V1(pgroonga_match_text); PG_FUNCTION_INFO_V1(pgroonga_query_text); PG_FUNCTION_INFO_V1(pgroonga_similar_text); +PG_FUNCTION_INFO_V1(pgroonga_prefix_text); PG_FUNCTION_INFO_V1(pgroonga_script_text); PG_FUNCTION_INFO_V1(pgroonga_match_contain_text); PG_FUNCTION_INFO_V1(pgroonga_query_contain_text); @@ -669,6 +670,22 @@ PGrnIsForRegexpSearchIndex(Relation index, int nthAttribute) return OidIsValid(regexpStrategyOID); } +static bool +PGrnIsForPrefixSearchIndex(Relation index, int nthAttribute) +{ + Oid prefixStrategyOID; + Oid leftType; + Oid rightType; + + leftType = index->rd_opcintype[nthAttribute]; + rightType = leftType; + prefixStrategyOID = get_opfamily_member(index->rd_opfamily[nthAttribute], + leftType, + rightType, + PGrnPrefixStrategyV2Number); + return OidIsValid(prefixStrategyOID); +} + /** * PGrnCreate */ @@ -704,6 +721,7 @@ PGrnCreate(Relation index, { data.forFullTextSearch = PGrnIsForFullTextSearchIndex(index, data.i); data.forRegexpSearch = PGrnIsForRegexpSearchIndex(index, data.i); + data.forPrefixSearch = PGrnIsForPrefixSearchIndex(index, data.i); data.attributeTypeID = PGrnGetType(index, data.i, &(data.attributeFlags)); PGrnCreateDataColumn(&data); @@ -1578,6 +1596,46 @@ pgroonga_similar_text(PG_FUNCTION_ARGS) } static grn_bool +pgroonga_prefix_raw(const char *text, unsigned int textSize, + const char *prefix, unsigned int prefixSize) +{ + grn_bool matched; + grn_obj targetBuffer; + grn_obj prefixBuffer; + + GRN_TEXT_INIT(&targetBuffer, GRN_OBJ_DO_SHALLOW_COPY); + GRN_TEXT_SET(ctx, &targetBuffer, text, textSize); + + GRN_TEXT_INIT(&prefixBuffer, GRN_OBJ_DO_SHALLOW_COPY); + GRN_TEXT_SET(ctx, &prefixBuffer, prefix, prefixSize); + + matched = grn_operator_exec_prefix(ctx, &targetBuffer, &prefixBuffer); + + GRN_OBJ_FIN(ctx, &targetBuffer); + GRN_OBJ_FIN(ctx, &prefixBuffer); + + return matched; +} + +/** + * pgroonga.prefix_text(target text, prefix text) : bool + */ +Datum +pgroonga_prefix_text(PG_FUNCTION_ARGS) +{ + text *target = PG_GETARG_TEXT_PP(0); + text *prefix = PG_GETARG_TEXT_PP(1); + bool matched = false; + + matched = pgroonga_prefix_raw(VARDATA_ANY(target), + VARSIZE_ANY_EXHDR(target), + VARDATA_ANY(prefix), + VARSIZE_ANY_EXHDR(prefix)); + + PG_RETURN_BOOL(matched); +} + +static grn_bool pgroonga_script_raw(const char *target, unsigned int targetSize, const char *script, unsigned int scriptSize) { @@ -2355,6 +2413,9 @@ PGrnSearchBuildCondition(IndexScanDesc scan, case PGrnSimilarStrategyV2Number: operator = GRN_OP_SIMILAR; break; + case PGrnPrefixStrategyV2Number: + operator = GRN_OP_PREFIX; + break; case PGrnScriptStrategyV2Number: break; case PGrnRegexpStrategyNumber: Modified: src/pgroonga.h (+6 -4) =================================================================== --- src/pgroonga.h 2016-03-29 00:06:02 +0900 (0e0306f) +++ src/pgroonga.h 2016-04-07 22:51:39 +0900 (6e7c00e) @@ -26,10 +26,11 @@ #define PGrnMatchStrategyV2Number 12 /* operator &@ (@ in Groonga) */ #define PGrnQueryStrategyV2Number 13 /* operator &? (query in Groonga) */ -#define PGrnSimilarStrategyV2Number 14 /* operator &~? (similar in Groonga) */ -#define PGrnScriptStrategyV2Number 15 /* operator &` (script in Groonga) */ -#define PGrnMatchContainStrategyNumber 16 /* operator &@> (@ in Groonga) */ -#define PGrnQueryContainStrategyNumber 17 /* operator &?> (query in Groonga) */ +#define PGrnSimilarStrategyV2Number 14 /* operator &~? (similar search) */ +#define PGrnPrefixStrategyV2Number 15 /* operator &^ (prefix search) */ +#define PGrnScriptStrategyV2Number 16 /* operator &` (script in Groonga) */ +#define PGrnMatchContainStrategyNumber 17 /* operator &@> (@ in Groonga) */ +#define PGrnQueryContainStrategyNumber 18 /* operator &?> (query in Groonga) */ /* file and table names */ #define PGrnLogBasename "pgroonga.log" @@ -70,6 +71,7 @@ extern Datum PGDLLEXPORT pgroonga_match_jsonb(PG_FUNCTION_ARGS); extern Datum PGDLLEXPORT pgroonga_match_text(PG_FUNCTION_ARGS); extern Datum PGDLLEXPORT pgroonga_query_text(PG_FUNCTION_ARGS); extern Datum PGDLLEXPORT pgroonga_similar_text(PG_FUNCTION_ARGS); +extern Datum PGDLLEXPORT pgroonga_prefix_text(PG_FUNCTION_ARGS); extern Datum PGDLLEXPORT pgroonga_script_text(PG_FUNCTION_ARGS); extern Datum PGDLLEXPORT pgroonga_match_contain_text(PG_FUNCTION_ARGS); extern Datum PGDLLEXPORT pgroonga_query_contain_text(PG_FUNCTION_ARGS); -------------- next part -------------- HTML����������������������������... Télécharger