## json_typeof and jsonb_typeof

query T
SELECT json_typeof('-123.4'::JSON)
----
number

query T
SELECT jsonb_typeof('-123.4'::JSON)
----
number

query T
SELECT json_typeof('"-123.4"'::JSON)
----
string

query T
SELECT jsonb_typeof('"-123.4"'::JSON)
----
string

query T
SELECT json_typeof('{"1": {"2": 3}}'::JSON)
----
object

query T
SELECT jsonb_typeof('{"1": {"2": 3}}'::JSON)
----
object

query T
SELECT json_typeof('[1, 2, [3]]'::JSON)
----
array

query T
SELECT jsonb_typeof('[1, 2, [3]]'::JSON)
----
array

query T
SELECT json_typeof('true'::JSON)
----
boolean

query T
SELECT jsonb_typeof('true'::JSON)
----
boolean

query T
SELECT json_typeof('false'::JSON)
----
boolean

query T
SELECT jsonb_typeof('false'::JSON)
----
boolean

query T
SELECT json_typeof('null'::JSON)
----
null

query T
SELECT jsonb_typeof('null'::JSON)
----
null

## array_to_json
query T
SELECT array_to_json(ARRAY[[1, 2], [3, 4]])
----
[[1, 2], [3, 4]]

query T
SELECT array_to_json('{1, 2, 3}'::INT[])
----
[1, 2, 3]

query T
SELECT array_to_json('{"a", "b", "c"}'::STRING[])
----
["a", "b", "c"]

query T
SELECT array_to_json('{1.0, 2.0, 3.0}'::DECIMAL[])
----
[1.0, 2.0, 3.0]

query T
SELECT array_to_json(NULL)
----
NULL

query T
SELECT array_to_json(ARRAY[1, 2, 3], NULL)
----
NULL

query T
SELECT array_to_json(ARRAY[1, 2, 3], false)
----
[1, 2, 3]

query error pq: array_to_json\(\): pretty printing is not supported
SELECT array_to_json(ARRAY[1, 2, 3], true)

query error pq: unknown signature: array_to_json\(string\)
SELECT array_to_json('hello world')

## to_json and to_jsonb

query T
SELECT to_json(123::INT)
----
123

query T
SELECT to_json('\a'::TEXT)
----
"\\a"

query T
SELECT to_json('\a'::TEXT COLLATE "fr_FR")
----
"\\a"

query T
SELECT to_json(3::OID::INT::OID)
----
"3"

query T
SELECT to_json('a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::UUID);
----
"a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11"

query T
SELECT to_json('\x0001'::BYTEA)
----
"\\x0001"

query T
SELECT to_json(true::BOOL)
----
true

query T
SELECT to_json(false::BOOL)
----
false

query T
SELECT to_json('"a"'::JSON)
----
"a"

query T
SELECT to_json(1.234::FLOAT)
----
1.234

query T
SELECT to_json(1.234::DECIMAL)
----
1.234

query T
SELECT to_json('10.1.0.0/16'::INET)
----
"10.1.0.0/16"

query T
SELECT to_json(ARRAY[[1, 2], [3, 4]])
----
[[1, 2], [3, 4]]

query T
SELECT to_json('2014-05-28 12:22:35.614298'::TIMESTAMP)
----
"2014-05-28T12:22:35.614298"

query T
SELECT to_json('2014-05-28 12:22:35.614298-04'::TIMESTAMPTZ)
----
"2014-05-28T16:22:35.614298Z"

query T
SELECT to_json('2014-05-28 12:22:35.614298-04'::TIMESTAMP)
----
"2014-05-28T12:22:35.614298"

query T
SELECT to_json('2014-05-28'::DATE)
----
"2014-05-28"

query T
SELECT to_json('00:00:00'::TIME)
----
"00:00:00"

query T
SELECT to_json('2h45m2s234ms'::INTERVAL)
----
"02:45:02.234"

query T
SELECT to_json((1, 2, 'hello', NULL, NULL))
----
{"f1": 1, "f2": 2, "f3": "hello", "f4": null, "f5": null}

query T
SELECT to_jsonb(123::INT)
----
123

query T
SELECT to_jsonb('\a'::TEXT)
----
"\\a"

query T
SELECT to_jsonb('\a'::TEXT COLLATE "fr_FR")
----
"\\a"

query T
SELECT to_jsonb(3::OID::INT::OID)
----
"3"

query T
SELECT to_jsonb('a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::UUID);
----
"a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11"

query T
SELECT to_jsonb('\x0001'::BYTEA)
----
"\\x0001"

query T
SELECT to_jsonb(true::BOOL)
----
true

query T
SELECT to_jsonb(false::BOOL)
----
false

query T
SELECT to_jsonb('"a"'::JSON)
----
"a"

query T
SELECT to_jsonb(1.234::FLOAT)
----
1.234

query T
SELECT to_jsonb(1.234::DECIMAL)
----
1.234

query T
SELECT to_jsonb('10.1.0.0/16'::INET)
----
"10.1.0.0/16"

query T
SELECT to_jsonb(ARRAY[[1, 2], [3, 4]])
----
[[1, 2], [3, 4]]

query T
SELECT to_jsonb('2014-05-28 12:22:35.614298'::TIMESTAMP)
----
"2014-05-28T12:22:35.614298"

query T
SELECT to_jsonb('2014-05-28 12:22:35.614298-04'::TIMESTAMPTZ)
----
"2014-05-28T16:22:35.614298Z"

query T
SELECT to_jsonb('2014-05-28 12:22:35.614298-04'::TIMESTAMP)
----
"2014-05-28T12:22:35.614298"

query T
SELECT to_jsonb('2014-05-28'::DATE)
----
"2014-05-28"

query T
SELECT to_jsonb('00:00:00'::TIME)
----
"00:00:00"

query T
SELECT to_jsonb('2h45m2s234ms'::INTERVAL)
----
"02:45:02.234"

query T
SELECT to_jsonb((1, 2, 'hello', NULL, NULL))
----
{"f1": 1, "f2": 2, "f3": "hello", "f4": null, "f5": null}

query T
SELECT to_json(x.*) FROM (VALUES (1,2)) AS x(a,b);
----
{"a": 1, "b": 2}

query T
SELECT to_json(x.*) FROM (VALUES (1,2)) AS x(a);
----
{"a": 1, "column2": 2}

query T
SELECT to_json(x.*) FROM (VALUES (1,2)) AS x(column2);
----
{"column2": 2}

# Regression test for #39502.
statement ok
SELECT json_agg((3808362714,))

## json_array_elements and jsonb_array_elements

query T colnames,nosort
SELECT json_array_elements('[1, 2, 3]'::JSON)
----
json_array_elements
1
2
3

query T colnames,nosort
SELECT * FROM json_array_elements('[1, 2, 3]'::JSON)
----
value
1
2
3

query T colnames,nosort
SELECT jsonb_array_elements('[1, 2, 3]'::JSON)
----
jsonb_array_elements
1
2
3

query T colnames,nosort
SELECT * FROM jsonb_array_elements('[1, 2, 3]'::JSON)
----
value
1
2
3

query T colnames,nosort
SELECT json_array_elements('[1, true, null, "text", -1.234, {"2": 3, "4": "5"}, [1, 2, 3]]'::JSON)
----
json_array_elements
1
true
null
"text"
-1.234
{"2": 3, "4": "5"}
[1, 2, 3]

query T colnames,nosort
SELECT * FROM json_array_elements('[1, true, null, "text", -1.234, {"2": 3, "4": "5"}, [1, 2, 3]]'::JSON)
----
value
1
true
null
"text"
-1.234
{"2": 3, "4": "5"}
[1, 2, 3]

query T
SELECT json_array_elements('[]'::JSON)
----


query error pq: cannot be called on a non-array
SELECT json_array_elements('{"1": 2}'::JSON)

query error pq: cannot be called on a non-array
SELECT jsonb_array_elements('{"1": 2}'::JSON)


## json_array_elements_text and jsonb_array_elements_text

query T colnames,nosort
SELECT json_array_elements_text('[1, 2, 3]'::JSON)
----
json_array_elements_text
1
2
3

query T colnames,nosort
SELECT * FROM json_array_elements_text('[1, 2, 3]'::JSON)
----
value
1
2
3

query T colnames,nosort
SELECT json_array_elements_text('[1, 2, 3]'::JSON)
----
json_array_elements_text
1
2
3

query T colnames,nosort
SELECT * FROM json_array_elements_text('[1, 2, 3]'::JSON)
----
value
1
2
3

query T nosort
SELECT json_array_elements_text('[1, true, null, "text", -1.234, {"2": 3, "4": "5"}, [1, 2, 3]]'::JSON)
----
1
true
NULL
text
-1.234
{"2": 3, "4": "5"}
[1, 2, 3]

query T
SELECT json_array_elements('[]'::JSON)
----

query error pq: cannot be called on a non-array
SELECT json_array_elements_text('{"1": 2}'::JSON)

query error pq: cannot be called on a non-array
SELECT jsonb_array_elements_text('{"1": 2}'::JSON)


## json_object_keys and jsonb_object_keys

query T nosort
SELECT json_object_keys('{"1": 2, "3": 4}'::JSON)
----
1
3

query T nosort
SELECT jsonb_object_keys('{"1": 2, "3": 4}'::JSON)
----
1
3

query T
SELECT json_object_keys('{}'::JSON)
----

query T
SELECT json_object_keys('{"\"1\"": 2}'::JSON)
----
"1"

# Keys are sorted.
query T colnames,nosort
SELECT json_object_keys('{"a": 1, "1": 2, "3": {"4": 5, "6": 7}}'::JSON)
----
json_object_keys
1
3
a

query T colnames,nosort
SELECT * FROM json_object_keys('{"a": 1, "1": 2, "3": {"4": 5, "6": 7}}'::JSON)
----
json_object_keys
1
3
a

query error pq: cannot call json_object_keys on a scalar
SELECT json_object_keys('null'::JSON)

query error pq: cannot call json_object_keys on an array
SELECT json_object_keys('[1, 2, 3]'::JSON)

## json_build_object

query T
SELECT json_build_object()
----
{}

query T
SELECT json_build_object('a', 2, 'b', 4)
----
{"a": 2, "b": 4}

query T
SELECT jsonb_build_object(true,'val',1, 0, 1.3, 2, date '2019-02-03' - date '2019-01-01', 4, '2001-01-01 11:00+3'::timestamptz, '11:00+3'::timetz)
----
{"1": 0, "1.3": 2, "2001-01-01 08:00:00+00": "11:00:00+03", "33": 4, "true": "val"}

query T
SELECT json_build_object('a',1,'b',1.2,'c',true,'d',null,'e','{"x": 3, "y": [1,2,3]}'::JSON)
----
{"a": 1, "b": 1.2, "c": true, "d": null, "e": {"x": 3, "y": [1, 2, 3]}}

query T
SELECT json_build_object(
       'a', json_build_object('b',false,'c',99),
       'd', json_build_object('e',ARRAY[9,8,7]::int[])
)
----
{"a": {"b": false, "c": 99}, "d": {"e": [9, 8, 7]}}

query T
SELECT json_build_object(a,3) FROM (SELECT 1 AS a, 2 AS b) r
----
{"1": 3}

query T
SELECT json_build_object('\a'::TEXT COLLATE "fr_FR", 1)
----
{"\\a": 1}

query T
SELECT json_build_object('\a', 1)
----
{"\\a": 1}

query T nosort
SELECT json_build_object(json_object_keys('{"x":3, "y":4}'::JSON), 2)
----
{"x": 2}
{"y": 2}

# Regression for panic when bit array is passed as argument.
query T
SELECT json_build_object('a', '0100110'::varbit)
----
{"a": "0100110"}

# Regression for an internal error when using an enum and void in the key.
statement ok
CREATE TYPE e AS ENUM ('e');

query T
SELECT json_build_object('e'::e, 1)
----
{"e": 1}

query T
SELECT json_build_object(''::void, 1)
----
{"": 1}

# even number of arguments
statement error pgcode 22023 json_build_object\(\): argument list must have even number of elements
SELECT json_build_object(1,2,3)

# keys must be scalar and not null
statement error pgcode 22004 json_build_object\(\): null value not allowed for object key
SELECT json_build_object(null,2)

statement error pgcode 22023 json_build_object\(\): key value must be scalar, not array, composite, or json
SELECT json_build_object((1,2),3)

statement error pgcode 22023 json_build_object\(\): key value must be scalar, not array, composite, or json
SELECT json_build_object('{"a":1,"b":2}'::JSON, 3)

statement error pgcode 22023 json_build_object\(\): key value must be scalar, not array, composite, or json
SELECT json_build_object('{1,2,3}'::int[], 3)

query T
SELECT json_build_object('a'::tsvector, 1, 'b'::tsquery, 2)
----
{"'a'": 1, "'b'": 2}

query T
SELECT json_extract_path('{"a": 1}', 'a')
----
1

query T
SELECT json_extract_path('{"a": 1}', 'a', NULL)
----
NULL

query T
SELECT json_extract_path('{"a": 1}')
----
{"a": 1}

query T
SELECT json_extract_path('{"a": {"b": 2}}', 'a')
----
{"b": 2}

query T
SELECT json_extract_path('{"a": {"b": 2}}', 'a', 'b')
----
2

query T
SELECT jsonb_extract_path('{"a": {"b": 2}}', 'a', 'b')
----
2

query T
SELECT json_extract_path('{"a": {"b": 2}}', 'a', 'b', 'c')
----
NULL

query T
SELECT json_extract_path('null')
----
null

query T
SELECT json_extract_path_text('{"a": 1}', 'a')
----
1

query T
SELECT json_extract_path_text('{"a": 1}', 'a', NULL)
----
NULL

query T
SELECT json_extract_path_text('{"a": 1}')
----
{"a": 1}

query T
SELECT json_extract_path_text('{"a": {"b": 2}}', 'a')
----
{"b": 2}

query T
SELECT json_extract_path_text('{"a": {"b": 2}}', 'a', 'b')
----
2

query T
SELECT jsonb_extract_path_text('{"a": {"b": 2}}', 'a', 'b')
----
2

query T
SELECT json_extract_path_text('{"a": {"b": 2}}', 'a', 'b', 'c')
----
NULL

query T
SELECT json_extract_path_text('null')
----
NULL

query T
SELECT jsonb_pretty('{"a": 1}')
----
{
    "a": 1
}

query T
SELECT '[1,2,3]'::JSON || '[4,5,6]'::JSON
----
[1, 2, 3, 4, 5, 6]

query T
SELECT '{"a": 1, "b": 2}'::JSON || '{"b": 3, "c": 4}'
----
{"a": 1, "b": 3, "c": 4}

query error pgcode 22023 invalid concatenation of jsonb objects
SELECT '{"a": 1, "b": 2}'::JSON || '"c"'

query T
SELECT json_build_array()
----
[]

query T
SELECT json_build_array('\x0001'::BYTEA)
----
["\\x0001"]

query T
SELECT json_build_array(1, '1'::JSON, 1.2, NULL, ARRAY['x', 'y'])
----
[1, 1, 1.2, null, ["x", "y"]]

query T
SELECT jsonb_build_array()
----
[]

query T
SELECT jsonb_build_array('\x0001'::BYTEA)
----
["\\x0001"]

query T
SELECT jsonb_build_array(1, '1'::JSON, 1.2, NULL, ARRAY['x', 'y'])
----
[1, 1, 1.2, null, ["x", "y"]]

# Regression for #37318
query T
SELECT jsonb_build_array('+Inf'::FLOAT8, 'NaN'::FLOAT8)::STRING::JSONB
----
["Infinity", "NaN"]

statement error pgcode 2202E json_object\(\): array must have even number of elements
SELECT json_object('{a,b,c}'::TEXT[])

statement error pgcode 22004 json_object\(\): null value not allowed for object key
SELECT json_object('{NULL, a}'::TEXT[])

statement error pgcode 22004 json_object\(\): null value not allowed for object key
SELECT json_object('{a,b,NULL,"d e f"}'::TEXT[],'{1,2,3,"a b c"}'::TEXT[])

query error pq: json_object\(\): mismatched array dimensions
SELECT json_object('{a,b,c,"d e f",g}'::TEXT[],'{1,2,3,"a b c"}'::TEXT[])

query error pq: json_object\(\): mismatched array dimensions
SELECT json_object('{a,b,c,"d e f"}'::TEXT[],'{1,2,3,"a b c",g}'::TEXT[])

query error pq: unknown signature: json_object\(collatedstring\{fr_FR\}\[\]\)
SELECT json_object(ARRAY['a'::TEXT COLLATE "fr_FR"])

query T
SELECT json_object('{}'::TEXT[])
----
{}

query T
SELECT json_object('{}'::TEXT[], '{}'::TEXT[])
----
{}

query T
SELECT json_object('{b, 3, a, 1, b, 4, a, 2}'::TEXT[])
----
{"a": "2", "b": "4"}

query T
SELECT json_object('{b, b, a, a}'::TEXT[], '{1, 2, 3, 4}'::TEXT[])
----
{"a": "4", "b": "2"}

query T
SELECT json_object('{a,1,b,2,3,NULL,"d e f","a b c"}'::TEXT[])
----
{"3": null, "a": "1", "b": "2", "d e f": "a b c"}

query T
SELECT json_object('{a,b,"","d e f"}'::TEXT[],'{1,2,3,"a b c"}'::TEXT[])
----
{"": "3", "a": "1", "b": "2", "d e f": "a b c"}

query T
SELECT json_object('{a,b,c,"d e f"}'::TEXT[],'{1,2,3,"a b c"}'::TEXT[])
----
{"a": "1", "b": "2", "c": "3", "d e f": "a b c"}

statement error pgcode 2202E jsonb_object\(\): array must have even number of elements
SELECT jsonb_object('{a,b,c}'::TEXT[])

statement error pgcode 22004 jsonb_object\(\): null value not allowed for object key
SELECT jsonb_object('{NULL, a}'::TEXT[])

statement error pgcode 22004 jsonb_object\(\): null value not allowed for object key
SELECT jsonb_object('{a,b,NULL,"d e f"}'::TEXT[],'{1,2,3,"a b c"}'::TEXT[])

query error pq: jsonb_object\(\): mismatched array dimensions
SELECT jsonb_object('{a,b,c,"d e f",g}'::TEXT[],'{1,2,3,"a b c"}'::TEXT[])

query error pq: jsonb_object\(\): mismatched array dimensions
SELECT jsonb_object('{a,b,c,"d e f"}'::TEXT[],'{1,2,3,"a b c",g}'::TEXT[])

query error pq: unknown signature: jsonb_object\(collatedstring\{fr_FR\}\[\]\)
SELECT jsonb_object(ARRAY['a'::TEXT COLLATE "fr_FR"])

query T
SELECT jsonb_object('{}'::TEXT[])
----
{}

query T
SELECT jsonb_object('{}'::TEXT[], '{}'::TEXT[])
----
{}

query T
SELECT jsonb_object('{b, 3, a, 1, b, 4, a, 2}'::TEXT[])
----
{"a": "2", "b": "4"}

query T
SELECT jsonb_object('{b, b, a, a}'::TEXT[], '{1, 2, 3, 4}'::TEXT[])
----
{"a": "4", "b": "2"}

query T
SELECT jsonb_object('{a,1,b,2,3,NULL,"d e f","a b c"}'::TEXT[])
----
{"3": null, "a": "1", "b": "2", "d e f": "a b c"}

query T
SELECT jsonb_object('{a,b,"","d e f"}'::TEXT[],'{1,2,3,"a b c"}'::TEXT[])
----
{"": "3", "a": "1", "b": "2", "d e f": "a b c"}

query T
SELECT jsonb_object('{a,b,c,"d e f"}'::TEXT[],'{1,2,3,"a b c"}'::TEXT[])
----
{"a": "1", "b": "2", "c": "3", "d e f": "a b c"}

query error pq: cannot deconstruct an array as an object
SELECT json_each('[1]'::JSON)

query error pq: cannot deconstruct a scalar
SELECT json_each('null'::JSON)

query TT
SELECT * FROM json_each('{}') q
----

query T colnames,nosort
SELECT json_each('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}')
----
json_each
(f1,"[1, 2, 3]")
(f2,"{""f3"": 1}")
(f4,null)
(f5,99)
(f6,"""stringy""")

query TT colnames,nosort
SELECT * FROM json_each('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}') q
----
key  value
f1   [1, 2, 3]
f2   {"f3": 1}
f4   null
f5   99
f6   "stringy"

query error pq: cannot deconstruct an array as an object
SELECT jsonb_each('[1]'::JSON)

query error pq: cannot deconstruct a scalar
SELECT jsonb_each('null'::JSON)

query TT
SELECT * FROM jsonb_each('{}') q
----

query T colnames,nosort
SELECT jsonb_each('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}')
----
jsonb_each
(f1,"[1, 2, 3]")
(f2,"{""f3"": 1}")
(f4,null)
(f5,99)
(f6,"""stringy""")

query TT colnames,nosort
SELECT * FROM jsonb_each('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}') q
----
key  value
f1   [1, 2, 3]
f2   {"f3": 1}
f4   null
f5   99
f6   "stringy"

query error pq: cannot deconstruct an array as an object
SELECT jsonb_each_text('[1]'::JSON)

query error pq: cannot deconstruct a scalar
SELECT jsonb_each_text('null'::JSON)

query TT
SELECT * FROM jsonb_each_text('{}') q
----

query T colnames,nosort
SELECT jsonb_each_text('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}')
----
jsonb_each_text
(f1,"[1, 2, 3]")
(f2,"{""f3"": 1}")
(f4,)
(f5,99)
(f6,stringy)

query T colnames,nosort
SELECT jsonb_each_text('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}') q
----
q
(f1,"[1, 2, 3]")
(f2,"{""f3"": 1}")
(f4,)
(f5,99)
(f6,stringy)

query TT colnames,nosort
SELECT * FROM jsonb_each_text('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}') q
----
key  value
f1   [1, 2, 3]
f2   {"f3": 1}
f4   NULL
f5   99
f6   stringy

query error pq: cannot deconstruct an array as an object
SELECT json_each_text('[1]'::JSON)

query error pq: cannot deconstruct a scalar
SELECT json_each_text('null'::JSON)

query TT
SELECT * FROM json_each_text('{}') q
----

query TT
SELECT * FROM json_each_text('{}') q
----

query T colnames,nosort
SELECT json_each_text('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}')
----
json_each_text
(f1,"[1, 2, 3]")
(f2,"{""f3"": 1}")
(f4,)
(f5,99)
(f6,stringy)

query T colnames,nosort
SELECT json_each_text('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}') q
----
q
(f1,"[1, 2, 3]")
(f2,"{""f3"": 1}")
(f4,)
(f5,99)
(f6,stringy)

query TT colnames,nosort
SELECT * FROM json_each_text('{"f1":[1,2,3],"f2":{"f3":1},"f4":null,"f5":99,"f6":"stringy"}') q
----
key  value
f1   [1, 2, 3]
f2   {"f3": 1}
f4   NULL
f5   99
f6   stringy

query T
SELECT json_set('{"a":1}', '{a}'::STRING[], '2')
----
{"a": 2}

query T
SELECT jsonb_set('{"a":1}', '{b}'::STRING[], '2')
----
{"a": 1, "b": 2}

statement error path element at position 1 is null
SELECT jsonb_set('{"a":1}', ARRAY[null, 'foo']::STRING[], '2')

statement error path element at position 1 is null
SELECT jsonb_set('{"a":1}', '{null,foo}'::STRING[], '2', true)

statement error path element at position 2 is null
SELECT jsonb_set('{"a":1}', '{foo,null}'::STRING[], '2', true)

query T
SELECT jsonb_set('{"a":1}', '{b}'::STRING[], '2', true)
----
{"a": 1, "b": 2}

query T
SELECT jsonb_set('{"a":1}', '{b}'::STRING[], '2', false)
----
{"a": 1}

query T
SELECT jsonb_set('[{"f1":1,"f2":null},2,null,3]', '{0,f1}'::STRING[], '[2,3,4]', false)
----
[{"f1": [2, 3, 4], "f2": null}, 2, null, 3]

query T
SELECT jsonb_set('[{"f1":1,"f2":null},2]', '{0,f3}'::STRING[], '[2,3,4]')
----
[{"f1": 1, "f2": null, "f3": [2, 3, 4]}, 2]

query T
SELECT jsonb_insert('{"a": [0, 1, 2]}', '{a, 1}'::STRING[], '"new_value"');
----
{"a": [0, "new_value", 1, 2]}

query T
SELECT jsonb_insert('[0, 1, 2, {"a": ["a", "b", "d"]}, 4]', '{3, a, 2}'::STRING[], '"c"')
----
[0, 1, 2, {"a": ["a", "b", "c", "d"]}, 4]

query T
SELECT jsonb_insert('{"a": "foo"}', '{b}'::STRING[], '"bar"')
----
{"a": "foo", "b": "bar"}

query T
SELECT jsonb_insert(NULL, '{a}', NULL, false)
----
NULL

query T
SELECT jsonb_insert('{"a": [0, 1, 2]}', '{a, 1}'::STRING[], '"new_value"', true)
----
{"a": [0, 1, "new_value", 2]}

query T
SELECT jsonb_insert('{"a": [0, 1, 2]}', '{a, -1}'::STRING[], '"new_value"', true)
----
{"a": [0, 1, 2, "new_value"]}

query error pq: jsonb_insert\(\): cannot replace existing key
SELECT jsonb_insert('{"a": "foo"}', '{a}'::STRING[], '"new_value"', false)

query T
SELECT jsonb_insert('{"a": "foo"}', '{a, 0}'::STRING[], '"new_value"', false)
----
{"a": "foo"}

query T
SELECT jsonb_insert('[0, 1, 2, 3]', '{3}'::STRING[], '10', true)
----
[0, 1, 2, 3, 10]

statement error cannot set path in scalar
SELECT jsonb_insert('1', '{a}'::STRING[], '10', true)

query T
SELECT jsonb_insert('1', NULL, '10')
----
NULL

statement error path element at position 1 is null
SELECT jsonb_insert('{"a": [0, 1, 2], "b": "hello", "c": "world"}', '{NULL, a, 0}'::STRING[], '"new_val"')

statement error path element at position 2 is null
SELECT jsonb_insert('{"a": [0, 1, 2], "b": "hello", "c": "world"}', '{a, NULL, 0}'::STRING[], '"new_val"')

query T
SELECT jsonb_strip_nulls(NULL)
----
NULL

query T
SELECT json_strip_nulls('1')
----
1

query T
SELECT json_strip_nulls('"a string"')
----
"a string"

query T
SELECT json_strip_nulls('null')
----
null

query T
SELECT json_strip_nulls('[1,2,null,3,4]')
----
[1, 2, null, 3, 4]

query T
SELECT json_strip_nulls('{"a":1,"b":null,"c":[2,null,3],"d":{"e":4,"f":null}}')
----
{"a": 1, "c": [2, null, 3], "d": {"e": 4}}

query T
SELECT json_strip_nulls('[1,{"a":1,"b":null,"c":2},3]')
----
[1, {"a": 1, "c": 2}, 3]

query T
SELECT jsonb_strip_nulls('{"a": {"b": null, "c": null}, "d": {}}')
----
{"a": {}, "d": {}}

query T
SELECT jsonb_strip_nulls(NULL)
----
NULL

query T
SELECT jsonb_strip_nulls('1')
----
1

query T
SELECT jsonb_strip_nulls('"a string"')
----
"a string"

query T
SELECT jsonb_strip_nulls('null')
----
null

query T
SELECT jsonb_strip_nulls('[1,2,null,3,4]')
----
[1, 2, null, 3, 4]

query T
SELECT jsonb_strip_nulls('{"a":1,"b":null,"c":[2,null,3],"d":{"e":4,"f":null}}')
----
{"a": 1, "c": [2, null, 3], "d": {"e": 4}}

query T
SELECT jsonb_strip_nulls('[1,{"a":1,"b":null,"c":2},3]')
----
[1, {"a": 1, "c": 2}, 3]

query T
SELECT jsonb_strip_nulls('{"a": {"b": null, "c": null}, "d": {}}')
----
{"a": {}, "d": {}}

query error pq: json_array_length\(\): cannot get array length of a non-array
SELECT json_array_length('{"f1":1,"f2":[5,6]}')

query error pq: json_array_length\(\): cannot get array length of a scalar
SELECT json_array_length('4')

query I
SELECT json_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]')
----
5

query I
SELECT json_array_length('[]')
----
0

query error pq: jsonb_array_length\(\): cannot get array length of a non-array
SELECT jsonb_array_length('{"f1":1,"f2":[5,6]}')

query error pq: jsonb_array_length\(\): cannot get array length of a scalar
SELECT jsonb_array_length('4')

query I
SELECT jsonb_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]')
----
5

query I
SELECT jsonb_array_length('[]')
----
0

query TTT
SELECT row_to_json(row(1,'foo')), row_to_json(NULL), row_to_json(row())
----
{"f1": 1, "f2": "foo"}  NULL  {}

query T
SELECT row_to_json(x) FROM (SELECT 1 AS "OnE", 2 AS "tO_") x
----
{"OnE": 1, "tO_": 2}


# TODO(jordan,radu): this should also work without the .*.
query T
select row_to_json(t.*)
from (
  select 1 as a, 2 as b
) t
----
{"a": 1, "b": 2}

query T
SELECT '["a", {"b":1}]'::jsonb #- '{1,b}'
----
["a", {}]

query BBBBBBBB
select
       jsonb_exists_any('{"id":12,"name":"Michael","address": {"postcode":12,"state":"California"}}'::jsonb, array['id']),
       jsonb_exists_any('{"id":12,"name":"Michael","address": {"postcode":12,"state":"California"}}'::jsonb->'address', array['state']),
       jsonb_exists_any('{"id":12,"name":"Michael","address": {"postcode":12,"state":"California"}}'::jsonb, array[NULL,'id']),
       jsonb_exists_any('{"id":12,"name":"Michael","address": {"postcode":12,"state":"California"}}'::jsonb, array[NULL,'ids']),
       jsonb_exists_any('["a","b"]', array['a']),
       jsonb_exists_any('["a", 10, 12]', '{"a"}'::text[]),
       jsonb_exists_any('["a"]', '{"a"}'),
       jsonb_exists_any('["a"]', '{}');
----
true	true	true	false	true	true	true	false

query error pq: unknown signature: jsonb_exists_any\(jsonb, int\[\]\)
select
    jsonb_exists_any('{"id":12,"name":"Michael","address": {"postcode":12,"state":"California"}}'::jsonb, array[1]);

query error pq: jsonb_exists_any\(\): could not parse "id" as type int: strconv\.ParseInt: parsing "id": invalid syntax
select
    jsonb_exists_any('{"id":12,"name":"Michael","address": {"postcode":12,"state":"California"}}'::jsonb, array['id',1]);

# json_populate_record
query FIII colnames
SELECT *, c FROM json_populate_record(((1.01, 2, 3) AS d, c, a), '{"a": 3, "c": 10, "d": 11.001}')
----
d       c   a c
11.001  10  3 10

query BTT colnames
SELECT * FROM json_populate_record(((true, ARRAY[1], ARRAY['f']) AS a, b, c), '{"a": true, "b": [1,2], "c": ["a", "b"]}')
----
a     b      c
true  {1,2}  {a,b}

query BT colnames
SELECT * FROM json_populate_record(((true, ((1, 'bar', ARRAY['a']) AS x, y, z)) AS a, b), '{"a": true, "b": {"x": "3", "y": "foo", "z": ["a", "b"]}}')
----
a     b
true  (3,foo,"{a,b}")

query BI colnames
SELECT * FROM json_populate_record(((true, 3) AS a, b), '{"a": null, "b": null}')
----
a     b
NULL  NULL

query T colnames
SELECT json_populate_record(((1.01, 2, 3) AS d, c, a), '{"a": 3, "c": 10, "d": 11.001}')
----
json_populate_record
(11.001,10,3)

query T colnames
SELECT json_populate_record(((1.01, 2) AS a, b), '{"a": "1.2345", "b": "33"}')
----
json_populate_record
(1.2345,33)

query F colnames
SELECT (json_populate_record(((1.01, 2, 3) AS d, c, a), '{"a": 3, "c": 10, "d": 11.001}')).d
----
d
11.001

statement error argument of json_populate_record must be an object
SELECT * FROM json_populate_record(((1, 2) AS a, b), '"a"')

statement ok
CREATE TABLE testtab (
	i	int,
	ia	int[],
	t	text,
	ta	text[],
	ts	timestamp,
	j	jsonb
)

query ITTTTT
SELECT * FROM json_populate_record(NULL::testtab, '{"i": 3, "ia": [1,2,3], "t": "foo", "ta": ["a", "b"], "ts": "2017-01-01 00:00", "j": {"a": "b", "c": 3, "d": [1,false,true,null,{"1":"2"}]}}'::JSON)
----
3  {1,2,3}  foo  {a,b}  2017-01-01 00:00:00 +0000 +0000  {"a": "b", "c": 3, "d": [1, false, true, null, {"1": "2"}]}

query T
SELECT json_populate_record(NULL::testtab, '{"i": 3, "ia": [1,2,3], "t": "foo", "ta": ["a", "b"], "ts": "2017-01-01 00:00", "j": {"a": "b", "c": 3, "d": [1,false,true,null,{"1":"2"}]}}'::JSON)
----
(3,"{1,2,3}",foo,"{a,b}","2017-01-01 00:00:00","{""a"": ""b"", ""c"": 3, ""d"": [1, false, true, null, {""1"": ""2""}]}")

query ITTTTT
SELECT * FROM json_populate_record(NULL::testtab, NULL)
----
NULL  NULL  NULL  NULL  NULL  NULL

query error could not parse \"foo\" as type int
SELECT json_populate_record(((3,) AS a), '{"a": "foo"}')

query error anonymous records cannot be used with json{b}_populate_record{set}
SELECT * FROM json_populate_record((1,2,3,4), '{"a": 3, "c": 10, "d": 11.001}')

query error anonymous records cannot be used with json{b}_populate_record{set}
SELECT * FROM json_populate_record(NULL, '{"a": 3, "c": 10, "d": 11.001}')

query error first argument of json{b}_populate_record{set} must be a record type
SELECT * FROM json_populate_record(1, '{"a": 3, "c": 10, "d": 11.001}')

query error first argument of json{b}_populate_record{set} must be a record type
SELECT * FROM json_populate_record(NULL::INT, '{"a": 3, "c": 10, "d": 11.001}')

query error anonymous records cannot be used with json{b}_populate_record{set}
SELECT * FROM json_populate_record(NULL::record, '{"a": 3, "c": 10, "d": 11.001}')

query error anonymous records cannot be used with json{b}_populate_record{set}
SELECT * FROM json_populate_recordset(NULL, '[{"a": 3, "c": 10, "d": 11.001}, {}]')

query error first argument of json{b}_populate_record{set} must be a record type
SELECT * FROM json_populate_recordset(NULL::INT, '[{"a": 3, "c": 10, "d": 11.001}, {}]')

query I
SELECT * FROM json_populate_record(((3,) AS a), NULL)
----
3

query FIII colnames,nosort
SELECT *, c FROM json_populate_recordset(((1.01, 2, 3) AS d, c, a), '[{"a": 3, "c": 10, "d": 11.001}, {}]')
----
d       c   a  c
11.001  10  3  10
1.01    2   3  2

query FITI colnames,nosort
SELECT *, c FROM json_populate_recordset(((NULL::NUMERIC, 2::INT, 3::TEXT) AS d, c, a), '[{"a": 3, "c": 10, "d": 11.001}, {}]')
----
d       c   a  c
11.001  10  3  10
NULL    2   3  2

query FIT
SELECT * FROM json_populate_recordset(((NULL::NUMERIC, 2::INT, 3::TEXT) AS d, c, a), NULL)
----

query FIT
SELECT * FROM json_populate_recordset(((NULL::NUMERIC, 2::INT, 3::TEXT) AS d, c, a), '[]')
----

query error argument of json_populate_recordset must be an array
SELECT * FROM json_populate_recordset(((NULL::NUMERIC, 2::INT, 3::TEXT) AS d, c, a), '{"foo": "bar"}')

query error argument of json_populate_recordset must be an array
SELECT * FROM json_populate_recordset(((NULL::NUMERIC, 2::INT, 3::TEXT) AS d, c, a), 'true')

query error argument of json_populate_recordset must be an array
SELECT * FROM json_populate_recordset(((NULL::NUMERIC, 2::INT, 3::TEXT) AS d, c, a), '0')

query error argument of json_populate_recordset must be an array
SELECT * FROM json_populate_recordset(((NULL::NUMERIC, 2::INT, 3::TEXT) AS d, c, a), 'null')

query error argument of json_populate_recordset must be an array of objects
SELECT * FROM json_populate_recordset(((NULL::NUMERIC, 2::INT, 3::TEXT) AS d, c, a), '[null]')

query error argument of json_populate_recordset must be an array of objects
SELECT * FROM json_populate_recordset(((NULL::NUMERIC, 2::INT, 3::TEXT) AS d, c, a), '[{"foo":"bar"}, 3]')

query ITTTTT nosort
SELECT * FROM json_populate_recordset(NULL::testtab, '[{"i": 3, "ia": [1,2,3], "t": "foo", "ta": ["a", "b"], "ts": "2017-01-01 00:00", "j": {"a": "b", "c": 3, "d": [1,false,true,null,{"1":"2"}]}}, {}]'::JSON)
----
3     {1,2,3}  foo   {a,b}  2017-01-01 00:00:00 +0000 +0000  {"a": "b", "c": 3, "d": [1, false, true, null, {"1": "2"}]}
NULL  NULL     NULL  NULL   NULL                             NULL

query error invalid non-object argument to json_to_record
SELECT * FROM json_to_record('3') AS t(a INT)

query error invalid non-object argument to json_to_record
SELECT * FROM json_to_record('"a"') AS t(a TEXT)

query error invalid non-object argument to json_to_record
SELECT * FROM json_to_record('null') AS t(a INT)

query error invalid non-object argument to json_to_record
SELECT * FROM json_to_record('true') AS t(a INT)

query error invalid non-object argument to json_to_record
SELECT * FROM json_to_record('[1,2]') AS t(a INT)

query error column definition list is required for functions returning \"record\"
SELECT * FROM json_to_record('{"a": "b"}') AS t(a)

query error column definition list is required for functions returning \"record\"
SELECT * FROM json_to_record('{"a": "b"}')

# Test that non-record generators don't permit col definition lists (with types).
query error a column definition list is only allowed for functions returning \"record\"
SELECT * FROM generate_series(1,10) g(g int)

statement ok
CREATE TABLE j (j) AS SELECT '{
  "str": "a",
  "int": 1,
  "bool": true,
  "nul": null,
  "dec": 2.45,
  "arrint": [1,2],
  "arrmixed": [1,2,true],
  "arrstr": ["a", "b"],
  "arrbool": [true, false],
  "obj": {"i": 3, "t": "blah", "z": true}
  }'::JSONB

statement ok
INSERT INTO j VALUES('{"str": "zzz"}')

query TIBTFTTTTT
SELECT t.* FROM j, json_to_record(j.j) AS t(
  str TEXT,
  int INT,
  bool BOOL,
  nul TEXT,
  dec DECIMAL,
  arrint INT[],
  arrmixed TEXT,
  arrstr TEXT[],
  arrbool BOOL[],
  obj TEXT
) ORDER BY rowid
----
a    1     true  NULL  2.45  {1,2}  [1, 2, true]  {a,b}  {t,f}  {"i": 3, "t": "blah", "z": true}
zzz  NULL  NULL  NULL  NULL  NULL   NULL          NULL   NULL   NULL

# Test that mismatched types return an error
query error could not parse \"true\" as type int
SELECT t.bool FROM j, json_to_record(j.j) AS t(bool INT)

# But types can be coerced.
query TT rowsort
SELECT t.* FROM j, json_to_record(j.j) AS t(int TEXT, bool TEXT)
----
1     true
NULL  NULL

# Mixed type arrays
query error could not parse \"2\" as type bool
SELECT t.arrmixed FROM j, json_to_record(j.j) AS t(arrmixed BOOL[])

# Record with custom type
query T rowsort
SELECT t.obj FROM j, json_to_record(j.j) AS t(obj testtab)
----
(3,,blah,,,)
NULL

# Test json_to_recordset
query TIBTFTTTTT
SELECT t.* FROM j, json_to_recordset(j.j || '[]' || j.j) AS t(
  str TEXT,
  int INT,
  bool BOOL,
  nul TEXT,
  dec DECIMAL,
  arrint INT[],
  arrmixed TEXT,
  arrstr TEXT[],
  arrbool BOOL[],
  obj TEXT
) ORDER BY rowid
----
a    1     true  NULL  2.45  {1,2}  [1, 2, true]  {a,b}  {t,f}  {"i": 3, "t": "blah", "z": true}
a    1     true  NULL  2.45  {1,2}  [1, 2, true]  {a,b}  {t,f}  {"i": 3, "t": "blah", "z": true}
zzz  NULL  NULL  NULL  NULL  NULL   NULL          NULL   NULL   NULL
zzz  NULL  NULL  NULL  NULL  NULL   NULL          NULL   NULL   NULL

query TT rowsort
SELECT * FROM jsonb_to_recordset('[{"foo": "bar"}, {"foo": "bar2"}]') AS t(foo TEXT),
              jsonb_to_recordset('[{"foo": "blah"}, {"foo": "blah2"}]') AS u(foo TEXT)
----
bar   blah
bar   blah2
bar2  blah
bar2  blah2

# Regression test for incorrectly using jsonString.String() for asserting that
# keys are ordered in the jsonObject (#121326).
query T rowsort
WITH cte(col) AS (
  VALUES
    ('false'::JSONB),
    (jsonb_object(ARRAY['0', '', e'\x14', '']::TEXT[]))
  )
SELECT jsonb_object_agg('k', 'v') OVER (PARTITION BY cte.col) FROM cte;
----
{"k": "v"}
{"k": "v"}
