# Add JSON columns as primary index.
statement ok
CREATE TABLE t (x JSONB PRIMARY KEY)

# Adding JSON primitive types.
statement ok
INSERT INTO t VALUES
  ('"a"'::JSONB),
  ('"b"'::JSONB),
  ('"aa"'::JSONB),
  ('"abcdefghi"'::JSONB),
  ('100'::JSONB),
  ('1'::JSONB),
  ('{"a": "b"}'),
  ('[]')

# Ensuring the ordering is intact.
query T
SELECT x FROM t ORDER BY x
----
[]
"a"
"aa"
"abcdefghi"
"b"
1
100
{"a": "b"}


# Test that unique indexes reject bad inserts.
statement error pq: duplicate key value violates unique constraint "t_pkey"
INSERT INTO t VALUES
  ('"a"'::JSONB)

query T
SELECT x FROM t@t_pkey ORDER BY x
----
[]
"a"
"aa"
"abcdefghi"
"b"
1
100
{"a": "b"}

# Use the index for point lookups.
query T
SELECT x FROM t@t_pkey WHERE x = '"a"'
----
"a"

query T
SELECT x FROM t@t_pkey WHERE x = '"aa"'
----
"aa"

query T
SELECT x FROM t@t_pkey WHERE x = '100'
----
100

query T
SELECT x FROM t@t_pkey WHERE x = '12'
----

query T
SELECT x FROM t@t_pkey WHERE x = '{"a": "b"}'
----
{"a": "b"}

# Using the index for bounded scans.
query T
SELECT x FROM t@t_pkey WHERE x > '1' ORDER BY x
----
100
{"a": "b"}

query T
SELECT x FROM t@t_pkey WHERE x < '1' ORDER BY x
----
[]
"a"
"aa"
"abcdefghi"
"b"


query T
SELECT x FROM t@t_pkey WHERE x > '1' OR x < '1' ORDER BY x
----
[]
"a"
"aa"
"abcdefghi"
"b"
100
{"a": "b"}

query T
SELECT x FROM t@t_pkey WHERE x > '1' AND x < '1' ORDER BY x
----

# Trying to order by in a descending fashion.
query T
SELECT x FROM t@t_pkey WHERE x > '1' OR x < '1' ORDER BY x DESC
----
{"a": "b"}
100
"b"
"abcdefghi"
"aa"
"a"
[]

# Adding more primitive JSON values.
statement ok
INSERT INTO t VALUES
  ('true'),
  ('false'),
  ('null'),
  ('"aaaaaaayouube"'),
  ('"testing spaces"'),
  ('"Testing Punctuation?!."')

query T
SELECT x FROM t@t_pkey ORDER BY x
----
[]
null
"Testing Punctuation?!."
"a"
"aa"
"aaaaaaayouube"
"abcdefghi"
"b"
"testing spaces"
1
100
false
true
{"a": "b"}

query T
SELECT x FROM t@t_pkey WHERE x > 'true' ORDER BY x
----
{"a": "b"}

query T
SELECT x FROM t@t_pkey WHERE x < 'false' ORDER BY x
----
[]
null
"Testing Punctuation?!."
"a"
"aa"
"aaaaaaayouube"
"abcdefghi"
"b"
"testing spaces"
1
100

# Testing JSON Arrays.
statement ok
DROP TABLE IF EXISTS t;
CREATE TABLE t (x JSONB PRIMARY KEY)

statement ok
INSERT INTO t VALUES
  ('[]'),
  ('[null]'),
  ('[1]'),
  ('[null, null, false, true, "a", 1]'),
  ('[{"a":"b"}]'),
  ('[{"a":"b", "c": [1, 2, 3, 4, 5]}]')

query T
SELECT x FROM t@t_pkey ORDER BY x
----
[]
[null]
[1]
[{"a": "b"}]
[{"a": "b", "c": [1, 2, 3, 4, 5]}]
[null, null, false, true, "a", 1]

query T
SELECT x FROM t@t_pkey where x = '[1]' ORDER BY x
----
[1]

query T
SELECT x FROM t@t_pkey where x >= '[1]' ORDER BY x
----
[1]
[{"a": "b"}]
[{"a": "b", "c": [1, 2, 3, 4, 5]}]
[null, null, false, true, "a", 1]

query T
SELECT x FROM t@t_pkey where x <= '[1]' ORDER BY x
----
[]
[null]
[1]

query T
SELECT x FROM t@t_pkey where x >= '[1]' AND x <= '{"a": "b"}' ORDER BY x
----
[1]
[{"a": "b"}]
[{"a": "b", "c": [1, 2, 3, 4, 5]}]
[null, null, false, true, "a", 1]

# Nested JSON Arrays.
statement ok
INSERT INTO t VALUES
  ('[1, [2, 3]]'),
  ('[1, [2, [3, [4]]]]')

query T
SELECT x FROM t@t_pkey WHERE x = '[1, [2, 3]]' ORDER BY x
----
[1, [2, 3]]

query T
SELECT x FROM t@t_pkey WHERE x = '[1, [2, [3, [4]]]]' ORDER BY x
----
[1, [2, [3, [4]]]]

# Testing the ordering again.
query T
SELECT x FROM t@t_pkey ORDER BY x
----
[]
[null]
[1]
[{"a": "b"}]
[{"a": "b", "c": [1, 2, 3, 4, 5]}]
[1, [2, 3]]
[1, [2, [3, [4]]]]
[null, null, false, true, "a", 1]

# Testing the scans with nested arrays.
query T
SELECT x FROM t@t_pkey WHERE x < '[1, [2, [3, [4]]]]' ORDER BY X
----
[]
[null]
[1]
[{"a": "b"}]
[{"a": "b", "c": [1, 2, 3, 4, 5]}]
[1, [2, 3]]

# Testing JSON Objects.
statement ok
DROP TABLE IF EXISTS t;
CREATE TABLE t (x JSONB PRIMARY KEY)

statement ok
INSERT INTO t VALUES
  ('{}'),
  ('{"a": 1}'),
  ('{"a": "sh", "b": 1}'),
  ('{"a": ["1"]}'),
  ('{"a": [{"b":"c"}]}'),
  ('{"c": true, "d": null, "newkey": "newvalue"}'),
  ('{"e": {"f": {"g": 1}}, "f": [1, 2, 3]}'),
  ('{ "aa": 1, "c": 1}'),
  ('{"b": 1, "d": 1}')

# Testing the ordering again.
query T
SELECT x FROM t@t_pkey ORDER BY x
----
{}
{"a": 1}
{"a": ["1"]}
{"a": [{"b": "c"}]}
{"a": "sh", "b": 1}
{"aa": 1, "c": 1}
{"b": 1, "d": 1}
{"e": {"f": {"g": 1}}, "f": [1, 2, 3]}
{"c": true, "d": null, "newkey": "newvalue"}

query T
SELECT x FROM t@t_pkey WHERE x >= '{}' ORDER BY x;
----
{}
{"a": 1}
{"a": ["1"]}
{"a": [{"b": "c"}]}
{"a": "sh", "b": 1}
{"aa": 1, "c": 1}
{"b": 1, "d": 1}
{"e": {"f": {"g": 1}}, "f": [1, 2, 3]}
{"c": true, "d": null, "newkey": "newvalue"}

query T
SELECT x FROM t@t_pkey WHERE x < '{}' ORDER BY x;
----

query T
SELECT x FROM t@t_pkey WHERE x = '{"e": {"f": {"g": 1}}, "f": [1, 2, 3]}' ORDER BY x;
----
{"e": {"f": {"g": 1}}, "f": [1, 2, 3]}

# Ensure that we can order by JSONs without any indexes.
statement ok
DROP TABLE t;
CREATE TABLE t (x JSONB);
INSERT INTO t VALUES
  ('{}'),
  ('[]'),
  ('true'),
  ('false'),
  ('null'),
  ('"crdb"'),
  ('[1, 2, 3]'),
  ('1'),
  ('{"a": "b", "c": "d"}'),
  (NULL)


query T
SELECT x FROM t@t_pkey ORDER BY x
----
NULL
[]
null
"crdb"
1
false
true
[1, 2, 3]
{}
{"a": "b", "c": "d"}

query T
SELECT x FROM t@t_pkey ORDER BY x DESC
----
{"a": "b", "c": "d"}
{}
[1, 2, 3]
true
false
1
"crdb"
null
[]
NULL

# Test to show JSON Null is different from NULL.
query T
SELECT x FROM t@t_pkey WHERE x IS NOT NULL ORDER BY x
----
[]
null
"crdb"
1
false
true
[1, 2, 3]
{}
{"a": "b", "c": "d"}


# Test JSONs of composite types without an index.
statement ok
CREATE TABLE tjson(x JSONB);
INSERT INTO tjson VALUES
  ('1.250'),
  ('1.0'),
  ('1.000'),
  ('1.111111'),
  ('10'),
  ('[1, 2.0, 1.21, 1.00]'),
  ('{"a": [1, 1.1], "b": 1.0000, "c": 10.0}')

# Ensure these are round tripped correctly.
query T
SELECT x FROM tjson ORDER BY x, rowid
----
1.0
1.000
1.111111
1.250
10
[1, 2.0, 1.21, 1.00]
{"a": [1, 1.1], "b": 1.0000, "c": 10.0}

# Test JSONs of composite types with an index.
statement ok
CREATE TABLE y(x JSONB PRIMARY KEY);
INSERT INTO y VALUES
  ('1.00'),
  ('1.250'),
  ('10'),
  ('[1, 2.0, 1.21, 1.00]'),
  ('{"a": [1, 1.1], "b": 1.0000, "c": 10.0}')

# Ensure these are round tripped correctly.
query T
SELECT x FROM y ORDER BY x
----
1.00
1.250
10
[1, 2.0, 1.21, 1.00]
{"a": [1, 1.1], "b": 1.0000, "c": 10.0}

# Test that unique indexes reject bad inserts for composite types.
statement error pq: duplicate key value violates unique constraint "y_pkey"
INSERT INTO y VALUES
  ('1.0000')

# Testing with the descending designation.
statement ok
DROP TABLE t;
CREATE TABLE t (x JSONB)

statement ok
CREATE INDEX i ON t(x DESC)

statement ok
INSERT INTO t VALUES
  ('{}'),
  ('[]'),
  ('true'),
  ('false'),
  ('null'),
  ('"crdb"'),
  ('[1, 2, 3]'),
  ('1'),
  ('{"a": "b", "c": "d"}'),
  ('[null]'),
  ('[1]'),
  ('[null, null, false, true, "a", 1]'),
  ('[{"a":"b"}]'),
  ('[{"a":"b", "c": [1, 2, 3, 4, 5]}]')

query T
SELECT x FROM t@i ORDER BY x;
----
[]
null
"crdb"
1
false
true
[null]
[1]
[{"a": "b"}]
[{"a": "b", "c": [1, 2, 3, 4, 5]}]
[1, 2, 3]
[null, null, false, true, "a", 1]
{}
{"a": "b", "c": "d"}


# Testing different joins on indexed JSONs.
statement ok
DROP TABLE IF EXISTS t1, t2 CASCADE;
CREATE TABLE t1 (x JSONB PRIMARY KEY);
CREATE TABLE t2 (x JSONB PRIMARY KEY);
INSERT INTO t1 VALUES
  ('[1, [2, 3]]'),
  ('[1, [2, [3, [4]]]]');
INSERT INTO t2 VALUES
  ('[1, [2, 3]]'),
  ('{}'),
  ('[1, [2, 4]]')


query T rowsort
SELECT t1.x FROM t1 INNER MERGE JOIN t2 ON t1.x = t2.x
----
[1, [2, 3]]

query T rowsort
SELECT t1.x FROM t1 INNER LOOKUP JOIN t2 ON t1.x = t2.x
----
[1, [2, 3]]

# Regression test for not supporting vectorized span encoder for JSONs (#101356).
statement ok
CREATE TABLE t101356 (j JSONB PRIMARY KEY, i1 INT, i2 INT, INDEX (i1));
INSERT INTO t101356 VALUES ('1'::JSON, 1, 1);

# This query reads from the index and then performs the index join - during the
# index join is when the vectorized span encoder is utilized.
query TII
SELECT * FROM t101356 WHERE i1 = 1
----
1  1  1
