[Groonga-commit] pgroonga/pgroonga at fed2054 [master] Support prefix RK search by '&^~' with prefix_search_ops_v2

Back to archive index

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 



More information about the Groonga-commit mailing list
Back to archive index