Kouhei Sutou
null+****@clear*****
Sun Feb 15 13:49:26 JST 2015
Kouhei Sutou 2015-02-15 13:49:26 +0900 (Sun, 15 Feb 2015) New Revision: 9066ebfe666e9ab0914361ed49e6f997f75c9d5d https://github.com/pgroonga/pgroonga/commit/9066ebfe666e9ab0914361ed49e6f997f75c9d5d Message: Support full-text search for text[] Added files: expected/array/text/single/contain/bitmapscan.out expected/array/text/single/contain/indexscan.out expected/array/text/single/contain/seqscan.out sql/array/text/single/contain/bitmapscan.sql sql/array/text/single/contain/indexscan.sql sql/array/text/single/contain/seqscan.sql Modified files: Makefile pgroonga.c pgroonga.h pgroonga.sql pgroonga_types.c Modified: Makefile (+3 -0) =================================================================== --- Makefile 2015-02-15 13:11:17 +0900 (938745b) +++ Makefile 2015-02-15 13:49:26 +0900 (7dc885a) @@ -40,6 +40,7 @@ installcheck: results/compare/integer/single/between installcheck: results/compare/integer/multiple/greater-than-equal installcheck: results/compare/integer/order_by_limit installcheck: results/compare/timestamp/single/between +installcheck: results/array/text/single/contain installcheck: results/array/varchar/single/contain installcheck: results/groonga @@ -73,6 +74,8 @@ results/compare/integer/order_by_limit: @mkdir -p $@ results/compare/timestamp/single/between: @mkdir -p $@ +results/array/text/single/contain: + @mkdir -p $@ results/array/varchar/single/contain: @mkdir -p $@ results/groonga: Added: expected/array/text/single/contain/bitmapscan.out (+29 -0) 100644 =================================================================== --- /dev/null +++ expected/array/text/single/contain/bitmapscan.out 2015-02-15 13:49:26 +0900 (db31cb0) @@ -0,0 +1,29 @@ +CREATE TABLE memos ( + title text, + contents text[] +); +INSERT INTO memos + VALUES ('PostgreSQL', + ARRAY['PostgreSQL is an OSS RDMBS', + 'PostgreSQL has partial full-text search support']); +INSERT INTO memos + VALUES ('Groonga', ARRAY['Groonga is an OSS full-text search engine', + 'Groonga has full full-text search support']); +INSERT INTO memos + VALUES ('PGroonga', + ARRAY['PGroonga is an OSS PostgreSQL extension', + 'PGroonga adds full full-text search support based on Groonga to PostgreSQL']); +CREATE INDEX pgroonga_memos_index ON memos USING pgroonga (contents); +SET enable_seqscan = off; +SET enable_indexscan = off; +SET enable_bitmapscan = on; +SELECT title, contents + FROM memos + WHERE contents %% 'Groonga'; + title | contents +----------+-------------------------------------------------------------------------------------------------------------------------- + Groonga | {"Groonga is an OSS full-text search engine","Groonga has full full-text search support"} + PGroonga | {"PGroonga is an OSS PostgreSQL extension","PGroonga adds full full-text search support based on Groonga to PostgreSQL"} +(2 rows) + +DROP TABLE memos; Added: expected/array/text/single/contain/indexscan.out (+29 -0) 100644 =================================================================== --- /dev/null +++ expected/array/text/single/contain/indexscan.out 2015-02-15 13:49:26 +0900 (c6209a8) @@ -0,0 +1,29 @@ +CREATE TABLE memos ( + title text, + contents text[] +); +INSERT INTO memos + VALUES ('PostgreSQL', + ARRAY['PostgreSQL is an OSS RDMBS', + 'PostgreSQL has partial full-text search support']); +INSERT INTO memos + VALUES ('Groonga', ARRAY['Groonga is an OSS full-text search engine', + 'Groonga has full full-text search support']); +INSERT INTO memos + VALUES ('PGroonga', + ARRAY['PGroonga is an OSS PostgreSQL extension', + 'PGroonga adds full full-text search support based on Groonga to PostgreSQL']); +CREATE INDEX pgroonga_memos_index ON memos USING pgroonga (contents); +SET enable_seqscan = off; +SET enable_indexscan = on; +SET enable_bitmapscan = off; +SELECT title, contents + FROM memos + WHERE contents %% 'Groonga'; + title | contents +----------+-------------------------------------------------------------------------------------------------------------------------- + Groonga | {"Groonga is an OSS full-text search engine","Groonga has full full-text search support"} + PGroonga | {"PGroonga is an OSS PostgreSQL extension","PGroonga adds full full-text search support based on Groonga to PostgreSQL"} +(2 rows) + +DROP TABLE memos; Added: expected/array/text/single/contain/seqscan.out (+29 -0) 100644 =================================================================== --- /dev/null +++ expected/array/text/single/contain/seqscan.out 2015-02-15 13:49:26 +0900 (5c2aed0) @@ -0,0 +1,29 @@ +CREATE TABLE memos ( + title text, + contents text[] +); +INSERT INTO memos + VALUES ('PostgreSQL', + ARRAY['PostgreSQL is an OSS RDMBS', + 'PostgreSQL has partial full-text search support']); +INSERT INTO memos + VALUES ('Groonga', ARRAY['Groonga is an OSS full-text search engine', + 'Groonga has full full-text search support']); +INSERT INTO memos + VALUES ('PGroonga', + ARRAY['PGroonga is an OSS PostgreSQL extension', + 'PGroonga adds full full-text search support based on Groonga to PostgreSQL']); +CREATE INDEX pgroonga_memos_index ON memos USING pgroonga (contents); +SET enable_seqscan = on; +SET enable_indexscan = off; +SET enable_bitmapscan = off; +SELECT title, contents + FROM memos + WHERE contents %% 'Groonga'; + title | contents +----------+-------------------------------------------------------------------------------------------------------------------------- + Groonga | {"Groonga is an OSS full-text search engine","Groonga has full full-text search support"} + PGroonga | {"PGroonga is an OSS PostgreSQL extension","PGroonga adds full full-text search support based on Groonga to PostgreSQL"} +(2 rows) + +DROP TABLE memos; Modified: pgroonga.c (+70 -3) =================================================================== --- pgroonga.c 2015-02-15 13:11:17 +0900 (4f57884) +++ pgroonga.c 2015-02-15 13:49:26 +0900 (ee2bd3f) @@ -99,6 +99,7 @@ PG_FUNCTION_INFO_V1(pgroonga_command); PG_FUNCTION_INFO_V1(pgroonga_contain_text); PG_FUNCTION_INFO_V1(pgroonga_contain_text_array); PG_FUNCTION_INFO_V1(pgroonga_contain_varchar); +PG_FUNCTION_INFO_V1(pgroonga_contain_varchar_array); PG_FUNCTION_INFO_V1(pgroonga_match); PG_FUNCTION_INFO_V1(pgroonga_insert); @@ -454,6 +455,10 @@ PGrnGetType(Relation index, AttrNumber n, unsigned char *flags) typeID = GRN_DB_SHORT_TEXT; typeFlags |= GRN_OBJ_VECTOR; break; + case TEXTARRAYOID: + typeID = GRN_DB_LONG_TEXT; + typeFlags |= GRN_OBJ_VECTOR; + break; default: ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -562,9 +567,25 @@ static bool PGrnIsForFullTextSearchIndex(Relation index) { Oid queryStrategyOID; + Oid leftType; + Oid rightType; + + leftType = index->rd_opcintype[0]; + switch (leftType) + { + case VARCHARARRAYOID: + rightType = VARCHAROID; + break; + case TEXTARRAYOID: + rightType = TEXTOID; + break; + default: + rightType = leftType; + break; + } queryStrategyOID = get_opfamily_member(index->rd_opfamily[0], - index->rd_opcintype[0], - index->rd_opcintype[0], + leftType, + rightType, PGrnQueryStrategyNumber); return (queryStrategyOID != InvalidOid); } @@ -976,7 +997,10 @@ pgroonga_contain_text_array(PG_FUNCTION_ARGS) element = DatumGetTextPP(elementDatum); GRN_TEXT_SET(ctx, &elementBuffer, VARDATA_ANY(element), VARSIZE_ANY_EXHDR(element)); - if (grn_operator_exec_equal(ctx, &buffer, &elementBuffer)) + if (pgroonga_contain_raw(GRN_TEXT_VALUE(&elementBuffer), + GRN_TEXT_LEN(&elementBuffer), + GRN_TEXT_VALUE(&buffer), + GRN_TEXT_LEN(&buffer))) { contained = true; break; @@ -1005,6 +1029,49 @@ pgroonga_contain_varchar(PG_FUNCTION_ARGS) } /** + * pgroonga.contain(target varchar[], query varchar) : bool + */ +Datum +pgroonga_contain_varchar_array(PG_FUNCTION_ARGS) +{ + ArrayType *target = PG_GETARG_ARRAYTYPE_P(0); + VarChar *query = PG_GETARG_VARCHAR_PP(1); + bool contained = false; + grn_obj elementBuffer; + int i, n; + + grn_obj_reinit(ctx, &buffer, GRN_DB_TEXT, 0); + GRN_TEXT_SET(ctx, &buffer, VARDATA_ANY(query), VARSIZE_ANY_EXHDR(query)); + + GRN_TEXT_INIT(&elementBuffer, GRN_OBJ_DO_SHALLOW_COPY); + + n = ARR_DIMS(target)[0]; + for (i = 1; i <= n; i++) + { + Datum elementDatum; + VarChar *element; + bool isNULL; + + elementDatum = array_ref(target, 1, &i, -1, -1, false, 'i', &isNULL); + if (isNULL) + continue; + + element = DatumGetVarCharPP(elementDatum); + GRN_TEXT_SET(ctx, &elementBuffer, + VARDATA_ANY(element), VARSIZE_ANY_EXHDR(element)); + if (grn_operator_exec_equal(ctx, &buffer, &elementBuffer)) + { + contained = true; + break; + } + } + + GRN_OBJ_FIN(ctx, &elementBuffer); + + PG_RETURN_BOOL(contained); +} + +/** * pgroonga.match(text, query) : bool */ Datum Modified: pgroonga.h (+2 -0) =================================================================== --- pgroonga.h 2015-02-15 13:11:17 +0900 (682a830) +++ pgroonga.h 2015-02-15 13:49:26 +0900 (59f3a95) @@ -52,6 +52,7 @@ extern Datum PGDLLEXPORT pgroonga_command(PG_FUNCTION_ARGS); extern Datum PGDLLEXPORT pgroonga_contain_text(PG_FUNCTION_ARGS); extern Datum PGDLLEXPORT pgroonga_contain_text_array(PG_FUNCTION_ARGS); extern Datum PGDLLEXPORT pgroonga_contain_varchar(PG_FUNCTION_ARGS); +extern Datum PGDLLEXPORT pgroonga_contain_varchar_array(PG_FUNCTION_ARGS); extern Datum PGDLLEXPORT pgroonga_match(PG_FUNCTION_ARGS); extern Datum PGDLLEXPORT pgroonga_insert(PG_FUNCTION_ARGS); @@ -69,6 +70,7 @@ extern Datum PGDLLEXPORT pgroonga_options(PG_FUNCTION_ARGS); /* in groonga_types.c */ extern Datum PGDLLEXPORT pgroonga_get_text(PG_FUNCTION_ARGS); +extern Datum PGDLLEXPORT pgroonga_get_text_array(PG_FUNCTION_ARGS); extern Datum PGDLLEXPORT pgroonga_get_varchar(PG_FUNCTION_ARGS); extern Datum PGDLLEXPORT pgroonga_get_varchar_array(PG_FUNCTION_ARGS); extern Datum PGDLLEXPORT pgroonga_get_bool(PG_FUNCTION_ARGS); Modified: pgroonga.sql (+32 -14) =================================================================== --- pgroonga.sql 2015-02-15 13:11:17 +0900 (671a5ce) +++ pgroonga.sql 2015-02-15 13:49:26 +0900 (3bec7d1) @@ -44,6 +44,13 @@ CREATE FUNCTION pgroonga.contain(varchar, varchar) IMMUTABLE STRICT; +CREATE FUNCTION pgroonga.contain(target varchar[], query varchar) + RETURNS bool + AS 'MODULE_PATHNAME', 'pgroonga_contain_varchar_array' + LANGUAGE C + IMMUTABLE + STRICT; + CREATE OPERATOR %% ( PROCEDURE = pgroonga.contain, LEFTARG = text, @@ -62,6 +69,12 @@ CREATE OPERATOR %% ( RIGHTARG = varchar ); +CREATE OPERATOR %% ( + PROCEDURE = pgroonga.contain, + LEFTARG = varchar[], + RIGHTARG = varchar +); + CREATE FUNCTION pgroonga.match(text, text) RETURNS bool @@ -70,14 +83,14 @@ CREATE FUNCTION pgroonga.match(text, text) IMMUTABLE STRICT; -CREATE FUNCTION pgroonga.match(varchar, varchar) +CREATE FUNCTION pgroonga.match(text[], text) RETURNS bool AS 'MODULE_PATHNAME', 'pgroonga_match' LANGUAGE C IMMUTABLE STRICT; -CREATE FUNCTION pgroonga.match(varchar[], varchar) +CREATE FUNCTION pgroonga.match(varchar, varchar) RETURNS bool AS 'MODULE_PATHNAME', 'pgroonga_match' LANGUAGE C @@ -92,13 +105,13 @@ CREATE OPERATOR @@ ( CREATE OPERATOR @@ ( PROCEDURE = pgroonga.match, - LEFTARG = varchar, - RIGHTARG = varchar + LEFTARG = text[], + RIGHTARG = text ); CREATE OPERATOR @@ ( PROCEDURE = pgroonga.match, - LEFTARG = varchar[], + LEFTARG = varchar, RIGHTARG = varchar ); @@ -156,6 +169,10 @@ CREATE FUNCTION pgroonga.get_text(internal, internal, text) RETURNS void AS 'MODULE_PATHNAME', 'pgroonga_get_text' LANGUAGE C; +CREATE FUNCTION pgroonga.get_text_array(internal, internal, text[]) + RETURNS void + AS 'MODULE_PATHNAME', 'pgroonga_get_text_array' + LANGUAGE C; CREATE FUNCTION pgroonga.get_varchar(internal, internal, varchar) RETURNS void AS 'MODULE_PATHNAME', 'pgroonga_get_varchar' @@ -239,6 +256,15 @@ CREATE OPERATOR CLASS pgroonga.full_text_search_text_ops DEFAULT FOR TYPE text FUNCTION 1 pgroonga.get_text(internal, internal, text), FUNCTION 2 pgroonga.get_text(internal, internal, text); +CREATE OPERATOR CLASS pgroonga.full_text_search_text_array_ops + DEFAULT + FOR TYPE text[] + USING pgroonga AS + OPERATOR 7 %% (text[], text), + OPERATOR 8 @@ (text[], text), + FUNCTION 1 pgroonga.get_text_array(internal, internal, text[]), + FUNCTION 2 pgroonga.get_text(internal, internal, text); + CREATE OPERATOR CLASS pgroonga.full_text_search_varchar_ops DEFAULT FOR TYPE varchar USING pgroonga AS OPERATOR 7 %%, @@ -256,19 +282,11 @@ CREATE OPERATOR CLASS pgroonga.varchar_ops FOR TYPE varchar FUNCTION 1 pgroonga.get_varchar(internal, internal, varchar), FUNCTION 2 pgroonga.get_varchar(internal, internal, varchar); -CREATE OPERATOR CLASS pgroonga.full_text_search_varchar_array_ops - FOR TYPE varchar[] - USING pgroonga AS - OPERATOR 7 %% (text[], text), - OPERATOR 8 @@ (varchar[], varchar), - FUNCTION 1 pgroonga.get_varchar_array(internal, internal, varchar[]), - FUNCTION 2 pgroonga.get_varchar(internal, internal, varchar); - CREATE OPERATOR CLASS pgroonga.varchar_array_ops DEFAULT FOR TYPE varchar[] USING pgroonga AS - OPERATOR 7 %% (text[], text), + OPERATOR 7 %% (varchar[], varchar), FUNCTION 1 pgroonga.get_varchar_array(internal, internal, varchar[]), FUNCTION 2 pgroonga.get_varchar(internal, internal, varchar); Modified: pgroonga_types.c (+32 -0) =================================================================== --- pgroonga_types.c 2015-02-15 13:11:17 +0900 (5a0fd46) +++ pgroonga_types.c 2015-02-15 13:49:26 +0900 (6d83810) @@ -15,6 +15,7 @@ #include <math.h> PG_FUNCTION_INFO_V1(pgroonga_get_text); +PG_FUNCTION_INFO_V1(pgroonga_get_text_array); PG_FUNCTION_INFO_V1(pgroonga_get_varchar); PG_FUNCTION_INFO_V1(pgroonga_get_varchar_array); PG_FUNCTION_INFO_V1(pgroonga_get_bool); @@ -38,6 +39,37 @@ pgroonga_get_text(PG_FUNCTION_ARGS) } Datum +pgroonga_get_text_array(PG_FUNCTION_ARGS) +{ + grn_ctx *ctx = (grn_ctx *) PG_GETARG_POINTER(0); + grn_obj *obj = (grn_obj *) PG_GETARG_POINTER(1); + ArrayType *value = PG_GETARG_ARRAYTYPE_P(2); + int i, n; + + n = ARR_DIMS(value)[0]; + for (i = 1; i <= n; i++) + { + int weight = 0; + Datum elementDatum; + text *element; + bool isNULL; + + elementDatum = array_ref(value, 1, &i, -1, -1, false, 'i', &isNULL); + if (isNULL) + continue; + + element = DatumGetTextPP(elementDatum); + grn_vector_add_element(ctx, obj, + VARDATA_ANY(element), + VARSIZE_ANY_EXHDR(element), + weight, + obj->header.domain); + } + + PG_RETURN_VOID(); +} + +Datum pgroonga_get_varchar(PG_FUNCTION_ARGS) { grn_ctx *ctx = (grn_ctx *) PG_GETARG_POINTER(0); Added: sql/array/text/single/contain/bitmapscan.sql (+28 -0) 100644 =================================================================== --- /dev/null +++ sql/array/text/single/contain/bitmapscan.sql 2015-02-15 13:49:26 +0900 (6b2e462) @@ -0,0 +1,28 @@ +CREATE TABLE memos ( + title text, + contents text[] +); + +INSERT INTO memos + VALUES ('PostgreSQL', + ARRAY['PostgreSQL is an OSS RDMBS', + 'PostgreSQL has partial full-text search support']); +INSERT INTO memos + VALUES ('Groonga', ARRAY['Groonga is an OSS full-text search engine', + 'Groonga has full full-text search support']); +INSERT INTO memos + VALUES ('PGroonga', + ARRAY['PGroonga is an OSS PostgreSQL extension', + 'PGroonga adds full full-text search support based on Groonga to PostgreSQL']); + +CREATE INDEX pgroonga_memos_index ON memos USING pgroonga (contents); + +SET enable_seqscan = off; +SET enable_indexscan = off; +SET enable_bitmapscan = on; + +SELECT title, contents + FROM memos + WHERE contents %% 'Groonga'; + +DROP TABLE memos; Added: sql/array/text/single/contain/indexscan.sql (+28 -0) 100644 =================================================================== --- /dev/null +++ sql/array/text/single/contain/indexscan.sql 2015-02-15 13:49:26 +0900 (6054737) @@ -0,0 +1,28 @@ +CREATE TABLE memos ( + title text, + contents text[] +); + +INSERT INTO memos + VALUES ('PostgreSQL', + ARRAY['PostgreSQL is an OSS RDMBS', + 'PostgreSQL has partial full-text search support']); +INSERT INTO memos + VALUES ('Groonga', ARRAY['Groonga is an OSS full-text search engine', + 'Groonga has full full-text search support']); +INSERT INTO memos + VALUES ('PGroonga', + ARRAY['PGroonga is an OSS PostgreSQL extension', + 'PGroonga adds full full-text search support based on Groonga to PostgreSQL']); + +CREATE INDEX pgroonga_memos_index ON memos USING pgroonga (contents); + +SET enable_seqscan = off; +SET enable_indexscan = on; +SET enable_bitmapscan = off; + +SELECT title, contents + FROM memos + WHERE contents %% 'Groonga'; + +DROP TABLE memos; Added: sql/array/text/single/contain/seqscan.sql (+28 -0) 100644 =================================================================== --- /dev/null +++ sql/array/text/single/contain/seqscan.sql 2015-02-15 13:49:26 +0900 (5742875) @@ -0,0 +1,28 @@ +CREATE TABLE memos ( + title text, + contents text[] +); + +INSERT INTO memos + VALUES ('PostgreSQL', + ARRAY['PostgreSQL is an OSS RDMBS', + 'PostgreSQL has partial full-text search support']); +INSERT INTO memos + VALUES ('Groonga', ARRAY['Groonga is an OSS full-text search engine', + 'Groonga has full full-text search support']); +INSERT INTO memos + VALUES ('PGroonga', + ARRAY['PGroonga is an OSS PostgreSQL extension', + 'PGroonga adds full full-text search support based on Groonga to PostgreSQL']); + +CREATE INDEX pgroonga_memos_index ON memos USING pgroonga (contents); + +SET enable_seqscan = on; +SET enable_indexscan = off; +SET enable_bitmapscan = off; + +SELECT title, contents + FROM memos + WHERE contents %% 'Groonga'; + +DROP TABLE memos; -------------- next part -------------- HTML����������������������������...Download