# Tests for InterestingOrderings property.

exec-ddl
CREATE TABLE abc (a INT, b INT, c INT, INDEX (a, b), UNIQUE INDEX (c))
----
TABLE abc
 ├── a int
 ├── b int
 ├── c int
 ├── rowid int not null (hidden)
 ├── INDEX primary
 │    └── rowid int not null (hidden)
 ├── INDEX secondary
 │    ├── a int
 │    ├── b int
 │    └── rowid int not null (hidden)
 └── INDEX secondary
      ├── c int
      └── rowid int not null (hidden) (storing)

# Scan operator.
opt
SELECT * FROM abc
----
scan abc
 ├── columns: a:1(int) b:2(int) c:3(int)
 ├── lax-key: (1-3)
 ├── fd: (3)~~>(1,2)
 ├── prune: (1-3)
 └── interesting orderings: (+1,+2) (+3)

opt
SELECT a, c FROM abc
----
scan abc
 ├── columns: a:1(int) c:3(int)
 ├── lax-key: (1,3)
 ├── fd: (3)~~>(1)
 ├── prune: (1,3)
 └── interesting orderings: (+1) (+3)

opt
SELECT b, c FROM abc
----
scan abc
 ├── columns: b:2(int) c:3(int)
 ├── lax-key: (2,3)
 ├── fd: (3)~~>(2)
 ├── prune: (2,3)
 └── interesting orderings: (+3)


# Project operator (we use build instead of opt).
build
SELECT a, c FROM abc
----
project
 ├── columns: a:1(int) c:3(int)
 ├── lax-key: (1,3)
 ├── fd: (3)~~>(1)
 ├── prune: (1,3)
 ├── interesting orderings: (+1) (+3)
 └── scan abc
      ├── columns: a:1(int) b:2(int) c:3(int) rowid:4(int!null)
      ├── key: (4)
      ├── fd: (4)-->(1-3), (3)~~>(1,2,4)
      ├── prune: (1-4)
      └── interesting orderings: (+4) (+1,+2,+4) (+3,+4)

build
SELECT b, c FROM abc
----
project
 ├── columns: b:2(int) c:3(int)
 ├── lax-key: (2,3)
 ├── fd: (3)~~>(2)
 ├── prune: (2,3)
 ├── interesting orderings: (+3)
 └── scan abc
      ├── columns: a:1(int) b:2(int) c:3(int) rowid:4(int!null)
      ├── key: (4)
      ├── fd: (4)-->(1-3), (3)~~>(1,2,4)
      ├── prune: (1-4)
      └── interesting orderings: (+4) (+1,+2,+4) (+3,+4)

# GroupBy operator.
opt
SELECT min(b), a FROM abc GROUP BY a
----
group-by
 ├── columns: min:5(int) a:1(int)
 ├── grouping columns: a:1(int)
 ├── internal-ordering: +1
 ├── key: (1)
 ├── fd: (1)-->(5)
 ├── prune: (5)
 ├── interesting orderings: (+1)
 ├── scan abc@secondary
 │    ├── columns: a:1(int) b:2(int)
 │    ├── ordering: +1
 │    ├── prune: (1,2)
 │    └── interesting orderings: (+1,+2)
 └── aggregations
      └── min [type=int, outer=(2)]
           └── variable: b [type=int]

opt
SELECT min(b), c FROM abc GROUP BY c
----
group-by
 ├── columns: min:5(int) c:3(int)
 ├── grouping columns: c:3(int)
 ├── key: (3)
 ├── fd: (3)-->(5)
 ├── prune: (5)
 ├── interesting orderings: (+3)
 ├── scan abc
 │    ├── columns: b:2(int) c:3(int)
 │    ├── lax-key: (2,3)
 │    ├── fd: (3)~~>(2)
 │    ├── prune: (2,3)
 │    └── interesting orderings: (+3)
 └── aggregations
      └── min [type=int, outer=(2)]
           └── variable: b [type=int]

# GroupBy with required ordering.
opt
SELECT array_agg(a), b, c FROM (SELECT * FROM abc ORDER BY b, a) GROUP BY b, c
----
group-by
 ├── columns: array_agg:5(int[]) b:2(int) c:3(int)
 ├── grouping columns: b:2(int) c:3(int)
 ├── internal-ordering: +1 opt(2,3)
 ├── key: (2,3)
 ├── fd: (3)~~>(2), (2,3)-->(5)
 ├── prune: (5)
 ├── sort
 │    ├── columns: a:1(int) b:2(int) c:3(int)
 │    ├── lax-key: (1-3)
 │    ├── fd: (3)~~>(1,2)
 │    ├── ordering: +1 opt(2,3) [actual: +1]
 │    ├── prune: (1-3)
 │    ├── interesting orderings: (+1,+2) (+3)
 │    └── scan abc
 │         ├── columns: a:1(int) b:2(int) c:3(int)
 │         ├── lax-key: (1-3)
 │         ├── fd: (3)~~>(1,2)
 │         ├── prune: (1-3)
 │         └── interesting orderings: (+1,+2) (+3)
 └── aggregations
      └── array-agg [type=int[], outer=(1)]
           └── variable: a [type=int]

# Scalar GroupBy case.
opt
SELECT max(a), min(b), sum(c) FROM abc
----
scalar-group-by
 ├── columns: max:5(int) min:6(int) sum:7(decimal)
 ├── cardinality: [1 - 1]
 ├── key: ()
 ├── fd: ()-->(5-7)
 ├── prune: (5-7)
 ├── scan abc
 │    ├── columns: a:1(int) b:2(int) c:3(int)
 │    ├── lax-key: (1-3)
 │    ├── fd: (3)~~>(1,2)
 │    ├── prune: (1-3)
 │    └── interesting orderings: (+1,+2) (+3)
 └── aggregations
      ├── max [type=int, outer=(1)]
      │    └── variable: a [type=int]
      ├── min [type=int, outer=(2)]
      │    └── variable: b [type=int]
      └── sum [type=decimal, outer=(3)]
           └── variable: c [type=int]

# LookupJoin operator.
opt
SELECT * FROM abc WHERE a = 1
----
index-join abc
 ├── columns: a:1(int!null) b:2(int) c:3(int)
 ├── lax-key: (2,3)
 ├── fd: ()-->(1), (3)~~>(2)
 ├── prune: (2,3)
 ├── interesting orderings: (+4) (+1,+2,+4)
 └── scan abc@secondary
      ├── columns: a:1(int!null) b:2(int) rowid:4(int!null)
      ├── constraint: /1/2/4: [/1 - /1]
      ├── key: (4)
      ├── fd: ()-->(1), (4)-->(2)
      ├── prune: (1,2,4)
      └── interesting orderings: (+4) (+1,+2,+4)

# Limit operator.
opt
SELECT * FROM abc ORDER BY a LIMIT 10
----
index-join abc
 ├── columns: a:1(int) b:2(int) c:3(int)
 ├── cardinality: [0 - 10]
 ├── lax-key: (1-3)
 ├── fd: (3)~~>(1,2)
 ├── ordering: +1
 ├── prune: (2,3)
 ├── interesting orderings: (+4) (+1,+2,+4)
 └── scan abc@secondary
      ├── columns: a:1(int) b:2(int) rowid:4(int!null)
      ├── limit: 10
      ├── key: (4)
      ├── fd: (4)-->(1,2)
      ├── ordering: +1
      ├── prune: (1,2,4)
      └── interesting orderings: (+4) (+1,+2,+4)

opt
SELECT * FROM abc ORDER BY b LIMIT 10
----
limit
 ├── columns: a:1(int) b:2(int) c:3(int)
 ├── internal-ordering: +2
 ├── cardinality: [0 - 10]
 ├── lax-key: (1-3)
 ├── fd: (3)~~>(1,2)
 ├── ordering: +2
 ├── prune: (1,3)
 ├── interesting orderings: (+2)
 ├── sort
 │    ├── columns: a:1(int) b:2(int) c:3(int)
 │    ├── lax-key: (1-3)
 │    ├── fd: (3)~~>(1,2)
 │    ├── ordering: +2
 │    ├── prune: (1-3)
 │    └── scan abc
 │         ├── columns: a:1(int) b:2(int) c:3(int)
 │         ├── lax-key: (1-3)
 │         ├── fd: (3)~~>(1,2)
 │         └── prune: (1-3)
 └── const: 10 [type=int]

opt
SELECT * FROM abc ORDER BY a OFFSET 10
----
offset
 ├── columns: a:1(int) b:2(int) c:3(int)
 ├── internal-ordering: +1
 ├── lax-key: (1-3)
 ├── fd: (3)~~>(1,2)
 ├── ordering: +1
 ├── prune: (2,3)
 ├── interesting orderings: (+1)
 ├── sort
 │    ├── columns: a:1(int) b:2(int) c:3(int)
 │    ├── lax-key: (1-3)
 │    ├── fd: (3)~~>(1,2)
 │    ├── ordering: +1
 │    ├── prune: (1-3)
 │    └── scan abc
 │         ├── columns: a:1(int) b:2(int) c:3(int)
 │         ├── lax-key: (1-3)
 │         ├── fd: (3)~~>(1,2)
 │         └── prune: (1-3)
 └── const: 10 [type=int]

exec-ddl
CREATE TABLE xyz (x INT, y INT, z INT, INDEX(z), UNIQUE INDEX(x,y))
----
TABLE xyz
 ├── x int
 ├── y int
 ├── z int
 ├── rowid int not null (hidden)
 ├── INDEX primary
 │    └── rowid int not null (hidden)
 ├── INDEX secondary
 │    ├── z int
 │    └── rowid int not null (hidden)
 └── INDEX secondary
      ├── x int
      ├── y int
      └── rowid int not null (hidden) (storing)

# Join operator.
opt
SELECT * FROM abc JOIN xyz ON a=x 
----
inner-join
 ├── columns: a:1(int!null) b:2(int) c:3(int) x:5(int!null) y:6(int) z:7(int)
 ├── lax-key: (2,3,5-7)
 ├── fd: (3)~~>(1,2), (5,6)~~>(7), (1)==(5), (5)==(1)
 ├── prune: (2,3,6,7)
 ├── interesting orderings: (+1,+2) (+3) (+7) (+5,+6)
 ├── scan abc
 │    ├── columns: a:1(int) b:2(int) c:3(int)
 │    ├── lax-key: (1-3)
 │    ├── fd: (3)~~>(1,2)
 │    ├── prune: (1-3)
 │    └── interesting orderings: (+1,+2) (+3)
 ├── scan xyz
 │    ├── columns: x:5(int) y:6(int) z:7(int)
 │    ├── lax-key: (5-7)
 │    ├── fd: (5,6)~~>(7)
 │    ├── prune: (5-7)
 │    └── interesting orderings: (+7) (+5,+6)
 └── filters
      └── a = x [type=bool, outer=(1,5), constraints=(/1: (/NULL - ]; /5: (/NULL - ]), fd=(1)==(5), (5)==(1)]
