# LogicTest: local

statement ok
CREATE TABLE t (x JSONB PRIMARY KEY)

# Testing range scans on forward indexes.

query T
EXPLAIN SELECT x FROM t WHERE x = 'null'::JSONB
----
distribution: local
vectorized: true
·
• scan
  missing stats
  table: t@t_pkey
  spans: [/'null' - /'null']

query T
EXPLAIN SELECT x FROM t WHERE x = '"a"'::JSONB
----
distribution: local
vectorized: true
·
• scan
  missing stats
  table: t@t_pkey
  spans: [/'"a"' - /'"a"']

query T
EXPLAIN SELECT x FROM t WHERE x = '1'::JSONB
----
distribution: local
vectorized: true
·
• scan
  missing stats
  table: t@t_pkey
  spans: [/'1' - /'1']

query T
EXPLAIN SELECT x FROM t WHERE x = 'false'::JSONB
----
distribution: local
vectorized: true
·
• scan
  missing stats
  table: t@t_pkey
  spans: [/'false' - /'false']

query T
EXPLAIN SELECT x FROM t WHERE x = 'true'::JSONB
----
distribution: local
vectorized: true
·
• scan
  missing stats
  table: t@t_pkey
  spans: [/'true' - /'true']

query T
EXPLAIN SELECT x from t WHERE x = '[1, 2, 3]'::JSONB
----
distribution: local
vectorized: true
·
• scan
  missing stats
  table: t@t_pkey
  spans: [/'[1, 2, 3]' - /'[1, 2, 3]']


query T
EXPLAIN SELECT x from t WHERE x = '{"a": [1, 2, 3], "b": [1, 2]}'::JSONB
----
distribution: local
vectorized: true
·
• scan
  missing stats
  table: t@t_pkey
  spans: [/'{"a": [1, 2, 3], "b": [1, 2]}' - /'{"a": [1, 2, 3], "b": [1, 2]}']


query T
EXPLAIN SELECT x FROM t WHERE x < '1'::JSONB
----
distribution: local
vectorized: true
·
• scan
  missing stats
  table: t@t_pkey
  spans: [ - /'1')

query T
EXPLAIN SELECT x FROM t WHERE x < '"ABCD"'::JSONB
----
distribution: local
vectorized: true
·
• scan
  missing stats
  table: t@t_pkey
  spans: [ - /'"ABCD"')

query T
EXPLAIN SELECT x FROM t WHERE x < '[1, 2, 3]'::JSONB
----
distribution: local
vectorized: true
·
• scan
  missing stats
  table: t@t_pkey
  spans: [ - /'[1, 2, 3]')

query T
EXPLAIN SELECT x FROM t WHERE x <= '[]'::JSONB
----
distribution: local
vectorized: true
·
• scan
  missing stats
  table: t@t_pkey
  spans: [ - /'[]']

query T
EXPLAIN SELECT x FROM t WHERE x > '{"a": "b"}'::JSONB
----
distribution: local
vectorized: true
·
• scan
  missing stats
  table: t@t_pkey
  spans: (/'{"a": "b"}' - ]

query T
EXPLAIN SELECT x FROM t WHERE x > '{"a": "b"}'::JSONB
----
distribution: local
vectorized: true
·
• scan
  missing stats
  table: t@t_pkey
  spans: (/'{"a": "b"}' - ]

query T
EXPLAIN SELECT x FROM t WHERE x > '{"a": "b"}'::JSONB AND x < '[1, 2, 3]'::JSONB
----
distribution: local
vectorized: true
·
• norows

query T
EXPLAIN SELECT x FROM t WHERE x <= '{"a": "b"}'::JSONB AND x >= '[1, 2, 3]'::JSONB
----
distribution: local
vectorized: true
·
• scan
  missing stats
  table: t@t_pkey
  spans: [/'[1, 2, 3]' - /'{"a": "b"}']

query T
EXPLAIN SELECT x FROM t WHERE x <= '"a"'::JSONB OR x >= 'null'::JSONB
----
distribution: local
vectorized: true
·
• filter
│ filter: (x <= '"a"') OR (x >= 'null')
│
└── • scan
      missing stats
      table: t@t_pkey
      spans: FULL SCAN

# Tests to show multiple spans are generated with an IN operator.

query T
EXPLAIN SELECT x FROM t WHERE x IN ('1', '"a"', '[1, 2, 3]', '{"a": "b"}')
----
distribution: local
vectorized: true
·
• scan
  missing stats
  table: t@t_pkey
  spans: [/'"a"' - /'"a"'] [/'1' - /'1'] [/'[1, 2, 3]' - /'[1, 2, 3]'] [/'{"a": "b"}' - /'{"a": "b"}']

query T
EXPLAIN SELECT x FROM t WHERE x IN ('null', '{}', '[]', '""')
----
distribution: local
vectorized: true
·
• scan
  missing stats
  table: t@t_pkey
  spans: [/'[]' - /'[]'] [/'null' - /'null'] [/'""' - /'""'] [/'{}' - /'{}']

# Multicolumn index, including JSONB

statement ok
CREATE TABLE s (x INT, y JSONB, z INT, INDEX i (x, y, z))


query T
EXPLAIN SELECT x, y, z FROM s WHERE x = 2 AND y < '[1, 2, 3]'::JSONB AND z = 100
----
distribution: local
vectorized: true
·
• filter
│ filter: z = 100
│
└── • scan
      missing stats
      table: s@i
      spans: (/2/NULL - /2/'[1, 2, 3]')

query T
EXPLAIN SELECT x, y, z FROM s WHERE y >= '"a"'::JSONB
----
distribution: local
vectorized: true
·
• filter
│ filter: y >= '"a"'
│
└── • scan
      missing stats
      table: s@s_pkey
      spans: FULL SCAN

# Ensuring that the presence of composite values results in
# encoding in the valueside as well for a given K/V pair.
statement ok
CREATE TABLE composite (k INT PRIMARY KEY, j JSONB, FAMILY (k, j));
CREATE INDEX on composite (j);

query T kvtrace
INSERT INTO composite VALUES (1, '1.00'::JSONB), (2, '1'::JSONB), (3, '2'::JSONB),
 (4, '3.0'::JSONB), (5, '"a"'::JSONB)
----
Scan /Table/20/1/10{8-9}
CPut /Table/108/1/1/0 -> /TUPLE/
InitPut /Table/108/2/"H*\x02\x00\x00\x89\x88" -> /BYTES/0x2f0f0c200000002000000403348964
CPut /Table/108/1/2/0 -> /TUPLE/
InitPut /Table/108/2/"H*\x02\x00\x00\x8a\x88" -> /BYTES/
CPut /Table/108/1/3/0 -> /TUPLE/
InitPut /Table/108/2/"H*\x04\x00\x00\x8b\x88" -> /BYTES/
CPut /Table/108/1/4/0 -> /TUPLE/
InitPut /Table/108/2/"H*\x06\x00\x00\x8c\x88" -> /BYTES/0x2f0f0c20000000200000040334891e
CPut /Table/108/1/5/0 -> /TUPLE/
InitPut /Table/108/2/"G\x12a\x00\x01\x00\x8d\x88" -> /BYTES/

query T kvtrace
SELECT j FROM composite where j = '1.00'::JSONB
----
Scan /Table/108/2/"H*\x02\x00\x0{0"-1"}

query T
SELECT j FROM composite ORDER BY j;
----
"a"
1.00
1
2
3.0

# JSON Expression Indexes.
statement ok
CREATE TABLE d (a INT, j JSON);
CREATE INDEX json_expr_index on d ((j->'a'))

statement ok
INSERT INTO d VALUES
        (1, '{"a": "hello"}'),
        (2, '{"a": "b"}'),
        (3, '{"a": "bye"}'),
        (4, '{"a": "json"}')


query T
EXPLAIN SELECT j from d where j->'a' = '"b"'
----
distribution: local
vectorized: true
·
• index join
│ table: d@d_pkey
│
└── • scan
      missing stats
      table: d@json_expr_index
      spans: [/'"b"' - /'"b"']


query T
EXPLAIN SELECT j from d where j->'a' = '"b"' OR j->'a' = '"bye"'
----
distribution: local
vectorized: true
·
• index join
│ table: d@d_pkey
│
└── • scan
      missing stats
      table: d@json_expr_index
      spans: [/'"b"' - /'"b"'] [/'"bye"' - /'"bye"']

# The expression index is not used for this query.
query T
EXPLAIN SELECT j from d where j > '{"a":"b"}'
----
distribution: local
vectorized: true
·
• filter
│ filter: j > '{"a": "b"}'
│
└── • scan
      missing stats
      table: d@d_pkey
      spans: FULL SCAN

query T
EXPLAIN SELECT j from d where j->'a' = '1'
----
distribution: local
vectorized: true
·
• index join
│ table: d@d_pkey
│
└── • scan
      missing stats
      table: d@json_expr_index
      spans: [/'1' - /'1']

query T
EXPLAIN SELECT j from d where j->'a' = 'null'
----
distribution: local
vectorized: true
·
• index join
│ table: d@d_pkey
│
└── • scan
      missing stats
      table: d@json_expr_index
      spans: [/'null' - /'null']

# Inverted Indexes where JSON is also forward indexed.
statement ok
INSERT INTO d VALUES
        (5, '{"a": "forward", "json": "inverted"}'),
        (6, '{"a": "c", "b": "d"}')


statement ok
CREATE INVERTED INDEX json_inv on d ((j->'a'), j)


query T
EXPLAIN SELECT j from d where j->'a' = '"forward"' AND j->'json' = '"inverted"'
----
distribution: local
vectorized: true
·
• index join
│ table: d@d_pkey
│
└── • scan
      missing stats
      table: d@json_inv
      spans: 1 span

query T
EXPLAIN SELECT j from d where j->'a' = '[1, 2, 3]' AND j->'json' = '{}'
----
distribution: local
vectorized: true
·
• filter
│ filter: (j->'json') = '{}'
│
└── • index join
    │ table: d@d_pkey
    │
    └── • inverted filter
        │ inverted column: j_inverted_key
        │ num spans: 2
        │
        └── • scan
              missing stats
              table: d@json_inv
              spans: 2 spans
