Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
-- Strings.
SELECT ' "" ' : : jsonb ; -- OK.
SELECT $ $ ' ' $ $ : : jsonb ; -- ERROR, single quotes are not allowed
SELECT ' "abc" ' : : jsonb ; -- OK
SELECT ' "abc ' : : jsonb ; -- ERROR, quotes not closed
SELECT ' "abc
def " '::jsonb; -- ERROR, unescaped newline in string constant
SELECT ' "\n\"\\" ' : : jsonb ; -- OK, legal escapes
SELECT ' "\v" ' : : jsonb ; -- ERROR, not a valid JSON escape
SELECT ' "\u" ' : : jsonb ; -- ERROR, incomplete escape
SELECT ' "\u00" ' : : jsonb ; -- ERROR, incomplete escape
SELECT ' "\u000g" ' : : jsonb ; -- ERROR, g is not a hex digit
SELECT ' "\u0000" ' : : jsonb ; -- OK, legal escape
-- use octet_length here so we don't get an odd unicode char in the
-- output
SELECT octet_length ( ' "\uaBcD" ' : : jsonb : : text ) ; -- OK, uppercase and lower case both OK
-- Numbers.
SELECT ' 1 ' : : jsonb ; -- OK
SELECT ' 0 ' : : jsonb ; -- OK
SELECT ' 01 ' : : jsonb ; -- ERROR, not valid according to JSON spec
SELECT ' 0.1 ' : : jsonb ; -- OK
SELECT ' 9223372036854775808 ' : : jsonb ; -- OK, even though it's too large for int8
SELECT ' 1e100 ' : : jsonb ; -- OK
SELECT ' 1.3e100 ' : : jsonb ; -- OK
SELECT ' 1f2 ' : : jsonb ; -- ERROR
SELECT ' 0.x1 ' : : jsonb ; -- ERROR
SELECT ' 1.3ex100 ' : : jsonb ; -- ERROR
-- Arrays.
SELECT ' [] ' : : jsonb ; -- OK
SELECT ' [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] ' : : jsonb ; -- OK
SELECT ' [1,2] ' : : jsonb ; -- OK
SELECT ' [1,2,] ' : : jsonb ; -- ERROR, trailing comma
SELECT ' [1,2 ' : : jsonb ; -- ERROR, no closing bracket
SELECT ' [1,[2] ' : : jsonb ; -- ERROR, no closing bracket
-- Objects.
SELECT ' {} ' : : jsonb ; -- OK
SELECT ' {"abc"} ' : : jsonb ; -- ERROR, no value
SELECT ' {"abc":1} ' : : jsonb ; -- OK
SELECT ' {1:"abc"} ' : : jsonb ; -- ERROR, keys must be strings
SELECT ' {"abc",1} ' : : jsonb ; -- ERROR, wrong separator
SELECT ' {"abc"=1} ' : : jsonb ; -- ERROR, totally wrong separator
SELECT ' {"abc"::1} ' : : jsonb ; -- ERROR, another wrong separator
SELECT ' {"abc":1,"def":2,"ghi":[3,4],"hij":{"klm":5,"nop":[6]}} ' : : jsonb ; -- OK
SELECT ' {"abc":1:2} ' : : jsonb ; -- ERROR, colon in wrong spot
SELECT ' {"abc":1,3} ' : : jsonb ; -- ERROR, no value
-- Miscellaneous stuff.
SELECT ' true ' : : jsonb ; -- OK
SELECT ' false ' : : jsonb ; -- OK
SELECT ' null ' : : jsonb ; -- OK
SELECT ' true ' : : jsonb ; -- OK, even with extra whitespace
SELECT ' true false ' : : jsonb ; -- ERROR, too many values
SELECT ' true, false ' : : jsonb ; -- ERROR, too many values
SELECT ' truf ' : : jsonb ; -- ERROR, not a keyword
SELECT ' trues ' : : jsonb ; -- ERROR, not a keyword
SELECT ' ' : : jsonb ; -- ERROR, no value
SELECT ' ' : : jsonb ; -- ERROR, no value
-- make sure jsonb is passed through json generators without being escaped
SELECT array_to_json ( ARRAY [ jsonb ' {"a":1} ' , jsonb ' {"b":[2,3]} ' ] ) ;
-- jsonb extraction functions
CREATE TEMP TABLE test_jsonb (
json_type text ,
test_json jsonb
) ;
INSERT INTO test_jsonb VALUES
( ' scalar ' , ' "a scalar" ' ) ,
( ' array ' , ' ["zero", "one","two",null,"four","five", [1,2,3],{"f1":9}] ' ) ,
( ' object ' , ' {"field1":"val1","field2":"val2","field3":null, "field4": 4, "field5": [1,2,3], "field6": {"f1":9}} ' ) ;
SELECT test_json - > ' x ' FROM test_jsonb WHERE json_type = ' scalar ' ;
SELECT test_json - > ' x ' FROM test_jsonb WHERE json_type = ' array ' ;
SELECT test_json - > ' x ' FROM test_jsonb WHERE json_type = ' object ' ;
SELECT test_json - > ' field2 ' FROM test_jsonb WHERE json_type = ' object ' ;
SELECT test_json - > > ' field2 ' FROM test_jsonb WHERE json_type = ' scalar ' ;
SELECT test_json - > > ' field2 ' FROM test_jsonb WHERE json_type = ' array ' ;
SELECT test_json - > > ' field2 ' FROM test_jsonb WHERE json_type = ' object ' ;
SELECT test_json - > 2 FROM test_jsonb WHERE json_type = ' scalar ' ;
SELECT test_json - > 2 FROM test_jsonb WHERE json_type = ' array ' ;
SELECT test_json - > 9 FROM test_jsonb WHERE json_type = ' array ' ;
SELECT test_json - > 2 FROM test_jsonb WHERE json_type = ' object ' ;
SELECT test_json - > > 6 FROM test_jsonb WHERE json_type = ' array ' ;
SELECT test_json - > > 7 FROM test_jsonb WHERE json_type = ' array ' ;
SELECT test_json - > > ' field4 ' FROM test_jsonb WHERE json_type = ' object ' ;
SELECT test_json - > > ' field5 ' FROM test_jsonb WHERE json_type = ' object ' ;
SELECT test_json - > > ' field6 ' FROM test_jsonb WHERE json_type = ' object ' ;
SELECT test_json - > > 2 FROM test_jsonb WHERE json_type = ' scalar ' ;
SELECT test_json - > > 2 FROM test_jsonb WHERE json_type = ' array ' ;
SELECT test_json - > > 2 FROM test_jsonb WHERE json_type = ' object ' ;
SELECT jsonb_object_keys ( test_json ) FROM test_jsonb WHERE json_type = ' scalar ' ;
SELECT jsonb_object_keys ( test_json ) FROM test_jsonb WHERE json_type = ' array ' ;
SELECT jsonb_object_keys ( test_json ) FROM test_jsonb WHERE json_type = ' object ' ;
-- nulls
SELECT ( test_json - > ' field3 ' ) IS NULL AS expect_false FROM test_jsonb WHERE json_type = ' object ' ;
SELECT ( test_json - > > ' field3 ' ) IS NULL AS expect_true FROM test_jsonb WHERE json_type = ' object ' ;
SELECT ( test_json - > 3 ) IS NULL AS expect_false FROM test_jsonb WHERE json_type = ' array ' ;
SELECT ( test_json - > > 3 ) IS NULL AS expect_true FROM test_jsonb WHERE json_type = ' array ' ;
2014-08-20 22:48:35 +02:00
-- corner cases
select ' {"a": [{"b": "c"}, {"b": "cc"}]} ' : : jsonb - > null : : text ;
select ' {"a": [{"b": "c"}, {"b": "cc"}]} ' : : jsonb - > null : : int ;
select ' {"a": [{"b": "c"}, {"b": "cc"}]} ' : : jsonb - > 1 ;
select ' {"a": [{"b": "c"}, {"b": "cc"}]} ' : : jsonb - > ' z ' ;
2014-08-21 01:05:05 +02:00
select ' {"a": [{"b": "c"}, {"b": "cc"}]} ' : : jsonb - > ' ' ;
2014-08-20 22:48:35 +02:00
select ' [{"b": "c"}, {"b": "cc"}] ' : : jsonb - > 1 ;
select ' [{"b": "c"}, {"b": "cc"}] ' : : jsonb - > 3 ;
select ' [{"b": "c"}, {"b": "cc"}] ' : : jsonb - > ' z ' ;
2014-08-22 19:17:58 +02:00
select ' {"a": "c", "b": null} ' : : jsonb - > ' b ' ;
2014-08-20 22:48:35 +02:00
select ' "foo" ' : : jsonb - > 1 ;
select ' "foo" ' : : jsonb - > ' z ' ;
2014-08-21 01:05:05 +02:00
select ' {"a": [{"b": "c"}, {"b": "cc"}]} ' : : jsonb - > > null : : text ;
select ' {"a": [{"b": "c"}, {"b": "cc"}]} ' : : jsonb - > > null : : int ;
select ' {"a": [{"b": "c"}, {"b": "cc"}]} ' : : jsonb - > > 1 ;
select ' {"a": [{"b": "c"}, {"b": "cc"}]} ' : : jsonb - > > ' z ' ;
select ' {"a": [{"b": "c"}, {"b": "cc"}]} ' : : jsonb - > > ' ' ;
select ' [{"b": "c"}, {"b": "cc"}] ' : : jsonb - > > 1 ;
select ' [{"b": "c"}, {"b": "cc"}] ' : : jsonb - > > 3 ;
select ' [{"b": "c"}, {"b": "cc"}] ' : : jsonb - > > ' z ' ;
2014-08-22 19:17:58 +02:00
select ' {"a": "c", "b": null} ' : : jsonb - > > ' b ' ;
2014-08-21 01:05:05 +02:00
select ' "foo" ' : : jsonb - > > 1 ;
select ' "foo" ' : : jsonb - > > ' z ' ;
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
-- equality and inequality
SELECT ' {"x":"y"} ' : : jsonb = ' {"x":"y"} ' : : jsonb ;
SELECT ' {"x":"y"} ' : : jsonb = ' {"x":"z"} ' : : jsonb ;
SELECT ' {"x":"y"} ' : : jsonb < > ' {"x":"y"} ' : : jsonb ;
SELECT ' {"x":"y"} ' : : jsonb < > ' {"x":"z"} ' : : jsonb ;
-- containment
SELECT jsonb_contains ( ' {"a":"b", "b":1, "c":null} ' , ' {"a":"b"} ' ) ;
SELECT jsonb_contains ( ' {"a":"b", "b":1, "c":null} ' , ' {"a":"b", "c":null} ' ) ;
SELECT jsonb_contains ( ' {"a":"b", "b":1, "c":null} ' , ' {"a":"b", "g":null} ' ) ;
SELECT jsonb_contains ( ' {"a":"b", "b":1, "c":null} ' , ' {"g":null} ' ) ;
SELECT jsonb_contains ( ' {"a":"b", "b":1, "c":null} ' , ' {"a":"c"} ' ) ;
SELECT jsonb_contains ( ' {"a":"b", "b":1, "c":null} ' , ' {"a":"b"} ' ) ;
SELECT jsonb_contains ( ' {"a":"b", "b":1, "c":null} ' , ' {"a":"b", "c":"q"} ' ) ;
SELECT ' {"a":"b", "b":1, "c":null} ' : : jsonb @ > ' {"a":"b"} ' ;
SELECT ' {"a":"b", "b":1, "c":null} ' : : jsonb @ > ' {"a":"b", "c":null} ' ;
SELECT ' {"a":"b", "b":1, "c":null} ' : : jsonb @ > ' {"a":"b", "g":null} ' ;
SELECT ' {"a":"b", "b":1, "c":null} ' : : jsonb @ > ' {"g":null} ' ;
SELECT ' {"a":"b", "b":1, "c":null} ' : : jsonb @ > ' {"a":"c"} ' ;
SELECT ' {"a":"b", "b":1, "c":null} ' : : jsonb @ > ' {"a":"b"} ' ;
SELECT ' {"a":"b", "b":1, "c":null} ' : : jsonb @ > ' {"a":"b", "c":"q"} ' ;
SELECT jsonb_contained ( ' {"a":"b"} ' , ' {"a":"b", "b":1, "c":null} ' ) ;
SELECT jsonb_contained ( ' {"a":"b", "c":null} ' , ' {"a":"b", "b":1, "c":null} ' ) ;
SELECT jsonb_contained ( ' {"a":"b", "g":null} ' , ' {"a":"b", "b":1, "c":null} ' ) ;
SELECT jsonb_contained ( ' {"g":null} ' , ' {"a":"b", "b":1, "c":null} ' ) ;
SELECT jsonb_contained ( ' {"a":"c"} ' , ' {"a":"b", "b":1, "c":null} ' ) ;
SELECT jsonb_contained ( ' {"a":"b"} ' , ' {"a":"b", "b":1, "c":null} ' ) ;
SELECT jsonb_contained ( ' {"a":"b", "c":"q"} ' , ' {"a":"b", "b":1, "c":null} ' ) ;
SELECT ' {"a":"b"} ' : : jsonb < @ ' {"a":"b", "b":1, "c":null} ' ;
SELECT ' {"a":"b", "c":null} ' : : jsonb < @ ' {"a":"b", "b":1, "c":null} ' ;
SELECT ' {"a":"b", "g":null} ' : : jsonb < @ ' {"a":"b", "b":1, "c":null} ' ;
SELECT ' {"g":null} ' : : jsonb < @ ' {"a":"b", "b":1, "c":null} ' ;
SELECT ' {"a":"c"} ' : : jsonb < @ ' {"a":"b", "b":1, "c":null} ' ;
SELECT ' {"a":"b"} ' : : jsonb < @ ' {"a":"b", "b":1, "c":null} ' ;
SELECT ' {"a":"b", "c":"q"} ' : : jsonb < @ ' {"a":"b", "b":1, "c":null} ' ;
-- Raw scalar may contain another raw scalar, array may contain a raw scalar
SELECT ' [5] ' : : jsonb @ > ' [5] ' ;
SELECT ' 5 ' : : jsonb @ > ' 5 ' ;
SELECT ' [5] ' : : jsonb @ > ' 5 ' ;
-- But a raw scalar cannot contain an array
SELECT ' 5 ' : : jsonb @ > ' [5] ' ;
-- In general, one thing should always contain itself. Test array containment:
SELECT ' ["9", ["7", "3"], 1] ' : : jsonb @ > ' ["9", ["7", "3"], 1] ' : : jsonb ;
SELECT ' ["9", ["7", "3"], ["1"]] ' : : jsonb @ > ' ["9", ["7", "3"], ["1"]] ' : : jsonb ;
-- array containment string matching confusion bug
SELECT ' { "name": "Bob", "tags": [ "enim", "qui"]} ' : : jsonb @ > ' {"tags":["qu"]} ' ;
-- array length
SELECT jsonb_array_length ( ' [1,2,3,{"f1":1,"f2":[5,6]},4] ' ) ;
SELECT jsonb_array_length ( ' [] ' ) ;
SELECT jsonb_array_length ( ' {"f1":1,"f2":[5,6]} ' ) ;
SELECT jsonb_array_length ( ' 4 ' ) ;
-- each
SELECT jsonb_each ( ' {"f1":[1,2,3],"f2":{"f3":1},"f4":null} ' ) ;
SELECT jsonb_each ( ' {"a":{"b":"c","c":"b","1":"first"},"b":[1,2],"c":"cc","1":"first","n":null} ' : : jsonb ) AS q ;
SELECT * FROM jsonb_each ( ' {"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"} ' ) q ;
SELECT * FROM jsonb_each ( ' {"a":{"b":"c","c":"b","1":"first"},"b":[1,2],"c":"cc","1":"first","n":null} ' : : jsonb ) AS q ;
SELECT jsonb_each_text ( ' {"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":"null"} ' ) ;
SELECT jsonb_each_text ( ' {"a":{"b":"c","c":"b","1":"first"},"b":[1,2],"c":"cc","1":"first","n":null} ' : : jsonb ) AS q ;
SELECT * FROM jsonb_each_text ( ' {"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"} ' ) q ;
SELECT * FROM jsonb_each_text ( ' {"a":{"b":"c","c":"b","1":"first"},"b":[1,2],"c":"cc","1":"first","n":null} ' : : jsonb ) AS q ;
-- exists
SELECT jsonb_exists ( ' {"a":null, "b":"qq"} ' , ' a ' ) ;
SELECT jsonb_exists ( ' {"a":null, "b":"qq"} ' , ' b ' ) ;
SELECT jsonb_exists ( ' {"a":null, "b":"qq"} ' , ' c ' ) ;
SELECT jsonb_exists ( ' {"a":"null", "b":"qq"} ' , ' a ' ) ;
SELECT jsonb ' {"a":null, "b":"qq"} ' ? ' a ' ;
SELECT jsonb ' {"a":null, "b":"qq"} ' ? ' b ' ;
SELECT jsonb ' {"a":null, "b":"qq"} ' ? ' c ' ;
SELECT jsonb ' {"a":"null", "b":"qq"} ' ? ' a ' ;
-- array exists - array elements should behave as keys
SELECT count ( * ) from testjsonb WHERE j - > ' array ' ? ' bar ' ;
-- type sensitive array exists - should return no rows (since "exists" only
-- matches strings that are either object keys or array elements)
SELECT count ( * ) from testjsonb WHERE j - > ' array ' ? ' 5 ' : : text ;
-- However, a raw scalar is *contained* within the array
SELECT count ( * ) from testjsonb WHERE j - > ' array ' @ > ' 5 ' : : jsonb ;
SELECT jsonb_exists_any ( ' {"a":null, "b":"qq"} ' , ARRAY [ ' a ' , ' b ' ] ) ;
SELECT jsonb_exists_any ( ' {"a":null, "b":"qq"} ' , ARRAY [ ' b ' , ' a ' ] ) ;
SELECT jsonb_exists_any ( ' {"a":null, "b":"qq"} ' , ARRAY [ ' c ' , ' a ' ] ) ;
SELECT jsonb_exists_any ( ' {"a":null, "b":"qq"} ' , ARRAY [ ' c ' , ' d ' ] ) ;
SELECT jsonb_exists_any ( ' {"a":null, "b":"qq"} ' , ' {} ' : : text [ ] ) ;
SELECT jsonb ' {"a":null, "b":"qq"} ' ? | ARRAY [ ' a ' , ' b ' ] ;
SELECT jsonb ' {"a":null, "b":"qq"} ' ? | ARRAY [ ' b ' , ' a ' ] ;
SELECT jsonb ' {"a":null, "b":"qq"} ' ? | ARRAY [ ' c ' , ' a ' ] ;
SELECT jsonb ' {"a":null, "b":"qq"} ' ? | ARRAY [ ' c ' , ' d ' ] ;
SELECT jsonb ' {"a":null, "b":"qq"} ' ? | ' {} ' : : text [ ] ;
SELECT jsonb_exists_all ( ' {"a":null, "b":"qq"} ' , ARRAY [ ' a ' , ' b ' ] ) ;
SELECT jsonb_exists_all ( ' {"a":null, "b":"qq"} ' , ARRAY [ ' b ' , ' a ' ] ) ;
SELECT jsonb_exists_all ( ' {"a":null, "b":"qq"} ' , ARRAY [ ' c ' , ' a ' ] ) ;
SELECT jsonb_exists_all ( ' {"a":null, "b":"qq"} ' , ARRAY [ ' c ' , ' d ' ] ) ;
SELECT jsonb_exists_all ( ' {"a":null, "b":"qq"} ' , ' {} ' : : text [ ] ) ;
SELECT jsonb ' {"a":null, "b":"qq"} ' ? & ARRAY [ ' a ' , ' b ' ] ;
SELECT jsonb ' {"a":null, "b":"qq"} ' ? & ARRAY [ ' b ' , ' a ' ] ;
SELECT jsonb ' {"a":null, "b":"qq"} ' ? & ARRAY [ ' c ' , ' a ' ] ;
SELECT jsonb ' {"a":null, "b":"qq"} ' ? & ARRAY [ ' c ' , ' d ' ] ;
SELECT jsonb ' {"a":null, "b":"qq"} ' ? & ARRAY [ ' a ' , ' a ' , ' b ' , ' b ' , ' b ' ] ;
SELECT jsonb ' {"a":null, "b":"qq"} ' ? & ' {} ' : : text [ ] ;
-- typeof
SELECT jsonb_typeof ( ' {} ' ) AS object ;
SELECT jsonb_typeof ( ' {"c":3,"p":"o"} ' ) AS object ;
SELECT jsonb_typeof ( ' [] ' ) AS array ;
SELECT jsonb_typeof ( ' ["a", 1] ' ) AS array ;
SELECT jsonb_typeof ( ' null ' ) AS " null " ;
SELECT jsonb_typeof ( ' 1 ' ) AS number ;
SELECT jsonb_typeof ( ' -1 ' ) AS number ;
SELECT jsonb_typeof ( ' 1.0 ' ) AS number ;
SELECT jsonb_typeof ( ' 1e2 ' ) AS number ;
SELECT jsonb_typeof ( ' -1.0 ' ) AS number ;
SELECT jsonb_typeof ( ' true ' ) AS boolean ;
SELECT jsonb_typeof ( ' false ' ) AS boolean ;
SELECT jsonb_typeof ( ' "hello" ' ) AS string ;
SELECT jsonb_typeof ( ' "true" ' ) AS string ;
SELECT jsonb_typeof ( ' "1.0" ' ) AS string ;
-- extract_path, extract_path_as_text
SELECT jsonb_extract_path ( ' {"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}} ' , ' f4 ' , ' f6 ' ) ;
SELECT jsonb_extract_path ( ' {"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}} ' , ' f2 ' ) ;
SELECT jsonb_extract_path ( ' {"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}} ' , ' f2 ' , 0 : : text ) ;
SELECT jsonb_extract_path ( ' {"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}} ' , ' f2 ' , 1 : : text ) ;
SELECT jsonb_extract_path_text ( ' {"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}} ' , ' f4 ' , ' f6 ' ) ;
SELECT jsonb_extract_path_text ( ' {"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}} ' , ' f2 ' ) ;
SELECT jsonb_extract_path_text ( ' {"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}} ' , ' f2 ' , 0 : : text ) ;
SELECT jsonb_extract_path_text ( ' {"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}} ' , ' f2 ' , 1 : : text ) ;
-- extract_path nulls
SELECT jsonb_extract_path ( ' {"f2":{"f3":1},"f4":{"f5":null,"f6":"stringy"}} ' , ' f4 ' , ' f5 ' ) IS NULL AS expect_false ;
SELECT jsonb_extract_path_text ( ' {"f2":{"f3":1},"f4":{"f5":null,"f6":"stringy"}} ' , ' f4 ' , ' f5 ' ) IS NULL AS expect_true ;
SELECT jsonb_extract_path ( ' {"f2":{"f3":1},"f4":[0,1,2,null]} ' , ' f4 ' , ' 3 ' ) IS NULL AS expect_false ;
SELECT jsonb_extract_path_text ( ' {"f2":{"f3":1},"f4":[0,1,2,null]} ' , ' f4 ' , ' 3 ' ) IS NULL AS expect_true ;
-- extract_path operators
SELECT ' {"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}} ' : : jsonb #>array['f4','f6'];
SELECT ' {"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}} ' : : jsonb #>array['f2'];
SELECT ' {"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}} ' : : jsonb #>array['f2','0'];
SELECT ' {"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}} ' : : jsonb #>array['f2','1'];
2014-08-20 22:48:35 +02:00
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
SELECT ' {"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}} ' : : jsonb #>>array['f4','f6'];
SELECT ' {"f2":{"f3":1},"f4":{"f5":99,"f6":"stringy"}} ' : : jsonb #>>array['f2'];
SELECT ' {"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}} ' : : jsonb #>>array['f2','0'];
SELECT ' {"f2":["f3",1],"f4":{"f5":99,"f6":"stringy"}} ' : : jsonb #>>array['f2','1'];
2014-08-20 22:48:35 +02:00
-- corner cases for same
2014-08-21 01:05:05 +02:00
select ' {"a": {"b":{"c": "foo"}}} ' : : jsonb #> '{}';
2014-08-22 19:17:58 +02:00
select ' [1,2,3] ' : : jsonb #> '{}';
select ' "foo" ' : : jsonb #> '{}';
select ' 42 ' : : jsonb #> '{}';
select ' null ' : : jsonb #> '{}';
2014-08-20 22:48:35 +02:00
select ' {"a": {"b":{"c": "foo"}}} ' : : jsonb #> array['a'];
2014-08-21 01:05:05 +02:00
select ' {"a": {"b":{"c": "foo"}}} ' : : jsonb #> array['a', null];
select ' {"a": {"b":{"c": "foo"}}} ' : : jsonb #> array['a', ''];
2014-08-20 22:48:35 +02:00
select ' {"a": {"b":{"c": "foo"}}} ' : : jsonb #> array['a','b'];
select ' {"a": {"b":{"c": "foo"}}} ' : : jsonb #> array['a','b','c'];
select ' {"a": {"b":{"c": "foo"}}} ' : : jsonb #> array['a','b','c','d'];
select ' {"a": {"b":{"c": "foo"}}} ' : : jsonb #> array['a','z','c'];
select ' {"a": [{"b": "c"}, {"b": "cc"}]} ' : : jsonb #> array['a','1','b'];
select ' {"a": [{"b": "c"}, {"b": "cc"}]} ' : : jsonb #> array['a','z','b'];
select ' [{"b": "c"}, {"b": "cc"}] ' : : jsonb #> array['1','b'];
select ' [{"b": "c"}, {"b": "cc"}] ' : : jsonb #> array['z','b'];
2014-08-22 19:17:58 +02:00
select ' [{"b": "c"}, {"b": null}] ' : : jsonb #> array['1','b'];
2014-08-20 22:48:35 +02:00
select ' "foo" ' : : jsonb #> array['z'];
select ' 42 ' : : jsonb #> array['f2'];
select ' 42 ' : : jsonb #> array['0'];
2014-08-21 01:05:05 +02:00
select ' {"a": {"b":{"c": "foo"}}} ' : : jsonb #>> '{}';
2014-08-22 19:17:58 +02:00
select ' [1,2,3] ' : : jsonb #>> '{}';
select ' "foo" ' : : jsonb #>> '{}';
select ' 42 ' : : jsonb #>> '{}';
select ' null ' : : jsonb #>> '{}';
2014-08-20 22:48:35 +02:00
select ' {"a": {"b":{"c": "foo"}}} ' : : jsonb #>> array['a'];
2014-08-21 01:05:05 +02:00
select ' {"a": {"b":{"c": "foo"}}} ' : : jsonb #>> array['a', null];
select ' {"a": {"b":{"c": "foo"}}} ' : : jsonb #>> array['a', ''];
2014-08-20 22:48:35 +02:00
select ' {"a": {"b":{"c": "foo"}}} ' : : jsonb #>> array['a','b'];
select ' {"a": {"b":{"c": "foo"}}} ' : : jsonb #>> array['a','b','c'];
select ' {"a": {"b":{"c": "foo"}}} ' : : jsonb #>> array['a','b','c','d'];
select ' {"a": {"b":{"c": "foo"}}} ' : : jsonb #>> array['a','z','c'];
select ' {"a": [{"b": "c"}, {"b": "cc"}]} ' : : jsonb #>> array['a','1','b'];
select ' {"a": [{"b": "c"}, {"b": "cc"}]} ' : : jsonb #>> array['a','z','b'];
select ' [{"b": "c"}, {"b": "cc"}] ' : : jsonb #>> array['1','b'];
select ' [{"b": "c"}, {"b": "cc"}] ' : : jsonb #>> array['z','b'];
2014-08-22 19:17:58 +02:00
select ' [{"b": "c"}, {"b": null}] ' : : jsonb #>> array['1','b'];
2014-08-20 22:48:35 +02:00
select ' "foo" ' : : jsonb #>> array['z'];
select ' 42 ' : : jsonb #>> array['f2'];
select ' 42 ' : : jsonb #>> array['0'];
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
-- array_elements
SELECT jsonb_array_elements ( ' [1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false] ' ) ;
SELECT * FROM jsonb_array_elements ( ' [1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false] ' ) q ;
SELECT jsonb_array_elements_text ( ' [1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"] ' ) ;
SELECT * FROM jsonb_array_elements_text ( ' [1,true,[1,[2,3]],null,{"f1":1,"f2":[7,8,9]},false,"stringy"] ' ) q ;
-- populate_record
CREATE TYPE jbpop AS ( a text , b int , c timestamp ) ;
SELECT * FROM jsonb_populate_record ( NULL : : jbpop , ' {"a":"blurfl","x":43.2} ' ) q ;
SELECT * FROM jsonb_populate_record ( row ( ' x ' , 3 , ' 2012-12-31 15:30:56 ' ) : : jbpop , ' {"a":"blurfl","x":43.2} ' ) q ;
2014-06-29 19:50:58 +02:00
SELECT * FROM jsonb_populate_record ( NULL : : jbpop , ' {"a":"blurfl","x":43.2} ' ) q ;
SELECT * FROM jsonb_populate_record ( row ( ' x ' , 3 , ' 2012-12-31 15:30:56 ' ) : : jbpop , ' {"a":"blurfl","x":43.2} ' ) q ;
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
2014-06-29 19:50:58 +02:00
SELECT * FROM jsonb_populate_record ( NULL : : jbpop , ' {"a":[100,200,false],"x":43.2} ' ) q ;
SELECT * FROM jsonb_populate_record ( row ( ' x ' , 3 , ' 2012-12-31 15:30:56 ' ) : : jbpop , ' {"a":[100,200,false],"x":43.2} ' ) q ;
SELECT * FROM jsonb_populate_record ( row ( ' x ' , 3 , ' 2012-12-31 15:30:56 ' ) : : jbpop , ' {"c":[100,200,false],"x":43.2} ' ) q ;
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
-- populate_recordset
2014-06-29 19:50:58 +02:00
SELECT * FROM jsonb_populate_recordset ( NULL : : jbpop , ' [{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}] ' ) q ;
SELECT * FROM jsonb_populate_recordset ( row ( ' def ' , 99 , NULL ) : : jbpop , ' [{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}] ' ) q ;
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
SELECT * FROM jsonb_populate_recordset ( NULL : : jbpop , ' [{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}] ' ) q ;
SELECT * FROM jsonb_populate_recordset ( row ( ' def ' , 99 , NULL ) : : jbpop , ' [{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}] ' ) q ;
SELECT * FROM jsonb_populate_recordset ( row ( ' def ' , 99 , NULL ) : : jbpop , ' [{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}] ' ) q ;
SELECT * FROM jsonb_populate_recordset ( row ( ' def ' , 99 , NULL ) : : jbpop , ' [{"c":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}] ' ) q ;
2014-06-29 19:50:58 +02:00
SELECT * FROM jsonb_populate_recordset ( NULL : : jbpop , ' [{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}] ' ) q ;
SELECT * FROM jsonb_populate_recordset ( row ( ' def ' , 99 , NULL ) : : jbpop , ' [{"a":"blurfl","x":43.2},{"b":3,"c":"2012-01-20 10:42:53"}] ' ) q ;
SELECT * FROM jsonb_populate_recordset ( row ( ' def ' , 99 , NULL ) : : jbpop , ' [{"a":[100,200,300],"x":43.2},{"a":{"z":true},"b":3,"c":"2012-01-20 10:42:53"}] ' ) q ;
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
-- handling of unicode surrogate pairs
2014-06-29 19:50:58 +02:00
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
SELECT octet_length ( ( jsonb ' { "a": "\ud83d\ude04\ud83d\udc36" } ' - > ' a ' ) : : text ) AS correct_in_utf8 ;
SELECT jsonb ' { "a": "\ud83d\ud83d" } ' - > ' a ' ; -- 2 high surrogates in a row
SELECT jsonb ' { "a": "\ude04\ud83d" } ' - > ' a ' ; -- surrogates in wrong order
SELECT jsonb ' { "a": "\ud83dX" } ' - > ' a ' ; -- orphan high surrogate
SELECT jsonb ' { "a": "\ude04X" } ' - > ' a ' ; -- orphan low surrogate
-- handling of simple unicode escapes
SELECT jsonb ' { "a": "the Copyright \u00a9 sign" } ' - > > ' a ' AS correct_in_utf8 ;
SELECT jsonb ' { "a": "dollar \u0024 character" } ' - > > ' a ' AS correct_everyWHERE ;
SELECT jsonb ' { "a": "null \u0000 escape" } ' - > > ' a ' AS not_unescaped ;
2014-03-26 15:18:24 +01:00
-- jsonb_to_record and jsonb_to_recordset
2014-06-29 19:50:58 +02:00
select * from jsonb_to_record ( ' {"a":1,"b":"foo","c":"bar"} ' )
2014-03-26 15:18:24 +01:00
as x ( a int , b text , d text ) ;
2014-06-29 19:50:58 +02:00
select * from jsonb_to_recordset ( ' [{"a":1,"b":"foo","d":false},{"a":2,"b":"bar","c":true}] ' )
2014-03-26 15:18:24 +01:00
as x ( a int , b text , c boolean ) ;
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
-- indexing
SELECT count ( * ) FROM testjsonb WHERE j @ > ' {"wait":null} ' ;
SELECT count ( * ) FROM testjsonb WHERE j @ > ' {"wait":"CC"} ' ;
SELECT count ( * ) FROM testjsonb WHERE j @ > ' {"wait":"CC", "public":true} ' ;
SELECT count ( * ) FROM testjsonb WHERE j @ > ' {"age":25} ' ;
SELECT count ( * ) FROM testjsonb WHERE j @ > ' {"age":25.0} ' ;
SELECT count ( * ) FROM testjsonb WHERE j ? ' public ' ;
2014-05-09 14:41:26 +02:00
SELECT count ( * ) FROM testjsonb WHERE j ? ' bar ' ;
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
SELECT count ( * ) FROM testjsonb WHERE j ? | ARRAY [ ' public ' , ' disabled ' ] ;
SELECT count ( * ) FROM testjsonb WHERE j ? & ARRAY [ ' public ' , ' disabled ' ] ;
CREATE INDEX jidx ON testjsonb USING gin ( j ) ;
SET enable_seqscan = off ;
SELECT count ( * ) FROM testjsonb WHERE j @ > ' {"wait":null} ' ;
SELECT count ( * ) FROM testjsonb WHERE j @ > ' {"wait":"CC"} ' ;
SELECT count ( * ) FROM testjsonb WHERE j @ > ' {"wait":"CC", "public":true} ' ;
SELECT count ( * ) FROM testjsonb WHERE j @ > ' {"age":25} ' ;
SELECT count ( * ) FROM testjsonb WHERE j @ > ' {"age":25.0} ' ;
SELECT count ( * ) FROM testjsonb WHERE j @ > ' {"array":["foo"]} ' ;
SELECT count ( * ) FROM testjsonb WHERE j @ > ' {"array":["bar"]} ' ;
-- excercise GIN_SEARCH_MODE_ALL
SELECT count ( * ) FROM testjsonb WHERE j @ > ' {} ' ;
SELECT count ( * ) FROM testjsonb WHERE j ? ' public ' ;
2014-05-09 14:41:26 +02:00
SELECT count ( * ) FROM testjsonb WHERE j ? ' bar ' ;
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
SELECT count ( * ) FROM testjsonb WHERE j ? | ARRAY [ ' public ' , ' disabled ' ] ;
SELECT count ( * ) FROM testjsonb WHERE j ? & ARRAY [ ' public ' , ' disabled ' ] ;
-- array exists - array elements should behave as keys (for GIN index scans too)
CREATE INDEX jidx_array ON testjsonb USING gin ( ( j - > ' array ' ) ) ;
SELECT count ( * ) from testjsonb WHERE j - > ' array ' ? ' bar ' ;
-- type sensitive array exists - should return no rows (since "exists" only
-- matches strings that are either object keys or array elements)
SELECT count ( * ) from testjsonb WHERE j - > ' array ' ? ' 5 ' : : text ;
-- However, a raw scalar is *contained* within the array
SELECT count ( * ) from testjsonb WHERE j - > ' array ' @ > ' 5 ' : : jsonb ;
RESET enable_seqscan ;
SELECT count ( * ) FROM ( SELECT ( jsonb_each ( j ) ) . key FROM testjsonb ) AS wow ;
SELECT key , count ( * ) FROM ( SELECT ( jsonb_each ( j ) ) . key FROM testjsonb ) AS wow GROUP BY key ORDER BY count DESC , key ;
-- sort/hash
SELECT count ( distinct j ) FROM testjsonb ;
SET enable_hashagg = off ;
SELECT count ( * ) FROM ( SELECT j FROM ( SELECT * FROM testjsonb UNION ALL SELECT * FROM testjsonb ) js GROUP BY j ) js2 ;
SET enable_hashagg = on ;
SET enable_sort = off ;
SELECT count ( * ) FROM ( SELECT j FROM ( SELECT * FROM testjsonb UNION ALL SELECT * FROM testjsonb ) js GROUP BY j ) js2 ;
SELECT distinct * FROM ( values ( jsonb ' {} ' | | ' ' ) , ( ' {} ' ) ) v ( j ) ;
SET enable_sort = on ;
RESET enable_hashagg ;
RESET enable_sort ;
DROP INDEX jidx ;
DROP INDEX jidx_array ;
-- btree
CREATE INDEX jidx ON testjsonb USING btree ( j ) ;
SET enable_seqscan = off ;
SELECT count ( * ) FROM testjsonb WHERE j > ' {"p":1} ' ;
SELECT count ( * ) FROM testjsonb WHERE j = ' {"pos":98, "line":371, "node":"CBA", "indexed":true} ' ;
2014-05-11 18:06:04 +02:00
- - gin path opclass
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
DROP INDEX jidx ;
2014-05-11 18:06:04 +02:00
CREATE INDEX jidx ON testjsonb USING gin ( j jsonb_path_ops ) ;
Introduce jsonb, a structured format for storing json.
The new format accepts exactly the same data as the json type. However, it is
stored in a format that does not require reparsing the orgiginal text in order
to process it, making it much more suitable for indexing and other operations.
Insignificant whitespace is discarded, and the order of object keys is not
preserved. Neither are duplicate object keys kept - the later value for a given
key is the only one stored.
The new type has all the functions and operators that the json type has,
with the exception of the json generation functions (to_json, json_agg etc.)
and with identical semantics. In addition, there are operator classes for
hash and btree indexing, and two classes for GIN indexing, that have no
equivalent in the json type.
This feature grew out of previous work by Oleg Bartunov and Teodor Sigaev, which
was intended to provide similar facilities to a nested hstore type, but which
in the end proved to have some significant compatibility issues.
Authors: Oleg Bartunov, Teodor Sigaev, Peter Geoghegan and Andrew Dunstan.
Review: Andres Freund
2014-03-23 21:40:19 +01:00
SET enable_seqscan = off ;
SELECT count ( * ) FROM testjsonb WHERE j @ > ' {"wait":null} ' ;
SELECT count ( * ) FROM testjsonb WHERE j @ > ' {"wait":"CC"} ' ;
SELECT count ( * ) FROM testjsonb WHERE j @ > ' {"wait":"CC", "public":true} ' ;
SELECT count ( * ) FROM testjsonb WHERE j @ > ' {"age":25} ' ;
SELECT count ( * ) FROM testjsonb WHERE j @ > ' {"age":25.0} ' ;
-- excercise GIN_SEARCH_MODE_ALL
SELECT count ( * ) FROM testjsonb WHERE j @ > ' {} ' ;
RESET enable_seqscan ;
DROP INDEX jidx ;
-- nested tests
SELECT ' {"ff":{"a":12,"b":16}} ' : : jsonb ;
SELECT ' {"ff":{"a":12,"b":16},"qq":123} ' : : jsonb ;
SELECT ' {"aa":["a","aaa"],"qq":{"a":12,"b":16,"c":["c1","c2"],"d":{"d1":"d1","d2":"d2","d1":"d3"}}} ' : : jsonb ;
SELECT ' {"aa":["a","aaa"],"qq":{"a":"12","b":"16","c":["c1","c2"],"d":{"d1":"d1","d2":"d2"}}} ' : : jsonb ;
SELECT ' {"aa":["a","aaa"],"qq":{"a":"12","b":"16","c":["c1","c2",["c3"],{"c4":4}],"d":{"d1":"d1","d2":"d2"}}} ' : : jsonb ;
SELECT ' {"ff":["a","aaa"]} ' : : jsonb ;
SELECT
' {"ff":{"a":12,"b":16},"qq":123,"x":[1,2],"Y":null} ' : : jsonb - > ' ff ' ,
' {"ff":{"a":12,"b":16},"qq":123,"x":[1,2],"Y":null} ' : : jsonb - > ' qq ' ,
( ' {"ff":{"a":12,"b":16},"qq":123,"x":[1,2],"Y":null} ' : : jsonb - > ' Y ' ) IS NULL AS f ,
( ' {"ff":{"a":12,"b":16},"qq":123,"x":[1,2],"Y":null} ' : : jsonb - > > ' Y ' ) IS NULL AS t ,
' {"ff":{"a":12,"b":16},"qq":123,"x":[1,2],"Y":null} ' : : jsonb - > ' x ' ;
-- nested containment
SELECT ' {"a":[1,2],"c":"b"} ' : : jsonb @ > ' {"a":[1,2]} ' ;
SELECT ' {"a":[2,1],"c":"b"} ' : : jsonb @ > ' {"a":[1,2]} ' ;
SELECT ' {"a":{"1":2},"c":"b"} ' : : jsonb @ > ' {"a":[1,2]} ' ;
SELECT ' {"a":{"2":1},"c":"b"} ' : : jsonb @ > ' {"a":[1,2]} ' ;
SELECT ' {"a":{"1":2},"c":"b"} ' : : jsonb @ > ' {"a":{"1":2}} ' ;
SELECT ' {"a":{"2":1},"c":"b"} ' : : jsonb @ > ' {"a":{"1":2}} ' ;
SELECT ' ["a","b"] ' : : jsonb @ > ' ["a","b","c","b"] ' ;
SELECT ' ["a","b","c","b"] ' : : jsonb @ > ' ["a","b"] ' ;
SELECT ' ["a","b","c",[1,2]] ' : : jsonb @ > ' ["a",[1,2]] ' ;
SELECT ' ["a","b","c",[1,2]] ' : : jsonb @ > ' ["b",[1,2]] ' ;
SELECT ' {"a":[1,2],"c":"b"} ' : : jsonb @ > ' {"a":[1]} ' ;
SELECT ' {"a":[1,2],"c":"b"} ' : : jsonb @ > ' {"a":[2]} ' ;
SELECT ' {"a":[1,2],"c":"b"} ' : : jsonb @ > ' {"a":[3]} ' ;
SELECT ' {"a":[1,2,{"c":3,"x":4}],"c":"b"} ' : : jsonb @ > ' {"a":[{"c":3}]} ' ;
SELECT ' {"a":[1,2,{"c":3,"x":4}],"c":"b"} ' : : jsonb @ > ' {"a":[{"x":4}]} ' ;
SELECT ' {"a":[1,2,{"c":3,"x":4}],"c":"b"} ' : : jsonb @ > ' {"a":[{"x":4},3]} ' ;
SELECT ' {"a":[1,2,{"c":3,"x":4}],"c":"b"} ' : : jsonb @ > ' {"a":[{"x":4},1]} ' ;
-- nested object field / array index lookup
SELECT ' {"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}} ' : : jsonb - > ' n ' ;
SELECT ' {"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}} ' : : jsonb - > ' a ' ;
SELECT ' {"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}} ' : : jsonb - > ' b ' ;
SELECT ' {"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}} ' : : jsonb - > ' c ' ;
SELECT ' {"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}} ' : : jsonb - > ' d ' ;
SELECT ' {"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}} ' : : jsonb - > ' d ' - > ' 1 ' ;
SELECT ' {"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}} ' : : jsonb - > ' e ' ;
SELECT ' {"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}} ' : : jsonb - > 0 ; - - expecting error
SELECT ' ["a","b","c",[1,2],null] ' : : jsonb - > 0 ;
SELECT ' ["a","b","c",[1,2],null] ' : : jsonb - > 1 ;
SELECT ' ["a","b","c",[1,2],null] ' : : jsonb - > 2 ;
SELECT ' ["a","b","c",[1,2],null] ' : : jsonb - > 3 ;
SELECT ' ["a","b","c",[1,2],null] ' : : jsonb - > 3 - > 1 ;
SELECT ' ["a","b","c",[1,2],null] ' : : jsonb - > 4 ;
SELECT ' ["a","b","c",[1,2],null] ' : : jsonb - > 5 ;
SELECT ' ["a","b","c",[1,2],null] ' : : jsonb - > - 1 ;
- - nested path extraction
SELECT ' {"a":"b","c":[1,2,3]} ' : : jsonb #> '{0}';
SELECT ' {"a":"b","c":[1,2,3]} ' : : jsonb #> '{a}';
SELECT ' {"a":"b","c":[1,2,3]} ' : : jsonb #> '{c}';
SELECT ' {"a":"b","c":[1,2,3]} ' : : jsonb #> '{c,0}';
SELECT ' {"a":"b","c":[1,2,3]} ' : : jsonb #> '{c,1}';
SELECT ' {"a":"b","c":[1,2,3]} ' : : jsonb #> '{c,2}';
SELECT ' {"a":"b","c":[1,2,3]} ' : : jsonb #> '{c,3}';
SELECT ' {"a":"b","c":[1,2,3]} ' : : jsonb #> '{c,-1}';
SELECT ' [0,1,2,[3,4],{"5":"five"}] ' : : jsonb #> '{0}';
SELECT ' [0,1,2,[3,4],{"5":"five"}] ' : : jsonb #> '{3}';
SELECT ' [0,1,2,[3,4],{"5":"five"}] ' : : jsonb #> '{4}';
SELECT ' [0,1,2,[3,4],{"5":"five"}] ' : : jsonb #> '{4,5}';
- - nested exists
SELECT ' {"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}} ' : : jsonb ? ' n ' ;
SELECT ' {"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}} ' : : jsonb ? ' a ' ;
SELECT ' {"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}} ' : : jsonb ? ' b ' ;
SELECT ' {"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}} ' : : jsonb ? ' c ' ;
SELECT ' {"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}} ' : : jsonb ? ' d ' ;
SELECT ' {"n":null,"a":1,"b":[1,2],"c":{"1":2},"d":{"1":[2,3]}} ' : : jsonb ? ' e ' ;