# LogicTest: local

statement ok
CREATE TABLE ab (a INT PRIMARY KEY, b INT); INSERT INTO ab (a, b) VALUES (1, 10)

## Table index change: Add/remove index that query depends on, and ensure that
## the plan is recomputed each time.
statement ok
PREPARE change_index AS SELECT * FROM [EXPLAIN SELECT * FROM ab WHERE b=10]

query T nosort
EXECUTE change_index
----
distribution: local
vectorized: true
·
• filter
│ filter: b = 10
│
└── • scan
      missing stats
      table: ab@ab_pkey
      spans: FULL SCAN

statement ok
CREATE INDEX bindex ON ab (b)

query T nosort
EXECUTE change_index
----
distribution: local
vectorized: true
·
• scan
  missing stats
  table: ab@bindex
  spans: [/10 - /10]

statement ok
DROP INDEX bindex

query T nosort
EXECUTE change_index
----
distribution: local
vectorized: true
·
• filter
│ filter: b = 10
│
└── • scan
      missing stats
      table: ab@ab_pkey
      spans: FULL SCAN

## Statistics change: Create statistics and ensure that the plan is recalculated.
statement ok
CREATE TABLE cd (c INT PRIMARY KEY, d INT)

statement ok
PREPARE change_stats AS SELECT * FROM [EXPLAIN SELECT * FROM ab JOIN cd ON a=c]

query T nosort
EXECUTE change_stats
----
distribution: local
vectorized: true
·
• merge join
│ equality: (a) = (c)
│ left cols are key
│ right cols are key
│
├── • scan
│     missing stats
│     table: ab@ab_pkey
│     spans: FULL SCAN
│
└── • scan
      missing stats
      table: cd@cd_pkey
      spans: FULL SCAN

statement ok
CREATE STATISTICS s FROM ab

# Now that the optimizer knows table ab has one row (and it assumes a much
# higher number of rows for cd), it should choose lookup join.
# We allow retry because stat cache invalidation happens asynchronously.
query T retry,nosort
EXECUTE change_stats
----
distribution: local
vectorized: true
·
• lookup join
│ table: cd@cd_pkey
│ equality: (a) = (c)
│ equality cols are key
│
└── • scan
      estimated row count: 1 (100% of the table; stats collected <hidden> ago)
      table: ab@ab_pkey
      spans: FULL SCAN

# Verify the plan of a very simple query which should be using the placeholder
# fast path.
statement ok
PREPARE pklookup AS SELECT b FROM ab WHERE a = $1

query T
EXPLAIN ANALYZE EXECUTE pklookup(1)
----
planning time: 10µs
execution time: 100µs
distribution: <hidden>
vectorized: <hidden>
plan type: generic, reused
rows decoded from KV: 1 (8 B, 2 KVs, 1 gRPC calls)
maximum memory usage: <hidden>
network usage: <hidden>
regions: <hidden>
isolation level: serializable
priority: normal
quality of service: regular
·
• scan
  sql nodes: <hidden>
  kv nodes: <hidden>
  regions: <hidden>
  actual row count: 1
  KV time: 0µs
  KV contention time: 0µs
  KV rows decoded: 1
  KV pairs read: 2
  KV bytes read: 8 B
  KV gRPC calls: 1
  estimated max memory allocated: 0 B
  estimated row count: 1
  table: ab@ab_pkey
  spans: [/1 - /1]

query T
EXPLAIN ANALYZE EXECUTE pklookup(2)
----
planning time: 10µs
execution time: 100µs
distribution: <hidden>
vectorized: <hidden>
plan type: generic, reused
maximum memory usage: <hidden>
network usage: <hidden>
regions: <hidden>
isolation level: serializable
priority: normal
quality of service: regular
·
• scan
  sql nodes: <hidden>
  kv nodes: <hidden>
  regions: <hidden>
  actual row count: 0
  KV time: 0µs
  KV contention time: 0µs
  KV rows decoded: 0
  KV bytes read: 0 B
  KV gRPC calls: 0
  estimated max memory allocated: 0 B
  estimated row count: 1
  table: ab@ab_pkey
  spans: [/2 - /2]
