exec-ddl
CREATE TABLE t.a
(
    k INT,
    f FLOAT,
    z DECIMAL,
    s STRING NOT NULL,
    PRIMARY KEY (k, f DESC)
)
----

opt
SELECT f FROM a ORDER BY f DESC
----
sort
 ├── columns: f:2!null
 ├── stats: [rows=1000]
 ├── cost: 1308.00194
 ├── ordering: -2
 └── scan a
      ├── columns: f:2!null
      ├── stats: [rows=1000]
      └── cost: 1078.52

# Test sort on 0 rows.
opt
SELECT f FROM a WHERE k IN () ORDER BY f DESC
----
values
 ├── columns: f:2!null
 ├── cardinality: [0 - 0]
 ├── stats: [rows=0]
 ├── cost: 0.01
 ├── key: ()
 └── fd: ()-->(2)

# Testing costing for segmented sort.
exec-ddl
CREATE TABLE abc (
  a INT,
  b INT,
  c INT,
  INDEX cb (c, b) STORING (a),
  INDEX ab (a, b) STORING (c)
)
----

# The ordering cannot take advantage of any interesting orderings
# the scan can provide.
opt
SELECT * FROM abc ORDER BY b, c, a
----
sort
 ├── columns: a:1 b:2 c:3
 ├── stats: [rows=1000]
 ├── cost: 1360.2643
 ├── ordering: +2,+3,+1
 └── scan abc
      ├── columns: a:1 b:2 c:3
      ├── stats: [rows=1000]
      └── cost: 1098.72

# The sort ordering has a common prefix with the ordering provided with index ab
opt
SELECT * FROM abc ORDER BY a, b, c
----
sort (segmented)
 ├── columns: a:1 b:2 c:3
 ├── stats: [rows=1000, distinct(1,2)=1000, null(1,2)=0.1]
 ├── cost: 1168.74
 ├── ordering: +1,+2,+3
 └── scan abc@ab
      ├── columns: a:1 b:2 c:3
      ├── stats: [rows=1000, distinct(1,2)=1000, null(1,2)=0.1]
      ├── cost: 1098.72
      └── ordering: +1,+2

# The sort ordering has a common prefix with the ordering provided with index cb
opt
SELECT * FROM abc ORDER BY c, b, a
----
sort (segmented)
 ├── columns: a:1 b:2 c:3
 ├── stats: [rows=1000, distinct(2,3)=1000, null(2,3)=0.1]
 ├── cost: 1168.74
 ├── ordering: +3,+2,+1
 └── scan abc@cb
      ├── columns: a:1 b:2 c:3
      ├── stats: [rows=1000, distinct(2,3)=1000, null(2,3)=0.1]
      ├── cost: 1098.72
      └── ordering: +3,+2

# Testing segmented sort cost with only one common prefix column (c).
opt
SELECT * FROM abc ORDER BY c, a, b
----
sort (segmented)
 ├── columns: a:1 b:2 c:3
 ├── stats: [rows=1000, distinct(3)=100, null(3)=10]
 ├── cost: 1229.50049
 ├── ordering: +3,+1,+2
 └── scan abc@cb
      ├── columns: a:1 b:2 c:3
      ├── stats: [rows=1000, distinct(3)=100, null(3)=10]
      ├── cost: 1098.72
      └── ordering: +3

# Reduce the number of segments/chunks.
exec-ddl
ALTER TABLE abc INJECT STATISTICS '[
  {
    "columns": ["a"],
    "created_at": "2018-01-01 1:30:00.00000+00:00",
    "row_count": 10000,
    "distinct_count": 5
  },
  {
    "columns": ["b"],
    "created_at": "2018-01-01 1:30:00.00000+00:00",
    "row_count": 10000,
    "distinct_count": 2
  }
]'
----

# Even with a few chunks (10 in the above case), segmented sort is useful.
opt
SELECT * FROM abc ORDER BY a, b, c
----
sort (segmented)
 ├── columns: a:1 b:2 c:3
 ├── stats: [rows=10000, distinct(1,2)=10, null(1,2)=0]
 ├── cost: 13423.3594
 ├── ordering: +1,+2,+3
 └── scan abc@ab
      ├── columns: a:1 b:2 c:3
      ├── stats: [rows=10000, distinct(1,2)=10, null(1,2)=0]
      ├── cost: 10728.72
      └── ordering: +1,+2

# Segmented sort should still be chosen with if equality columns help provide the required ordering.
opt
SELECT * FROM abc  WHERE a = b ORDER BY b, a, c
----
sort (segmented)
 ├── columns: a:1!null b:2!null c:3
 ├── stats: [rows=2000, distinct(1)=2, null(1)=0, distinct(2)=2, null(2)=0, distinct(1,2)=4, null(1,2)=0]
 ├── cost: 11296.8376
 ├── fd: (1)==(2), (2)==(1)
 ├── ordering: +(1|2),+3 [actual: +1,+3]
 └── select
      ├── columns: a:1!null b:2!null c:3
      ├── stats: [rows=2000, distinct(1)=2, null(1)=0, distinct(2)=2, null(2)=0, distinct(1,2)=4, null(1,2)=0]
      ├── cost: 10818.05
      ├── fd: (1)==(2), (2)==(1)
      ├── ordering: +(1|2) [actual: +1]
      ├── scan abc@ab
      │    ├── columns: a:1!null b:2 c:3
      │    ├── constraint: /1/2/4: (/NULL - ]
      │    ├── stats: [rows=10000, distinct(1)=5, null(1)=0]
      │    ├── cost: 10718.02
      │    └── ordering: +1
      └── filters
           └── a:1 = b:2 [outer=(1,2), constraints=(/1: (/NULL - ]; /2: (/NULL - ]), fd=(1)==(2), (2)==(1)]
