exec-ddl
CREATE TABLE a (k INT PRIMARY KEY, i INT, s STRING, d DECIMAL NOT NULL)
----

opt
SELECT k, s FROM a WHERE s >= 'foo'
----
select
 ├── columns: k:1!null s:3!null
 ├── stats: [rows=333.3333, distinct(3)=33.3333, null(3)=0]
 ├── cost: 1098.65
 ├── key: (1)
 ├── fd: (1)-->(3)
 ├── scan a
 │    ├── columns: k:1!null s:3
 │    ├── stats: [rows=1000, distinct(1)=1000, null(1)=0, distinct(3)=100, null(3)=10]
 │    ├── cost: 1088.62
 │    ├── key: (1)
 │    └── fd: (1)-->(3)
 └── filters
      └── s:3 >= 'foo' [outer=(3), constraints=(/3: [/'foo' - ]; tight)]

exec-ddl
CREATE TABLE g (
  id INT PRIMARY KEY,
  geog GEOGRAPHY
)
----

exec-ddl
ALTER TABLE g INJECT STATISTICS '[
  {
    "columns": [
      "id"
    ],
    "created_at": "2021-01-01 00:00:00",
    "distinct_count": 500000,
    "name": "__auto__",
    "row_count": 500000
  }
]'
----

# If there is a limit hint, n, the filter is not expected to be evaluated for
# each input row. It is only expected to be evaluated on the number of rows
# required to produce n rows.
opt
SELECT id FROM g
WHERE st_dwithin(geog, st_makepoint(1.0, 1.0)::geography, 200)
LIMIT 10
----
project
 ├── columns: id:1!null
 ├── cardinality: [0 - 10]
 ├── immutable
 ├── stats: [rows=10]
 ├── cost: 204.633636
 ├── key: (1)
 └── limit
      ├── columns: id:1!null geog:2!null
      ├── cardinality: [0 - 10]
      ├── immutable
      ├── stats: [rows=10]
      ├── cost: 204.523636
      ├── key: (1)
      ├── fd: (1)-->(2)
      ├── select
      │    ├── columns: id:1!null geog:2!null
      │    ├── immutable
      │    ├── stats: [rows=55000, distinct(2)=50000, null(2)=0]
      │    ├── cost: 204.413636
      │    ├── key: (1)
      │    ├── fd: (1)-->(2)
      │    ├── limit hint: 10.00
      │    ├── scan g
      │    │    ├── columns: id:1!null geog:2
      │    │    ├── stats: [rows=500000, distinct(1)=500000, null(1)=0, distinct(2)=50000, null(2)=5000]
      │    │    ├── cost: 112.565455
      │    │    ├── key: (1)
      │    │    ├── fd: (1)-->(2)
      │    │    └── limit hint: 90.91
      │    └── filters
      │         └── st_dwithin(geog:2, '0101000020E6100000000000000000F03F000000000000F03F', 200.0) [outer=(2), immutable, constraints=(/2: (/NULL - ])]
      └── 10

# There is no error when calculating the cost with a limit hint if the
# selectivity is zero. The build command is used to avoid normalizing the
# expression to an empty Values expression.
build
SELECT id FROM g
WHERE false
LIMIT 10
----
limit
 ├── columns: id:1!null
 ├── cardinality: [0 - 0]
 ├── stats: [rows=0]
 ├── cost: 535028.66
 ├── key: (1)
 ├── project
 │    ├── columns: id:1!null
 │    ├── cardinality: [0 - 0]
 │    ├── stats: [rows=0]
 │    ├── cost: 535028.65
 │    ├── key: (1)
 │    ├── limit hint: 10.00
 │    └── select
 │         ├── columns: id:1!null geog:2 crdb_internal_mvcc_timestamp:3 tableoid:4
 │         ├── cardinality: [0 - 0]
 │         ├── stats: [rows=0]
 │         ├── cost: 535028.64
 │         ├── key: (1)
 │         ├── fd: (1)-->(2-4)
 │         ├── limit hint: 10.00
 │         ├── scan g
 │         │    ├── columns: id:1!null geog:2 crdb_internal_mvcc_timestamp:3 tableoid:4
 │         │    ├── stats: [rows=500000]
 │         │    ├── cost: 530028.62
 │         │    ├── key: (1)
 │         │    └── fd: (1)-->(2-4)
 │         └── filters
 │              └── false [constraints=(contradiction; tight)]
 └── 10

exec-ddl
CREATE TABLE zigzag (n INT PRIMARY KEY, a INT, b INT, c STRING, INDEX a_idx(a), INDEX b_idx(b), UNIQUE INDEX c_idx(b,c));
----

# Verify huge cost on scan operator when there is a zigzag join hint.
opt
SELECT * FROM zigzag@{FORCE_ZIGZAG=a_idx,FORCE_ZIGZAG=c_idx} WHERE a = 3 AND b = 7;
----
select
 ├── columns: n:1!null a:2!null b:3!null c:4
 ├── stats: [rows=0.9108108, distinct(2)=0.910811, null(2)=0, distinct(3)=0.910811, null(3)=0, distinct(2,3)=0.910811, null(2,3)=0]
 ├── cost: 1e+100
 ├── cost-flags: huge-cost-penalty
 ├── key: (1)
 ├── fd: ()-->(2,3), (1)-->(4), (3,4)~~>(1)
 ├── scan zigzag
 │    ├── columns: n:1!null a:2 b:3 c:4
 │    ├── flags: force-zigzag=a_idx,c_idx
 │    ├── stats: [rows=1000, distinct(1)=1000, null(1)=0, distinct(2)=100, null(2)=10, distinct(3)=100, null(3)=10, distinct(2,3)=1000, null(2,3)=0.1]
 │    ├── cost: 1e+100
 │    ├── cost-flags: huge-cost-penalty
 │    ├── key: (1)
 │    └── fd: (1)-->(2-4), (3,4)~~>(1,2)
 └── filters
      ├── a:2 = 3 [outer=(2), constraints=(/2: [/3 - /3]; tight), fd=()-->(2)]
      └── b:3 = 7 [outer=(3), constraints=(/3: [/7 - /7]; tight), fd=()-->(3)]

# Test formating when mixing names/ids.
opt
SELECT * FROM zigzag@{FORCE_ZIGZAG=[2],FORCE_ZIGZAG=c_idx} WHERE a = 3 AND b = 7;
----
select
 ├── columns: n:1!null a:2!null b:3!null c:4
 ├── stats: [rows=0.9108108, distinct(2)=0.910811, null(2)=0, distinct(3)=0.910811, null(3)=0, distinct(2,3)=0.910811, null(2,3)=0]
 ├── cost: 1e+100
 ├── cost-flags: huge-cost-penalty
 ├── key: (1)
 ├── fd: ()-->(2,3), (1)-->(4), (3,4)~~>(1)
 ├── scan zigzag
 │    ├── columns: n:1!null a:2 b:3 c:4
 │    ├── flags: force-zigzag=a_idx,c_idx
 │    ├── stats: [rows=1000, distinct(1)=1000, null(1)=0, distinct(2)=100, null(2)=10, distinct(3)=100, null(3)=10, distinct(2,3)=1000, null(2,3)=0.1]
 │    ├── cost: 1e+100
 │    ├── cost-flags: huge-cost-penalty
 │    ├── key: (1)
 │    └── fd: (1)-->(2-4), (3,4)~~>(1,2)
 └── filters
      ├── a:2 = 3 [outer=(2), constraints=(/2: [/3 - /3]; tight), fd=()-->(2)]
      └── b:3 = 7 [outer=(3), constraints=(/3: [/7 - /7]; tight), fd=()-->(3)]
