[Groonga-commit] pgroonga/pgroonga at 745c02e [master] Add pgroonga.text_array_full_text_search_ops_v2

アーカイブの一覧に戻る

Kouhei Sutou null+****@clear*****
Tue May 2 10:19:35 JST 2017


Kouhei Sutou	2017-05-02 10:19:35 +0900 (Tue, 02 May 2017)

  New Revision: 745c02e1fb9732c94a0500a157ebff9769f1cbde
  https://github.com/pgroonga/pgroonga/commit/745c02e1fb9732c94a0500a157ebff9769f1cbde

  Message:
    Add pgroonga.text_array_full_text_search_ops_v2

  Added files:
    expected/full-text-search/text-array/single/match-contain-v2/bitmapscan.out
    expected/full-text-search/text-array/single/match-contain-v2/indexscan.out
    expected/full-text-search/text-array/single/match-contain-v2/seqscan.out
    expected/full-text-search/text-array/single/match-v2/bitmapscan.out
    expected/full-text-search/text-array/single/match-v2/indexscan.out
    expected/full-text-search/text-array/single/match-v2/seqscan.out
    expected/full-text-search/text-array/single/query-contain-v2/bitmapscan.out
    expected/full-text-search/text-array/single/query-contain-v2/indexscan.out
    expected/full-text-search/text-array/single/query-contain-v2/seqscan.out
    expected/full-text-search/text-array/single/query-v2/bitmapscan.out
    expected/full-text-search/text-array/single/query-v2/indexscan.out
    expected/full-text-search/text-array/single/query-v2/seqscan.out
    expected/full-text-search/text-array/single/script-v2/bitmapscan.out
    expected/full-text-search/text-array/single/script-v2/indexscan.out
    expected/full-text-search/text-array/single/script-v2/seqscan.out
    expected/full-text-search/text-array/single/similar-v2/bitmapscan.out
    expected/full-text-search/text-array/single/similar-v2/indexscan.out
    expected/full-text-search/text-array/single/similar-v2/seqscan.out
    sql/full-text-search/text-array/single/match-contain-v2/bitmapscan.sql
    sql/full-text-search/text-array/single/match-contain-v2/indexscan.sql
    sql/full-text-search/text-array/single/match-contain-v2/seqscan.sql
    sql/full-text-search/text-array/single/match-v2/bitmapscan.sql
    sql/full-text-search/text-array/single/match-v2/indexscan.sql
    sql/full-text-search/text-array/single/match-v2/seqscan.sql
    sql/full-text-search/text-array/single/query-contain-v2/bitmapscan.sql
    sql/full-text-search/text-array/single/query-contain-v2/indexscan.sql
    sql/full-text-search/text-array/single/query-contain-v2/seqscan.sql
    sql/full-text-search/text-array/single/query-v2/bitmapscan.sql
    sql/full-text-search/text-array/single/query-v2/indexscan.sql
    sql/full-text-search/text-array/single/query-v2/seqscan.sql
    sql/full-text-search/text-array/single/script-v2/bitmapscan.sql
    sql/full-text-search/text-array/single/script-v2/indexscan.sql
    sql/full-text-search/text-array/single/script-v2/seqscan.sql
    sql/full-text-search/text-array/single/similar-v2/bitmapscan.sql
    sql/full-text-search/text-array/single/similar-v2/indexscan.sql
    sql/full-text-search/text-array/single/similar-v2/seqscan.sql
  Modified files:
    data/pgroonga--1.2.0--1.2.1.sql
    data/pgroonga.sql
    src/pgroonga.c

  Modified: data/pgroonga--1.2.0--1.2.1.sql (+90 -0)
===================================================================
--- data/pgroonga--1.2.0--1.2.1.sql    2017-05-02 09:21:39 +0900 (44f0cd4)
+++ data/pgroonga--1.2.0--1.2.1.sql    2017-05-02 10:19:35 +0900 (3444843)
@@ -45,3 +45,93 @@ CREATE OPERATOR CLASS pgroonga.text_array_term_search_ops_v2 FOR TYPE text[]
 	USING pgroonga AS
 		OPERATOR 20 &^> (text[], text),
 		OPERATOR 21 &^~> (text[], text);
+
+-- Add pgroonga.text_array_full_text_search_ops_v2
+CREATE FUNCTION pgroonga.match_text_array(text[], text)
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_match_text_array'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &@ (
+	PROCEDURE = pgroonga.match_text_array,
+	LEFTARG = text[],
+	RIGHTARG = text
+);
+
+CREATE FUNCTION pgroonga.query_text_array(text[], text)
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_query_text_array'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &? (
+	PROCEDURE = pgroonga.query_text_array,
+	LEFTARG = text[],
+	RIGHTARG = text
+);
+
+CREATE FUNCTION pgroonga.similar_text_array(text[], text)
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_similar_text_array'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &~? (
+	PROCEDURE = pgroonga.similar_text_array,
+	LEFTARG = text[],
+	RIGHTARG = text
+);
+
+CREATE FUNCTION pgroonga.script_text_array(text[], text)
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_script_text_array'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &` (
+	PROCEDURE = pgroonga.script_text_array,
+	LEFTARG = text[],
+	RIGHTARG = text
+);
+
+CREATE FUNCTION pgroonga.match_contain_text_array(text[], text[])
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_match_contain_text_array'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &@> (
+	PROCEDURE = pgroonga.match_contain_text_array,
+	LEFTARG = text[],
+	RIGHTARG = text[]
+);
+
+CREATE FUNCTION pgroonga.query_contain_text_array(text[], text[])
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_query_contain_text_array'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &?> (
+	PROCEDURE = pgroonga.query_contain_text_array,
+	LEFTARG = text[],
+	RIGHTARG = text[]
+);
+
+CREATE OPERATOR CLASS pgroonga.text_array_full_text_search_ops_v2
+	FOR TYPE text[]
+	USING pgroonga AS
+		OPERATOR 12 &@ (text[], text),
+		OPERATOR 13 &? (text[], text),
+		OPERATOR 14 &~? (text[], text),
+		OPERATOR 15 &` (text[], text),
+		OPERATOR 18 &@> (text[], text[]),
+		OPERATOR 19 &?> (text[], text[]);
+

  Modified: data/pgroonga.sql (+88 -0)
===================================================================
--- data/pgroonga.sql    2017-05-02 09:21:39 +0900 (94997f3)
+++ data/pgroonga.sql    2017-05-02 10:19:35 +0900 (f5c2dfc)
@@ -292,6 +292,19 @@ CREATE OPERATOR &@ (
 	RIGHTARG = text
 );
 
+CREATE FUNCTION pgroonga.match_text_array(text[], text)
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_match_text_array'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &@ (
+	PROCEDURE = pgroonga.match_text_array,
+	LEFTARG = text[],
+	RIGHTARG = text
+);
+
 CREATE FUNCTION pgroonga.query_text(text, text)
 	RETURNS bool
 	AS 'MODULE_PATHNAME', 'pgroonga_query_text'
@@ -305,6 +318,19 @@ CREATE OPERATOR &? (
 	RIGHTARG = text
 );
 
+CREATE FUNCTION pgroonga.query_text_array(text[], text)
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_query_text_array'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &? (
+	PROCEDURE = pgroonga.query_text_array,
+	LEFTARG = text[],
+	RIGHTARG = text
+);
+
 CREATE FUNCTION pgroonga.similar_text(text, text)
 	RETURNS bool
 	AS 'MODULE_PATHNAME', 'pgroonga_similar_text'
@@ -318,6 +344,19 @@ CREATE OPERATOR &~? (
 	RIGHTARG = text
 );
 
+CREATE FUNCTION pgroonga.similar_text_array(text[], text)
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_similar_text_array'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &~? (
+	PROCEDURE = pgroonga.similar_text_array,
+	LEFTARG = text[],
+	RIGHTARG = text
+);
+
 CREATE FUNCTION pgroonga.prefix_text(text, text)
 	RETURNS bool
 	AS 'MODULE_PATHNAME', 'pgroonga_prefix_text'
@@ -357,6 +396,19 @@ CREATE OPERATOR &` (
 	RIGHTARG = text
 );
 
+CREATE FUNCTION pgroonga.script_text_array(text[], text)
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_script_text_array'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &` (
+	PROCEDURE = pgroonga.script_text_array,
+	LEFTARG = text[],
+	RIGHTARG = text
+);
+
 CREATE FUNCTION pgroonga.match_contain_text(text, text[])
 	RETURNS bool
 	AS 'MODULE_PATHNAME', 'pgroonga_match_contain_text'
@@ -370,6 +422,19 @@ CREATE OPERATOR &@> (
 	RIGHTARG = text[]
 );
 
+CREATE FUNCTION pgroonga.match_contain_text_array(text[], text[])
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_match_contain_text_array'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &@> (
+	PROCEDURE = pgroonga.match_contain_text_array,
+	LEFTARG = text[],
+	RIGHTARG = text[]
+);
+
 CREATE FUNCTION pgroonga.query_contain_text(text, text[])
 	RETURNS bool
 	AS 'MODULE_PATHNAME', 'pgroonga_query_contain_text'
@@ -383,6 +448,19 @@ CREATE OPERATOR &?> (
 	RIGHTARG = text[]
 );
 
+CREATE FUNCTION pgroonga.query_contain_text_array(text[], text[])
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_query_contain_text_array'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &?> (
+	PROCEDURE = pgroonga.query_contain_text_array,
+	LEFTARG = text[],
+	RIGHTARG = text[]
+);
+
 CREATE FUNCTION pgroonga.prefix_text_array(text[], text)
 	RETURNS bool
 	AS 'MODULE_PATHNAME', 'pgroonga_prefix_text_array'
@@ -665,6 +743,16 @@ CREATE OPERATOR CLASS pgroonga.text_full_text_search_ops_v2 FOR TYPE text
 		OPERATOR 18 &@> (text, text[]),
 		OPERATOR 19 &?> (text, text[]);
 
+CREATE OPERATOR CLASS pgroonga.text_array_full_text_search_ops_v2
+	FOR TYPE text[]
+	USING pgroonga AS
+		OPERATOR 12 &@ (text[], text),
+		OPERATOR 13 &? (text[], text),
+		OPERATOR 14 &~? (text[], text),
+		OPERATOR 15 &` (text[], text),
+		OPERATOR 18 &@> (text[], text[]),
+		OPERATOR 19 &?> (text[], text[]);
+
 CREATE OPERATOR CLASS pgroonga.text_term_search_ops_v2 FOR TYPE text
 	USING pgroonga AS
 		OPERATOR 16 &^,

  Added: expected/full-text-search/text-array/single/match-contain-v2/bitmapscan.out (+42 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/text-array/single/match-contain-v2/bitmapscan.out    2017-05-02 10:19:35 +0900 (3d5fe2f)
@@ -0,0 +1,42 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &@> Array['rdbms', 'engine'];
+                                    QUERY PLAN                                     
+-----------------------------------------------------------------------------------
+ Bitmap Heap Scan on memos  (cost=0.00..4.01 rows=2 width=64)
+   Recheck Cond: (contents &@> '{rdbms,engine}'::text[])
+   ->  Bitmap Index Scan on pgroonga_memos_index  (cost=0.00..0.00 rows=1 width=0)
+         Index Cond: (contents &@> '{rdbms,engine}'::text[])
+(4 rows)
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &@> Array['rdbms', '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/full-text-search/text-array/single/match-contain-v2/indexscan.out (+40 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/text-array/single/match-contain-v2/indexscan.out    2017-05-02 10:19:35 +0900 (59dcefa)
@@ -0,0 +1,40 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &@> Array['rdbms', 'engine'];
+                                    QUERY PLAN                                     
+-----------------------------------------------------------------------------------
+ Index Scan using pgroonga_memos_index on memos  (cost=0.00..4.01 rows=2 width=64)
+   Index Cond: (contents &@> '{rdbms,engine}'::text[])
+(2 rows)
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &@> Array['rdbms', '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/full-text-search/text-array/single/match-contain-v2/seqscan.out (+30 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/text-array/single/match-contain-v2/seqscan.out    2017-05-02 10:19:35 +0900 (6e6336e)
@@ -0,0 +1,30 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+SELECT title, contents
+  FROM memos
+ WHERE contents &@> Array['rdbms', '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/full-text-search/text-array/single/match-v2/bitmapscan.out (+42 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/text-array/single/match-v2/bitmapscan.out    2017-05-02 10:19:35 +0900 (23b0bd7)
@@ -0,0 +1,42 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &@ 'Groonga';
+                                    QUERY PLAN                                     
+-----------------------------------------------------------------------------------
+ Bitmap Heap Scan on memos  (cost=0.00..4.01 rows=2 width=64)
+   Recheck Cond: (contents &@ 'Groonga'::text)
+   ->  Bitmap Index Scan on pgroonga_memos_index  (cost=0.00..0.00 rows=1 width=0)
+         Index Cond: (contents &@ 'Groonga'::text)
+(4 rows)
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &@ 'Groonga';
+  title   |                                                         contents                                                         
+----------+--------------------------------------------------------------------------------------------------------------------------
+ Groonga  | {"Groonga is an OSS full-text search engine","Groonga has full full-text search support"}
+ PGroonga | {"PGroonga is an OSS PostgreSQL extension","PGroonga adds full full-text search support based on Groonga to PostgreSQL"}
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/text-array/single/match-v2/indexscan.out (+40 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/text-array/single/match-v2/indexscan.out    2017-05-02 10:19:35 +0900 (564e2b8)
@@ -0,0 +1,40 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &@ 'Groonga';
+                                    QUERY PLAN                                     
+-----------------------------------------------------------------------------------
+ Index Scan using pgroonga_memos_index on memos  (cost=0.00..4.01 rows=2 width=64)
+   Index Cond: (contents &@ 'Groonga'::text)
+(2 rows)
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &@ 'Groonga';
+  title   |                                                         contents                                                         
+----------+--------------------------------------------------------------------------------------------------------------------------
+ Groonga  | {"Groonga is an OSS full-text search engine","Groonga has full full-text search support"}
+ PGroonga | {"PGroonga is an OSS PostgreSQL extension","PGroonga adds full full-text search support based on Groonga to PostgreSQL"}
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/text-array/single/match-v2/seqscan.out (+30 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/text-array/single/match-v2/seqscan.out    2017-05-02 10:19:35 +0900 (646f718)
@@ -0,0 +1,30 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+SELECT title, contents
+  FROM memos
+ WHERE contents &@ 'Groonga';
+  title   |                                                         contents                                                         
+----------+--------------------------------------------------------------------------------------------------------------------------
+ Groonga  | {"Groonga is an OSS full-text search engine","Groonga has full full-text search support"}
+ PGroonga | {"PGroonga is an OSS PostgreSQL extension","PGroonga adds full full-text search support based on Groonga to PostgreSQL"}
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/text-array/single/query-contain-v2/bitmapscan.out (+42 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/text-array/single/query-contain-v2/bitmapscan.out    2017-05-02 10:19:35 +0900 (f138e33)
@@ -0,0 +1,42 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &?> Array['rdbms', 'groonga engine'];
+                                    QUERY PLAN                                     
+-----------------------------------------------------------------------------------
+ Bitmap Heap Scan on memos  (cost=0.00..4.01 rows=2 width=64)
+   Recheck Cond: (contents &?> '{rdbms,"groonga engine"}'::text[])
+   ->  Bitmap Index Scan on pgroonga_memos_index  (cost=0.00..0.00 rows=1 width=0)
+         Index Cond: (contents &?> '{rdbms,"groonga engine"}'::text[])
+(4 rows)
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &?> Array['rdbms', 'groonga 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/full-text-search/text-array/single/query-contain-v2/indexscan.out (+40 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/text-array/single/query-contain-v2/indexscan.out    2017-05-02 10:19:35 +0900 (bcd63fb)
@@ -0,0 +1,40 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &?> Array['rdbms', 'groonga engine'];
+                                    QUERY PLAN                                     
+-----------------------------------------------------------------------------------
+ Index Scan using pgroonga_memos_index on memos  (cost=0.00..4.01 rows=2 width=64)
+   Index Cond: (contents &?> '{rdbms,"groonga engine"}'::text[])
+(2 rows)
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &?> Array['rdbms', 'groonga engine'];
+   title    |                                         contents                                          
+------------+-------------------------------------------------------------------------------------------
+ Groonga    | {"Groonga is an OSS full-text search engine","Groonga has full full-text search support"}
+ PostgreSQL | {"PostgreSQL is an OSS RDBMS","PostgreSQL has partial full-text search support"}
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/text-array/single/query-contain-v2/seqscan.out (+30 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/text-array/single/query-contain-v2/seqscan.out    2017-05-02 10:19:35 +0900 (454cb2f)
@@ -0,0 +1,30 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+SELECT title, contents
+  FROM memos
+ WHERE contents &?> Array['rdbms', 'groonga 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/full-text-search/text-array/single/query-v2/bitmapscan.out (+42 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/text-array/single/query-v2/bitmapscan.out    2017-05-02 10:19:35 +0900 (6b290cc)
@@ -0,0 +1,42 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &? 'rdbms OR engine';
+                                    QUERY PLAN                                     
+-----------------------------------------------------------------------------------
+ Bitmap Heap Scan on memos  (cost=0.00..4.01 rows=2 width=64)
+   Recheck Cond: (contents &? 'rdbms OR engine'::text)
+   ->  Bitmap Index Scan on pgroonga_memos_index  (cost=0.00..0.00 rows=1 width=0)
+         Index Cond: (contents &? 'rdbms OR engine'::text)
+(4 rows)
+
+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/full-text-search/text-array/single/query-v2/indexscan.out (+40 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/text-array/single/query-v2/indexscan.out    2017-05-02 10:19:35 +0900 (fdadccf)
@@ -0,0 +1,40 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &? 'rdbms OR engine';
+                                    QUERY PLAN                                     
+-----------------------------------------------------------------------------------
+ Index Scan using pgroonga_memos_index on memos  (cost=0.00..4.01 rows=2 width=64)
+   Index Cond: (contents &? 'rdbms OR engine'::text)
+(2 rows)
+
+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/full-text-search/text-array/single/query-v2/seqscan.out (+30 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/text-array/single/query-v2/seqscan.out    2017-05-02 10:19:35 +0900 (b5881a8)
@@ -0,0 +1,30 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+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;

  Added: expected/full-text-search/text-array/single/script-v2/bitmapscan.out (+42 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/text-array/single/script-v2/bitmapscan.out    2017-05-02 10:19:35 +0900 (38eb7d3)
@@ -0,0 +1,42 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &` 'contents @ "rdbms" || contents @ "engine"';
+                                     QUERY PLAN                                      
+-------------------------------------------------------------------------------------
+ Bitmap Heap Scan on memos  (cost=0.00..4.01 rows=2 width=64)
+   Recheck Cond: (contents &` 'contents @ "rdbms" || contents @ "engine"'::text)
+   ->  Bitmap Index Scan on pgroonga_memos_index  (cost=0.00..0.00 rows=1 width=0)
+         Index Cond: (contents &` 'contents @ "rdbms" || contents @ "engine"'::text)
+(4 rows)
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &` 'contents @ "rdbms" || contents @ "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/full-text-search/text-array/single/script-v2/indexscan.out (+40 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/text-array/single/script-v2/indexscan.out    2017-05-02 10:19:35 +0900 (7eff521)
@@ -0,0 +1,40 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &` 'contents @ "rdbms" || contents @ "engine"';
+                                    QUERY PLAN                                     
+-----------------------------------------------------------------------------------
+ Index Scan using pgroonga_memos_index on memos  (cost=0.00..4.01 rows=2 width=64)
+   Index Cond: (contents &` 'contents @ "rdbms" || contents @ "engine"'::text)
+(2 rows)
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &` 'contents @ "rdbms" || contents @ "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/full-text-search/text-array/single/script-v2/seqscan.out (+30 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/text-array/single/script-v2/seqscan.out    2017-05-02 10:19:35 +0900 (68d89c9)
@@ -0,0 +1,30 @@
+CREATE TABLE memos (
+  title text,
+  text 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 (text pgroonga.text_array_full_text_search_ops_v2);
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+SELECT title, text
+  FROM memos
+ WHERE text &` 'text @ "rdbms" || text @ "engine"';
+   title    |                                           text                                            
+------------+-------------------------------------------------------------------------------------------
+ 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/full-text-search/text-array/single/similar-v2/bitmapscan.out (+42 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/text-array/single/similar-v2/bitmapscan.out    2017-05-02 10:19:35 +0900 (738379d)
@@ -0,0 +1,42 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &~? 'Mroonga is a MySQL plugin that uses Groonga.';
+                                       QUERY PLAN                                        
+-----------------------------------------------------------------------------------------
+ Bitmap Heap Scan on memos  (cost=0.00..4.01 rows=2 width=64)
+   Recheck Cond: (contents &~? 'Mroonga is a MySQL plugin that uses Groonga.'::text)
+   ->  Bitmap Index Scan on pgroonga_memos_index  (cost=0.00..0.00 rows=1 width=0)
+         Index Cond: (contents &~? 'Mroonga is a MySQL plugin that uses Groonga.'::text)
+(4 rows)
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &~? 'Mroonga is a MySQL plugin that uses Groonga.';
+  title   |                                                         contents                                                         
+----------+--------------------------------------------------------------------------------------------------------------------------
+ Groonga  | {"Groonga is an OSS full-text search engine","Groonga has full full-text search support"}
+ PGroonga | {"PGroonga is an OSS PostgreSQL extension","PGroonga adds full full-text search support based on Groonga to PostgreSQL"}
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/text-array/single/similar-v2/indexscan.out (+40 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/text-array/single/similar-v2/indexscan.out    2017-05-02 10:19:35 +0900 (1b67197)
@@ -0,0 +1,40 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &~? 'Mroonga is a MySQL plugin that uses Groonga.';
+                                    QUERY PLAN                                     
+-----------------------------------------------------------------------------------
+ Index Scan using pgroonga_memos_index on memos  (cost=0.00..4.01 rows=2 width=64)
+   Index Cond: (contents &~? 'Mroonga is a MySQL plugin that uses Groonga.'::text)
+(2 rows)
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &~? 'Mroonga is a MySQL plugin that uses Groonga.';
+  title   |                                                         contents                                                         
+----------+--------------------------------------------------------------------------------------------------------------------------
+ Groonga  | {"Groonga is an OSS full-text search engine","Groonga has full full-text search support"}
+ PGroonga | {"PGroonga is an OSS PostgreSQL extension","PGroonga adds full full-text search support based on Groonga to PostgreSQL"}
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/text-array/single/similar-v2/seqscan.out (+25 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/text-array/single/similar-v2/seqscan.out    2017-05-02 10:19:35 +0900 (6741d5c)
@@ -0,0 +1,25 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+SELECT title, contents
+  FROM memos
+ WHERE contents &~? 'Mroonga is a MySQL plugin that uses Groonga.';
+ERROR:  pgroonga: operator &~? is available only in index scan
+DROP TABLE memos;

  Added: sql/full-text-search/text-array/single/match-contain-v2/bitmapscan.sql (+34 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/text-array/single/match-contain-v2/bitmapscan.sql    2017-05-02 10:19:35 +0900 (c391008)
@@ -0,0 +1,34 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &@> Array['rdbms', 'engine'];
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &@> Array['rdbms', 'engine'];
+
+DROP TABLE memos;

  Added: sql/full-text-search/text-array/single/match-contain-v2/indexscan.sql (+34 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/text-array/single/match-contain-v2/indexscan.sql    2017-05-02 10:19:35 +0900 (73fa764)
@@ -0,0 +1,34 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &@> Array['rdbms', 'engine'];
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &@> Array['rdbms', 'engine'];
+
+DROP TABLE memos;

  Added: sql/full-text-search/text-array/single/match-contain-v2/seqscan.sql (+29 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/text-array/single/match-contain-v2/seqscan.sql    2017-05-02 10:19:35 +0900 (a259812)
@@ -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 pgroonga.text_array_full_text_search_ops_v2);
+
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &@> Array['rdbms', 'engine'];
+
+DROP TABLE memos;

  Added: sql/full-text-search/text-array/single/match-v2/bitmapscan.sql (+34 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/text-array/single/match-v2/bitmapscan.sql    2017-05-02 10:19:35 +0900 (d3d2203)
@@ -0,0 +1,34 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &@ 'Groonga';
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &@ 'Groonga';
+
+DROP TABLE memos;

  Added: sql/full-text-search/text-array/single/match-v2/indexscan.sql (+34 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/text-array/single/match-v2/indexscan.sql    2017-05-02 10:19:35 +0900 (e93e31c)
@@ -0,0 +1,34 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &@ 'Groonga';
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &@ 'Groonga';
+
+DROP TABLE memos;

  Added: sql/full-text-search/text-array/single/match-v2/seqscan.sql (+29 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/text-array/single/match-v2/seqscan.sql    2017-05-02 10:19:35 +0900 (64dddb5)
@@ -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 pgroonga.text_array_full_text_search_ops_v2);
+
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &@ 'Groonga';
+
+DROP TABLE memos;

  Added: sql/full-text-search/text-array/single/query-contain-v2/bitmapscan.sql (+34 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/text-array/single/query-contain-v2/bitmapscan.sql    2017-05-02 10:19:35 +0900 (953a1d0)
@@ -0,0 +1,34 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &?> Array['rdbms', 'groonga engine'];
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &?> Array['rdbms', 'groonga engine'];
+
+DROP TABLE memos;

  Added: sql/full-text-search/text-array/single/query-contain-v2/indexscan.sql (+34 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/text-array/single/query-contain-v2/indexscan.sql    2017-05-02 10:19:35 +0900 (43d0f99)
@@ -0,0 +1,34 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &?> Array['rdbms', 'groonga engine'];
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &?> Array['rdbms', 'groonga engine'];
+
+DROP TABLE memos;

  Added: sql/full-text-search/text-array/single/query-contain-v2/seqscan.sql (+29 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/text-array/single/query-contain-v2/seqscan.sql    2017-05-02 10:19:35 +0900 (13956a2)
@@ -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 pgroonga.text_array_full_text_search_ops_v2);
+
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &?> Array['rdbms', 'groonga engine'];
+
+DROP TABLE memos;

  Added: sql/full-text-search/text-array/single/query-v2/bitmapscan.sql (+34 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/text-array/single/query-v2/bitmapscan.sql    2017-05-02 10:19:35 +0900 (70c6ec9)
@@ -0,0 +1,34 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &? 'rdbms OR engine';
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &? 'rdbms OR engine';
+
+DROP TABLE memos;

  Added: sql/full-text-search/text-array/single/query-v2/indexscan.sql (+34 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/text-array/single/query-v2/indexscan.sql    2017-05-02 10:19:35 +0900 (606f87f)
@@ -0,0 +1,34 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &? 'rdbms OR engine';
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &? 'rdbms OR engine';
+
+DROP TABLE memos;

  Added: sql/full-text-search/text-array/single/query-v2/seqscan.sql (+29 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/text-array/single/query-v2/seqscan.sql    2017-05-02 10:19:35 +0900 (57c1d08)
@@ -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 pgroonga.text_array_full_text_search_ops_v2);
+
+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;

  Added: sql/full-text-search/text-array/single/script-v2/bitmapscan.sql (+34 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/text-array/single/script-v2/bitmapscan.sql    2017-05-02 10:19:35 +0900 (277e499)
@@ -0,0 +1,34 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &` 'contents @ "rdbms" || contents @ "engine"';
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &` 'contents @ "rdbms" || contents @ "engine"';
+
+DROP TABLE memos;

  Added: sql/full-text-search/text-array/single/script-v2/indexscan.sql (+34 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/text-array/single/script-v2/indexscan.sql    2017-05-02 10:19:35 +0900 (9b14e25)
@@ -0,0 +1,34 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &` 'contents @ "rdbms" || contents @ "engine"';
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &` 'contents @ "rdbms" || contents @ "engine"';
+
+DROP TABLE memos;

  Added: sql/full-text-search/text-array/single/script-v2/seqscan.sql (+29 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/text-array/single/script-v2/seqscan.sql    2017-05-02 10:19:35 +0900 (340fa12)
@@ -0,0 +1,29 @@
+CREATE TABLE memos (
+  title text,
+  text 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 (text pgroonga.text_array_full_text_search_ops_v2);
+
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+
+SELECT title, text
+  FROM memos
+ WHERE text &` 'text @ "rdbms" || text @ "engine"';
+
+DROP TABLE memos;

  Added: sql/full-text-search/text-array/single/similar-v2/bitmapscan.sql (+34 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/text-array/single/similar-v2/bitmapscan.sql    2017-05-02 10:19:35 +0900 (f2ffef0)
@@ -0,0 +1,34 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &~? 'Mroonga is a MySQL plugin that uses Groonga.';
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &~? 'Mroonga is a MySQL plugin that uses Groonga.';
+
+DROP TABLE memos;

  Added: sql/full-text-search/text-array/single/similar-v2/indexscan.sql (+34 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/text-array/single/similar-v2/indexscan.sql    2017-05-02 10:19:35 +0900 (8eab213)
@@ -0,0 +1,34 @@
+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 pgroonga.text_array_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+
+EXPLAIN
+SELECT title, contents
+  FROM memos
+ WHERE contents &~? 'Mroonga is a MySQL plugin that uses Groonga.';
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &~? 'Mroonga is a MySQL plugin that uses Groonga.';
+
+DROP TABLE memos;

  Added: sql/full-text-search/text-array/single/similar-v2/seqscan.sql (+29 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/text-array/single/similar-v2/seqscan.sql    2017-05-02 10:19:35 +0900 (be79ea4)
@@ -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 pgroonga.text_array_full_text_search_ops_v2);
+
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+
+SELECT title, contents
+  FROM memos
+ WHERE contents &~? 'Mroonga is a MySQL plugin that uses Groonga.';
+
+DROP TABLE memos;

  Modified: src/pgroonga.c (+264 -157)
===================================================================
--- src/pgroonga.c    2017-05-02 09:21:39 +0900 (2e5c6ab)
+++ src/pgroonga.c    2017-05-02 10:19:35 +0900 (402726b)
@@ -141,6 +141,39 @@ PGRN_FUNCTION_INFO_V1(pgroonga_score);
 PGRN_FUNCTION_INFO_V1(pgroonga_table_name);
 PGRN_FUNCTION_INFO_V1(pgroonga_command);
 
+/*
+ * Naming conversions:
+ *
+ *   * pgroonga_#{operation}_#{type}(operand1 #{type}, operand2 #{type})
+ *     * e.g.: pgroonga_match_text(target text, term text)
+ *     * true when #{operand1} #{operation} #{operand2} is true,
+ *       false otherwise.
+ *     * e.g.: "PGroonga is great" match "great" -> true
+ *
+ *   * pgroonga_#{operation}_#{type}_array(operands1 #{type}[],
+ *                                         operand2 #{type})
+ *     * e.g.: pgroonga_match_text_array(targets text[], term text)
+ *     * true when #{one of operands1} #{operation} #{operand2} is true,
+ *       false otherwise.
+ *     * e.g.: ["PGroonga is great", "PostgreSQL is great"] match "PGroonga"
+ *       -> true
+ *
+ *   * pgroonga_#{operation}_in_#{type}(operand1 #{type}, operands2 #{type}[])
+ *     * e.g.: pgroonga_match_in_text(target text, terms text[])
+ *     * true when #{operand1} #{operation} #{one of operands2} is true,
+ *       false otherwise.
+ *     * e.g.: "PGroonga is great" match ["PGroonga", "PostgreSQL"]
+ *       -> true
+ *
+ *   * pgroonga_#{operation}_in_#{type}_array(operands1 #{type}[],
+ *                                            operands2 #{type}[])
+ *     * e.g.: pgroonga_match_in_text_array(targets1 text[], terms2 text[])
+ *     * true when #{one of operands1} #{operation} #{one of operands2} is true,
+ *       false otherwise.
+ *     * e.g.: ["PGroonga is great", "PostgreSQL is great"] match
+ *       ["Groonga", "PostgreSQL"] -> true
+ */
+
 PGRN_FUNCTION_INFO_V1(pgroonga_match_term_text);
 PGRN_FUNCTION_INFO_V1(pgroonga_match_term_text_array);
 PGRN_FUNCTION_INFO_V1(pgroonga_match_term_varchar);
@@ -153,13 +186,19 @@ PGRN_FUNCTION_INFO_V1(pgroonga_match_regexp_varchar);
 
 /* v2 */
 PGRN_FUNCTION_INFO_V1(pgroonga_match_text);
+PGRN_FUNCTION_INFO_V1(pgroonga_match_text_array);
 PGRN_FUNCTION_INFO_V1(pgroonga_query_text);
+PGRN_FUNCTION_INFO_V1(pgroonga_query_text_array);
 PGRN_FUNCTION_INFO_V1(pgroonga_similar_text);
+PGRN_FUNCTION_INFO_V1(pgroonga_similar_text_array);
 PGRN_FUNCTION_INFO_V1(pgroonga_script_text);
+PGRN_FUNCTION_INFO_V1(pgroonga_script_text_array);
 PGRN_FUNCTION_INFO_V1(pgroonga_prefix_text);
 PGRN_FUNCTION_INFO_V1(pgroonga_prefix_rk_text);
 PGRN_FUNCTION_INFO_V1(pgroonga_match_contain_text);
+PGRN_FUNCTION_INFO_V1(pgroonga_match_contain_text_array);
 PGRN_FUNCTION_INFO_V1(pgroonga_query_contain_text);
+PGRN_FUNCTION_INFO_V1(pgroonga_query_contain_text_array);
 PGRN_FUNCTION_INFO_V1(pgroonga_prefix_text_array);
 PGRN_FUNCTION_INFO_V1(pgroonga_prefix_contain_text_array);
 PGRN_FUNCTION_INFO_V1(pgroonga_prefix_rk_text_array);
@@ -1346,7 +1385,100 @@ pgroonga_command(PG_FUNCTION_ARGS)
 	PG_RETURN_TEXT_P(result);
 }
 
-static grn_bool
+typedef bool (*PGrnBinaryOperatorTextFunction)(const char *operand1,
+											   unsigned int operandSize1,
+											   const char *operand2,
+											   unsigned int operandSize2);
+
+static bool
+pgroonga_execute_binary_operator_text_array(ArrayType *operands1,
+											text *operand2,
+											PGrnBinaryOperatorTextFunction operator)
+{
+	int i, n;
+
+	n = ARR_DIMS(operands1)[0];
+	for (i = 1; i <= n; i++)
+	{
+		Datum operandDatum1;
+		text *operand1;
+		bool isNULL;
+
+		operandDatum1 = array_ref(operands1, 1, &i, -1, -1, false, 'i', &isNULL);
+		if (isNULL)
+			continue;
+
+		operand1 = DatumGetTextPP(operandDatum1);
+		if (operator(VARDATA_ANY(operand1),
+					 VARSIZE_ANY_EXHDR(operand1),
+					 VARDATA_ANY(operand2),
+					 VARSIZE_ANY_EXHDR(operand2)))
+			return true;
+	}
+
+	return false;
+}
+
+/* TODO: "in" will be better than "contain". */
+static bool
+pgroonga_execute_binary_operator_contain_text(text *operand1,
+											  ArrayType *operands2,
+											  PGrnBinaryOperatorTextFunction operator)
+{
+	int i, n;
+
+	n = ARR_DIMS(operands2)[0];
+	for (i = 1; i <= n; i++)
+	{
+		Datum operandDatum2;
+		text *operand2;
+		bool isNULL;
+
+		operandDatum2 = array_ref(operands2, 1, &i, -1, -1, false, 'i', &isNULL);
+		if (isNULL)
+			continue;
+
+		operand2 = DatumGetTextPP(operandDatum2);
+		if (operator(VARDATA_ANY(operand1),
+					 VARSIZE_ANY_EXHDR(operand1),
+					 VARDATA_ANY(operand2),
+					 VARSIZE_ANY_EXHDR(operand2)))
+			return true;
+	}
+
+	return false;
+}
+
+/* TODO: "in" will be better than "contain". */
+static bool
+pgroonga_execute_binary_operator_contain_text_array(ArrayType *operands1,
+													ArrayType *operands2,
+													PGrnBinaryOperatorTextFunction operator)
+{
+	int i, n;
+
+	n = ARR_DIMS(operands1)[0];
+	for (i = 1; i <= n; i++)
+	{
+		Datum operandDatum1;
+		text *operand1;
+		bool isNULL;
+
+		operandDatum1 = array_ref(operands1, 1, &i, -1, -1, false, 'i', &isNULL);
+		if (isNULL)
+			continue;
+
+		operand1 = DatumGetTextPP(operandDatum1);
+		if (pgroonga_execute_binary_operator_contain_text(operand1,
+														  operands2,
+														  operator))
+			return true;
+	}
+
+	return false;
+}
+
+static bool
 pgroonga_match_term_raw(const char *text, unsigned int textSize,
 						const char *term, unsigned int termSize)
 {
@@ -1391,43 +1523,14 @@ pgroonga_match_term_text(PG_FUNCTION_ARGS)
 Datum
 pgroonga_match_term_text_array(PG_FUNCTION_ARGS)
 {
-	ArrayType *target = PG_GETARG_ARRAYTYPE_P(0);
+	ArrayType *targets = PG_GETARG_ARRAYTYPE_P(0);
 	text *term = PG_GETARG_TEXT_PP(1);
-	bool matched = false;
-	grn_obj elementBuffer;
-	int i, n;
-
-	grn_obj_reinit(ctx, &(buffers->general), GRN_DB_TEXT, 0);
-	GRN_TEXT_SET(ctx, &(buffers->general), VARDATA_ANY(term), VARSIZE_ANY_EXHDR(term));
-
-	GRN_TEXT_INIT(&elementBuffer, GRN_OBJ_DO_SHALLOW_COPY);
-
-	n = ARR_DIMS(target)[0];
-	for (i = 1; i <= n; i++)
-	{
-		Datum elementDatum;
-		text *element;
-		bool isNULL;
-
-		elementDatum = array_ref(target, 1, &i, -1, -1, false, 'i', &isNULL);
-		if (isNULL)
-			continue;
-
-		element = DatumGetTextPP(elementDatum);
-		GRN_TEXT_SET(ctx, &elementBuffer,
-					 VARDATA_ANY(element), VARSIZE_ANY_EXHDR(element));
-		if (pgroonga_match_term_raw(GRN_TEXT_VALUE(&elementBuffer),
-									GRN_TEXT_LEN(&elementBuffer),
-									GRN_TEXT_VALUE(&(buffers->general)),
-									GRN_TEXT_LEN(&(buffers->general))))
-		{
-			matched = true;
-			break;
-		}
-	}
-
-	GRN_OBJ_FIN(ctx, &elementBuffer);
+	grn_bool matched;
 
+	matched =
+		pgroonga_execute_binary_operator_text_array(targets,
+													term,
+													pgroonga_match_term_raw);
 	PG_RETURN_BOOL(matched);
 }
 
@@ -1490,7 +1593,7 @@ pgroonga_match_term_varchar_array(PG_FUNCTION_ARGS)
 	PG_RETURN_BOOL(matched);
 }
 
-static grn_bool
+static bool
 pgroonga_match_query_raw(const char *target, unsigned int targetSize,
 						 const char *query, unsigned int querySize)
 {
@@ -1500,7 +1603,7 @@ pgroonga_match_query_raw(const char *target, unsigned int targetSize,
 		GRN_EXPR_SYNTAX_QUERY | GRN_EXPR_ALLOW_LEADING_NOT;
 	grn_rc rc;
 	grn_obj *result;
-	bool matched = false;
+	grn_bool matched = false;
 
 	GRN_EXPR_CREATE_FOR_QUERY(ctx,
 							  matchSequentialSearchData.table,
@@ -1576,31 +1679,12 @@ pgroonga_match_query_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_query_raw(VARDATA_ANY(target),
-										   VARSIZE_ANY_EXHDR(target),
-										   VARDATA_ANY(query),
-										   VARSIZE_ANY_EXHDR(query));
-		if (matched)
-		{
-			break;
-		}
-	}
+	grn_bool matched;
 
+	matched =
+		pgroonga_execute_binary_operator_text_array(targets,
+													query,
+													pgroonga_match_query_raw);
 	PG_RETURN_BOOL(matched);
 }
 
@@ -1622,7 +1706,7 @@ pgroonga_match_query_varchar(PG_FUNCTION_ARGS)
 	PG_RETURN_BOOL(matched);
 }
 
-static grn_bool
+static bool
 pgroonga_match_regexp_raw(const char *text, unsigned int textSize,
 						  const char *pattern, unsigned int patternSize)
 {
@@ -1697,6 +1781,23 @@ pgroonga_match_text(PG_FUNCTION_ARGS)
 }
 
 /**
+ * pgroonga.match_text_array(targets text[], term text) : bool
+ */
+Datum
+pgroonga_match_text_array(PG_FUNCTION_ARGS)
+{
+	ArrayType *targets = PG_GETARG_ARRAYTYPE_P(0);
+	text *term = PG_GETARG_TEXT_PP(1);
+	grn_bool matched;
+
+	matched =
+		pgroonga_execute_binary_operator_text_array(targets,
+													term,
+													pgroonga_match_term_raw);
+	PG_RETURN_BOOL(matched);
+}
+
+/**
  * pgroonga.query_text(target text, query text) : bool
  */
 Datum
@@ -1715,6 +1816,21 @@ pgroonga_query_text(PG_FUNCTION_ARGS)
 }
 
 /**
+ * pgroonga.query_text_array(targets text[], query text) : bool
+ */
+Datum
+pgroonga_query_text_array(PG_FUNCTION_ARGS)
+{
+	ArrayType *targets = PG_GETARG_ARRAYTYPE_P(0);
+	text *query = PG_GETARG_TEXT_PP(1);
+
+	return pgroonga_execute_binary_operator_text_array(targets,
+													   query,
+													   pgroonga_match_query_raw);
+
+}
+
+/**
  * pgroonga.similar_text(target text, document text) : bool
  */
 Datum
@@ -1740,7 +1856,20 @@ pgroonga_similar_text(PG_FUNCTION_ARGS)
 	PG_RETURN_BOOL(false);
 }
 
-static grn_bool
+/**
+ * pgroonga.similar_text_array(targets text[], document text) : bool
+ */
+Datum
+pgroonga_similar_text_array(PG_FUNCTION_ARGS)
+{
+	ereport(ERROR,
+			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+			 errmsg("pgroonga: operator &~? is available only in index scan")));
+
+	PG_RETURN_BOOL(false);
+}
+
+static bool
 pgroonga_script_raw(const char *target, unsigned int targetSize,
 					const char *script, unsigned int scriptSize)
 {
@@ -1749,7 +1878,7 @@ pgroonga_script_raw(const char *target, unsigned int targetSize,
 	grn_expr_flags flags = GRN_EXPR_SYNTAX_SCRIPT;
 	grn_rc rc;
 	grn_obj *result;
-	bool matched = false;
+	grn_bool matched = false;
 
 	GRN_EXPR_CREATE_FOR_QUERY(ctx,
 							  matchSequentialSearchData.table,
@@ -1817,7 +1946,24 @@ pgroonga_script_text(PG_FUNCTION_ARGS)
 	PG_RETURN_BOOL(matched);
 }
 
-static grn_bool
+/**
+ * pgroonga.script_text_array(targets text[], script text) : bool
+ */
+Datum
+pgroonga_script_text_array(PG_FUNCTION_ARGS)
+{
+	ArrayType *targets = PG_GETARG_ARRAYTYPE_P(0);
+	text *script = PG_GETARG_TEXT_PP(1);
+	bool matched;
+
+	matched =
+		pgroonga_execute_binary_operator_text_array(targets,
+													script,
+													pgroonga_script_raw);
+	PG_RETURN_BOOL(matched);
+}
+
+static bool
 pgroonga_prefix_raw(const char *text, unsigned int textSize,
 					const char *prefix, unsigned int prefixSize)
 {
@@ -1857,13 +2003,13 @@ pgroonga_prefix_text(PG_FUNCTION_ARGS)
 	PG_RETURN_BOOL(matched);
 }
 
-static grn_bool
+static 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;
+	bool matched;
 	grn_id id;
 
 	GRN_EXPR_CREATE_FOR_QUERY(ctx,
@@ -1936,29 +2082,29 @@ pgroonga_match_contain_text(PG_FUNCTION_ARGS)
 {
 	text *target = PG_GETARG_TEXT_PP(0);
 	ArrayType *keywords = PG_GETARG_ARRAYTYPE_P(1);
-	grn_bool matched = GRN_FALSE;
-	int i, n;
+	bool matched;
 
-	n = ARR_DIMS(keywords)[0];
-	for (i = 1; i <= n; i++)
-	{
-		Datum keywordDatum;
-		text *keyword;
-		bool isNULL;
-
-		keywordDatum = array_ref(keywords, 1, &i, -1, -1, false, 'i', &isNULL);
-		if (isNULL)
-			continue;
+	matched =
+		pgroonga_execute_binary_operator_contain_text(target,
+													  keywords,
+													  pgroonga_match_term_raw);
+	PG_RETURN_BOOL(matched);
+}
 
-		keyword = DatumGetTextPP(keywordDatum);
-		matched = pgroonga_match_term_raw(VARDATA_ANY(target),
-										  VARSIZE_ANY_EXHDR(target),
-										  VARDATA_ANY(keyword),
-										  VARSIZE_ANY_EXHDR(keyword));
-		if (matched)
-			break;
-	}
+/**
+ * pgroonga.match_contain_text_array(targets text[], keywords text[]) : bool
+ */
+Datum
+pgroonga_match_contain_text_array(PG_FUNCTION_ARGS)
+{
+	ArrayType *targets = PG_GETARG_ARRAYTYPE_P(0);
+	ArrayType *keywords = PG_GETARG_ARRAYTYPE_P(1);
+	bool matched;
 
+	matched =
+		pgroonga_execute_binary_operator_contain_text_array(targets,
+															keywords,
+															pgroonga_match_term_raw);
 	PG_RETURN_BOOL(matched);
 }
 
@@ -1970,29 +2116,28 @@ pgroonga_query_contain_text(PG_FUNCTION_ARGS)
 {
 	text *target = PG_GETARG_TEXT_PP(0);
 	ArrayType *queries = PG_GETARG_ARRAYTYPE_P(1);
-	grn_bool matched = GRN_FALSE;
-	int i, n;
-
-	n = ARR_DIMS(queries)[0];
-	for (i = 1; i <= n; i++)
-	{
-		Datum queryDatum;
-		text *query;
-		bool isNULL;
+	grn_bool matched;
 
-		queryDatum = array_ref(queries, 1, &i, -1, -1, false, 'i', &isNULL);
-		if (isNULL)
-			continue;
+	matched = pgroonga_execute_binary_operator_contain_text(target,
+															queries,
+															pgroonga_match_query_raw);
+	PG_RETURN_BOOL(matched);
+}
 
-		query = DatumGetTextPP(queryDatum);
-		matched = pgroonga_match_query_raw(VARDATA_ANY(target),
-										   VARSIZE_ANY_EXHDR(target),
-										   VARDATA_ANY(query),
-										   VARSIZE_ANY_EXHDR(query));
-		if (matched)
-			break;
-	}
+/**
+ * pgroonga.query_contain_text_array(targets text[], queries text[]) : bool
+ */
+Datum
+pgroonga_query_contain_text_array(PG_FUNCTION_ARGS)
+{
+	ArrayType *targets = PG_GETARG_ARRAYTYPE_P(0);
+	ArrayType *queries = PG_GETARG_ARRAYTYPE_P(1);
+	bool matched;
 
+	matched =
+		pgroonga_execute_binary_operator_contain_text_array(targets,
+															queries,
+															pgroonga_match_query_raw);
 	PG_RETURN_BOOL(matched);
 }
 
@@ -2004,32 +2149,12 @@ pgroonga_prefix_text_array(PG_FUNCTION_ARGS)
 {
 	ArrayType *targets = PG_GETARG_ARRAYTYPE_P(0);
 	text *prefix = 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_prefix_raw(VARDATA_ANY(target),
-									  VARSIZE_ANY_EXHDR(target),
-									  VARDATA_ANY(prefix),
-									  VARSIZE_ANY_EXHDR(prefix));
-		if (matched)
-		{
-			break;
-		}
-	}
+	bool matched;
 
+	matched =
+		pgroonga_execute_binary_operator_text_array(targets,
+													prefix,
+													pgroonga_prefix_raw);
 	PG_RETURN_BOOL(matched);
 }
 
@@ -2052,31 +2177,12 @@ pgroonga_prefix_rk_text_array(PG_FUNCTION_ARGS)
 {
 	ArrayType *targets = PG_GETARG_ARRAYTYPE_P(0);
 	text *prefix = 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_prefix_rk_raw(VARDATA_ANY(target),
-										 VARSIZE_ANY_EXHDR(target),
-										 VARDATA_ANY(prefix),
-										 VARSIZE_ANY_EXHDR(prefix));
-		if (matched)
-		{
-			break;
-		}
-	}
+	bool matched;
 
+	matched =
+		pgroonga_execute_binary_operator_text_array(targets,
+													prefix,
+													pgroonga_prefix_rk_raw);
 	PG_RETURN_BOOL(matched);
 }
 
@@ -2967,6 +3073,7 @@ PGrnSearchBuildCondition(Relation index,
 		switch (attribute->atttypid)
 		{
 		case TEXTOID:
+		case TEXTARRAYOID:
 			valueTypeID = TEXTARRAYOID;
 			break;
 		}




More information about the Groonga-commit mailing list
アーカイブの一覧に戻る