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

Back to archive index

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 



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