# LogicTest: local

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)
                │           strategy  inserter
                └── 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
                │         strategy  deleter
                └── 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
                │              strategy  updater
                └── 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)
                │           strategy  upserter
                └── 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)
                │           strategy  inserter
                └── 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
                │         strategy  deleter
                └── 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
                │              strategy  updater
                └── 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)
                │           strategy  upserter
                └── 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)
                │           strategy  inserter
                └── values  ·         ·
·                           size      1 column, 1 row

query TTT
EXPLAIN SELECT * FROM [INSERT INTO t VALUES (2) RETURNING x], t
----
hash-join                   ·         ·
 │                          type      cross
 ├── spool                  ·         ·
 │    └── run               ·         ·
 │         └── insert       ·         ·
 │              │           into      t(x)
 │              │           strategy  inserter
 │              └── 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)
                │                          strategy  inserter
                └── render                 ·         ·
                     └── run               ·         ·
                          └── insert       ·         ·
                               │           into      t(x)
                               │           strategy  inserter
                               └── 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)
      │           strategy  inserter
      └── 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)
      │                               strategy  inserter
      └── spool                       ·         ·
           └── render                 ·         ·
                └── run               ·         ·
                     └── insert       ·         ·
                          │           into      t(x)
                          │           strategy  inserter
                          └── 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)
                          │           strategy  inserter
                          └── 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)
                │           strategy  inserter
                └── values  ·         ·
·                           size      1 column, 1 row
