# LogicTest: local

# Tests for subqueries (SELECT statements which are part of a bigger statement).

statement ok
CREATE TABLE abc (a INT PRIMARY KEY, b INT, c INT)

# Prevent the merge queue from immediately discarding our splits.
statement ok
SET CLUSTER SETTING kv.range_merge.queue_enabled = false;

query TTT
EXPLAIN ALTER TABLE abc SPLIT AT VALUES ((SELECT 42))
----
root                          ·             ·
 ├── split                    ·             ·
 │    └── values              ·             ·
 │                            size          1 column, 1 row
 └── subquery                 ·             ·
      │                       id            @S1
      │                       original sql  (SELECT 42)
      │                       exec mode     one row
      └── limit               ·             ·
           │                  count         2
           └── render         ·             ·
                └── emptyrow  ·             ·

statement ok
ALTER TABLE abc SPLIT AT VALUES ((SELECT 1))

query TTT
EXPLAIN SELECT EXISTS (SELECT a FROM abc)
----
root                      ·             ·
 ├── render               ·             ·
 │    └── emptyrow        ·             ·
 └── subquery             ·             ·
      │                   id            @S1
      │                   original sql  EXISTS (SELECT a FROM abc)
      │                   exec mode     exists
      └── limit           ·             ·
           │              count         1
           └── render     ·             ·
                └── scan  ·             ·
·                         table         abc@primary
·                         spans         ALL
·                         limit         1

query TTTTT
EXPLAIN (VERBOSE) SELECT * FROM abc WHERE a = (SELECT max(a) FROM abc WHERE EXISTS(SELECT * FROM abc WHERE c=a+3))
----
root                              ·             ·                                                                            (a, b, c)                    a!=NULL; key(a)
 ├── scan                         ·             ·                                                                            (a, b, c)                    a!=NULL; key(a)
 │                                table         abc@primary                                                                  ·                            ·
 │                                spans         ALL                                                                          ·                            ·
 │                                filter        a = @S2                                                                      ·                            ·
 ├── subquery                     ·             ·                                                                            (a, b, c)                    a!=NULL; key(a)
 │    │                           id            @S1                                                                          ·                            ·
 │    │                           original sql  EXISTS (SELECT * FROM abc WHERE c = (a + 3))                                 ·                            ·
 │    │                           exec mode     exists                                                                       ·                            ·
 │    └── limit                   ·             ·                                                                            (a, b[omitted], c)           a!=NULL; c!=NULL; key(a)
 │         │                      count         1                                                                            ·                            ·
 │         └── scan               ·             ·                                                                            (a, b[omitted], c)           a!=NULL; c!=NULL; key(a)
 │                                table         abc@primary                                                                  ·                            ·
 │                                spans         ALL                                                                          ·                            ·
 │                                filter        c = (a + 3)                                                                  ·                            ·
 └── subquery                     ·             ·                                                                            (a, b, c)                    a!=NULL; key(a)
      │                           id            @S2                                                                          ·                            ·
      │                           original sql  (SELECT max(a) FROM abc WHERE EXISTS (SELECT * FROM abc WHERE c = (a + 3)))  ·                            ·
      │                           exec mode     one row                                                                      ·                            ·
      └── limit                   ·             ·                                                                            (max)                        ·
           │                      count         2                                                                            ·                            ·
           └── group              ·             ·                                                                            (max)                        ·
                │                 aggregate 0   max(a)                                                                       ·                            ·
                │                 scalar        ·                                                                            ·                            ·
                └── render        ·             ·                                                                            (a)                          a!=NULL; key(a); -a
                     │            render 0      test.public.abc.a                                                            ·                            ·
                     └── revscan  ·             ·                                                                            (a, b[omitted], c[omitted])  a!=NULL; key(a); -a
·                                 table         abc@primary                                                                  ·                            ·
·                                 spans         ALL                                                                          ·                            ·
·                                 filter        @S1 AND (a IS NOT NULL)                                                      ·                            ·

# check that residual filters are not expanded twice
query TTTTT
EXPLAIN (VERBOSE) SELECT a FROM abc WHERE a IN (SELECT a FROM abc)
----
root                 ·             ·                    (a)                          a!=NULL; key(a)
 ├── render          ·             ·                    (a)                          a!=NULL; key(a)
 │    │              render 0      test.public.abc.a    ·                            ·
 │    └── scan       ·             ·                    (a, b[omitted], c[omitted])  a!=NULL; key(a)
 │                   table         abc@primary          ·                            ·
 │                   spans         ALL                  ·                            ·
 │                   filter        a IN @S1             ·                            ·
 └── subquery        ·             ·                    (a)                          a!=NULL; key(a)
      │              id            @S1                  ·                            ·
      │              original sql  (SELECT a FROM abc)  ·                            ·
      │              exec mode     all rows normalized  ·                            ·
      └── render     ·             ·                    (a)                          a!=NULL; key(a)
           │         render 0      test.public.abc.a    ·                            ·
           └── scan  ·             ·                    (a, b[omitted], c[omitted])  a!=NULL; key(a)
·                    table         abc@primary          ·                            ·
·                    spans         ALL                  ·                            ·

query TTT
EXPLAIN SELECT * FROM (SELECT * FROM (VALUES (1, 8, 8), (3, 1, 1), (2, 4, 4)) AS moo (moo1, moo2, moo3) ORDER BY moo2) as foo (foo1) ORDER BY foo1
----
sort         ·      ·
 │           order  +foo1
 └── values  ·      ·
·            size   3 columns, 3 rows

# the subquery's plan must be visible in EXPLAIN
query TTT
EXPLAIN VALUES (1), ((SELECT 2))
----
root                          ·             ·
 ├── values                   ·             ·
 │                            size          1 column, 2 rows
 └── subquery                 ·             ·
      │                       id            @S1
      │                       original sql  (SELECT 2)
      │                       exec mode     one row
      └── limit               ·             ·
           │                  count         2
           └── render         ·             ·
                └── emptyrow  ·             ·

# This test checks that the double sub-query plan expansion caused by a
# sub-expression being shared by two or more plan nodes does not
# panic.
statement ok
CREATE TABLE tab4(col0 INTEGER, col1 FLOAT, col3 INTEGER, col4 FLOAT)

statement ok
CREATE INDEX idx_tab4_0 ON tab4 (col4,col0)

query TTT
EXPLAIN SELECT col0 FROM tab4 WHERE (col0 <= 0 AND col4 <= 5.38) OR (col4 IN (SELECT col1 FROM tab4 WHERE col1 > 8.27)) AND (col3 <= 5 AND (col3 BETWEEN 7 AND 9))
----
root                 ·             ·
 ├── render          ·             ·
 │    └── scan       ·             ·
 │                   table         tab4@primary
 │                   spans         ALL
 │                   filter        ((col0 <= 0) AND (col4 <= 5.38)) OR ((((col4 IN @S1) AND (col3 <= 5)) AND (col3 >= 7)) AND (col3 <= 9))
 └── subquery        ·             ·
      │              id            @S1
      │              original sql  (SELECT col1 FROM tab4 WHERE col1 > 8.27)
      │              exec mode     all rows normalized
      └── render     ·             ·
           └── scan  ·             ·
·                    table         tab4@primary
·                    spans         ALL
·                    filter        col1 > 8.27
