[Groonga-commit] pgroonga/pgroonga at 6572bba [master] Support &@ and &? in jsonb

Back to archive index

Kouhei Sutou null+****@clear*****
Mon May 8 20:19:05 JST 2017


Kouhei Sutou	2017-05-08 20:19:05 +0900 (Mon, 08 May 2017)

  New Revision: 6572bba48b752c4fc2a31577f1844704a27fa5c8
  https://github.com/pgroonga/pgroonga/commit/6572bba48b752c4fc2a31577f1844704a27fa5c8

  Message:
    Support &@ and &? in jsonb

  Added files:
    expected/jsonb/match-v2/element/bitmapscan.out
    expected/jsonb/match-v2/element/indexscan.out
    expected/jsonb/match-v2/element/seqscan.out
    expected/jsonb/match-v2/value/bitmapscan.out
    expected/jsonb/match-v2/value/indexscan.out
    expected/jsonb/match-v2/value/seqscan.out
    expected/jsonb/query-v2/element/bitmapscan.out
    expected/jsonb/query-v2/element/indexscan.out
    expected/jsonb/query-v2/element/seqscan.out
    expected/jsonb/query-v2/value/bitmapscan.out
    expected/jsonb/query-v2/value/indexscan.out
    expected/jsonb/query-v2/value/seqscan.out
    sql/jsonb/match-v2/element/bitmapscan.sql
    sql/jsonb/match-v2/element/indexscan.sql
    sql/jsonb/match-v2/element/seqscan.sql
    sql/jsonb/match-v2/value/bitmapscan.sql
    sql/jsonb/match-v2/value/indexscan.sql
    sql/jsonb/match-v2/value/seqscan.sql
    sql/jsonb/query-v2/element/bitmapscan.sql
    sql/jsonb/query-v2/element/indexscan.sql
    sql/jsonb/query-v2/element/seqscan.sql
    sql/jsonb/query-v2/value/bitmapscan.sql
    sql/jsonb/query-v2/value/indexscan.sql
    sql/jsonb/query-v2/value/seqscan.sql
  Modified files:
    data/pgroonga--1.2.0--1.2.1.sql
    data/pgroonga.sql
    src/pgrn-jsonb.c

  Modified: data/pgroonga--1.2.0--1.2.1.sql (+61 -1)
===================================================================
--- data/pgroonga--1.2.0--1.2.1.sql    2017-05-08 18:49:51 +0900 (4f88b8c)
+++ data/pgroonga--1.2.0--1.2.1.sql    2017-05-08 20:19:05 +0900 (6ec3679)
@@ -366,6 +366,39 @@ ALTER OPERATOR FAMILY pgroonga.varchar_array_ops USING pgroonga
 	ADD
 		OPERATOR 12 &@ (varchar[], varchar);
 
+-- Rename "pgroonga_match_jsonb" to "pgroonga_match_script_jsonb"
+DO LANGUAGE plpgsql $$
+BEGIN
+	PERFORM 1
+		FROM pg_type
+		WHERE typname = 'jsonb';
+
+	IF FOUND THEN
+		DROP OPERATOR CLASS pgroonga.jsonb_ops USING pgroonga;
+		DROP OPERATOR @@ (jsonb, text);
+		DROP FUNCTION pgroonga.match_query(jsonb, text);
+
+		CREATE FUNCTION pgroonga.match_script_jsonb(jsonb, text)
+			RETURNS bool
+			AS 'MODULE_PATHNAME', 'pgroonga_match_script_jsonb'
+			LANGUAGE C
+			IMMUTABLE
+			STRICT;
+
+		CREATE OPERATOR @@ (
+			PROCEDURE = pgroonga.match_script_jsonb,
+			LEFTARG = jsonb,
+			RIGHTARG = text
+		);
+
+		CREATE OPERATOR CLASS pgroonga.jsonb_ops DEFAULT FOR TYPE jsonb
+			USING pgroonga AS
+				OPERATOR 9 @@ (jsonb, text),
+				OPERATOR 11 @>;
+	END IF;
+END;
+$$;
+
 -- Add pgroonga.jsonb_ops_v2
 DO LANGUAGE plpgsql $$
 BEGIN
@@ -374,6 +407,32 @@ BEGIN
 		WHERE typname = 'jsonb';
 
 	IF FOUND THEN
+		CREATE FUNCTION pgroonga.match_jsonb(jsonb, text)
+			RETURNS bool
+			AS 'MODULE_PATHNAME', 'pgroonga_match_jsonb'
+			LANGUAGE C
+			IMMUTABLE
+			STRICT;
+
+		CREATE OPERATOR &@ (
+			PROCEDURE = pgroonga.match_jsonb,
+			LEFTARG = jsonb,
+			RIGHTARG = text
+		);
+
+		CREATE FUNCTION pgroonga.query_jsonb(jsonb, text)
+			RETURNS bool
+			AS 'MODULE_PATHNAME', 'pgroonga_query_jsonb'
+			LANGUAGE C
+			IMMUTABLE
+			STRICT;
+
+		CREATE OPERATOR &? (
+			PROCEDURE = pgroonga.query_jsonb,
+			LEFTARG = jsonb,
+			RIGHTARG = text
+		);
+
 		CREATE FUNCTION pgroonga.script_jsonb(jsonb, text)
 			RETURNS bool
 			AS 'MODULE_PATHNAME', 'pgroonga_script_jsonb'
@@ -391,6 +450,8 @@ BEGIN
 			USING pgroonga AS
 				OPERATOR 9 @@ (jsonb, text), -- For backward compatibility
 				OPERATOR 11 @>,
+				OPERATOR 12 &@ (jsonb, text),
+				OPERATOR 13 &? (jsonb, text),
 				OPERATOR 15 &` (jsonb, text);
 	END IF;
 END;
@@ -410,4 +471,3 @@ BEGIN
 	END IF;
 END;
 $$;
-

  Modified: data/pgroonga.sql (+51 -3)
===================================================================
--- data/pgroonga.sql    2017-05-08 18:49:51 +0900 (7e0089e)
+++ data/pgroonga.sql    2017-05-08 20:19:05 +0900 (62b57d6)
@@ -331,6 +331,29 @@ CREATE OPERATOR &@ (
 	RIGHTARG = varchar
 );
 
+DO LANGUAGE plpgsql $$
+BEGIN
+	PERFORM 1
+		FROM pg_type
+		WHERE typname = 'jsonb';
+
+	IF FOUND THEN
+		CREATE FUNCTION pgroonga.match_jsonb(jsonb, text)
+			RETURNS bool
+			AS 'MODULE_PATHNAME', 'pgroonga_match_jsonb'
+			LANGUAGE C
+			IMMUTABLE
+			STRICT;
+
+		CREATE OPERATOR &@ (
+			PROCEDURE = pgroonga.match_jsonb,
+			LEFTARG = jsonb,
+			RIGHTARG = text
+		);
+	END IF;
+END;
+$$;
+
 CREATE FUNCTION pgroonga.query_text(text, text)
 	RETURNS bool
 	AS 'MODULE_PATHNAME', 'pgroonga_query_text'
@@ -370,6 +393,29 @@ CREATE OPERATOR &? (
 	RIGHTARG = varchar
 );
 
+DO LANGUAGE plpgsql $$
+BEGIN
+	PERFORM 1
+		FROM pg_type
+		WHERE typname = 'jsonb';
+
+	IF FOUND THEN
+		CREATE FUNCTION pgroonga.query_jsonb(jsonb, text)
+			RETURNS bool
+			AS 'MODULE_PATHNAME', 'pgroonga_query_jsonb'
+			LANGUAGE C
+			IMMUTABLE
+			STRICT;
+
+		CREATE OPERATOR &? (
+			PROCEDURE = pgroonga.query_jsonb,
+			LEFTARG = jsonb,
+			RIGHTARG = text
+		);
+	END IF;
+END;
+$$;
+
 CREATE FUNCTION pgroonga.similar_text(text, text)
 	RETURNS bool
 	AS 'MODULE_PATHNAME', 'pgroonga_similar_text'
@@ -893,15 +939,15 @@ BEGIN
 		WHERE typname = 'jsonb';
 
 	IF FOUND THEN
-		CREATE FUNCTION pgroonga.match_query(jsonb, text)
+		CREATE FUNCTION pgroonga.match_script_jsonb(jsonb, text)
 			RETURNS bool
-			AS 'MODULE_PATHNAME', 'pgroonga_match_jsonb'
+			AS 'MODULE_PATHNAME', 'pgroonga_match_script_jsonb'
 			LANGUAGE C
 			IMMUTABLE
 			STRICT;
 
 		CREATE OPERATOR @@ (
-			PROCEDURE = pgroonga.match_query,
+			PROCEDURE = pgroonga.match_script_jsonb,
 			LEFTARG = jsonb,
 			RIGHTARG = text
 		);
@@ -1007,6 +1053,8 @@ BEGIN
 			USING pgroonga AS
 				OPERATOR 9 @@ (jsonb, text), -- For backward compatibility
 				OPERATOR 11 @>,
+				OPERATOR 12 &@ (jsonb, text),
+				OPERATOR 13 &? (jsonb, text),
 				OPERATOR 15 &` (jsonb, text);
 	END IF;
 END;

  Added: expected/jsonb/match-v2/element/bitmapscan.out (+38 -0) 100644
===================================================================
--- /dev/null
+++ expected/jsonb/match-v2/element/bitmapscan.out    2017-05-08 20:19:05 +0900 (a3fdf59)
@@ -0,0 +1,38 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+INSERT INTO fruits VALUES (1, '["apple"]');
+INSERT INTO fruits VALUES (2, '["banana", "apple"]');
+INSERT INTO fruits VALUES (3, '["peach"]');
+CREATE INDEX pgroonga_index ON fruits
+  USING pgroonga (items pgroonga.jsonb_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+EXPLAIN (COSTS OFF)
+SELECT id, items
+  FROM fruits
+ WHERE items &@ 'app'
+ ORDER BY id;
+                    QUERY PLAN                    
+--------------------------------------------------
+ Sort
+   Sort Key: id
+   ->  Bitmap Heap Scan on fruits
+         Recheck Cond: (items &@ 'app'::text)
+         ->  Bitmap Index Scan on pgroonga_index
+               Index Cond: (items &@ 'app'::text)
+(6 rows)
+
+SELECT id, items
+  FROM fruits
+ WHERE items &@ 'app'
+ ORDER BY id;
+ id |        items        
+----+---------------------
+  1 | ["apple"]
+  2 | ["banana", "apple"]
+(2 rows)
+
+DROP TABLE fruits;

  Added: expected/jsonb/match-v2/element/indexscan.out (+36 -0) 100644
===================================================================
--- /dev/null
+++ expected/jsonb/match-v2/element/indexscan.out    2017-05-08 20:19:05 +0900 (ee6642d)
@@ -0,0 +1,36 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+INSERT INTO fruits VALUES (1, '["apple"]');
+INSERT INTO fruits VALUES (2, '["banana", "apple"]');
+INSERT INTO fruits VALUES (3, '["peach"]');
+CREATE INDEX pgroonga_index ON fruits
+  USING pgroonga (items pgroonga.jsonb_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+EXPLAIN (COSTS OFF)
+SELECT id, items
+  FROM fruits
+ WHERE items &@ 'app'
+ ORDER BY id;
+                   QUERY PLAN                    
+-------------------------------------------------
+ Sort
+   Sort Key: id
+   ->  Index Scan using pgroonga_index on fruits
+         Index Cond: (items &@ 'app'::text)
+(4 rows)
+
+SELECT id, items
+  FROM fruits
+ WHERE items &@ 'app'
+ ORDER BY id;
+ id |        items        
+----+---------------------
+  1 | ["apple"]
+  2 | ["banana", "apple"]
+(2 rows)
+
+DROP TABLE fruits;

  Added: expected/jsonb/match-v2/element/seqscan.out (+21 -0) 100644
===================================================================
--- /dev/null
+++ expected/jsonb/match-v2/element/seqscan.out    2017-05-08 20:19:05 +0900 (df4164a)
@@ -0,0 +1,21 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+INSERT INTO fruits VALUES (1, '["apple"]');
+INSERT INTO fruits VALUES (2, '["banana", "apple"]');
+INSERT INTO fruits VALUES (3, '["peach"]');
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+SELECT id, items
+  FROM fruits
+ WHERE items &@ 'app'
+ ORDER BY id;
+ id |        items        
+----+---------------------
+  1 | ["apple"]
+  2 | ["banana", "apple"]
+(2 rows)
+
+DROP TABLE fruits;

  Added: expected/jsonb/match-v2/value/bitmapscan.out (+38 -0) 100644
===================================================================
--- /dev/null
+++ expected/jsonb/match-v2/value/bitmapscan.out    2017-05-08 20:19:05 +0900 (9864d71)
@@ -0,0 +1,38 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+INSERT INTO fruits VALUES (1, '{"name": "apple"}');
+INSERT INTO fruits VALUES (2, '{"type": "apple"}');
+INSERT INTO fruits VALUES (3, '{"name": "peach"}');
+CREATE INDEX pgroonga_index ON fruits
+  USING pgroonga (items pgroonga.jsonb_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+EXPLAIN (COSTS OFF)
+SELECT id, items
+  FROM fruits
+ WHERE items &@ 'app'
+ ORDER BY id;
+                    QUERY PLAN                    
+--------------------------------------------------
+ Sort
+   Sort Key: id
+   ->  Bitmap Heap Scan on fruits
+         Recheck Cond: (items &@ 'app'::text)
+         ->  Bitmap Index Scan on pgroonga_index
+               Index Cond: (items &@ 'app'::text)
+(6 rows)
+
+SELECT id, items
+  FROM fruits
+ WHERE items &@ 'app'
+ ORDER BY id;
+ id |       items       
+----+-------------------
+  1 | {"name": "apple"}
+  2 | {"type": "apple"}
+(2 rows)
+
+DROP TABLE fruits;

  Added: expected/jsonb/match-v2/value/indexscan.out (+36 -0) 100644
===================================================================
--- /dev/null
+++ expected/jsonb/match-v2/value/indexscan.out    2017-05-08 20:19:05 +0900 (4981a9f)
@@ -0,0 +1,36 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+INSERT INTO fruits VALUES (1, '{"name": "apple"}');
+INSERT INTO fruits VALUES (2, '{"type": "apple"}');
+INSERT INTO fruits VALUES (3, '{"name": "peach"}');
+CREATE INDEX pgroonga_index ON fruits
+  USING pgroonga (items pgroonga.jsonb_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+EXPLAIN (COSTS OFF)
+SELECT id, items
+  FROM fruits
+ WHERE items &@ 'app'
+ ORDER BY id;
+                   QUERY PLAN                    
+-------------------------------------------------
+ Sort
+   Sort Key: id
+   ->  Index Scan using pgroonga_index on fruits
+         Index Cond: (items &@ 'app'::text)
+(4 rows)
+
+SELECT id, items
+  FROM fruits
+ WHERE items &@ 'app'
+ ORDER BY id;
+ id |       items       
+----+-------------------
+  1 | {"name": "apple"}
+  2 | {"type": "apple"}
+(2 rows)
+
+DROP TABLE fruits;

  Added: expected/jsonb/match-v2/value/seqscan.out (+21 -0) 100644
===================================================================
--- /dev/null
+++ expected/jsonb/match-v2/value/seqscan.out    2017-05-08 20:19:05 +0900 (24c85e8)
@@ -0,0 +1,21 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+INSERT INTO fruits VALUES (1, '{"name": "apple"}');
+INSERT INTO fruits VALUES (2, '{"type": "apple"}');
+INSERT INTO fruits VALUES (3, '{"name": "peach"}');
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+SELECT id, items
+  FROM fruits
+ WHERE items &@ 'app'
+ ORDER BY id;
+ id |       items       
+----+-------------------
+  1 | {"name": "apple"}
+  2 | {"type": "apple"}
+(2 rows)
+
+DROP TABLE fruits;

  Added: expected/jsonb/query-v2/element/bitmapscan.out (+38 -0) 100644
===================================================================
--- /dev/null
+++ expected/jsonb/query-v2/element/bitmapscan.out    2017-05-08 20:19:05 +0900 (943df62)
@@ -0,0 +1,38 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+INSERT INTO fruits VALUES (1, '["apple"]');
+INSERT INTO fruits VALUES (2, '["banana", "apple"]');
+INSERT INTO fruits VALUES (3, '["peach"]');
+CREATE INDEX pgroonga_index ON fruits
+  USING pgroonga (items pgroonga.jsonb_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+EXPLAIN (COSTS OFF)
+SELECT id, items
+  FROM fruits
+ WHERE items &? 'banana OR peach'
+ ORDER BY id;
+                          QUERY PLAN                          
+--------------------------------------------------------------
+ Sort
+   Sort Key: id
+   ->  Bitmap Heap Scan on fruits
+         Recheck Cond: (items &? 'banana OR peach'::text)
+         ->  Bitmap Index Scan on pgroonga_index
+               Index Cond: (items &? 'banana OR peach'::text)
+(6 rows)
+
+SELECT id, items
+  FROM fruits
+ WHERE items &? 'banana OR peach'
+ ORDER BY id;
+ id |        items        
+----+---------------------
+  2 | ["banana", "apple"]
+  3 | ["peach"]
+(2 rows)
+
+DROP TABLE fruits;

  Added: expected/jsonb/query-v2/element/indexscan.out (+36 -0) 100644
===================================================================
--- /dev/null
+++ expected/jsonb/query-v2/element/indexscan.out    2017-05-08 20:19:05 +0900 (6f3ddac)
@@ -0,0 +1,36 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+INSERT INTO fruits VALUES (1, '["apple"]');
+INSERT INTO fruits VALUES (2, '["banana", "apple"]');
+INSERT INTO fruits VALUES (3, '["peach"]');
+CREATE INDEX pgroonga_index ON fruits
+  USING pgroonga (items pgroonga.jsonb_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+EXPLAIN (COSTS OFF)
+SELECT id, items
+  FROM fruits
+ WHERE items &? 'banana OR peach'
+ ORDER BY id;
+                       QUERY PLAN                       
+--------------------------------------------------------
+ Sort
+   Sort Key: id
+   ->  Index Scan using pgroonga_index on fruits
+         Index Cond: (items &? 'banana OR peach'::text)
+(4 rows)
+
+SELECT id, items
+  FROM fruits
+ WHERE items &? 'banana OR peach'
+ ORDER BY id;
+ id |        items        
+----+---------------------
+  2 | ["banana", "apple"]
+  3 | ["peach"]
+(2 rows)
+
+DROP TABLE fruits;

  Added: expected/jsonb/query-v2/element/seqscan.out (+21 -0) 100644
===================================================================
--- /dev/null
+++ expected/jsonb/query-v2/element/seqscan.out    2017-05-08 20:19:05 +0900 (da01d1d)
@@ -0,0 +1,21 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+INSERT INTO fruits VALUES (1, '["apple"]');
+INSERT INTO fruits VALUES (2, '["banana", "apple"]');
+INSERT INTO fruits VALUES (3, '["peach"]');
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+SELECT id, items
+  FROM fruits
+ WHERE items &? 'banana OR peach'
+ ORDER BY id;
+ id |        items        
+----+---------------------
+  2 | ["banana", "apple"]
+  3 | ["peach"]
+(2 rows)
+
+DROP TABLE fruits;

  Added: expected/jsonb/query-v2/value/bitmapscan.out (+40 -0) 100644
===================================================================
--- /dev/null
+++ expected/jsonb/query-v2/value/bitmapscan.out    2017-05-08 20:19:05 +0900 (0bd4889)
@@ -0,0 +1,40 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+INSERT INTO fruits VALUES (1, '{"name": "apple"}');
+INSERT INTO fruits VALUES (2, '{"type": "apple"}');
+INSERT INTO fruits VALUES (3, '{"name": "peach"}');
+INSERT INTO fruits VALUES (4, '{"like": "banana"}');
+CREATE INDEX pgroonga_index ON fruits
+  USING pgroonga (items pgroonga.jsonb_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+EXPLAIN (COSTS OFF)
+SELECT id, items
+  FROM fruits
+ WHERE items &? 'apple OR banana'
+ ORDER BY id;
+                          QUERY PLAN                          
+--------------------------------------------------------------
+ Sort
+   Sort Key: id
+   ->  Bitmap Heap Scan on fruits
+         Recheck Cond: (items &? 'apple OR banana'::text)
+         ->  Bitmap Index Scan on pgroonga_index
+               Index Cond: (items &? 'apple OR banana'::text)
+(6 rows)
+
+SELECT id, items
+  FROM fruits
+ WHERE items &? 'apple OR banana'
+ ORDER BY id;
+ id |       items        
+----+--------------------
+  1 | {"name": "apple"}
+  2 | {"type": "apple"}
+  4 | {"like": "banana"}
+(3 rows)
+
+DROP TABLE fruits;

  Added: expected/jsonb/query-v2/value/indexscan.out (+38 -0) 100644
===================================================================
--- /dev/null
+++ expected/jsonb/query-v2/value/indexscan.out    2017-05-08 20:19:05 +0900 (1a6ec71)
@@ -0,0 +1,38 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+INSERT INTO fruits VALUES (1, '{"name": "apple"}');
+INSERT INTO fruits VALUES (2, '{"type": "apple"}');
+INSERT INTO fruits VALUES (3, '{"name": "peach"}');
+INSERT INTO fruits VALUES (4, '{"like": "banana"}');
+CREATE INDEX pgroonga_index ON fruits
+  USING pgroonga (items pgroonga.jsonb_ops_v2);
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+EXPLAIN (COSTS OFF)
+SELECT id, items
+  FROM fruits
+ WHERE items &? 'apple OR banana'
+ ORDER BY id;
+                       QUERY PLAN                       
+--------------------------------------------------------
+ Sort
+   Sort Key: id
+   ->  Index Scan using pgroonga_index on fruits
+         Index Cond: (items &? 'apple OR banana'::text)
+(4 rows)
+
+SELECT id, items
+  FROM fruits
+ WHERE items &? 'apple OR banana'
+ ORDER BY id;
+ id |       items        
+----+--------------------
+  1 | {"name": "apple"}
+  2 | {"type": "apple"}
+  4 | {"like": "banana"}
+(3 rows)
+
+DROP TABLE fruits;

  Added: expected/jsonb/query-v2/value/seqscan.out (+23 -0) 100644
===================================================================
--- /dev/null
+++ expected/jsonb/query-v2/value/seqscan.out    2017-05-08 20:19:05 +0900 (2cab725)
@@ -0,0 +1,23 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+INSERT INTO fruits VALUES (1, '{"name": "apple"}');
+INSERT INTO fruits VALUES (2, '{"type": "apple"}');
+INSERT INTO fruits VALUES (3, '{"name": "peach"}');
+INSERT INTO fruits VALUES (4, '{"like": "banana"}');
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+SELECT id, items
+  FROM fruits
+ WHERE items &? 'apple OR banana'
+ ORDER BY id;
+ id |       items        
+----+--------------------
+  1 | {"name": "apple"}
+  2 | {"type": "apple"}
+  4 | {"like": "banana"}
+(3 rows)
+
+DROP TABLE fruits;

  Added: sql/jsonb/match-v2/element/bitmapscan.sql (+28 -0) 100644
===================================================================
--- /dev/null
+++ sql/jsonb/match-v2/element/bitmapscan.sql    2017-05-08 20:19:05 +0900 (9f9ba58)
@@ -0,0 +1,28 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+
+INSERT INTO fruits VALUES (1, '["apple"]');
+INSERT INTO fruits VALUES (2, '["banana", "apple"]');
+INSERT INTO fruits VALUES (3, '["peach"]');
+
+CREATE INDEX pgroonga_index ON fruits
+  USING pgroonga (items pgroonga.jsonb_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+
+EXPLAIN (COSTS OFF)
+SELECT id, items
+  FROM fruits
+ WHERE items &@ 'app'
+ ORDER BY id;
+
+SELECT id, items
+  FROM fruits
+ WHERE items &@ 'app'
+ ORDER BY id;
+
+DROP TABLE fruits;

  Added: sql/jsonb/match-v2/element/indexscan.sql (+28 -0) 100644
===================================================================
--- /dev/null
+++ sql/jsonb/match-v2/element/indexscan.sql    2017-05-08 20:19:05 +0900 (59881a9)
@@ -0,0 +1,28 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+
+INSERT INTO fruits VALUES (1, '["apple"]');
+INSERT INTO fruits VALUES (2, '["banana", "apple"]');
+INSERT INTO fruits VALUES (3, '["peach"]');
+
+CREATE INDEX pgroonga_index ON fruits
+  USING pgroonga (items pgroonga.jsonb_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+
+EXPLAIN (COSTS OFF)
+SELECT id, items
+  FROM fruits
+ WHERE items &@ 'app'
+ ORDER BY id;
+
+SELECT id, items
+  FROM fruits
+ WHERE items &@ 'app'
+ ORDER BY id;
+
+DROP TABLE fruits;

  Added: sql/jsonb/match-v2/element/seqscan.sql (+19 -0) 100644
===================================================================
--- /dev/null
+++ sql/jsonb/match-v2/element/seqscan.sql    2017-05-08 20:19:05 +0900 (4cd4b99)
@@ -0,0 +1,19 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+
+INSERT INTO fruits VALUES (1, '["apple"]');
+INSERT INTO fruits VALUES (2, '["banana", "apple"]');
+INSERT INTO fruits VALUES (3, '["peach"]');
+
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+
+SELECT id, items
+  FROM fruits
+ WHERE items &@ 'app'
+ ORDER BY id;
+
+DROP TABLE fruits;

  Added: sql/jsonb/match-v2/value/bitmapscan.sql (+28 -0) 100644
===================================================================
--- /dev/null
+++ sql/jsonb/match-v2/value/bitmapscan.sql    2017-05-08 20:19:05 +0900 (2da4383)
@@ -0,0 +1,28 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+
+INSERT INTO fruits VALUES (1, '{"name": "apple"}');
+INSERT INTO fruits VALUES (2, '{"type": "apple"}');
+INSERT INTO fruits VALUES (3, '{"name": "peach"}');
+
+CREATE INDEX pgroonga_index ON fruits
+  USING pgroonga (items pgroonga.jsonb_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+
+EXPLAIN (COSTS OFF)
+SELECT id, items
+  FROM fruits
+ WHERE items &@ 'app'
+ ORDER BY id;
+
+SELECT id, items
+  FROM fruits
+ WHERE items &@ 'app'
+ ORDER BY id;
+
+DROP TABLE fruits;

  Added: sql/jsonb/match-v2/value/indexscan.sql (+28 -0) 100644
===================================================================
--- /dev/null
+++ sql/jsonb/match-v2/value/indexscan.sql    2017-05-08 20:19:05 +0900 (e0d672c)
@@ -0,0 +1,28 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+
+INSERT INTO fruits VALUES (1, '{"name": "apple"}');
+INSERT INTO fruits VALUES (2, '{"type": "apple"}');
+INSERT INTO fruits VALUES (3, '{"name": "peach"}');
+
+CREATE INDEX pgroonga_index ON fruits
+  USING pgroonga (items pgroonga.jsonb_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+
+EXPLAIN (COSTS OFF)
+SELECT id, items
+  FROM fruits
+ WHERE items &@ 'app'
+ ORDER BY id;
+
+SELECT id, items
+  FROM fruits
+ WHERE items &@ 'app'
+ ORDER BY id;
+
+DROP TABLE fruits;

  Added: sql/jsonb/match-v2/value/seqscan.sql (+19 -0) 100644
===================================================================
--- /dev/null
+++ sql/jsonb/match-v2/value/seqscan.sql    2017-05-08 20:19:05 +0900 (258cdbd)
@@ -0,0 +1,19 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+
+INSERT INTO fruits VALUES (1, '{"name": "apple"}');
+INSERT INTO fruits VALUES (2, '{"type": "apple"}');
+INSERT INTO fruits VALUES (3, '{"name": "peach"}');
+
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+
+SELECT id, items
+  FROM fruits
+ WHERE items &@ 'app'
+ ORDER BY id;
+
+DROP TABLE fruits;

  Added: sql/jsonb/query-v2/element/bitmapscan.sql (+28 -0) 100644
===================================================================
--- /dev/null
+++ sql/jsonb/query-v2/element/bitmapscan.sql    2017-05-08 20:19:05 +0900 (086addd)
@@ -0,0 +1,28 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+
+INSERT INTO fruits VALUES (1, '["apple"]');
+INSERT INTO fruits VALUES (2, '["banana", "apple"]');
+INSERT INTO fruits VALUES (3, '["peach"]');
+
+CREATE INDEX pgroonga_index ON fruits
+  USING pgroonga (items pgroonga.jsonb_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+
+EXPLAIN (COSTS OFF)
+SELECT id, items
+  FROM fruits
+ WHERE items &? 'banana OR peach'
+ ORDER BY id;
+
+SELECT id, items
+  FROM fruits
+ WHERE items &? 'banana OR peach'
+ ORDER BY id;
+
+DROP TABLE fruits;

  Added: sql/jsonb/query-v2/element/indexscan.sql (+28 -0) 100644
===================================================================
--- /dev/null
+++ sql/jsonb/query-v2/element/indexscan.sql    2017-05-08 20:19:05 +0900 (f049788)
@@ -0,0 +1,28 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+
+INSERT INTO fruits VALUES (1, '["apple"]');
+INSERT INTO fruits VALUES (2, '["banana", "apple"]');
+INSERT INTO fruits VALUES (3, '["peach"]');
+
+CREATE INDEX pgroonga_index ON fruits
+  USING pgroonga (items pgroonga.jsonb_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+
+EXPLAIN (COSTS OFF)
+SELECT id, items
+  FROM fruits
+ WHERE items &? 'banana OR peach'
+ ORDER BY id;
+
+SELECT id, items
+  FROM fruits
+ WHERE items &? 'banana OR peach'
+ ORDER BY id;
+
+DROP TABLE fruits;

  Added: sql/jsonb/query-v2/element/seqscan.sql (+19 -0) 100644
===================================================================
--- /dev/null
+++ sql/jsonb/query-v2/element/seqscan.sql    2017-05-08 20:19:05 +0900 (50f0642)
@@ -0,0 +1,19 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+
+INSERT INTO fruits VALUES (1, '["apple"]');
+INSERT INTO fruits VALUES (2, '["banana", "apple"]');
+INSERT INTO fruits VALUES (3, '["peach"]');
+
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+
+SELECT id, items
+  FROM fruits
+ WHERE items &? 'banana OR peach'
+ ORDER BY id;
+
+DROP TABLE fruits;

  Added: sql/jsonb/query-v2/value/bitmapscan.sql (+29 -0) 100644
===================================================================
--- /dev/null
+++ sql/jsonb/query-v2/value/bitmapscan.sql    2017-05-08 20:19:05 +0900 (bb950de)
@@ -0,0 +1,29 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+
+INSERT INTO fruits VALUES (1, '{"name": "apple"}');
+INSERT INTO fruits VALUES (2, '{"type": "apple"}');
+INSERT INTO fruits VALUES (3, '{"name": "peach"}');
+INSERT INTO fruits VALUES (4, '{"like": "banana"}');
+
+CREATE INDEX pgroonga_index ON fruits
+  USING pgroonga (items pgroonga.jsonb_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = off;
+SET enable_bitmapscan = on;
+
+EXPLAIN (COSTS OFF)
+SELECT id, items
+  FROM fruits
+ WHERE items &? 'apple OR banana'
+ ORDER BY id;
+
+SELECT id, items
+  FROM fruits
+ WHERE items &? 'apple OR banana'
+ ORDER BY id;
+
+DROP TABLE fruits;

  Added: sql/jsonb/query-v2/value/indexscan.sql (+29 -0) 100644
===================================================================
--- /dev/null
+++ sql/jsonb/query-v2/value/indexscan.sql    2017-05-08 20:19:05 +0900 (80e5123)
@@ -0,0 +1,29 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+
+INSERT INTO fruits VALUES (1, '{"name": "apple"}');
+INSERT INTO fruits VALUES (2, '{"type": "apple"}');
+INSERT INTO fruits VALUES (3, '{"name": "peach"}');
+INSERT INTO fruits VALUES (4, '{"like": "banana"}');
+
+CREATE INDEX pgroonga_index ON fruits
+  USING pgroonga (items pgroonga.jsonb_ops_v2);
+
+SET enable_seqscan = off;
+SET enable_indexscan = on;
+SET enable_bitmapscan = off;
+
+EXPLAIN (COSTS OFF)
+SELECT id, items
+  FROM fruits
+ WHERE items &? 'apple OR banana'
+ ORDER BY id;
+
+SELECT id, items
+  FROM fruits
+ WHERE items &? 'apple OR banana'
+ ORDER BY id;
+
+DROP TABLE fruits;

  Added: sql/jsonb/query-v2/value/seqscan.sql (+20 -0) 100644
===================================================================
--- /dev/null
+++ sql/jsonb/query-v2/value/seqscan.sql    2017-05-08 20:19:05 +0900 (4d277ab)
@@ -0,0 +1,20 @@
+CREATE TABLE fruits (
+  id int,
+  items jsonb
+);
+
+INSERT INTO fruits VALUES (1, '{"name": "apple"}');
+INSERT INTO fruits VALUES (2, '{"type": "apple"}');
+INSERT INTO fruits VALUES (3, '{"name": "peach"}');
+INSERT INTO fruits VALUES (4, '{"like": "banana"}');
+
+SET enable_seqscan = on;
+SET enable_indexscan = off;
+SET enable_bitmapscan = off;
+
+SELECT id, items
+  FROM fruits
+ WHERE items &? 'apple OR banana'
+ ORDER BY id;
+
+DROP TABLE fruits;

  Modified: src/pgrn-jsonb.c (+229 -46)
===================================================================
--- src/pgrn-jsonb.c    2017-05-08 18:49:51 +0900 (b177bfa)
+++ src/pgrn-jsonb.c    2017-05-08 20:19:05 +0900 (66e7a05)
@@ -19,10 +19,14 @@
 
 #include <xxhash.h>
 
+#include <string.h>
+
 #ifdef PGRN_SUPPORT_JSONB
-PGRN_FUNCTION_INFO_V1(pgroonga_match_jsonb);
+PGRN_FUNCTION_INFO_V1(pgroonga_match_script_jsonb);
 
 /* v2 */
+PGRN_FUNCTION_INFO_V1(pgroonga_match_jsonb);
+PGRN_FUNCTION_INFO_V1(pgroonga_query_jsonb);
 PGRN_FUNCTION_INFO_V1(pgroonga_script_jsonb);
 #endif
 
@@ -1041,17 +1045,27 @@ PGrnJSONBDeleteValues(grn_obj *valuesTable, grn_obj *valueIDs)
 }
 
 static bool
-pgroonga_script_jsonb_raw(Jsonb *target,
-						  const char *script, unsigned int scriptSize)
+PGrnJSONBMatchExpression(Jsonb *target,
+						 const char *term,
+						 unsigned int termSize,
+						 const char *query,
+						 unsigned int querySize,
+						 const char *script,
+						 unsigned int scriptSize,
+						 const char *logTag)
 {
 	grn_obj valueIDs;
 	PGrnJSONBInsertData data;
 	JsonbIterator *iter;
-	grn_obj *filter = NULL;
-	grn_obj *dummy_variable = NULL;
+	grn_obj *matchTarget = NULL;
+	grn_obj *condition = NULL;
+	grn_obj *dummyVariable = NULL;
 	grn_obj *result = NULL;
 	bool matched = false;
 
+	if (termSize == 0 && querySize == 0 && scriptSize == 0)
+		return false;
+
 	data.index = NULL;
 	data.pathsTable  = tmpPathsTable;
 	data.valuesTable = tmpValuesTable;
@@ -1064,28 +1078,81 @@ pgroonga_script_jsonb_raw(Jsonb *target,
 
 	PG_TRY();
 	{
-		GRN_EXPR_CREATE_FOR_QUERY(ctx, tmpValuesTable, filter, dummy_variable);
-		PGrnCheck("jsonb_script: failed to create expression object");
-		grn_expr_parse(ctx, filter,
-					   script, scriptSize,
-					   NULL, GRN_OP_MATCH, GRN_OP_AND,
-					   GRN_EXPR_SYNTAX_SCRIPT);
-		PGrnCheck("jsonb_script: failed to parse script: <%.*s>",
-				  (int)scriptSize,
-				  script);
+		GRN_EXPR_CREATE_FOR_QUERY(ctx, tmpValuesTable, condition, dummyVariable);
+		PGrnCheck("jsonb: %s: failed to create condition expression object",
+				  logTag);
+		if (termSize > 0)
+		{
+			const char *targetName = "string";
+			grn_obj *column;
+
+			column = grn_obj_column(ctx,
+									tmpValuesTable,
+									targetName,
+									strlen(targetName));
+			grn_expr_append_obj(ctx, condition, column, GRN_OP_GET_VALUE, 1);
+			grn_expr_append_const_str(ctx, condition,
+									  term, termSize,
+									  GRN_OP_PUSH, 1);
+			grn_expr_append_op(ctx, condition, GRN_OP_MATCH, 2);
+		}
+		else if (querySize > 0)
+		{
+			const char *matchColumns = "string";
+
+			GRN_EXPR_CREATE_FOR_QUERY(ctx,
+									  tmpValuesTable,
+									  matchTarget,
+									  dummyVariable);
+			PGrnCheck("jsonb: %s: "
+					  "failed to create match target expression object",
+					  logTag);
+			grn_expr_parse(ctx, matchTarget,
+						   matchColumns,
+						   strlen(matchColumns),
+						   NULL, GRN_OP_MATCH, GRN_OP_AND,
+						   GRN_EXPR_SYNTAX_SCRIPT);
+			PGrnCheck("jsonb: %s: failed to parse match columns: <%.*s>",
+					  logTag,
+					  (int)strlen(matchColumns),
+					  matchColumns);
+			grn_expr_parse(ctx, condition,
+						   query, querySize,
+						   matchTarget, GRN_OP_MATCH, GRN_OP_AND,
+						   GRN_EXPR_SYNTAX_QUERY);
+			PGrnCheck("jsonb: %s: failed to parse query: <%.*s>",
+					  logTag,
+					  (int)querySize,
+					  query);
+		}
+		else if (scriptSize > 0)
+		{
+			grn_expr_parse(ctx, condition,
+						   script, scriptSize,
+						   NULL, GRN_OP_MATCH, GRN_OP_AND,
+						   GRN_EXPR_SYNTAX_SCRIPT);
+			PGrnCheck("jsonb: %s: failed to parse script: <%.*s>",
+					  logTag,
+					  (int)scriptSize,
+					  script);
+		}
 		result = grn_table_create(ctx, NULL, 0, NULL,
 								  GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC,
 								  tmpValuesTable, NULL);
-		PGrnCheck("jsonb_script: failed to create result table");
-		grn_table_select(ctx, tmpValuesTable, filter, result, GRN_OP_OR);
-		PGrnCheck("jsonb_script: failed to select");
+		PGrnCheck("jsonb: %s: failed to create result table",
+				  logTag);
+		grn_table_select(ctx, tmpValuesTable, condition, result, GRN_OP_OR);
+		PGrnCheck("jsonb: %s: failed to select",
+				  logTag);
 	}
 	PG_CATCH();
 	{
 		if (result)
 			grn_obj_close(ctx, result);
-		if (filter)
-			grn_obj_close(ctx, filter);
+		if (condition)
+			grn_obj_close(ctx, condition);
+		if (matchTarget)
+			grn_obj_close(ctx, matchTarget);
 		PGrnJSONBDeleteValues(tmpValuesTable, &valueIDs);
 		GRN_OBJ_FIN(ctx, &valueIDs);
 		PG_RE_THROW();
@@ -1094,8 +1161,10 @@ pgroonga_script_jsonb_raw(Jsonb *target,
 
 	matched = grn_table_size(ctx, result) > 0;
 
-	grn_obj_close(ctx, filter);
 	grn_obj_close(ctx, result);
+	grn_obj_close(ctx, condition);
+	if (matchTarget)
+		grn_obj_close(ctx, matchTarget);
 
 	PGrnJSONBDeleteValues(tmpValuesTable, &valueIDs);
 	GRN_OBJ_FIN(ctx, &valueIDs);
@@ -1104,18 +1173,59 @@ pgroonga_script_jsonb_raw(Jsonb *target,
 }
 
 /**
- * pgroonga.match_jsonb(jsonb, query) : bool
+ * pgroonga.match_script_jsonb(jsonb, query) : bool
  */
 Datum
-pgroonga_match_jsonb(PG_FUNCTION_ARGS)
+pgroonga_match_script_jsonb(PG_FUNCTION_ARGS)
 {
-	Jsonb *jsonb = PG_GETARG_JSONB(0);
+	Jsonb *target = PG_GETARG_JSONB(0);
 	text *script = PG_GETARG_TEXT_PP(1);
 	bool matched;
 
-	matched = pgroonga_script_jsonb_raw(jsonb,
-										VARDATA_ANY(script),
-										VARSIZE_ANY_EXHDR(script));
+	matched = PGrnJSONBMatchExpression(target,
+									   NULL, 0,
+									   NULL, 0,
+									   VARDATA_ANY(script),
+									   VARSIZE_ANY_EXHDR(script),
+									   "script");
+	PG_RETURN_BOOL(matched);
+}
+
+/**
+ * pgroonga.match_jsonb(target jsonb, term text) : bool
+ */
+Datum
+pgroonga_match_jsonb(PG_FUNCTION_ARGS)
+{
+	Jsonb *target = PG_GETARG_JSONB(0);
+	text *term = PG_GETARG_TEXT_PP(1);
+	bool matched;
+
+	matched = PGrnJSONBMatchExpression(target,
+									   VARDATA_ANY(term),
+									   VARSIZE_ANY_EXHDR(term),
+									   NULL, 0,
+									   NULL, 0,
+									   "match");
+	PG_RETURN_BOOL(matched);
+}
+
+/**
+ * pgroonga.query_jsonb(target jsonb, query text) : bool
+ */
+Datum
+pgroonga_query_jsonb(PG_FUNCTION_ARGS)
+{
+	Jsonb *target = PG_GETARG_JSONB(0);
+	text *query = PG_GETARG_TEXT_PP(1);
+	bool matched;
+
+	matched = PGrnJSONBMatchExpression(target,
+									   NULL, 0,
+									   VARDATA_ANY(query),
+									   VARSIZE_ANY_EXHDR(query),
+									   NULL, 0,
+									   "query");
 	PG_RETURN_BOOL(matched);
 }
 
@@ -1125,13 +1235,16 @@ pgroonga_match_jsonb(PG_FUNCTION_ARGS)
 Datum
 pgroonga_script_jsonb(PG_FUNCTION_ARGS)
 {
-	Jsonb *jsonb = PG_GETARG_JSONB(0);
+	Jsonb *target = PG_GETARG_JSONB(0);
 	text *script = PG_GETARG_TEXT_PP(1);
 	bool matched;
 
-	matched = pgroonga_script_jsonb_raw(jsonb,
-										VARDATA_ANY(script),
-										VARSIZE_ANY_EXHDR(script));
+	matched = PGrnJSONBMatchExpression(target,
+									   NULL, 0,
+									   NULL, 0,
+									   VARDATA_ANY(script),
+									   VARSIZE_ANY_EXHDR(script),
+									   "script");
 	PG_RETURN_BOOL(matched);
 }
 
@@ -1242,11 +1355,11 @@ PGrnJSONBInsert(Relation index,
 
 #ifdef PGRN_SUPPORT_JSONB
 static void
-PGrnSearchBuildConditionJSONQuery(PGrnSearchData *data,
-								  grn_obj *subFilter,
-								  grn_obj *targetColumn,
-								  grn_obj *filter,
-								  unsigned int *nthCondition)
+PGrnSearchBuildConditionJSONScript(PGrnSearchData *data,
+								   grn_obj *subFilter,
+								   grn_obj *targetColumn,
+								   grn_obj *filter,
+								   unsigned int *nthCondition)
 {
 	grn_expr_append_obj(ctx, data->expression,
 						subFilter, GRN_OP_PUSH, 1);
@@ -1263,6 +1376,51 @@ PGrnSearchBuildConditionJSONQuery(PGrnSearchData *data,
 }
 
 static void
+PGrnSearchBuildConditionJSONMatch(PGrnSearchData *data,
+								  grn_obj *subFilter,
+								  grn_obj *targetColumn,
+								  grn_obj *term)
+{
+	unsigned int nthCondition = 0;
+
+	GRN_BULK_REWIND(&(buffers->general));
+
+	GRN_TEXT_PUTS(ctx, &(buffers->general), "string @ ");
+	grn_text_esc(ctx, &(buffers->general),
+				 GRN_TEXT_VALUE(term),
+				 GRN_TEXT_LEN(term));
+
+	PGrnSearchBuildConditionJSONScript(data,
+									   subFilter,
+									   targetColumn,
+									   &(buffers->general),
+									   &nthCondition);
+}
+
+static void
+PGrnSearchBuildConditionJSONQuery(PGrnSearchData *data,
+								  grn_obj *subFilter,
+								  grn_obj *targetColumn,
+								  grn_obj *query)
+{
+	unsigned int nthCondition = 0;
+
+	GRN_BULK_REWIND(&(buffers->general));
+
+	GRN_TEXT_PUTS(ctx, &(buffers->general), "query(\"string\", ");
+	grn_text_esc(ctx, &(buffers->general),
+				 GRN_TEXT_VALUE(query),
+				 GRN_TEXT_LEN(query));
+	GRN_TEXT_PUTS(ctx, &(buffers->general), ")");
+
+	PGrnSearchBuildConditionJSONScript(data,
+									   subFilter,
+									   targetColumn,
+									   &(buffers->general),
+									   &nthCondition);
+}
+
+static void
 PGrnSearchBuildConditionJSONContainType(PGrnSearchData *data,
 										grn_obj *subFilter,
 										grn_obj *targetColumn,
@@ -1282,8 +1440,8 @@ PGrnSearchBuildConditionJSONContainType(PGrnSearchData *data,
 				 GRN_TEXT_VALUE(&(buffers->path)),
 				 GRN_TEXT_LEN(&(buffers->path)));
 
-	PGrnSearchBuildConditionJSONQuery(data, subFilter, targetColumn,
-									  &(buffers->general), nthCondition);
+	PGrnSearchBuildConditionJSONScript(data, subFilter, targetColumn,
+									   &(buffers->general), nthCondition);
 }
 
 static void
@@ -1342,8 +1500,8 @@ PGrnSearchBuildConditionJSONContainValue(PGrnSearchData *data,
 				 GRN_TEXT_VALUE(&(buffers->path)),
 				 GRN_TEXT_LEN(&(buffers->path)));
 
-	PGrnSearchBuildConditionJSONQuery(data, subFilter, targetColumn,
-									  &(buffers->general), nthCondition);
+	PGrnSearchBuildConditionJSONScript(data, subFilter, targetColumn,
+									   &(buffers->general), nthCondition);
 }
 
 static void
@@ -1448,23 +1606,48 @@ PGrnJSONBBuildSearchCondition(PGrnSearchData *data,
 	subFilter = PGrnLookup("sub_filter", ERROR);
 	grn_obj_reinit(ctx, &(buffers->general), GRN_DB_TEXT, 0);
 
-	if (key->sk_strategy == PGrnQueryStrategyNumber ||
-		key->sk_strategy == PGrnScriptStrategyV2Number)
+	switch (key->sk_strategy)
+	{
+	case PGrnQueryStrategyNumber: /* For backward compatibility */
+	case PGrnScriptStrategyV2Number:
 	{
 		unsigned int nthCondition = 0;
 		PGrnConvertFromData(key->sk_argument, TEXTOID, &(buffers->general));
+		PGrnSearchBuildConditionJSONScript(data,
+										   subFilter,
+										   targetColumn,
+										   &(buffers->general),
+										   &nthCondition);
+		break;
+	}
+	case PGrnMatchStrategyV2Number:
+		grn_obj_reinit(ctx, &(buffers->keyword), GRN_DB_TEXT, 0);
+		PGrnConvertFromData(key->sk_argument, TEXTOID, &(buffers->keyword));
+		PGrnSearchBuildConditionJSONMatch(data,
+										  subFilter,
+										  targetColumn,
+										  &(buffers->keyword));
+		break;
+	case PGrnQueryStrategyV2Number:
+		grn_obj_reinit(ctx, &(buffers->keyword), GRN_DB_TEXT, 0);
+		PGrnConvertFromData(key->sk_argument, TEXTOID, &(buffers->keyword));
 		PGrnSearchBuildConditionJSONQuery(data,
 										  subFilter,
 										  targetColumn,
-										  &(buffers->general),
-										  &nthCondition);
-	}
-	else
-	{
+										  &(buffers->keyword));
+		break;
+	case PGrnJSONContainStrategyNumber:
 		PGrnSearchBuildConditionJSONContain(data,
 											subFilter,
 											targetColumn,
 											DatumGetJsonb(key->sk_argument));
+		break;
+	default:
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+				 errmsg("pgroonga: jsonb: unsupported strategy number: %d",
+						key->sk_strategy)));
+		break;
 	}
 	return true;
 #else
-------------- next part --------------
HTML����������������������������...
下载 



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