[Groonga-commit] pgroonga/pgroonga at e089ebe [master] Support sequential scan against @@

Back to archive index

Kouhei Sutou null+****@clear*****
Wed Oct 28 21:03:37 JST 2015


Kouhei Sutou	2015-10-28 21:03:37 +0900 (Wed, 28 Oct 2015)

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

  Message:
    Support sequential scan against @@

  Added files:
    expected/array/text/single/query/bitmapscan.out
    expected/array/text/single/query/indexscan.out
    expected/array/text/single/query/seqscan.out
    sql/array/text/single/query/bitmapscan.sql
    sql/array/text/single/query/indexscan.sql
    sql/array/text/single/query/seqscan.sql
  Modified files:
    expected/full-text-search/text/single/match/seqscan.out
    pgroonga.c
    pgroonga.h
    pgroonga.sql
    sql/full-text-search/text/single/match/seqscan.sql

  Added: expected/array/text/single/query/bitmapscan.out (+29 -0) 100644
===================================================================
--- /dev/null
+++ expected/array/text/single/query/bitmapscan.out    2015-10-28 21:03:37 +0900 (f7353bf)
@@ -0,0 +1,29 @@
+CREATE TABLE memos (
+  title text,
+  contents text[]
+);
+INSERT INTO memos
+     VALUES ('PostgreSQL',
+             ARRAY['PostgreSQL is an OSS RDBMS',
+                   '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 @@ 'rdbms OR engine';
+   title    |                                         contents                                          
+------------+-------------------------------------------------------------------------------------------
+ PostgreSQL | {"PostgreSQL is an OSS RDBMS","PostgreSQL has partial full-text search support"}
+ Groonga    | {"Groonga is an OSS full-text search engine","Groonga has full full-text search support"}
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/array/text/single/query/indexscan.out (+29 -0) 100644
===================================================================
--- /dev/null
+++ expected/array/text/single/query/indexscan.out    2015-10-28 21:03:37 +0900 (ab54ab7)
@@ -0,0 +1,29 @@
+CREATE TABLE memos (
+  title text,
+  contents text[]
+);
+INSERT INTO memos
+     VALUES ('PostgreSQL',
+             ARRAY['PostgreSQL is an OSS RDBMS',
+                   '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 @@ 'rdbms OR engine';
+   title    |                                         contents                                          
+------------+-------------------------------------------------------------------------------------------
+ PostgreSQL | {"PostgreSQL is an OSS RDBMS","PostgreSQL has partial full-text search support"}
+ Groonga    | {"Groonga is an OSS full-text search engine","Groonga has full full-text search support"}
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/array/text/single/query/seqscan.out (+29 -0) 100644
===================================================================
--- /dev/null
+++ expected/array/text/single/query/seqscan.out    2015-10-28 21:03:37 +0900 (dcab8f5)
@@ -0,0 +1,29 @@
+CREATE TABLE memos (
+  title text,
+  contents text[]
+);
+INSERT INTO memos
+     VALUES ('PostgreSQL',
+             ARRAY['PostgreSQL is an OSS RDBMS',
+                   '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 @@ 'rdbms OR engine';
+   title    |                                         contents                                          
+------------+-------------------------------------------------------------------------------------------
+ PostgreSQL | {"PostgreSQL is an OSS RDBMS","PostgreSQL has partial full-text search support"}
+ Groonga    | {"Groonga is an OSS full-text search engine","Groonga has full full-text search support"}
+(2 rows)
+
+DROP TABLE memos;

  Modified: expected/full-text-search/text/single/match/seqscan.out (+1 -0)
===================================================================
--- expected/full-text-search/text/single/match/seqscan.out    2015-10-25 22:52:27 +0900 (7a10793)
+++ expected/full-text-search/text/single/match/seqscan.out    2015-10-28 21:03:37 +0900 (c8f22b2)
@@ -1,3 +1,4 @@
+SET search_path = "$user",public,pgroonga,pg_catalog;
 CREATE TABLE memos (
   id integer,
   content text

  Modified: pgroonga.c (+168 -10)
===================================================================
--- pgroonga.c    2015-10-25 22:52:27 +0900 (66c39b1)
+++ pgroonga.c    2015-10-28 21:03:37 +0900 (dd3eba0)
@@ -32,6 +32,7 @@
 #include <xxhash.h>
 
 #include <stdlib.h>
+#include <string.h>
 #include <math.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -163,6 +164,13 @@ typedef struct PGrnSearchData
 	bool    isEmptyCondition;
 } PGrnSearchData;
 
+typedef struct PGrnSequentialSearchData
+{
+	grn_obj *table;
+	grn_obj *textColumn;
+	grn_id recordID;
+} PGrnSequentialSearchData;
+
 static slist_head PGrnScanOpaques = SLIST_STATIC_INIT(PGrnScanOpaques);
 
 PG_FUNCTION_INFO_V1(pgroonga_score);
@@ -174,7 +182,9 @@ 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_match_text);
+PG_FUNCTION_INFO_V1(pgroonga_match_text_array);
+PG_FUNCTION_INFO_V1(pgroonga_match_varchar);
 PG_FUNCTION_INFO_V1(pgroonga_match_regexp_text);
 PG_FUNCTION_INFO_V1(pgroonga_match_regexp_varchar);
 
@@ -203,6 +213,7 @@ static grn_obj headBuffer;
 static grn_obj bodyBuffer;
 static grn_obj footBuffer;
 static grn_obj inspectBuffer;
+static PGrnSequentialSearchData sequentialSearchData;
 
 static const char *
 PGrnInspect(grn_obj *object)
@@ -416,12 +427,21 @@ PGrnEnsureDatabase(void)
 }
 
 static void
+PGrnFinalizeSequentialSearchData(void)
+{
+	grn_obj_close(ctx, sequentialSearchData.textColumn);
+	grn_obj_close(ctx, sequentialSearchData.table);
+}
+
+static void
 PGrnOnProcExit(int code, Datum arg)
 {
 	if (ctx)
 	{
 		grn_obj *db;
 
+		PGrnFinalizeSequentialSearchData();
+
 		GRN_OBJ_FIN(ctx, &inspectBuffer);
 		GRN_OBJ_FIN(ctx, &footBuffer);
 		GRN_OBJ_FIN(ctx, &bodyBuffer);
@@ -550,6 +570,28 @@ PGrnInitializeOptions(void)
 						 PGrnOptionValidateNormalizer);
 }
 
+static void
+PGrnInitializeSequentialSearchData(void)
+{
+	sequentialSearchData.table = grn_table_create(ctx,
+												  NULL, 0,
+												  NULL,
+												  GRN_OBJ_TABLE_NO_KEY,
+												  NULL, NULL);
+	sequentialSearchData.textColumn =
+		grn_column_create(ctx,
+						  sequentialSearchData.table,
+						  "text", strlen("text"),
+						  NULL,
+						  GRN_OBJ_COLUMN_SCALAR,
+						  grn_ctx_at(ctx, GRN_DB_TEXT));
+	sequentialSearchData.recordID =
+		grn_table_add(ctx,
+					  sequentialSearchData.table,
+					  NULL, 0,
+					  NULL);
+}
+
 void
 _PG_init(void)
 {
@@ -591,6 +633,8 @@ _PG_init(void)
 	PGrnInitializeGroongaInformation();
 
 	PGrnInitializeOptions();
+
+	PGrnInitializeSequentialSearchData();
 }
 
 static int
@@ -2261,22 +2305,136 @@ pgroonga_contain_varchar_array(PG_FUNCTION_ARGS)
 	PG_RETURN_BOOL(contained);
 }
 
+static grn_bool
+pgroonga_match_text_raw(const char *target, unsigned int targetSize,
+						const char *query, unsigned int querySize)
+{
+	grn_obj *expression;
+	grn_obj *variable;
+	grn_expr_flags flags =
+		GRN_EXPR_SYNTAX_QUERY | GRN_EXPR_ALLOW_LEADING_NOT;
+	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,
+						query, querySize,
+						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, &buffer, GRN_DB_TEXT, 0);
+	GRN_TEXT_SET(ctx, &buffer, target, targetSize);
+	grn_obj_set_value(ctx,
+					  sequentialSearchData.textColumn,
+					  sequentialSearchData.recordID,
+					  &buffer,
+					  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.match(text, query) : bool
+ * pgroonga.match_text(target text, query text) : bool
  */
 Datum
-pgroonga_match(PG_FUNCTION_ARGS)
+pgroonga_match_text(PG_FUNCTION_ARGS)
 {
-#ifdef NOT_USED
-	text *text = PG_GETARG_TEXT_PP(0);
+	text *target = PG_GETARG_TEXT_PP(0);
 	text *query = PG_GETARG_TEXT_PP(1);
-#endif
+	bool matched = false;
 
-	ereport(ERROR,
-			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-			 errmsg("pgroonga: operator @@ is available only in index scans")));
+	matched = pgroonga_match_text_raw(VARDATA_ANY(target),
+									  VARSIZE_ANY_EXHDR(target),
+									  VARDATA_ANY(query),
+									  VARSIZE_ANY_EXHDR(query));
 
-	PG_RETURN_BOOL(false);
+	PG_RETURN_BOOL(matched);
+}
+
+/**
+ * pgroonga.match_text(targets text[], query text) : bool
+ */
+Datum
+pgroonga_match_text_array(PG_FUNCTION_ARGS)
+{
+	ArrayType *targets = PG_GETARG_ARRAYTYPE_P(0);
+	text *query = PG_GETARG_TEXT_PP(1);
+	bool matched = false;
+	int i, n;
+
+	n = ARR_DIMS(targets)[0];
+	for (i = 1; i <= n; i++)
+	{
+		Datum targetDatum;
+		text *target;
+		bool isNULL;
+
+		targetDatum = array_ref(targets, 1, &i, -1, -1, false, 'i', &isNULL);
+		if (isNULL)
+			continue;
+
+		target = DatumGetTextPP(targetDatum);
+		matched = pgroonga_match_text_raw(VARDATA_ANY(target),
+										  VARSIZE_ANY_EXHDR(target),
+										  VARDATA_ANY(query),
+										  VARSIZE_ANY_EXHDR(query));
+		if (matched)
+		{
+			break;
+		}
+	}
+
+	PG_RETURN_BOOL(matched);
+}
+
+/**
+ * pgroonga.match_varchar(target varchar, query varchar) : bool
+ */
+Datum
+pgroonga_match_varchar(PG_FUNCTION_ARGS)
+{
+	VarChar *target = PG_GETARG_VARCHAR_PP(0);
+	VarChar *query = PG_GETARG_VARCHAR_PP(1);
+	bool matched = false;
+
+	matched = pgroonga_match_text_raw(VARDATA_ANY(target),
+									  VARSIZE_ANY_EXHDR(target),
+									  VARDATA_ANY(query),
+									  VARSIZE_ANY_EXHDR(query));
+
+	PG_RETURN_BOOL(matched);
 }
 
 /**

  Modified: pgroonga.h (+3 -1)
===================================================================
--- pgroonga.h    2015-10-25 22:52:27 +0900 (469c2ae)
+++ pgroonga.h    2015-10-28 21:03:37 +0900 (ca694b7)
@@ -52,7 +52,9 @@ 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_match_text(PG_FUNCTION_ARGS);
+extern Datum PGDLLEXPORT pgroonga_match_text_array(PG_FUNCTION_ARGS);
+extern Datum PGDLLEXPORT pgroonga_match_varchar(PG_FUNCTION_ARGS);
 extern Datum PGDLLEXPORT pgroonga_match_jsonb(PG_FUNCTION_ARGS);
 
 extern Datum PGDLLEXPORT pgroonga_insert(PG_FUNCTION_ARGS);

  Modified: pgroonga.sql (+3 -3)
===================================================================
--- pgroonga.sql    2015-10-25 22:52:27 +0900 (f4898c9)
+++ pgroonga.sql    2015-10-28 21:03:37 +0900 (6b47394)
@@ -85,21 +85,21 @@ CREATE OPERATOR %% (
 
 CREATE FUNCTION pgroonga.match(text, text)
 	RETURNS bool
-	AS 'MODULE_PATHNAME', 'pgroonga_match'
+	AS 'MODULE_PATHNAME', 'pgroonga_match_text'
 	LANGUAGE C
 	IMMUTABLE
 	STRICT;
 
 CREATE FUNCTION pgroonga.match(text[], text)
 	RETURNS bool
-	AS 'MODULE_PATHNAME', 'pgroonga_match'
+	AS 'MODULE_PATHNAME', 'pgroonga_match_text_array'
 	LANGUAGE C
 	IMMUTABLE
 	STRICT;
 
 CREATE FUNCTION pgroonga.match(varchar, varchar)
 	RETURNS bool
-	AS 'MODULE_PATHNAME', 'pgroonga_match'
+	AS 'MODULE_PATHNAME', 'pgroonga_match_varchar'
 	LANGUAGE C
 	IMMUTABLE
 	STRICT;

  Added: sql/array/text/single/query/bitmapscan.sql (+28 -0) 100644
===================================================================
--- /dev/null
+++ sql/array/text/single/query/bitmapscan.sql    2015-10-28 21:03:37 +0900 (864d135)
@@ -0,0 +1,28 @@
+CREATE TABLE memos (
+  title text,
+  contents text[]
+);
+
+INSERT INTO memos
+     VALUES ('PostgreSQL',
+             ARRAY['PostgreSQL is an OSS RDBMS',
+                   '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 @@ 'rdbms OR engine';
+
+DROP TABLE memos;

  Added: sql/array/text/single/query/indexscan.sql (+28 -0) 100644
===================================================================
--- /dev/null
+++ sql/array/text/single/query/indexscan.sql    2015-10-28 21:03:37 +0900 (2fcbd11)
@@ -0,0 +1,28 @@
+CREATE TABLE memos (
+  title text,
+  contents text[]
+);
+
+INSERT INTO memos
+     VALUES ('PostgreSQL',
+             ARRAY['PostgreSQL is an OSS RDBMS',
+                   '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 @@ 'rdbms OR engine';
+
+DROP TABLE memos;

  Added: sql/array/text/single/query/seqscan.sql (+28 -0) 100644
===================================================================
--- /dev/null
+++ sql/array/text/single/query/seqscan.sql    2015-10-28 21:03:37 +0900 (bbc0ab6)
@@ -0,0 +1,28 @@
+CREATE TABLE memos (
+  title text,
+  contents text[]
+);
+
+INSERT INTO memos
+     VALUES ('PostgreSQL',
+             ARRAY['PostgreSQL is an OSS RDBMS',
+                   '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 @@ 'rdbms OR engine';
+
+DROP TABLE memos;

  Modified: sql/full-text-search/text/single/match/seqscan.sql (+2 -0)
===================================================================
--- sql/full-text-search/text/single/match/seqscan.sql    2015-10-25 22:52:27 +0900 (222f87a)
+++ sql/full-text-search/text/single/match/seqscan.sql    2015-10-28 21:03:37 +0900 (3346413)
@@ -1,3 +1,5 @@
+SET search_path = "$user",public,pgroonga,pg_catalog;
+
 CREATE TABLE memos (
   id integer,
   content text
-------------- next part --------------
HTML����������������������������...
Download 



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