[Groonga-commit] pgroonga/pgroonga at f673eb5 [master] Add &` operator

Zurück zum Archiv-Index

Kouhei Sutou null+****@clear*****
Mon Feb 22 00:20:59 JST 2016


Kouhei Sutou	2016-02-22 00:20:59 +0900 (Mon, 22 Feb 2016)

  New Revision: f673eb505376258df24ad75f25141edf561aace2
  https://github.com/pgroonga/pgroonga/commit/f673eb505376258df24ad75f25141edf561aace2

  Message:
    Add &` operator
    
    It enables script syntax but it's not useful on seqscan...

  Added files:
    expected/full-text-search/text/single/script-v2/bitmapscan.out
    expected/full-text-search/text/single/script-v2/indexscan.out
    expected/full-text-search/text/single/script-v2/seqscan.out
    sql/full-text-search/text/single/script-v2/bitmapscan.sql
    sql/full-text-search/text/single/script-v2/indexscan.sql
    sql/full-text-search/text/single/script-v2/seqscan.sql
  Modified files:
    pgroonga.sql
    src/pgroonga.c
    src/pgroonga.h

  Added: expected/full-text-search/text/single/script-v2/bitmapscan.out (+22 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/text/single/script-v2/bitmapscan.out    2016-02-22 00:20:59 +0900 (6594e30)
@@ -0,0 +1,22 @@
+CREATE TABLE memos (
+  id integer,
+  content text
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.text_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+SELECT id, content
+  FROM memos
+ WHERE content &` 'content @ "rdbms" || content @ "engine"';
+ id |                 content                  
+----+------------------------------------------
+  1 | PostgreSQL is a RDBMS.
+  2 | Groonga is fast full text search engine.
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/text/single/script-v2/indexscan.out (+22 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/text/single/script-v2/indexscan.out    2016-02-22 00:20:59 +0900 (cd0d49f)
@@ -0,0 +1,22 @@
+CREATE TABLE memos (
+  id integer,
+  content text
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.text_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+SELECT id, content
+  FROM memos
+ WHERE content &` 'content @ "rdbms" || content @ "engine"';
+ id |                 content                  
+----+------------------------------------------
+  1 | PostgreSQL is a RDBMS.
+  2 | Groonga is fast full text search engine.
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/text/single/script-v2/seqscan.out (+20 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/text/single/script-v2/seqscan.out    2016-02-22 00:20:59 +0900 (3012904)
@@ -0,0 +1,20 @@
+CREATE TABLE memos (
+  id integer,
+  text text
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+SELECT id, text
+  FROM memos
+ WHERE text &` 'text @ "rdbms" || text @ "engine"';
+ id |                   text                   
+----+------------------------------------------
+  1 | PostgreSQL is a RDBMS.
+  2 | Groonga is fast full text search engine.
+(2 rows)
+
+DROP TABLE memos;

  Modified: pgroonga.sql (+17 -3)
===================================================================
--- pgroonga.sql    2016-02-18 00:10:37 +0900 (d082421)
+++ pgroonga.sql    2016-02-22 00:20:59 +0900 (3207764)
@@ -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
-	15,		-- amstrategies
+	16,		-- amstrategies
 	0,		-- amsupport
 	true,		-- amcanorder
 	true,		-- amcanorderbyop
@@ -401,6 +401,19 @@ CREATE OPERATOR &? (
 	RIGHTARG = text
 );
 
+CREATE FUNCTION pgroonga.script_text(text, text)
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_script_text'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &` (
+	PROCEDURE = pgroonga.script_text,
+	LEFTARG = text,
+	RIGHTARG = text
+);
+
 CREATE FUNCTION pgroonga.match_contain_text(text, text[])
 	RETURNS bool
 	AS 'MODULE_PATHNAME', 'pgroonga_match_contain_text'
@@ -433,5 +446,6 @@ CREATE OPERATOR CLASS pgroonga.text_full_text_search_ops_v2 FOR TYPE text
 		OPERATOR 7 pg_catalog.~~*,
 		OPERATOR 12 &@,
 		OPERATOR 13 &?,
-		OPERATOR 14 &@> (text, text[]),
-		OPERATOR 15 &?> (text, text[]);
+		OPERATOR 14 &`,
+		OPERATOR 15 &@> (text, text[]),
+		OPERATOR 16 &?> (text, text[]);

  Added: sql/full-text-search/text/single/script-v2/bitmapscan.sql (+21 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/text/single/script-v2/bitmapscan.sql    2016-02-22 00:20:59 +0900 (505d66b)
@@ -0,0 +1,21 @@
+CREATE TABLE memos (
+  id integer,
+  content text
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.text_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+
+SELECT id, content
+  FROM memos
+ WHERE content &` 'content @ "rdbms" || content @ "engine"';
+
+DROP TABLE memos;

  Added: sql/full-text-search/text/single/script-v2/indexscan.sql (+21 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/text/single/script-v2/indexscan.sql    2016-02-22 00:20:59 +0900 (cca62ae)
@@ -0,0 +1,21 @@
+CREATE TABLE memos (
+  id integer,
+  content text
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.text_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+
+SELECT id, content
+  FROM memos
+ WHERE content &` 'content @ "rdbms" || content @ "engine"';
+
+DROP TABLE memos;

  Added: sql/full-text-search/text/single/script-v2/seqscan.sql (+18 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/text/single/script-v2/seqscan.sql    2016-02-22 00:20:59 +0900 (78bc983)
@@ -0,0 +1,18 @@
+CREATE TABLE memos (
+  id integer,
+  text text
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+
+SELECT id, text
+  FROM memos
+ WHERE text &` 'text @ "rdbms" || text @ "engine"';
+
+DROP TABLE memos;

  Modified: src/pgroonga.c (+150 -0)
===================================================================
--- src/pgroonga.c    2016-02-18 00:10:37 +0900 (e754c77)
+++ src/pgroonga.c    2016-02-22 00:20:59 +0900 (913c6c2)
@@ -142,6 +142,7 @@ PG_FUNCTION_INFO_V1(pgroonga_match_regexp_varchar);
 /* v2 */
 PG_FUNCTION_INFO_V1(pgroonga_match_text);
 PG_FUNCTION_INFO_V1(pgroonga_query_text);
+PG_FUNCTION_INFO_V1(pgroonga_script_text);
 PG_FUNCTION_INFO_V1(pgroonga_match_contain_text);
 PG_FUNCTION_INFO_V1(pgroonga_query_contain_text);
 
@@ -605,6 +606,38 @@ PGrnIsQueryContainStrategyIndex(Relation index, int nthAttribute)
 }
 
 static bool
+PGrnIsScriptStrategyIndex(Relation index, int nthAttribute)
+{
+	Oid strategyOID;
+	Oid leftType;
+	Oid rightType;
+
+	leftType = index->rd_opcintype[nthAttribute];
+
+	switch (leftType)
+	{
+	case VARCHARARRAYOID:
+		rightType = VARCHAROID;
+		break;
+	case TEXTARRAYOID:
+		rightType = TEXTOID;
+		break;
+	default:
+		rightType = leftType;
+		break;
+	}
+
+	strategyOID = get_opfamily_member(index->rd_opfamily[nthAttribute],
+									  leftType,
+									  rightType,
+									  PGrnScriptStrategyV2Number);
+	if (OidIsValid(strategyOID))
+		return true;
+
+	return false;
+}
+
+static bool
 PGrnIsForFullTextSearchIndex(Relation index, int nthAttribute)
 {
 	if (PGrnIsQueryStrategyIndex(index, nthAttribute))
@@ -613,6 +646,9 @@ PGrnIsForFullTextSearchIndex(Relation index, int nthAttribute)
 	if (PGrnIsQueryContainStrategyIndex(index, nthAttribute))
 		return true;
 
+	if (PGrnIsScriptStrategyIndex(index, nthAttribute))
+		return true;
+
 	return false;
 }
 
@@ -1514,6 +1550,83 @@ pgroonga_query_text(PG_FUNCTION_ARGS)
 	PG_RETURN_BOOL(matched);
 }
 
+static grn_bool
+pgroonga_script_raw(const char *target, unsigned int targetSize,
+					const char *script, unsigned int scriptSize)
+{
+	grn_obj *expression;
+	grn_obj *variable;
+	grn_expr_flags flags = GRN_EXPR_SYNTAX_SCRIPT;
+	grn_rc rc;
+	grn_obj *result;
+	bool matched = false;
+
+	GRN_EXPR_CREATE_FOR_QUERY(ctx,
+							  sequentialSearchData.table,
+							  expression,
+							  variable);
+	if (!expression)
+	{
+		ereport(ERROR,
+				(errcode(ERRCODE_OUT_OF_MEMORY),
+				 errmsg("pgroonga: failed to create expression: %s",
+						ctx->errbuf)));
+	}
+
+	rc = grn_expr_parse(ctx,
+						expression,
+						script, scriptSize,
+						sequentialSearchData.textColumn,
+						GRN_OP_MATCH, GRN_OP_AND,
+						flags);
+	if (rc != GRN_SUCCESS)
+	{
+		char message[GRN_CTX_MSGSIZE];
+		grn_strncpy(message, GRN_CTX_MSGSIZE,
+					ctx->errbuf, GRN_CTX_MSGSIZE);
+
+		grn_obj_close(ctx, expression);
+		ereport(ERROR,
+				(errcode(PGrnRCToPgErrorCode(rc)),
+				 errmsg("pgroonga: failed to parse expression: %s",
+						message)));
+	}
+
+	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,
+					  &(buffers->general),
+					  GRN_OBJ_SET);
+	GRN_RECORD_SET(ctx, variable, sequentialSearchData.recordID);
+
+	result = grn_expr_exec(ctx, expression, 0);
+	GRN_OBJ_IS_TRUE(ctx, result, matched);
+
+	grn_obj_close(ctx, expression);
+
+	return matched;
+}
+
+/**
+ * pgroonga.script_text(target text, script text) : bool
+ */
+Datum
+pgroonga_script_text(PG_FUNCTION_ARGS)
+{
+	text *target = PG_GETARG_TEXT_PP(0);
+	text *script = PG_GETARG_TEXT_PP(1);
+	bool matched = false;
+
+	matched = pgroonga_script_raw(VARDATA_ANY(target),
+								  VARSIZE_ANY_EXHDR(target),
+								  VARDATA_ANY(script),
+								  VARSIZE_ANY_EXHDR(script));
+
+	PG_RETURN_BOOL(matched);
+}
+
 /**
  * pgroonga.match_contain_text(target text, keywords text[]) : bool
  */
@@ -2103,6 +2216,35 @@ PGrnSearchBuildConditionQuery(PGrnScanOpaque so,
 }
 
 static void
+PGrnSearchBuildConditionScript(PGrnScanOpaque so,
+							   PGrnSearchData *data,
+							   grn_obj *targetColumn,
+							   const char *script,
+							   unsigned int scriptSize)
+{
+	grn_rc rc;
+	grn_obj *matchTarget, *matchTargetVariable;
+	grn_expr_flags flags = GRN_EXPR_SYNTAX_SCRIPT;
+
+	GRN_EXPR_CREATE_FOR_QUERY(ctx, so->sourcesTable,
+							  matchTarget, matchTargetVariable);
+	GRN_PTR_PUT(ctx, &(data->matchTargets), matchTarget);
+	grn_expr_append_obj(ctx, matchTarget, targetColumn, GRN_OP_PUSH, 1);
+
+	rc = grn_expr_parse(ctx, data->expression,
+						script, scriptSize,
+						matchTarget, GRN_OP_MATCH, GRN_OP_AND,
+						flags);
+	if (rc != GRN_SUCCESS)
+	{
+		ereport(ERROR,
+				(errcode(PGrnRCToPgErrorCode(rc)),
+				 errmsg("pgroonga: failed to parse expression: %s",
+						ctx->errbuf)));
+	}
+}
+
+static void
 PGrnSearchBuildConditionBinaryOperation(PGrnSearchData *data,
 										grn_obj *targetColumn,
 										grn_obj *value,
@@ -2182,6 +2324,7 @@ PGrnSearchBuildCondition(IndexScanDesc scan,
 		break;
 	case PGrnQueryStrategyNumber:
 	case PGrnQueryStrategyV2Number:
+	case PGrnScriptStrategyV2Number:
 		break;
 	case PGrnRegexpStrategyNumber:
 		operator = GRN_OP_REGEXP;
@@ -2230,6 +2373,13 @@ PGrnSearchBuildCondition(IndexScanDesc scan,
 									  GRN_TEXT_VALUE(&(buffers->general)),
 									  GRN_TEXT_LEN(&(buffers->general)));
 		break;
+	case PGrnScriptStrategyV2Number:
+		PGrnSearchBuildConditionScript(so,
+									   data,
+									   targetColumn,
+									   GRN_TEXT_VALUE(&(buffers->general)),
+									   GRN_TEXT_LEN(&(buffers->general)));
+		break;
 	case PGrnQueryContainStrategyNumber:
 	{
 		grn_obj *queries = &(buffers->general);

  Modified: src/pgroonga.h (+3 -2)
===================================================================
--- src/pgroonga.h    2016-02-18 00:10:37 +0900 (c915668)
+++ src/pgroonga.h    2016-02-22 00:20:59 +0900 (a5d8918)
@@ -26,8 +26,9 @@
 
 #define PGrnMatchStrategyV2Number		12	/* operator &@	(@ in Groonga) */
 #define PGrnQueryStrategyV2Number		13	/* operator &?  (query in Groonga) */
-#define PGrnMatchContainStrategyNumber	14	/* operator &@> (@ in Groonga) */
-#define PGrnQueryContainStrategyNumber	15	/* operator &?> (query in Groonga) */
+#define PGrnScriptStrategyV2Number		14	/* operator &`  (script in Groonga) */
+#define PGrnMatchContainStrategyNumber	15	/* operator &@> (@ in Groonga) */
+#define PGrnQueryContainStrategyNumber	16	/* operator &?> (query in Groonga) */
 
 /* file and table names */
 #define PGrnLogBasename					"pgroonga.log"
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Zurück zum Archiv-Index