# LogicTest: local-opt

statement ok
CREATE TABLE t(x INT PRIMARY KEY); INSERT INTO t VALUES(1);

# Check that if a mutation uses further processing, a spool is added.
query TTT
EXPLAIN WITH a AS (INSERT INTO t VALUES (2) RETURNING x)
        SELECT * FROM a LIMIT 1
----
limit                       ·      ·
 │                          count  1
 └── spool                  ·      ·
      │                     limit  1
      └── run               ·      ·
           └── insert       ·      ·
                │           into   t(x)
                └── values  ·      ·
·                           size   1 column, 1 row

query TTT
EXPLAIN WITH a AS (DELETE FROM t RETURNING x)
        SELECT * FROM a LIMIT 1
----
limit                     ·      ·
 │                        count  1
 └── spool                ·      ·
      │                   limit  1
      └── run             ·      ·
           └── delete     ·      ·
                │         from   t
                └── scan  ·      ·
·                         table  t@primary
·                         spans  ALL


query TTT
EXPLAIN WITH a AS (UPDATE t SET x = x + 1 RETURNING x)
        SELECT * FROM a LIMIT 1
----
limit                          ·      ·
 │                             count  1
 └── spool                     ·      ·
      │                        limit  1
      └── run                  ·      ·
           └── update          ·      ·
                │              table  t
                │              set    x
                └── render     ·      ·
                     └── scan  ·      ·
·                              table  t@primary
·                              spans  ALL

query TTT
EXPLAIN WITH a AS (UPSERT INTO t VALUES (2) RETURNING x)
        SELECT * FROM a LIMIT 1
----
limit                       ·      ·
 │                          count  1
 └── spool                  ·      ·
      │                     limit  1
      └── run               ·      ·
           └── upsert       ·      ·
                │           into   t(x)
                └── values  ·      ·
·                           size   1 column, 1 row

# Ditto all mutations, with the statement source syntax.
query TTT
EXPLAIN SELECT * FROM [INSERT INTO t VALUES (2) RETURNING x] LIMIT 1
----
limit                       ·      ·
 │                          count  1
 └── spool                  ·      ·
      │                     limit  1
      └── run               ·      ·
           └── insert       ·      ·
                │           into   t(x)
                └── values  ·      ·
·                           size   1 column, 1 row

query TTT
EXPLAIN SELECT * FROM [DELETE FROM t RETURNING x] LIMIT 1
----
limit                     ·      ·
 │                        count  1
 └── spool                ·      ·
      │                   limit  1
      └── run             ·      ·
           └── delete     ·      ·
                │         from   t
                └── scan  ·      ·
·                         table  t@primary
·                         spans  ALL

query TTT
EXPLAIN SELECT * FROM [UPDATE t SET x = x + 1 RETURNING x] LIMIT 1
----
limit                          ·      ·
 │                             count  1
 └── spool                     ·      ·
      │                        limit  1
      └── run                  ·      ·
           └── update          ·      ·
                │              table  t
                │              set    x
                └── render     ·      ·
                     └── scan  ·      ·
·                              table  t@primary
·                              spans  ALL

query TTT
EXPLAIN SELECT * FROM [UPSERT INTO t VALUES (2) RETURNING x] LIMIT 1
----
limit                       ·      ·
 │                          count  1
 └── spool                  ·      ·
      │                     limit  1
      └── run               ·      ·
           └── upsert       ·      ·
                │           into   t(x)
                └── values  ·      ·
·                           size   1 column, 1 row

# Check that a spool is also inserted for other processings than LIMIT.
query TTT
EXPLAIN SELECT * FROM [INSERT INTO t VALUES (2) RETURNING x] ORDER BY x
----
sort                        ·      ·
 │                          order  +x
 └── spool                  ·      ·
      └── run               ·      ·
           └── insert       ·      ·
                │           into   t(x)
                └── values  ·      ·
·                           size   1 column, 1 row

query TTT
EXPLAIN SELECT * FROM [INSERT INTO t VALUES (2) RETURNING x], t
----
join                        ·      ·
 │                          type   cross
 ├── spool                  ·      ·
 │    └── run               ·      ·
 │         └── insert       ·      ·
 │              │           into   t(x)
 │              └── values  ·      ·
 │                          size   1 column, 1 row
 └── scan                   ·      ·
·                           table  t@primary
·                           spans  ALL

# Check that if a spool is already added at some level, then it is not added
# again at levels below.
query TTT
EXPLAIN WITH a AS (INSERT INTO t VALUES(2) RETURNING x),
             b AS (INSERT INTO t SELECT x+1 FROM a RETURNING x)
        SELECT * FROM b LIMIT 1
----
limit                                      ·      ·
 │                                         count  1
 └── spool                                 ·      ·
      │                                    limit  1
      └── run                              ·      ·
           └── insert                      ·      ·
                │                          into   t(x)
                └── render                 ·      ·
                     └── run               ·      ·
                          └── insert       ·      ·
                               │           into   t(x)
                               └── values  ·      ·
·                                          size   1 column, 1 row

# Check that no spool is inserted if a top-level render is elided.
query TTT
EXPLAIN SELECT * FROM [INSERT INTO t VALUES (2) RETURNING x]
----
run               ·     ·
 └── insert       ·     ·
      │           into  t(x)
      └── values  ·     ·
·                 size  1 column, 1 row

# Check that no spool is used for a top-level INSERT, but
# sub-INSERTs still get a spool.
query TTT
EXPLAIN INSERT INTO t SELECT x+1 FROM [INSERT INTO t VALUES(2) RETURNING x]
----
count                                 ·     ·
 └── insert                           ·     ·
      │                               into  t(x)
      └── spool                       ·     ·
           └── render                 ·     ·
                └── run               ·     ·
                     └── insert       ·     ·
                          │           into  t(x)
                          └── values  ·     ·
·                                     size  1 column, 1 row

# Check that simple computations using RETURNING get their spool pulled up.
query TTT
EXPLAIN SELECT * FROM [INSERT INTO t VALUES (1) RETURNING x+10] WHERE @1 < 3 LIMIT 10
----
limit                                 ·       ·
 │                                    count   10
 └── spool                            ·       ·
      │                               limit   10
      └── filter                      ·       ·
           │                          filter  "?column?" < 3
           └── render                 ·       ·
                └── run               ·       ·
                     └── insert       ·       ·
                          │           into    t(x)
                          └── values  ·       ·
·                                     size    1 column, 1 row

# Check that a pulled up spool gets elided at the top level.
query TTT
EXPLAIN SELECT * FROM [INSERT INTO t VALUES (1) RETURNING x+10] WHERE @1 < 3
----
filter                      ·       ·
 │                          filter  "?column?" < 3
 └── render                 ·       ·
      └── run               ·       ·
           └── insert       ·       ·
                │           into    t(x)
                └── values  ·       ·
·                           size    1 column, 1 row
