[Groonga-commit] pgroonga/pgroonga at f7fe15f [master] Add pgroonga.varchar_full_text_search_ops_v2

Back to archive index

Kouhei Sutou null+****@clear*****
Tue May 2 15:12:39 JST 2017


Kouhei Sutou	2017-05-02 15:12:39 +0900 (Tue, 02 May 2017)

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

  Message:
    Add pgroonga.varchar_full_text_search_ops_v2

  Added files:
    expected/full-text-search/varchar/single/compatibility/v2/match-v1/bitmapscan.out
    expected/full-text-search/varchar/single/compatibility/v2/match-v1/indexscan.out
    expected/full-text-search/varchar/single/compatibility/v2/match-v1/seqscan.out
    expected/full-text-search/varchar/single/compatibility/v2/query-v1/bitmapscan.out
    expected/full-text-search/varchar/single/compatibility/v2/query-v1/indexscan.out
    expected/full-text-search/varchar/single/compatibility/v2/query-v1/seqscan.out
    expected/full-text-search/varchar/single/match-in-v2/bitmapscan.out
    expected/full-text-search/varchar/single/match-in-v2/indexscan.out
    expected/full-text-search/varchar/single/match-in-v2/seqscan.out
    expected/full-text-search/varchar/single/match-v2/bitmapscan.out
    expected/full-text-search/varchar/single/match-v2/indexscan.out
    expected/full-text-search/varchar/single/match-v2/seqscan.out
    expected/full-text-search/varchar/single/query-in-v2/bitmapscan.out
    expected/full-text-search/varchar/single/query-in-v2/indexscan.out
    expected/full-text-search/varchar/single/query-in-v2/seqscan.out
    expected/full-text-search/varchar/single/query-v2/bitmapscan.out
    expected/full-text-search/varchar/single/query-v2/indexscan.out
    expected/full-text-search/varchar/single/query-v2/seqscan.out
    expected/full-text-search/varchar/single/script-v2/bitmapscan.out
    expected/full-text-search/varchar/single/script-v2/indexscan.out
    expected/full-text-search/varchar/single/script-v2/seqscan.out
    expected/full-text-search/varchar/single/similar-v2/bitmapscan.out
    expected/full-text-search/varchar/single/similar-v2/indexscan.out
    expected/full-text-search/varchar/single/similar-v2/seqscan.out
    sql/full-text-search/varchar/single/compatibility/v2/match-v1/bitmapscan.sql
    sql/full-text-search/varchar/single/compatibility/v2/match-v1/indexscan.sql
    sql/full-text-search/varchar/single/compatibility/v2/match-v1/seqscan.sql
    sql/full-text-search/varchar/single/compatibility/v2/query-v1/bitmapscan.sql
    sql/full-text-search/varchar/single/compatibility/v2/query-v1/indexscan.sql
    sql/full-text-search/varchar/single/compatibility/v2/query-v1/seqscan.sql
    sql/full-text-search/varchar/single/match-in-v2/bitmapscan.sql
    sql/full-text-search/varchar/single/match-in-v2/indexscan.sql
    sql/full-text-search/varchar/single/match-in-v2/seqscan.sql
    sql/full-text-search/varchar/single/match-v2/bitmapscan.sql
    sql/full-text-search/varchar/single/match-v2/indexscan.sql
    sql/full-text-search/varchar/single/match-v2/seqscan.sql
    sql/full-text-search/varchar/single/query-in-v2/bitmapscan.sql
    sql/full-text-search/varchar/single/query-in-v2/indexscan.sql
    sql/full-text-search/varchar/single/query-in-v2/seqscan.sql
    sql/full-text-search/varchar/single/query-v2/bitmapscan.sql
    sql/full-text-search/varchar/single/query-v2/indexscan.sql
    sql/full-text-search/varchar/single/query-v2/seqscan.sql
    sql/full-text-search/varchar/single/script-v2/bitmapscan.sql
    sql/full-text-search/varchar/single/script-v2/indexscan.sql
    sql/full-text-search/varchar/single/script-v2/seqscan.sql
    sql/full-text-search/varchar/single/similar-v2/bitmapscan.sql
    sql/full-text-search/varchar/single/similar-v2/indexscan.sql
    sql/full-text-search/varchar/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 (+91 -0)
===================================================================
--- data/pgroonga--1.2.0--1.2.1.sql    2017-05-02 12:50:09 +0900 (9594b0f)
+++ data/pgroonga--1.2.0--1.2.1.sql    2017-05-02 15:12:39 +0900 (799a890)
@@ -136,3 +136,94 @@ CREATE OPERATOR CLASS pgroonga.text_array_full_text_search_ops_v2
 		OPERATOR 15 &` (text[], text),
 		OPERATOR 18 &@> (text[], text[]),
 		OPERATOR 19 &?> (text[], text[]);
+
+-- Add pgroonga.varchar_full_text_search_ops_v2
+CREATE FUNCTION pgroonga.match_varchar(varchar, varchar)
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_match_varchar'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &@ (
+	PROCEDURE = pgroonga.match_varchar,
+	LEFTARG = varchar,
+	RIGHTARG = varchar
+);
+
+CREATE FUNCTION pgroonga.query_varchar(varchar, varchar)
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_query_varchar'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &? (
+	PROCEDURE = pgroonga.query_varchar,
+	LEFTARG = varchar,
+	RIGHTARG = varchar
+);
+
+CREATE FUNCTION pgroonga.similar_varchar(varchar, varchar)
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_similar_varchar'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &~? (
+	PROCEDURE = pgroonga.similar_varchar,
+	LEFTARG = varchar,
+	RIGHTARG = varchar
+);
+
+CREATE FUNCTION pgroonga.script_varchar(varchar, varchar)
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_script_varchar'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &` (
+	PROCEDURE = pgroonga.script_varchar,
+	LEFTARG = varchar,
+	RIGHTARG = varchar
+);
+
+CREATE FUNCTION pgroonga.match_in_varchar(varchar, varchar[])
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_match_in_varchar'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &@> (
+	PROCEDURE = pgroonga.match_in_varchar,
+	LEFTARG = varchar,
+	RIGHTARG = varchar[]
+);
+
+CREATE FUNCTION pgroonga.query_in_varchar(varchar, varchar[])
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_query_in_varchar'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &?> (
+	PROCEDURE = pgroonga.query_in_varchar,
+	LEFTARG = varchar,
+	RIGHTARG = varchar[]
+);
+
+CREATE OPERATOR CLASS pgroonga.varchar_full_text_search_ops_v2
+	FOR TYPE varchar
+	USING pgroonga AS
+		OPERATOR 8 %%, -- For backward compatibility
+		OPERATOR 9 @@, -- For backward compatibility
+		OPERATOR 12 &@,
+		OPERATOR 13 &?,
+		OPERATOR 14 &~?,
+		OPERATOR 15 &`,
+		OPERATOR 18 &@> (varchar, varchar[]),
+		OPERATOR 19 &?> (varchar, varchar[]);

  Modified: data/pgroonga.sql (+90 -0)
===================================================================
--- data/pgroonga.sql    2017-05-02 12:50:09 +0900 (69cca0a)
+++ data/pgroonga.sql    2017-05-02 15:12:39 +0900 (d93fe8b)
@@ -305,6 +305,19 @@ CREATE OPERATOR &@ (
 	RIGHTARG = text
 );
 
+CREATE FUNCTION pgroonga.match_varchar(varchar, varchar)
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_match_varchar'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &@ (
+	PROCEDURE = pgroonga.match_varchar,
+	LEFTARG = varchar,
+	RIGHTARG = varchar
+);
+
 CREATE FUNCTION pgroonga.query_text(text, text)
 	RETURNS bool
 	AS 'MODULE_PATHNAME', 'pgroonga_query_text'
@@ -331,6 +344,19 @@ CREATE OPERATOR &? (
 	RIGHTARG = text
 );
 
+CREATE FUNCTION pgroonga.query_varchar(varchar, varchar)
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_query_varchar'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &? (
+	PROCEDURE = pgroonga.query_varchar,
+	LEFTARG = varchar,
+	RIGHTARG = varchar
+);
+
 CREATE FUNCTION pgroonga.similar_text(text, text)
 	RETURNS bool
 	AS 'MODULE_PATHNAME', 'pgroonga_similar_text'
@@ -357,6 +383,19 @@ CREATE OPERATOR &~? (
 	RIGHTARG = text
 );
 
+CREATE FUNCTION pgroonga.similar_varchar(varchar, varchar)
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_similar_varchar'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &~? (
+	PROCEDURE = pgroonga.similar_varchar,
+	LEFTARG = varchar,
+	RIGHTARG = varchar
+);
+
 CREATE FUNCTION pgroonga.prefix_text(text, text)
 	RETURNS bool
 	AS 'MODULE_PATHNAME', 'pgroonga_prefix_text'
@@ -409,6 +448,19 @@ CREATE OPERATOR &` (
 	RIGHTARG = text
 );
 
+CREATE FUNCTION pgroonga.script_varchar(varchar, varchar)
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_script_varchar'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &` (
+	PROCEDURE = pgroonga.script_varchar,
+	LEFTARG = varchar,
+	RIGHTARG = varchar
+);
+
 CREATE FUNCTION pgroonga.match_in_text(text, text[])
 	RETURNS bool
 	AS 'MODULE_PATHNAME', 'pgroonga_match_in_text'
@@ -435,6 +487,19 @@ CREATE OPERATOR &@> (
 	RIGHTARG = text[]
 );
 
+CREATE FUNCTION pgroonga.match_in_varchar(varchar, varchar[])
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_match_in_varchar'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &@> (
+	PROCEDURE = pgroonga.match_in_varchar,
+	LEFTARG = varchar,
+	RIGHTARG = varchar[]
+);
+
 CREATE FUNCTION pgroonga.query_in_text(text, text[])
 	RETURNS bool
 	AS 'MODULE_PATHNAME', 'pgroonga_query_in_text'
@@ -461,6 +526,19 @@ CREATE OPERATOR &?> (
 	RIGHTARG = text[]
 );
 
+CREATE FUNCTION pgroonga.query_in_varchar(varchar, varchar[])
+	RETURNS bool
+	AS 'MODULE_PATHNAME', 'pgroonga_query_in_varchar'
+	LANGUAGE C
+	IMMUTABLE
+	STRICT;
+
+CREATE OPERATOR &?> (
+	PROCEDURE = pgroonga.query_in_varchar,
+	LEFTARG = varchar,
+	RIGHTARG = varchar[]
+);
+
 CREATE FUNCTION pgroonga.prefix_text_array(text[], text)
 	RETURNS bool
 	AS 'MODULE_PATHNAME', 'pgroonga_prefix_text_array'
@@ -757,6 +835,18 @@ CREATE OPERATOR CLASS pgroonga.text_array_full_text_search_ops_v2
 		OPERATOR 18 &@> (text[], text[]),
 		OPERATOR 19 &?> (text[], text[]);
 
+CREATE OPERATOR CLASS pgroonga.varchar_full_text_search_ops_v2
+	FOR TYPE varchar
+	USING pgroonga AS
+		OPERATOR 8 %%, -- For backward compatibility
+		OPERATOR 9 @@, -- For backward compatibility
+		OPERATOR 12 &@,
+		OPERATOR 13 &?,
+		OPERATOR 14 &~?,
+		OPERATOR 15 &`,
+		OPERATOR 18 &@> (varchar, varchar[]),
+		OPERATOR 19 &?> (varchar, varchar[]);
+
 CREATE OPERATOR CLASS pgroonga.text_term_search_ops_v2 FOR TYPE text
 	USING pgroonga AS
 		OPERATOR 16 &^,

  Added: expected/full-text-search/varchar/single/compatibility/v2/match-v1/bitmapscan.out (+34 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/varchar/single/compatibility/v2/match-v1/bitmapscan.out    2017-05-02 15:12:39 +0900 (55fa165)
@@ -0,0 +1,34 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+EXPLAIN (COSTS OFF)
+SELECT id, content
+  FROM memos
+ WHERE content %% 'Groonga';
+                          QUERY PLAN                           
+---------------------------------------------------------------
+ Bitmap Heap Scan on memos
+   Recheck Cond: (content %% 'Groonga'::character varying)
+   ->  Bitmap Index Scan on grnindex
+         Index Cond: (content %% 'Groonga'::character varying)
+(4 rows)
+
+SELECT id, content
+  FROM memos
+ WHERE content %% 'Groonga';
+ id |                        content                        
+----+-------------------------------------------------------
+  2 | Groonga is fast full text search engine.
+  3 | PGroonga is a PostgreSQL extension that uses Groonga.
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/varchar/single/compatibility/v2/match-v1/indexscan.out (+32 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/varchar/single/compatibility/v2/match-v1/indexscan.out    2017-05-02 15:12:39 +0900 (d9e40c6)
@@ -0,0 +1,32 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+EXPLAIN (COSTS OFF)
+SELECT id, content
+  FROM memos
+ WHERE content %% 'Groonga';
+                       QUERY PLAN                        
+---------------------------------------------------------
+ Index Scan using grnindex on memos
+   Index Cond: (content %% 'Groonga'::character varying)
+(2 rows)
+
+SELECT id, content
+  FROM memos
+ WHERE content %% 'Groonga';
+ id |                        content                        
+----+-------------------------------------------------------
+  2 | Groonga is fast full text search engine.
+  3 | PGroonga is a PostgreSQL extension that uses Groonga.
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/varchar/single/compatibility/v2/match-v1/seqscan.out (+22 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/varchar/single/compatibility/v2/match-v1/seqscan.out    2017-05-02 15:12:39 +0900 (c68d33b)
@@ -0,0 +1,22 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+SELECT id, content
+  FROM memos
+ WHERE content %% 'Groonga';
+ id |                        content                        
+----+-------------------------------------------------------
+  2 | Groonga is fast full text search engine.
+  3 | PGroonga is a PostgreSQL extension that uses Groonga.
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/varchar/single/compatibility/v2/query-v1/bitmapscan.out (+34 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/varchar/single/compatibility/v2/query-v1/bitmapscan.out    2017-05-02 15:12:39 +0900 (e2db945)
@@ -0,0 +1,34 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+EXPLAIN (COSTS OFF)
+SELECT id, content
+  FROM memos
+ WHERE content @@ 'rdbms OR engine';
+                              QUERY PLAN                               
+-----------------------------------------------------------------------
+ Bitmap Heap Scan on memos
+   Recheck Cond: (content @@ 'rdbms OR engine'::character varying)
+   ->  Bitmap Index Scan on grnindex
+         Index Cond: (content @@ 'rdbms OR engine'::character varying)
+(4 rows)
+
+SELECT id, content
+  FROM memos
+ WHERE content @@ 'rdbms OR engine';
+ id |                 content                  
+----+------------------------------------------
+  1 | PostgreSQL is a RDBMS.
+  2 | Groonga is fast full text search engine.
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/varchar/single/compatibility/v2/query-v1/indexscan.out (+32 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/varchar/single/compatibility/v2/query-v1/indexscan.out    2017-05-02 15:12:39 +0900 (a087ee6)
@@ -0,0 +1,32 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+EXPLAIN (COSTS OFF)
+SELECT id, content
+  FROM memos
+ WHERE content @@ 'rdbms OR engine';
+                           QUERY PLAN                            
+-----------------------------------------------------------------
+ Index Scan using grnindex on memos
+   Index Cond: (content @@ 'rdbms OR engine'::character varying)
+(2 rows)
+
+SELECT id, content
+  FROM memos
+ WHERE content @@ 'rdbms OR engine';
+ id |                 content                  
+----+------------------------------------------
+  1 | PostgreSQL is a RDBMS.
+  2 | Groonga is fast full text search engine.
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/varchar/single/compatibility/v2/query-v1/seqscan.out (+23 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/varchar/single/compatibility/v2/query-v1/seqscan.out    2017-05-02 15:12:39 +0900 (52d938b)
@@ -0,0 +1,23 @@
+SET search_path = "$user",public,pgroonga,pg_catalog;
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+SELECT id, content
+  FROM memos
+ WHERE content @@ 'rdbms OR engine';
+ id |                 content                  
+----+------------------------------------------
+  1 | PostgreSQL is a RDBMS.
+  2 | Groonga is fast full text search engine.
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/varchar/single/match-in-v2/bitmapscan.out (+34 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/varchar/single/match-in-v2/bitmapscan.out    2017-05-02 15:12:39 +0900 (b4343f0)
@@ -0,0 +1,34 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+CREATE INDEX pgrn_index ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+EXPLAIN (COSTS OFF)
+SELECT id, content
+  FROM memos
+ WHERE content &@> Array['rdbms', 'engine']::varchar[];
+                               QUERY PLAN                                
+-------------------------------------------------------------------------
+ Bitmap Heap Scan on memos
+   Recheck Cond: (content &@> '{rdbms,engine}'::character varying[])
+   ->  Bitmap Index Scan on pgrn_index
+         Index Cond: (content &@> '{rdbms,engine}'::character varying[])
+(4 rows)
+
+SELECT id, content
+  FROM memos
+ WHERE content &@> Array['rdbms', 'engine']::varchar[];
+ id |                 content                  
+----+------------------------------------------
+  1 | PostgreSQL is a RDBMS.
+  2 | Groonga is fast full text search engine.
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/varchar/single/match-in-v2/indexscan.out (+32 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/varchar/single/match-in-v2/indexscan.out    2017-05-02 15:12:39 +0900 (bc4943e)
@@ -0,0 +1,32 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+CREATE INDEX pgrn_index ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+EXPLAIN (COSTS OFF)
+SELECT id, content
+  FROM memos
+ WHERE content &@> Array['rdbms', 'engine']::varchar[];
+                            QUERY PLAN                             
+-------------------------------------------------------------------
+ Index Scan using pgrn_index on memos
+   Index Cond: (content &@> '{rdbms,engine}'::character varying[])
+(2 rows)
+
+SELECT id, content
+  FROM memos
+ WHERE content &@> Array['rdbms', 'engine']::varchar[];
+ id |                 content                  
+----+------------------------------------------
+  1 | PostgreSQL is a RDBMS.
+  2 | Groonga is fast full text search engine.
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/varchar/single/match-in-v2/seqscan.out (+20 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/varchar/single/match-in-v2/seqscan.out    2017-05-02 15:12:39 +0900 (fd313eb)
@@ -0,0 +1,20 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+SELECT id, content
+  FROM memos
+ WHERE content &@> Array['rdbms', 'engine']::varchar[];
+ id |                 content                  
+----+------------------------------------------
+  1 | PostgreSQL is a RDBMS.
+  2 | Groonga is fast full text search engine.
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/varchar/single/match-v2/bitmapscan.out (+22 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/varchar/single/match-v2/bitmapscan.out    2017-05-02 15:12:39 +0900 (cc03b18)
@@ -0,0 +1,22 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+SELECT id, content
+  FROM memos
+ WHERE content &@ 'Groonga';
+ id |                        content                        
+----+-------------------------------------------------------
+  2 | Groonga is fast full text search engine.
+  3 | PGroonga is a PostgreSQL extension that uses Groonga.
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/varchar/single/match-v2/indexscan.out (+22 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/varchar/single/match-v2/indexscan.out    2017-05-02 15:12:39 +0900 (f150ee9)
@@ -0,0 +1,22 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+SELECT id, content
+  FROM memos
+ WHERE content &@ 'Groonga';
+ id |                        content                        
+----+-------------------------------------------------------
+  2 | Groonga is fast full text search engine.
+  3 | PGroonga is a PostgreSQL extension that uses Groonga.
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/varchar/single/match-v2/seqscan.out (+22 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/varchar/single/match-v2/seqscan.out    2017-05-02 15:12:39 +0900 (2b60aaf)
@@ -0,0 +1,22 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+SELECT id, content
+  FROM memos
+ WHERE content &@ 'Groonga';
+ id |                        content                        
+----+-------------------------------------------------------
+  2 | Groonga is fast full text search engine.
+  3 | PGroonga is a PostgreSQL extension that uses Groonga.
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/varchar/single/query-in-v2/bitmapscan.out (+34 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/varchar/single/query-in-v2/bitmapscan.out    2017-05-02 15:12:39 +0900 (46b5716)
@@ -0,0 +1,34 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+CREATE INDEX pgrn_index ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+EXPLAIN (COSTS OFF)
+SELECT id, content
+  FROM memos
+ WHERE content &?> Array['rdbms', 'groonga engine']::varchar[];
+                                    QUERY PLAN                                     
+-----------------------------------------------------------------------------------
+ Bitmap Heap Scan on memos
+   Recheck Cond: (content &?> '{rdbms,"groonga engine"}'::character varying[])
+   ->  Bitmap Index Scan on pgrn_index
+         Index Cond: (content &?> '{rdbms,"groonga engine"}'::character varying[])
+(4 rows)
+
+SELECT id, content
+  FROM memos
+ WHERE content &?> Array['rdbms', 'groonga engine']::varchar[];
+ id |                 content                  
+----+------------------------------------------
+  1 | PostgreSQL is a RDBMS.
+  2 | Groonga is fast full text search engine.
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/varchar/single/query-in-v2/indexscan.out (+32 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/varchar/single/query-in-v2/indexscan.out    2017-05-02 15:12:39 +0900 (9bcc3d6)
@@ -0,0 +1,32 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+CREATE INDEX pgrn_index ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+EXPLAIN (COSTS OFF)
+SELECT id, content
+  FROM memos
+ WHERE content &?> Array['rdbms', 'groonga engine']::varchar[];
+                                 QUERY PLAN                                  
+-----------------------------------------------------------------------------
+ Index Scan using pgrn_index on memos
+   Index Cond: (content &?> '{rdbms,"groonga engine"}'::character varying[])
+(2 rows)
+
+SELECT id, content
+  FROM memos
+ WHERE content &?> Array['rdbms', 'groonga engine']::varchar[];
+ id |                 content                  
+----+------------------------------------------
+  2 | Groonga is fast full text search engine.
+  1 | PostgreSQL is a RDBMS.
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/varchar/single/query-in-v2/seqscan.out (+20 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/varchar/single/query-in-v2/seqscan.out    2017-05-02 15:12:39 +0900 (0e3cbf3)
@@ -0,0 +1,20 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+SELECT id, content
+  FROM memos
+ WHERE content &?> Array['rdbms', 'groonga engine']::varchar[];
+ id |                 content                  
+----+------------------------------------------
+  1 | PostgreSQL is a RDBMS.
+  2 | Groonga is fast full text search engine.
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/varchar/single/query-v2/bitmapscan.out (+22 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/varchar/single/query-v2/bitmapscan.out    2017-05-02 15:12:39 +0900 (77ac274)
@@ -0,0 +1,22 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+SELECT id, content
+  FROM memos
+ WHERE content &? 'rdbms OR engine';
+ id |                 content                  
+----+------------------------------------------
+  1 | PostgreSQL is a RDBMS.
+  2 | Groonga is fast full text search engine.
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/varchar/single/query-v2/indexscan.out (+22 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/varchar/single/query-v2/indexscan.out    2017-05-02 15:12:39 +0900 (89f46a2)
@@ -0,0 +1,22 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+SELECT id, content
+  FROM memos
+ WHERE content &? 'rdbms OR engine';
+ id |                 content                  
+----+------------------------------------------
+  1 | PostgreSQL is a RDBMS.
+  2 | Groonga is fast full text search engine.
+(2 rows)
+
+DROP TABLE memos;

  Added: expected/full-text-search/varchar/single/query-v2/seqscan.out (+23 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/varchar/single/query-v2/seqscan.out    2017-05-02 15:12:39 +0900 (280d1ab)
@@ -0,0 +1,23 @@
+SET search_path = "$user",public,pgroonga,pg_catalog;
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+SELECT id, content
+  FROM memos
+ WHERE content &? 'rdbms OR engine';
+ id |                 content                  
+----+------------------------------------------
+  1 | PostgreSQL is a RDBMS.
+  2 | Groonga is fast full text search engine.
+(2 rows)
+
+DROP TABLE memos;

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

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

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

  Added: expected/full-text-search/varchar/single/similar-v2/bitmapscan.out (+21 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/varchar/single/similar-v2/bitmapscan.out    2017-05-02 15:12:39 +0900 (4496152)
@@ -0,0 +1,21 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+SELECT id, content
+  FROM memos
+ WHERE content &~? 'Mroonga is a MySQL plugin that uses Groonga.';
+ id |                        content                        
+----+-------------------------------------------------------
+  3 | PGroonga is a PostgreSQL extension that uses Groonga.
+(1 row)
+
+DROP TABLE memos;

  Added: expected/full-text-search/varchar/single/similar-v2/indexscan.out (+21 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/varchar/single/similar-v2/indexscan.out    2017-05-02 15:12:39 +0900 (6002920)
@@ -0,0 +1,21 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+SELECT id, content
+  FROM memos
+ WHERE content &~? 'Mroonga is a MySQL plugin that uses Groonga.';
+ id |                        content                        
+----+-------------------------------------------------------
+  3 | PGroonga is a PostgreSQL extension that uses Groonga.
+(1 row)
+
+DROP TABLE memos;

  Added: expected/full-text-search/varchar/single/similar-v2/seqscan.out (+17 -0) 100644
===================================================================
--- /dev/null
+++ expected/full-text-search/varchar/single/similar-v2/seqscan.out    2017-05-02 15:12:39 +0900 (a754ac4)
@@ -0,0 +1,17 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+SELECT id, content
+  FROM memos
+ WHERE content &~? '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/varchar/single/compatibility/v2/match-v1/bitmapscan.sql (+26 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/varchar/single/compatibility/v2/match-v1/bitmapscan.sql    2017-05-02 15:12:39 +0900 (8c2e5ed)
@@ -0,0 +1,26 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+
+EXPLAIN (COSTS OFF)
+SELECT id, content
+  FROM memos
+ WHERE content %% 'Groonga';
+
+SELECT id, content
+  FROM memos
+ WHERE content %% 'Groonga';
+
+DROP TABLE memos;

  Added: sql/full-text-search/varchar/single/compatibility/v2/match-v1/indexscan.sql (+26 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/varchar/single/compatibility/v2/match-v1/indexscan.sql    2017-05-02 15:12:39 +0900 (2170592)
@@ -0,0 +1,26 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+
+EXPLAIN (COSTS OFF)
+SELECT id, content
+  FROM memos
+ WHERE content %% 'Groonga';
+
+SELECT id, content
+  FROM memos
+ WHERE content %% 'Groonga';
+
+DROP TABLE memos;

  Added: sql/full-text-search/varchar/single/compatibility/v2/match-v1/seqscan.sql (+21 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/varchar/single/compatibility/v2/match-v1/seqscan.sql    2017-05-02 15:12:39 +0900 (4026a7b)
@@ -0,0 +1,21 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+
+SELECT id, content
+  FROM memos
+ WHERE content %% 'Groonga';
+
+DROP TABLE memos;

  Added: sql/full-text-search/varchar/single/compatibility/v2/query-v1/bitmapscan.sql (+26 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/varchar/single/compatibility/v2/query-v1/bitmapscan.sql    2017-05-02 15:12:39 +0900 (8ce3d6e)
@@ -0,0 +1,26 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+
+EXPLAIN (COSTS OFF)
+SELECT id, content
+  FROM memos
+ WHERE content @@ 'rdbms OR engine';
+
+SELECT id, content
+  FROM memos
+ WHERE content @@ 'rdbms OR engine';
+
+DROP TABLE memos;

  Added: sql/full-text-search/varchar/single/compatibility/v2/query-v1/indexscan.sql (+26 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/varchar/single/compatibility/v2/query-v1/indexscan.sql    2017-05-02 15:12:39 +0900 (1ba7f63)
@@ -0,0 +1,26 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+
+EXPLAIN (COSTS OFF)
+SELECT id, content
+  FROM memos
+ WHERE content @@ 'rdbms OR engine';
+
+SELECT id, content
+  FROM memos
+ WHERE content @@ 'rdbms OR engine';
+
+DROP TABLE memos;

  Added: sql/full-text-search/varchar/single/compatibility/v2/query-v1/seqscan.sql (+23 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/varchar/single/compatibility/v2/query-v1/seqscan.sql    2017-05-02 15:12:39 +0900 (1ca51d9)
@@ -0,0 +1,23 @@
+SET search_path = "$user",public,pgroonga,pg_catalog;
+
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+
+SELECT id, content
+  FROM memos
+ WHERE content @@ 'rdbms OR engine';
+
+DROP TABLE memos;

  Added: sql/full-text-search/varchar/single/match-in-v2/bitmapscan.sql (+26 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/varchar/single/match-in-v2/bitmapscan.sql    2017-05-02 15:12:39 +0900 (4adddad)
@@ -0,0 +1,26 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+CREATE INDEX pgrn_index ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+
+EXPLAIN (COSTS OFF)
+SELECT id, content
+  FROM memos
+ WHERE content &@> Array['rdbms', 'engine']::varchar[];
+
+SELECT id, content
+  FROM memos
+ WHERE content &@> Array['rdbms', 'engine']::varchar[];
+
+DROP TABLE memos;

  Added: sql/full-text-search/varchar/single/match-in-v2/indexscan.sql (+26 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/varchar/single/match-in-v2/indexscan.sql    2017-05-02 15:12:39 +0900 (11b1ff3)
@@ -0,0 +1,26 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+CREATE INDEX pgrn_index ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+
+EXPLAIN (COSTS OFF)
+SELECT id, content
+  FROM memos
+ WHERE content &@> Array['rdbms', 'engine']::varchar[];
+
+SELECT id, content
+  FROM memos
+ WHERE content &@> Array['rdbms', 'engine']::varchar[];
+
+DROP TABLE memos;

  Added: sql/full-text-search/varchar/single/match-in-v2/seqscan.sql (+18 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/varchar/single/match-in-v2/seqscan.sql    2017-05-02 15:12:39 +0900 (6d42cf4)
@@ -0,0 +1,18 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+
+SELECT id, content
+  FROM memos
+ WHERE content &@> Array['rdbms', 'engine']::varchar[];
+
+DROP TABLE memos;

  Added: sql/full-text-search/varchar/single/match-v2/bitmapscan.sql (+21 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/varchar/single/match-v2/bitmapscan.sql    2017-05-02 15:12:39 +0900 (604e84b)
@@ -0,0 +1,21 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+
+SELECT id, content
+  FROM memos
+ WHERE content &@ 'Groonga';
+
+DROP TABLE memos;

  Added: sql/full-text-search/varchar/single/match-v2/indexscan.sql (+21 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/varchar/single/match-v2/indexscan.sql    2017-05-02 15:12:39 +0900 (ca1fa25)
@@ -0,0 +1,21 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+
+SELECT id, content
+  FROM memos
+ WHERE content &@ 'Groonga';
+
+DROP TABLE memos;

  Added: sql/full-text-search/varchar/single/match-v2/seqscan.sql (+21 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/varchar/single/match-v2/seqscan.sql    2017-05-02 15:12:39 +0900 (d8c69a1)
@@ -0,0 +1,21 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+
+SELECT id, content
+  FROM memos
+ WHERE content &@ 'Groonga';
+
+DROP TABLE memos;

  Added: sql/full-text-search/varchar/single/query-in-v2/bitmapscan.sql (+26 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/varchar/single/query-in-v2/bitmapscan.sql    2017-05-02 15:12:39 +0900 (bc6dbff)
@@ -0,0 +1,26 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+CREATE INDEX pgrn_index ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+
+EXPLAIN (COSTS OFF)
+SELECT id, content
+  FROM memos
+ WHERE content &?> Array['rdbms', 'groonga engine']::varchar[];
+
+SELECT id, content
+  FROM memos
+ WHERE content &?> Array['rdbms', 'groonga engine']::varchar[];
+
+DROP TABLE memos;

  Added: sql/full-text-search/varchar/single/query-in-v2/indexscan.sql (+26 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/varchar/single/query-in-v2/indexscan.sql    2017-05-02 15:12:39 +0900 (5f5257e)
@@ -0,0 +1,26 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+CREATE INDEX pgrn_index ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+
+EXPLAIN (COSTS OFF)
+SELECT id, content
+  FROM memos
+ WHERE content &?> Array['rdbms', 'groonga engine']::varchar[];
+
+SELECT id, content
+  FROM memos
+ WHERE content &?> Array['rdbms', 'groonga engine']::varchar[];
+
+DROP TABLE memos;

  Added: sql/full-text-search/varchar/single/query-in-v2/seqscan.sql (+18 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/varchar/single/query-in-v2/seqscan.sql    2017-05-02 15:12:39 +0900 (8c3c9db)
@@ -0,0 +1,18 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+
+SELECT id, content
+  FROM memos
+ WHERE content &?> Array['rdbms', 'groonga engine']::varchar[];
+
+DROP TABLE memos;

  Added: sql/full-text-search/varchar/single/query-v2/bitmapscan.sql (+21 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/varchar/single/query-v2/bitmapscan.sql    2017-05-02 15:12:39 +0900 (ea6bd0f)
@@ -0,0 +1,21 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+
+SELECT id, content
+  FROM memos
+ WHERE content &? 'rdbms OR engine';
+
+DROP TABLE memos;

  Added: sql/full-text-search/varchar/single/query-v2/indexscan.sql (+21 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/varchar/single/query-v2/indexscan.sql    2017-05-02 15:12:39 +0900 (bbfb7eb)
@@ -0,0 +1,21 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+
+SELECT id, content
+  FROM memos
+ WHERE content &? 'rdbms OR engine';
+
+DROP TABLE memos;

  Added: sql/full-text-search/varchar/single/query-v2/seqscan.sql (+23 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/varchar/single/query-v2/seqscan.sql    2017-05-02 15:12:39 +0900 (cc9b455)
@@ -0,0 +1,23 @@
+SET search_path = "$user",public,pgroonga,pg_catalog;
+
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+
+SELECT id, content
+  FROM memos
+ WHERE content &? 'rdbms OR engine';
+
+DROP TABLE memos;

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

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

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

  Added: sql/full-text-search/varchar/single/similar-v2/bitmapscan.sql (+21 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/varchar/single/similar-v2/bitmapscan.sql    2017-05-02 15:12:39 +0900 (659d8bf)
@@ -0,0 +1,21 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+
+SELECT id, content
+  FROM memos
+ WHERE content &~? 'Mroonga is a MySQL plugin that uses Groonga.';
+
+DROP TABLE memos;

  Added: sql/full-text-search/varchar/single/similar-v2/indexscan.sql (+21 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/varchar/single/similar-v2/indexscan.sql    2017-05-02 15:12:39 +0900 (890ab2b)
@@ -0,0 +1,21 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+
+SELECT id, content
+  FROM memos
+ WHERE content &~? 'Mroonga is a MySQL plugin that uses Groonga.';
+
+DROP TABLE memos;

  Added: sql/full-text-search/varchar/single/similar-v2/seqscan.sql (+21 -0) 100644
===================================================================
--- /dev/null
+++ sql/full-text-search/varchar/single/similar-v2/seqscan.sql    2017-05-02 15:12:39 +0900 (7b489a1)
@@ -0,0 +1,21 @@
+CREATE TABLE memos (
+  id integer,
+  content varchar(256)
+);
+
+INSERT INTO memos VALUES (1, 'PostgreSQL is a RDBMS.');
+INSERT INTO memos VALUES (2, 'Groonga is fast full text search engine.');
+INSERT INTO memos VALUES (3, 'PGroonga is a PostgreSQL extension that uses Groonga.');
+
+CREATE INDEX grnindex ON memos
+ USING pgroonga (content pgroonga.varchar_full_text_search_ops_v2);
+
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+
+SELECT id, content
+  FROM memos
+ WHERE content &~? 'Mroonga is a MySQL plugin that uses Groonga.';
+
+DROP TABLE memos;

  Modified: src/pgroonga.c (+244 -99)
===================================================================
--- src/pgroonga.c    2017-05-02 12:50:09 +0900 (7a8bcc9)
+++ src/pgroonga.c    2017-05-02 15:12:39 +0900 (f7612c3)
@@ -187,18 +187,24 @@ 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_match_varchar);
 PGRN_FUNCTION_INFO_V1(pgroonga_query_text);
 PGRN_FUNCTION_INFO_V1(pgroonga_query_text_array);
+PGRN_FUNCTION_INFO_V1(pgroonga_query_varchar);
 PGRN_FUNCTION_INFO_V1(pgroonga_similar_text);
 PGRN_FUNCTION_INFO_V1(pgroonga_similar_text_array);
+PGRN_FUNCTION_INFO_V1(pgroonga_similar_varchar);
 PGRN_FUNCTION_INFO_V1(pgroonga_script_text);
 PGRN_FUNCTION_INFO_V1(pgroonga_script_text_array);
+PGRN_FUNCTION_INFO_V1(pgroonga_script_varchar);
 PGRN_FUNCTION_INFO_V1(pgroonga_prefix_text);
 PGRN_FUNCTION_INFO_V1(pgroonga_prefix_rk_text);
 PGRN_FUNCTION_INFO_V1(pgroonga_match_in_text);
 PGRN_FUNCTION_INFO_V1(pgroonga_match_in_text_array);
+PGRN_FUNCTION_INFO_V1(pgroonga_match_in_varchar);
 PGRN_FUNCTION_INFO_V1(pgroonga_query_in_text);
 PGRN_FUNCTION_INFO_V1(pgroonga_query_in_text_array);
+PGRN_FUNCTION_INFO_V1(pgroonga_query_in_varchar);
 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);
@@ -1385,15 +1391,43 @@ pgroonga_command(PG_FUNCTION_ARGS)
 	PG_RETURN_TEXT_P(result);
 }
 
-typedef bool (*PGrnBinaryOperatorTextFunction)(const char *operand1,
-											   unsigned int operandSize1,
-											   const char *operand2,
-											   unsigned int operandSize2);
+static void
+PGrnDatumExtractString(Datum datum,
+					   Oid type,
+					   const char **string,
+					   unsigned int *size)
+{
+	switch (type)
+	{
+	case VARCHAROID:
+	{
+		VarChar *varCharData = DatumGetVarCharPP(datum);
+		*string = VARDATA_ANY(varCharData);
+		*size = VARSIZE_ANY_EXHDR(varCharData);
+		break;
+	}
+	case TEXTOID:
+	{
+		text *textData = DatumGetTextPP(datum);
+		*string = VARDATA_ANY(textData);
+		*size = VARSIZE_ANY_EXHDR(textData);
+		break;
+	}
+	default:
+		break;
+	}
+}
+
+typedef bool (*PGrnBinaryOperatorStringFunction)(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)
+pgroonga_execute_binary_operator_string_array(ArrayType *operands1,
+											  const char *operand2,
+											  unsigned int operandSize2,
+											  PGrnBinaryOperatorStringFunction operator)
 {
 	int i, n;
 
@@ -1401,18 +1435,23 @@ pgroonga_execute_binary_operator_text_array(ArrayType *operands1,
 	for (i = 1; i <= n; i++)
 	{
 		Datum operandDatum1;
-		text *operand1;
+		const char *operand1 = NULL;
+		unsigned int operandSize1 = 0;
 		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)))
+		PGrnDatumExtractString(operandDatum1,
+							   ARR_ELEMTYPE(operands1),
+							   &operand1,
+							   &operandSize1);
+		if (!operand1)
+			continue;
+
+		if (operator(operand1, operandSize1,
+					 operand2, operandSize2))
 			return true;
 	}
 
@@ -1420,9 +1459,10 @@ pgroonga_execute_binary_operator_text_array(ArrayType *operands1,
 }
 
 static bool
-pgroonga_execute_binary_operator_in_text(text *operand1,
-										 ArrayType *operands2,
-										 PGrnBinaryOperatorTextFunction operator)
+pgroonga_execute_binary_operator_in_string(const char *operand1,
+										   unsigned int operandSize1,
+										   ArrayType *operands2,
+										   PGrnBinaryOperatorStringFunction operator)
 {
 	int i, n;
 
@@ -1430,18 +1470,23 @@ pgroonga_execute_binary_operator_in_text(text *operand1,
 	for (i = 1; i <= n; i++)
 	{
 		Datum operandDatum2;
-		text *operand2;
+		const char *operand2 = NULL;
+		unsigned int operandSize2 = 0;
 		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)))
+		PGrnDatumExtractString(operandDatum2,
+							   ARR_ELEMTYPE(operands2),
+							   &operand2,
+							   &operandSize2);
+		if (!operand2)
+			continue;
+
+		if (operator(operand1, operandSize1,
+					 operand2, operandSize2))
 			return true;
 	}
 
@@ -1449,9 +1494,9 @@ pgroonga_execute_binary_operator_in_text(text *operand1,
 }
 
 static bool
-pgroonga_execute_binary_operator_in_text_array(ArrayType *operands1,
-											   ArrayType *operands2,
-											   PGrnBinaryOperatorTextFunction operator)
+pgroonga_execute_binary_operator_in_string_array(ArrayType *operands1,
+												 ArrayType *operands2,
+												 PGrnBinaryOperatorStringFunction operator)
 {
 	int i, n;
 
@@ -1459,17 +1504,25 @@ pgroonga_execute_binary_operator_in_text_array(ArrayType *operands1,
 	for (i = 1; i <= n; i++)
 	{
 		Datum operandDatum1;
-		text *operand1;
+		const char *operand1 = NULL;
+		unsigned int operandSize1 = 0;
 		bool isNULL;
 
 		operandDatum1 = array_ref(operands1, 1, &i, -1, -1, false, 'i', &isNULL);
 		if (isNULL)
 			continue;
 
-		operand1 = DatumGetTextPP(operandDatum1);
-		if (pgroonga_execute_binary_operator_in_text(operand1,
-													 operands2,
-													 operator))
+		PGrnDatumExtractString(operandDatum1,
+							   ARR_ELEMTYPE(operands1),
+							   &operand1,
+							   &operandSize1);
+		if (!operand1)
+			continue;
+
+		if (pgroonga_execute_binary_operator_in_string(operand1,
+													   operandSize1,
+													   operands2,
+													   operator))
 			return true;
 	}
 
@@ -1523,12 +1576,13 @@ pgroonga_match_term_text_array(PG_FUNCTION_ARGS)
 {
 	ArrayType *targets = PG_GETARG_ARRAYTYPE_P(0);
 	text *term = PG_GETARG_TEXT_PP(1);
-	grn_bool matched;
+	bool matched;
 
 	matched =
-		pgroonga_execute_binary_operator_text_array(targets,
-													term,
-													pgroonga_match_term_raw);
+		pgroonga_execute_binary_operator_string_array(targets,
+													  VARDATA_ANY(term),
+													  VARSIZE_ANY_EXHDR(term),
+													  pgroonga_match_term_raw);
 	PG_RETURN_BOOL(matched);
 }
 
@@ -1554,40 +1608,15 @@ pgroonga_match_term_varchar(PG_FUNCTION_ARGS)
 Datum
 pgroonga_match_term_varchar_array(PG_FUNCTION_ARGS)
 {
-	ArrayType *target = PG_GETARG_ARRAYTYPE_P(0);
+	ArrayType *targets = PG_GETARG_ARRAYTYPE_P(0);
 	VarChar *term = PG_GETARG_VARCHAR_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;
-		VarChar *element;
-		bool isNULL;
-
-		elementDatum = array_ref(target, 1, &i, -1, -1, false, 'i', &isNULL);
-		if (isNULL)
-			continue;
-
-		element = DatumGetVarCharPP(elementDatum);
-		GRN_TEXT_SET(ctx, &elementBuffer,
-					 VARDATA_ANY(element), VARSIZE_ANY_EXHDR(element));
-		if (grn_operator_exec_equal(ctx, &(buffers->general), &elementBuffer))
-		{
-			matched = true;
-			break;
-		}
-	}
-
-	GRN_OBJ_FIN(ctx, &elementBuffer);
+	bool matched;
 
+	matched =
+		pgroonga_execute_binary_operator_string_array(targets,
+													  VARDATA_ANY(term),
+													  VARSIZE_ANY_EXHDR(term),
+													  pgroonga_match_term_raw);
 	PG_RETURN_BOOL(matched);
 }
 
@@ -1659,7 +1688,7 @@ pgroonga_match_query_text(PG_FUNCTION_ARGS)
 {
 	text *target = PG_GETARG_TEXT_PP(0);
 	text *query = PG_GETARG_TEXT_PP(1);
-	bool matched = false;
+	bool matched;
 
 	matched = pgroonga_match_query_raw(VARDATA_ANY(target),
 									   VARSIZE_ANY_EXHDR(target),
@@ -1677,12 +1706,13 @@ pgroonga_match_query_text_array(PG_FUNCTION_ARGS)
 {
 	ArrayType *targets = PG_GETARG_ARRAYTYPE_P(0);
 	text *query = PG_GETARG_TEXT_PP(1);
-	grn_bool matched;
+	bool matched;
 
 	matched =
-		pgroonga_execute_binary_operator_text_array(targets,
-													query,
-													pgroonga_match_query_raw);
+		pgroonga_execute_binary_operator_string_array(targets,
+													  VARDATA_ANY(query),
+													  VARSIZE_ANY_EXHDR(query),
+													  pgroonga_match_query_raw);
 	PG_RETURN_BOOL(matched);
 }
 
@@ -1786,12 +1816,30 @@ pgroonga_match_text_array(PG_FUNCTION_ARGS)
 {
 	ArrayType *targets = PG_GETARG_ARRAYTYPE_P(0);
 	text *term = PG_GETARG_TEXT_PP(1);
-	grn_bool matched;
+	bool matched;
 
 	matched =
-		pgroonga_execute_binary_operator_text_array(targets,
-													term,
-													pgroonga_match_term_raw);
+		pgroonga_execute_binary_operator_string_array(targets,
+													  VARDATA_ANY(term),
+													  VARSIZE_ANY_EXHDR(term),
+													  pgroonga_match_term_raw);
+	PG_RETURN_BOOL(matched);
+}
+
+/**
+ * pgroonga.match_varchar(target varchar, term varchar) : bool
+ */
+Datum
+pgroonga_match_varchar(PG_FUNCTION_ARGS)
+{
+	VarChar *target = PG_GETARG_VARCHAR_PP(0);
+	VarChar *term = PG_GETARG_VARCHAR_PP(1);
+	bool matched;
+
+	matched = pgroonga_match_term_raw(VARDATA_ANY(target),
+									  VARSIZE_ANY_EXHDR(target),
+									  VARDATA_ANY(term),
+									  VARSIZE_ANY_EXHDR(term));
 	PG_RETURN_BOOL(matched);
 }
 
@@ -1821,11 +1869,31 @@ pgroonga_query_text_array(PG_FUNCTION_ARGS)
 {
 	ArrayType *targets = PG_GETARG_ARRAYTYPE_P(0);
 	text *query = PG_GETARG_TEXT_PP(1);
+	bool matched;
 
-	return pgroonga_execute_binary_operator_text_array(targets,
-													   query,
-													   pgroonga_match_query_raw);
+	matched =
+		pgroonga_execute_binary_operator_string_array(targets,
+													  VARDATA_ANY(query),
+													  VARSIZE_ANY_EXHDR(query),
+													  pgroonga_match_query_raw);
+	PG_RETURN_BOOL(matched);
+}
+
+/**
+ * pgroonga.query_varchar(target varchar, term varchar) : bool
+ */
+Datum
+pgroonga_query_varchar(PG_FUNCTION_ARGS)
+{
+	VarChar *target = PG_GETARG_VARCHAR_PP(0);
+	VarChar *query = PG_GETARG_VARCHAR_PP(1);
+	grn_bool matched;
 
+	matched = pgroonga_match_query_raw(VARDATA_ANY(target),
+									   VARSIZE_ANY_EXHDR(target),
+									   VARDATA_ANY(query),
+									   VARSIZE_ANY_EXHDR(query));
+	PG_RETURN_BOOL(matched);
 }
 
 /**
@@ -1867,6 +1935,19 @@ pgroonga_similar_text_array(PG_FUNCTION_ARGS)
 	PG_RETURN_BOOL(false);
 }
 
+/**
+ * pgroonga.similar_varchar(target varchar, document varchar) : bool
+ */
+Datum
+pgroonga_similar_varchar(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)
@@ -1955,9 +2036,28 @@ pgroonga_script_text_array(PG_FUNCTION_ARGS)
 	bool matched;
 
 	matched =
-		pgroonga_execute_binary_operator_text_array(targets,
-													script,
-													pgroonga_script_raw);
+		pgroonga_execute_binary_operator_string_array(targets,
+													  VARDATA_ANY(script),
+													  VARSIZE_ANY_EXHDR(script),
+													  pgroonga_script_raw);
+	PG_RETURN_BOOL(matched);
+}
+
+/**
+ * pgroonga.script_varchar(target varchar, script varchar) : bool
+ */
+Datum
+pgroonga_script_varchar(PG_FUNCTION_ARGS)
+{
+	VarChar *target = PG_GETARG_VARCHAR_PP(0);
+	VarChar *script = PG_GETARG_VARCHAR_PP(1);
+	bool matched = false;
+
+	matched = pgroonga_script_raw(VARDATA_ANY(target),
+								  VARSIZE_ANY_EXHDR(target),
+								  VARDATA_ANY(script),
+								  VARSIZE_ANY_EXHDR(script));
+
 	PG_RETURN_BOOL(matched);
 }
 
@@ -2083,9 +2183,10 @@ pgroonga_match_in_text(PG_FUNCTION_ARGS)
 	bool matched;
 
 	matched =
-		pgroonga_execute_binary_operator_in_text(target,
-												 keywords,
-												 pgroonga_match_term_raw);
+		pgroonga_execute_binary_operator_in_string(VARDATA_ANY(target),
+												   VARSIZE_ANY_EXHDR(target),
+												   keywords,
+												   pgroonga_match_term_raw);
 	PG_RETURN_BOOL(matched);
 }
 
@@ -2100,9 +2201,27 @@ pgroonga_match_in_text_array(PG_FUNCTION_ARGS)
 	bool matched;
 
 	matched =
-		pgroonga_execute_binary_operator_in_text_array(targets,
-													   keywords,
-													   pgroonga_match_term_raw);
+		pgroonga_execute_binary_operator_in_string_array(targets,
+														 keywords,
+														 pgroonga_match_term_raw);
+	PG_RETURN_BOOL(matched);
+}
+
+/**
+ * pgroonga.match_in_varchar(target varchar, keywords varchar[]) : bool
+ */
+Datum
+pgroonga_match_in_varchar(PG_FUNCTION_ARGS)
+{
+	VarChar *target = PG_GETARG_VARCHAR_PP(0);
+	ArrayType *keywords = PG_GETARG_ARRAYTYPE_P(1);
+	bool matched;
+
+	matched =
+		pgroonga_execute_binary_operator_in_string(VARDATA_ANY(target),
+												   VARSIZE_ANY_EXHDR(target),
+												   keywords,
+												   pgroonga_match_term_raw);
 	PG_RETURN_BOOL(matched);
 }
 
@@ -2116,9 +2235,11 @@ pgroonga_query_in_text(PG_FUNCTION_ARGS)
 	ArrayType *queries = PG_GETARG_ARRAYTYPE_P(1);
 	grn_bool matched;
 
-	matched = pgroonga_execute_binary_operator_in_text(target,
-													   queries,
-													   pgroonga_match_query_raw);
+	matched =
+		pgroonga_execute_binary_operator_in_string(VARDATA_ANY(target),
+												   VARSIZE_ANY_EXHDR(target),
+												   queries,
+												   pgroonga_match_query_raw);
 	PG_RETURN_BOOL(matched);
 }
 
@@ -2133,9 +2254,27 @@ pgroonga_query_in_text_array(PG_FUNCTION_ARGS)
 	bool matched;
 
 	matched =
-		pgroonga_execute_binary_operator_in_text_array(targets,
-													   queries,
-													   pgroonga_match_query_raw);
+		pgroonga_execute_binary_operator_in_string_array(targets,
+														 queries,
+														 pgroonga_match_query_raw);
+	PG_RETURN_BOOL(matched);
+}
+
+/**
+ * pgroonga.query_in_varchar(target varchar, queries varchar[]) : bool
+ */
+Datum
+pgroonga_query_in_varchar(PG_FUNCTION_ARGS)
+{
+	VarChar *target = PG_GETARG_VARCHAR_PP(0);
+	ArrayType *queries = PG_GETARG_ARRAYTYPE_P(1);
+	grn_bool matched;
+
+	matched =
+		pgroonga_execute_binary_operator_in_string(VARDATA_ANY(target),
+												   VARSIZE_ANY_EXHDR(target),
+												   queries,
+												   pgroonga_match_query_raw);
 	PG_RETURN_BOOL(matched);
 }
 
@@ -2150,9 +2289,10 @@ pgroonga_prefix_text_array(PG_FUNCTION_ARGS)
 	bool matched;
 
 	matched =
-		pgroonga_execute_binary_operator_text_array(targets,
-													prefix,
-													pgroonga_prefix_raw);
+		pgroonga_execute_binary_operator_string_array(targets,
+													  VARDATA_ANY(prefix),
+													  VARSIZE_ANY_EXHDR(prefix),
+													  pgroonga_prefix_raw);
 	PG_RETURN_BOOL(matched);
 }
 
@@ -2178,9 +2318,10 @@ pgroonga_prefix_rk_text_array(PG_FUNCTION_ARGS)
 	bool matched;
 
 	matched =
-		pgroonga_execute_binary_operator_text_array(targets,
-													prefix,
-													pgroonga_prefix_rk_raw);
+		pgroonga_execute_binary_operator_string_array(targets,
+													  VARDATA_ANY(prefix),
+													  VARSIZE_ANY_EXHDR(prefix),
+													  pgroonga_prefix_rk_raw);
 	PG_RETURN_BOOL(matched);
 }
 
@@ -3070,6 +3211,10 @@ PGrnSearchBuildCondition(Relation index,
 	case PGrnMatchInStrategyV2Number:
 		switch (attribute->atttypid)
 		{
+		case VARCHAROID:
+		case VARCHARARRAYOID:
+			valueTypeID = VARCHARARRAYOID;
+			break;
 		case TEXTOID:
 		case TEXTARRAYOID:
 			valueTypeID = TEXTARRAYOID;




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