Kouhei Sutou
null+****@clear*****
Fri Apr 8 01:16:50 JST 2016
Kouhei Sutou 2016-04-08 01:16:50 +0900 (Fri, 08 Apr 2016) New Revision: fed205492a6634266db26ac4af7daa10d3c43eac https://github.com/pgroonga/pgroonga/commit/fed205492a6634266db26ac4af7daa10d3c43eac Message: Support prefix RK search by '&^~' with prefix_search_ops_v2 Added files: expected/prefix/text/prefix-rk/bitmapscan.out expected/prefix/text/prefix-rk/indexscan.out expected/prefix/text/prefix-rk/seqscan.out sql/prefix/text/prefix-rk/bitmapscan.sql sql/prefix/text/prefix-rk/indexscan.sql sql/prefix/text/prefix-rk/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-rk/bitmapscan.out (+23 -0) 100644 =================================================================== --- /dev/null +++ expected/prefix/text/prefix-rk/bitmapscan.out 2016-04-08 01:16:50 +0900 (b9c82dc) @@ -0,0 +1,23 @@ +CREATE TABLE readings ( + katakana text +); +INSERT INTO readings VALUES ('ポストグレスキューエル'); +INSERT INTO readings VALUES ('グルンガ'); +INSERT INTO readings VALUES ('ピージールンガ'); +INSERT INTO readings VALUES ('ピージーロジカル'); +CREATE INDEX pgrn_index ON readings + USING pgroonga (katakana pgroonga.prefix_search_ops_v2); +SET enable_seqscan = off; +SET enable_indexscan = off; +SET enable_bitmapscan = on; +SELECT katakana + FROM readings + WHERE katakana &^~ 'p'; + katakana +------------------------ + ポストグレスキューエル + ピージールンガ + ピージーロジカル +(3 rows) + +DROP TABLE readings; Added: expected/prefix/text/prefix-rk/indexscan.out (+23 -0) 100644 =================================================================== --- /dev/null +++ expected/prefix/text/prefix-rk/indexscan.out 2016-04-08 01:16:50 +0900 (a79a38d) @@ -0,0 +1,23 @@ +CREATE TABLE readings ( + katakana text +); +INSERT INTO readings VALUES ('ポストグレスキューエル'); +INSERT INTO readings VALUES ('グルンガ'); +INSERT INTO readings VALUES ('ピージールンガ'); +INSERT INTO readings VALUES ('ピージーロジカル'); +CREATE INDEX pgrn_index ON readings + USING pgroonga (katakana pgroonga.prefix_search_ops_v2); +SET enable_seqscan = off; +SET enable_indexscan = on; +SET enable_bitmapscan = off; +SELECT katakana + FROM readings + WHERE katakana &^~ 'p'; + katakana +------------------------ + ピージールンガ + ピージーロジカル + ポストグレスキューエル +(3 rows) + +DROP TABLE readings; Added: expected/prefix/text/prefix-rk/seqscan.out (+21 -0) 100644 =================================================================== --- /dev/null +++ expected/prefix/text/prefix-rk/seqscan.out 2016-04-08 01:16:50 +0900 (f7073ce) @@ -0,0 +1,21 @@ +CREATE TABLE readings ( + katakana text +); +INSERT INTO readings VALUES ('ポストグレスキューエル'); +INSERT INTO readings VALUES ('グルンガ'); +INSERT INTO readings VALUES ('ピージールンガ'); +INSERT INTO readings VALUES ('ピージーロジカル'); +SET enable_seqscan = on; +SET enable_indexscan = off; +SET enable_bitmapscan = off; +SELECT katakana + FROM readings + WHERE katakana &^~ 'p'; + katakana +------------------------ + ポストグレスキューエル + ピージールンガ + ピージーロジカル +(3 rows) + +DROP TABLE readings; Modified: pgroonga.sql (+19 -5) =================================================================== --- pgroonga.sql 2016-04-08 00:27:57 +0900 (aaef1fb) +++ pgroonga.sql 2016-04-08 01:16:50 +0900 (1987abb) @@ -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 - 18, -- amstrategies + 19, -- amstrategies 0, -- amsupport true, -- amcanorder true, -- amcanorderbyop @@ -427,6 +427,19 @@ CREATE OPERATOR &^ ( RIGHTARG = text ); +CREATE FUNCTION pgroonga.prefix_rk_text(text, text) + RETURNS bool + AS 'MODULE_PATHNAME', 'pgroonga_prefix_rk_text' + LANGUAGE C + IMMUTABLE + STRICT; + +CREATE OPERATOR &^~ ( + PROCEDURE = pgroonga.prefix_rk_text, + LEFTARG = text, + RIGHTARG = text +); + CREATE FUNCTION pgroonga.script_text(text, text) RETURNS bool AS 'MODULE_PATHNAME', 'pgroonga_script_text' @@ -473,10 +486,11 @@ CREATE OPERATOR CLASS pgroonga.text_full_text_search_ops_v2 FOR TYPE text OPERATOR 12 &@, OPERATOR 13 &?, OPERATOR 14 &~?, - OPERATOR 16 &`, - OPERATOR 17 &@> (text, text[]), - OPERATOR 18 &?> (text, text[]); + OPERATOR 17 &`, + OPERATOR 18 &@> (text, text[]), + OPERATOR 19 &?> (text, text[]); CREATE OPERATOR CLASS pgroonga.prefix_search_ops_v2 FOR TYPE text USING pgroonga AS - OPERATOR 15 &^; + OPERATOR 15 &^, + OPERATOR 16 &^~; Added: sql/prefix/text/prefix-rk/bitmapscan.sql (+21 -0) 100644 =================================================================== --- /dev/null +++ sql/prefix/text/prefix-rk/bitmapscan.sql 2016-04-08 01:16:50 +0900 (4927138) @@ -0,0 +1,21 @@ +CREATE TABLE readings ( + katakana text +); + +INSERT INTO readings VALUES ('ポストグレスキューエル'); +INSERT INTO readings VALUES ('グルンガ'); +INSERT INTO readings VALUES ('ピージールンガ'); +INSERT INTO readings VALUES ('ピージーロジカル'); + +CREATE INDEX pgrn_index ON readings + USING pgroonga (katakana pgroonga.prefix_search_ops_v2); + +SET enable_seqscan = off; +SET enable_indexscan = off; +SET enable_bitmapscan = on; + +SELECT katakana + FROM readings + WHERE katakana &^~ 'p'; + +DROP TABLE readings; Added: sql/prefix/text/prefix-rk/indexscan.sql (+21 -0) 100644 =================================================================== --- /dev/null +++ sql/prefix/text/prefix-rk/indexscan.sql 2016-04-08 01:16:50 +0900 (496b961) @@ -0,0 +1,21 @@ +CREATE TABLE readings ( + katakana text +); + +INSERT INTO readings VALUES ('ポストグレスキューエル'); +INSERT INTO readings VALUES ('グルンガ'); +INSERT INTO readings VALUES ('ピージールンガ'); +INSERT INTO readings VALUES ('ピージーロジカル'); + +CREATE INDEX pgrn_index ON readings + USING pgroonga (katakana pgroonga.prefix_search_ops_v2); + +SET enable_seqscan = off; +SET enable_indexscan = on; +SET enable_bitmapscan = off; + +SELECT katakana + FROM readings + WHERE katakana &^~ 'p'; + +DROP TABLE readings; Added: sql/prefix/text/prefix-rk/seqscan.sql (+18 -0) 100644 =================================================================== --- /dev/null +++ sql/prefix/text/prefix-rk/seqscan.sql 2016-04-08 01:16:50 +0900 (daf9b2b) @@ -0,0 +1,18 @@ +CREATE TABLE readings ( + katakana text +); + +INSERT INTO readings VALUES ('ポストグレスキューエル'); +INSERT INTO readings VALUES ('グルンガ'); +INSERT INTO readings VALUES ('ピージールンガ'); +INSERT INTO readings VALUES ('ピージーロジカル'); + +SET enable_seqscan = on; +SET enable_indexscan = off; +SET enable_bitmapscan = off; + +SELECT katakana + FROM readings + WHERE katakana &^~ 'p'; + +DROP TABLE readings; Modified: src/pgrn_create.c (+35 -12) =================================================================== --- src/pgrn_create.c 2016-04-08 00:27:57 +0900 (69637ca) +++ src/pgrn_create.c 2016-04-08 01:16:50 +0900 (2fd2f49) @@ -36,6 +36,20 @@ void PGrnCreateDataColumn(PGrnCreateData *data) { grn_obj_flags flags = 0; + grn_obj *range; + grn_id rangeID; + + if (data->forPrefixSearch) { + char lexiconName[GRN_TABLE_MAX_KEY_SIZE]; + + snprintf(lexiconName, sizeof(lexiconName), + PGrnLexiconNameFormat, data->relNode, data->i); + range = PGrnLookup(lexiconName, ERROR); + rangeID = grn_obj_id(ctx, range); + } else { + rangeID = data->attributeTypeID; + range = grn_ctx_at(ctx, rangeID); + } if (data->attributeFlags & GRN_OBJ_VECTOR) { @@ -47,7 +61,7 @@ PGrnCreateDataColumn(PGrnCreateData *data) if (PGrnIsLZ4Available) { - switch (data->attributeTypeID) + switch (rangeID) { case GRN_DB_SHORT_TEXT: case GRN_DB_TEXT: @@ -65,12 +79,12 @@ PGrnCreateDataColumn(PGrnCreateData *data) PGrnCreateColumn(data->sourcesTable, columnName, flags, - grn_ctx_at(ctx, data->attributeTypeID)); + range); } } void -PGrnCreateIndexColumn(PGrnCreateData *data) +PGrnCreateLexicon(PGrnCreateData *data) { grn_id typeID = GRN_ID_NIL; char lexiconName[GRN_TABLE_MAX_KEY_SIZE]; @@ -124,14 +138,23 @@ PGrnCreateIndexColumn(PGrnCreateData *data) PGrnLookup(normalizerName, ERROR)); } } +} - { - grn_obj_flags flags = GRN_OBJ_COLUMN_INDEX; - if (data->forFullTextSearch || data->forRegexpSearch) - flags |= GRN_OBJ_WITH_POSITION; - PGrnCreateColumn(lexicon, - PGrnIndexColumnName, - flags, - data->sourcesTable); - } +void +PGrnCreateIndexColumn(PGrnCreateData *data) +{ + char lexiconName[GRN_TABLE_MAX_KEY_SIZE]; + grn_obj *lexicon; + grn_obj_flags flags = GRN_OBJ_COLUMN_INDEX; + + snprintf(lexiconName, sizeof(lexiconName), + PGrnLexiconNameFormat, data->relNode, data->i); + lexicon = PGrnLookup(lexiconName, ERROR); + + if (data->forFullTextSearch || data->forRegexpSearch) + flags |= GRN_OBJ_WITH_POSITION; + PGrnCreateColumn(lexicon, + PGrnIndexColumnName, + flags, + data->sourcesTable); } Modified: src/pgrn_create.h (+1 -0) =================================================================== --- src/pgrn_create.h 2016-04-08 00:27:57 +0900 (a909560) +++ src/pgrn_create.h 2016-04-08 01:16:50 +0900 (c775777) @@ -24,5 +24,6 @@ typedef struct PGrnCreateData void PGrnCreateSourcesCtidColumn(PGrnCreateData *data); void PGrnCreateSourcesTable(PGrnCreateData *data); +void PGrnCreateLexicon(PGrnCreateData *data); void PGrnCreateDataColumn(PGrnCreateData *data); void PGrnCreateIndexColumn(PGrnCreateData *data); Modified: src/pgroonga.c (+189 -29) =================================================================== --- src/pgroonga.c 2016-04-08 00:27:57 +0900 (0804195) +++ src/pgroonga.c 2016-04-08 01:16:50 +0900 (fdb425c) @@ -111,12 +111,19 @@ typedef struct PGrnScanOpaqueData typedef PGrnScanOpaqueData *PGrnScanOpaque; -typedef struct PGrnSequentialSearchData +typedef struct PGrnMatchSequentialSearchData { grn_obj *table; grn_obj *textColumn; grn_id recordID; -} PGrnSequentialSearchData; +} PGrnMatchSequentialSearchData; + +typedef struct PGrnPrefixRKSequentialSearchData +{ + grn_obj *table; + grn_obj *key; + grn_obj *resultTable; +} PGrnPrefixRKSequentialSearchData; #ifdef PGRN_SUPPORT_SCORE static slist_head PGrnScanOpaques = SLIST_STATIC_INIT(PGrnScanOpaques); @@ -144,6 +151,7 @@ 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_prefix_rk_text); PG_FUNCTION_INFO_V1(pgroonga_script_text); PG_FUNCTION_INFO_V1(pgroonga_match_contain_text); PG_FUNCTION_INFO_V1(pgroonga_query_contain_text); @@ -165,7 +173,8 @@ PG_FUNCTION_INFO_V1(pgroonga_costestimate); static grn_ctx *ctx = NULL; static struct PGrnBuffers *buffers = &PGrnBuffers; -static PGrnSequentialSearchData sequentialSearchData; +static PGrnMatchSequentialSearchData matchSequentialSearchData; +static PGrnPrefixRKSequentialSearchData prefixRKSequentialSearchData; static grn_encoding PGrnGetEncoding(void) @@ -231,10 +240,18 @@ PGrnEnsureDatabase(void) } static void -PGrnFinalizeSequentialSearchData(void) +PGrnFinalizeMatchSequentialSearchData(void) { - grn_obj_close(ctx, sequentialSearchData.textColumn); - grn_obj_close(ctx, sequentialSearchData.table); + grn_obj_close(ctx, matchSequentialSearchData.textColumn); + grn_obj_close(ctx, matchSequentialSearchData.table); +} + +static void +PGrnFinalizePrefixRKSequentialSearchData(void) +{ + grn_obj_close(ctx, prefixRKSequentialSearchData.resultTable); + grn_obj_close(ctx, prefixRKSequentialSearchData.key); + grn_obj_close(ctx, prefixRKSequentialSearchData.table); } static void @@ -246,7 +263,8 @@ PGrnOnProcExit(int code, Datum arg) PGrnFinalizeJSONB(); - PGrnFinalizeSequentialSearchData(); + PGrnFinalizeMatchSequentialSearchData(); + PGrnFinalizePrefixRKSequentialSearchData(); PGrnFinalizeBuffers(); @@ -261,27 +279,53 @@ PGrnOnProcExit(int code, Datum arg) } static void -PGrnInitializeSequentialSearchData(void) -{ - sequentialSearchData.table = grn_table_create(ctx, - NULL, 0, - NULL, - GRN_OBJ_TABLE_NO_KEY, - NULL, NULL); - sequentialSearchData.textColumn = +PGrnInitializeMatchSequentialSearchData(void) +{ + matchSequentialSearchData.table = grn_table_create(ctx, + NULL, 0, + NULL, + GRN_OBJ_TABLE_NO_KEY, + NULL, NULL); + matchSequentialSearchData.textColumn = grn_column_create(ctx, - sequentialSearchData.table, + matchSequentialSearchData.table, "text", strlen("text"), NULL, GRN_OBJ_COLUMN_SCALAR, grn_ctx_at(ctx, GRN_DB_TEXT)); - sequentialSearchData.recordID = + matchSequentialSearchData.recordID = grn_table_add(ctx, - sequentialSearchData.table, + matchSequentialSearchData.table, NULL, 0, NULL); } +static void +PGrnInitializePrefixRKSequentialSearchData(void) +{ + prefixRKSequentialSearchData.table = + grn_table_create(ctx, + NULL, 0, + NULL, + GRN_OBJ_TABLE_PAT_KEY, + grn_ctx_at(ctx, GRN_DB_SHORT_TEXT), + NULL); + + prefixRKSequentialSearchData.key = + grn_obj_column(ctx, + prefixRKSequentialSearchData.table, + GRN_COLUMN_NAME_KEY, + GRN_COLUMN_NAME_KEY_LEN); + + prefixRKSequentialSearchData.resultTable = + grn_table_create(ctx, + NULL, 0, + NULL, + GRN_OBJ_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC, + prefixRKSequentialSearchData.table, + NULL); +} + void _PG_init(void) { @@ -316,7 +360,8 @@ _PG_init(void) PGrnInitializeOptions(); - PGrnInitializeSequentialSearchData(); + PGrnInitializeMatchSequentialSearchData(); + PGrnInitializePrefixRKSequentialSearchData(); PGrnInitializeJSONB(); } @@ -724,6 +769,7 @@ PGrnCreate(Relation index, data.forPrefixSearch = PGrnIsForPrefixSearchIndex(index, data.i); data.attributeTypeID = PGrnGetType(index, data.i, &(data.attributeFlags)); + PGrnCreateLexicon(&data); PGrnCreateDataColumn(&data); PGrnCreateIndexColumn(&data); } @@ -1358,7 +1404,7 @@ pgroonga_match_query_raw(const char *target, unsigned int targetSize, bool matched = false; GRN_EXPR_CREATE_FOR_QUERY(ctx, - sequentialSearchData.table, + matchSequentialSearchData.table, expression, variable); if (!expression) @@ -1372,7 +1418,7 @@ pgroonga_match_query_raw(const char *target, unsigned int targetSize, rc = grn_expr_parse(ctx, expression, query, querySize, - sequentialSearchData.textColumn, + matchSequentialSearchData.textColumn, GRN_OP_MATCH, GRN_OP_AND, flags); if (rc != GRN_SUCCESS) @@ -1391,11 +1437,11 @@ pgroonga_match_query_raw(const char *target, unsigned int targetSize, grn_obj_reinit(ctx, &(buffers->general), GRN_DB_TEXT, 0); GRN_TEXT_SET(ctx, &(buffers->general), target, targetSize); grn_obj_set_value(ctx, - sequentialSearchData.textColumn, - sequentialSearchData.recordID, + matchSequentialSearchData.textColumn, + matchSequentialSearchData.recordID, &(buffers->general), GRN_OBJ_SET); - GRN_RECORD_SET(ctx, variable, sequentialSearchData.recordID); + GRN_RECORD_SET(ctx, variable, matchSequentialSearchData.recordID); result = grn_expr_exec(ctx, expression, 0); GRN_OBJ_IS_TRUE(ctx, result, matched); @@ -1636,6 +1682,77 @@ pgroonga_prefix_text(PG_FUNCTION_ARGS) } static grn_bool +pgroonga_prefix_rk_raw(const char *text, unsigned int textSize, + const char *prefix, unsigned int prefixSize) +{ + grn_obj *expression; + grn_obj *variable; + grn_bool matched; + grn_id id; + + GRN_EXPR_CREATE_FOR_QUERY(ctx, + prefixRKSequentialSearchData.table, + expression, + variable); + if (!expression) + { + ereport(ERROR, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("pgroonga: failed to create expression: %s", + ctx->errbuf))); + } + + grn_expr_append_obj(ctx, expression, + grn_ctx_get(ctx, "prefix_rk_search", -1), + GRN_OP_PUSH, 1); + grn_expr_append_obj(ctx, expression, + prefixRKSequentialSearchData.key, + GRN_OP_GET_VALUE, 1); + grn_expr_append_const_str(ctx, expression, + prefix, prefixSize, + GRN_OP_PUSH, 1); + grn_expr_append_op(ctx, expression, GRN_OP_CALL, 2); + + id = grn_table_add(ctx, + prefixRKSequentialSearchData.table, + text, textSize, NULL); + grn_table_select(ctx, + prefixRKSequentialSearchData.table, + expression, + prefixRKSequentialSearchData.resultTable, + GRN_OP_OR); + matched = grn_table_size(ctx, prefixRKSequentialSearchData.resultTable) > 0; + grn_table_delete(ctx, + prefixRKSequentialSearchData.resultTable, + &id, sizeof(grn_id)); + grn_table_delete(ctx, + prefixRKSequentialSearchData.table, + text, textSize); + + grn_obj_close(ctx, expression); + + return matched; +} + +/** + * pgroonga.prefix_rk_text(target text, prefix text) : bool + */ +Datum +pgroonga_prefix_rk_text(PG_FUNCTION_ARGS) +{ + text *target = PG_GETARG_TEXT_PP(0); + text *prefix = PG_GETARG_TEXT_PP(1); + bool matched = false; + + matched = pgroonga_prefix_rk_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) { @@ -1647,7 +1764,7 @@ pgroonga_script_raw(const char *target, unsigned int targetSize, bool matched = false; GRN_EXPR_CREATE_FOR_QUERY(ctx, - sequentialSearchData.table, + matchSequentialSearchData.table, expression, variable); if (!expression) @@ -1661,7 +1778,7 @@ pgroonga_script_raw(const char *target, unsigned int targetSize, rc = grn_expr_parse(ctx, expression, script, scriptSize, - sequentialSearchData.textColumn, + matchSequentialSearchData.textColumn, GRN_OP_MATCH, GRN_OP_AND, flags); if (rc != GRN_SUCCESS) @@ -1680,11 +1797,11 @@ pgroonga_script_raw(const char *target, unsigned int targetSize, grn_obj_reinit(ctx, &(buffers->general), GRN_DB_TEXT, 0); GRN_TEXT_SET(ctx, &(buffers->general), target, targetSize); grn_obj_set_value(ctx, - sequentialSearchData.textColumn, - sequentialSearchData.recordID, + matchSequentialSearchData.textColumn, + matchSequentialSearchData.recordID, &(buffers->general), GRN_OBJ_SET); - GRN_RECORD_SET(ctx, variable, sequentialSearchData.recordID); + GRN_RECORD_SET(ctx, variable, matchSequentialSearchData.recordID); result = grn_expr_exec(ctx, expression, 0); GRN_OBJ_IS_TRUE(ctx, result, matched); @@ -2301,6 +2418,35 @@ PGrnSearchBuildConditionQuery(PGrnScanOpaque so, } static void +PGrnSearchBuildConditionPrefixRK(PGrnScanOpaque so, + PGrnSearchData *data, + grn_obj *targetColumn, + const char *prefix, + unsigned int prefixSize) +{ + grn_obj subFilterScript; + + GRN_TEXT_INIT(&subFilterScript, 0); + GRN_TEXT_PUTS(ctx, &subFilterScript, "prefix_rk_search(_key, "); + grn_text_esc(ctx, &subFilterScript, prefix, prefixSize); + GRN_TEXT_PUTS(ctx, &subFilterScript, ")"); + + grn_expr_append_obj(ctx, data->expression, + grn_ctx_get(ctx, "sub_filter", -1), + GRN_OP_PUSH, 1); + grn_expr_append_obj(ctx, data->expression, + targetColumn, + GRN_OP_GET_VALUE, 1); + grn_expr_append_const_str(ctx, data->expression, + GRN_TEXT_VALUE(&subFilterScript), + GRN_TEXT_LEN(&subFilterScript), + GRN_OP_PUSH, 1); + grn_expr_append_op(ctx, data->expression, GRN_OP_CALL, 2); + + GRN_OBJ_FIN(ctx, &subFilterScript); +} + +static void PGrnSearchBuildConditionScript(PGrnScanOpaque so, PGrnSearchData *data, grn_obj *targetColumn, @@ -2416,6 +2562,8 @@ PGrnSearchBuildCondition(IndexScanDesc scan, case PGrnPrefixStrategyV2Number: operator = GRN_OP_PREFIX; break; + case PGrnPrefixRKStrategyV2Number: + break; case PGrnScriptStrategyV2Number: break; case PGrnRegexpStrategyNumber: @@ -2465,6 +2613,13 @@ PGrnSearchBuildCondition(IndexScanDesc scan, GRN_TEXT_VALUE(&(buffers->general)), GRN_TEXT_LEN(&(buffers->general))); break; + case PGrnPrefixRKStrategyV2Number: + PGrnSearchBuildConditionPrefixRK(so, + data, + targetColumn, + GRN_TEXT_VALUE(&(buffers->general)), + GRN_TEXT_LEN(&(buffers->general))); + break; case PGrnScriptStrategyV2Number: PGrnSearchBuildConditionScript(so, data, @@ -3518,6 +3673,11 @@ pgroonga_canreturn(PG_FUNCTION_ARGS) { PG_RETURN_BOOL(false); } + + if (PGrnIsForPrefixSearchIndex(index, i)) + { + PG_RETURN_BOOL(false); + } } PG_RETURN_BOOL(true); Modified: src/pgroonga.h (+5 -3) =================================================================== --- src/pgroonga.h 2016-04-08 00:27:57 +0900 (6e7c00e) +++ src/pgroonga.h 2016-04-08 01:16:50 +0900 (1a3d458) @@ -28,9 +28,10 @@ #define PGrnQueryStrategyV2Number 13 /* 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) */ +#define PGrnPrefixRKStrategyV2Number 16 /* operator &^~ (prefix RK search) */ +#define PGrnScriptStrategyV2Number 17 /* operator &` (script in Groonga) */ +#define PGrnMatchContainStrategyNumber 18 /* operator &@> (@ in Groonga) */ +#define PGrnQueryContainStrategyNumber 19 /* operator &?> (query in Groonga) */ /* file and table names */ #define PGrnLogBasename "pgroonga.log" @@ -72,6 +73,7 @@ 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_prefix_rk_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