# LogicTest: local

statement ok
CREATE TABLE t (
  a INT PRIMARY KEY,
  b INT,
  c BOOLEAN
)

query TTT
EXPLAIN SELECT a, b FROM t ORDER BY b
----
sort            ·      ·
 │              order  +b
 └── render     ·      ·
      └── scan  ·      ·
·               table  t@primary
·               spans  ALL

query TTT
EXPLAIN SELECT a, b FROM t ORDER BY b DESC
----
sort            ·      ·
 │              order  -b
 └── render     ·      ·
      └── scan  ·      ·
·               table  t@primary
·               spans  ALL

query TTT
EXPLAIN SELECT a, b FROM t ORDER BY b LIMIT 2
----
limit                ·         ·
 │                   count     2
 └── sort            ·         ·
      │              order     +b
      │              strategy  top 2
      └── render     ·         ·
           └── scan  ·         ·
·                    table     t@primary
·                    spans     ALL

query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT c FROM t ORDER BY b LIMIT 2
----
limit                     ·         ·                (c)                 weak-key(c)
 │                        count     2                ·                   ·
 └── distinct             ·         ·                (c)                 weak-key(c)
      └── sort            ·         ·                (c)                 ·
           │              order     +b               ·                   ·
           │              strategy  iterative        ·                   ·
           └── render     ·         ·                (c, b)              ·
                │         render 0  test.public.t.c  ·                   ·
                │         render 1  test.public.t.b  ·                   ·
                └── scan  ·         ·                (a[omitted], b, c)  a!=NULL; key(a)
·                         table     t@primary        ·                   ·
·                         spans     ALL              ·                   ·

query TTT
EXPLAIN SELECT b FROM t ORDER BY a DESC
----
nosort             ·      ·
 │                 order  -a
 └── render        ·      ·
      └── revscan  ·      ·
·                  table  t@primary
·                  spans  ALL

# Check that LIMIT propagates past nosort nodes.
query TTT
EXPLAIN SELECT b FROM t ORDER BY a LIMIT 1
----
limit                ·      ·
 │                   count  1
 └── nosort          ·      ·
      │              order  +a
      └── render     ·      ·
           └── scan  ·      ·
·                    table  t@primary
·                    spans  ALL
·                    limit  1

query TTT
EXPLAIN SELECT b FROM t ORDER BY a DESC, b ASC
----
nosort             ·      ·
 │                 order  -a,+b
 └── render        ·      ·
      └── revscan  ·      ·
·                  table  t@primary
·                  spans  ALL

query TTT
EXPLAIN SELECT b FROM t ORDER BY a DESC, b DESC
----
nosort             ·      ·
 │                 order  -a,-b
 └── render        ·      ·
      └── revscan  ·      ·
·                  table  t@primary
·                  spans  ALL

query TTTTT
EXPLAIN (VERBOSE) SELECT * FROM t ORDER BY (b, t.*)
----
sort       ·      ·          (a, b, c)  a!=NULL; key(a); +b,+a
 │         order  +b,+a,+c   ·          ·
 └── scan  ·      ·          (a, b, c)  a!=NULL; key(a)
·          table  t@primary  ·          ·
·          spans  ALL        ·          ·

query TTTTT
EXPLAIN (VERBOSE) SELECT * FROM t ORDER BY (b, a), c
----
sort       ·      ·          (a, b, c)  a!=NULL; key(a); +b,+a
 │         order  +b,+a,+c   ·          ·
 └── scan  ·      ·          (a, b, c)  a!=NULL; key(a)
·          table  t@primary  ·          ·
·          spans  ALL        ·          ·

query TTTTT
EXPLAIN (VERBOSE) SELECT * FROM t ORDER BY b, (a, c)
----
sort       ·      ·          (a, b, c)  a!=NULL; key(a); +b,+a
 │         order  +b,+a,+c   ·          ·
 └── scan  ·      ·          (a, b, c)  a!=NULL; key(a)
·          table  t@primary  ·          ·
·          spans  ALL        ·          ·

query TTTTT
EXPLAIN (VERBOSE) SELECT * FROM t ORDER BY (b, (a, c))
----
sort       ·      ·          (a, b, c)  a!=NULL; key(a); +b,+a
 │         order  +b,+a,+c   ·          ·
 └── scan  ·      ·          (a, b, c)  a!=NULL; key(a)
·          table  t@primary  ·          ·
·          spans  ALL        ·          ·

# Check that sort is skipped if the ORDER BY clause is constant.
query TTT
EXPLAIN SELECT * FROM t ORDER BY 1+2
----
nosort          ·      ·
 │              order  +"?column?"
 └── render     ·      ·
      └── scan  ·      ·
·               table  t@primary
·               spans  ALL

query TTT
EXPLAIN SELECT 1, * FROM t ORDER BY 1
----
render     ·      ·
 └── scan  ·      ·
·          table  t@primary
·          spans  ALL

query TTT
EXPLAIN SELECT * FROM t ORDER BY length('abc')
----
nosort          ·      ·
 │              order  +length
 └── render     ·      ·
      └── scan  ·      ·
·               table  t@primary
·               spans  ALL

# Check that the sort key reuses the existing render.
query TTTTT
EXPLAIN (VERBOSE) SELECT b+2 AS c FROM t ORDER BY b+2
----
sort            ·         ·                    (c)                          +c
 │              order     +c                   ·                            ·
 └── render     ·         ·                    (c)                          ·
      │         render 0  test.public.t.b + 2  ·                            ·
      └── scan  ·         ·                    (a[omitted], b, c[omitted])  a!=NULL; key(a)
·               table     t@primary            ·                            ·
·               spans     ALL                  ·                            ·

# Check that the sort picks up a renamed render properly.
query TTTTT
EXPLAIN (VERBOSE) SELECT b+2 AS y FROM t ORDER BY y
----
sort            ·         ·                    (y)                          +y
 │              order     +y                   ·                            ·
 └── render     ·         ·                    (y)                          ·
      │         render 0  test.public.t.b + 2  ·                            ·
      └── scan  ·         ·                    (a[omitted], b, c[omitted])  a!=NULL; key(a)
·               table     t@primary            ·                            ·
·               spans     ALL                  ·                            ·

statement ok
CREATE TABLE abc (
  a INT,
  b INT,
  c INT,
  d VARCHAR,
  PRIMARY KEY (a, b, c),
  UNIQUE INDEX bc (b, c),
  INDEX ba (b, a),
  FAMILY (a, b, c),
  FAMILY (d)
)

statement ok
INSERT INTO abc VALUES (1, 2, 3, 'one'), (4, 5, 6, 'Two')

statement ok
SET tracing = on,kv,results; SELECT * FROM abc ORDER BY a; SET tracing = off

query T
SELECT message FROM [SHOW KV TRACE FOR SESSION]
 WHERE message LIKE 'fetched:%' OR message LIKE 'output row%'
----
fetched: /abc/primary/1/2/3 -> NULL
fetched: /abc/primary/1/2/3/d -> 'one'
output row: [1 2 3 'one']
fetched: /abc/primary/4/5/6 -> NULL
fetched: /abc/primary/4/5/6/d -> 'Two'
output row: [4 5 6 'Two']

statement ok
SET tracing = on,kv,results; SELECT a, b FROM abc ORDER BY b, a; SET tracing = off

query T
SELECT message FROM [SHOW KV TRACE FOR SESSION]
 WHERE message LIKE 'fetched:%' OR message LIKE 'output row%'
----
fetched: /abc/ba/2/1/3 -> NULL
output row: [1 2]
fetched: /abc/ba/5/4/6 -> NULL
output row: [4 5]

# The non-unique index ba includes column c (required to make the keys unique)
# so the results will already be sorted.
query TTT
EXPLAIN SELECT a, b, c FROM abc ORDER BY b, a, c
----
render     ·      ·
 └── scan  ·      ·
·          table  abc@ba
·          spans  ALL

# We use the WHERE condition to force the use of index ba.
query TTT
EXPLAIN SELECT a, b, c FROM abc WHERE b > 10 ORDER BY b, a, d
----
sort             ·      ·
 │               order  +b,+a,+d
 └── index-join  ·      ·
      ├── scan   ·      ·
      │          table  abc@bc
      │          spans  /11-
      └── scan   ·      ·
·                table  abc@primary

# We cannot have rows with identical values for a,b,c so we don't need to
# sort for d.
query TTT
EXPLAIN SELECT a, b, c, d FROM abc WHERE b > 10 ORDER BY b, a, c, d
----
index-join  ·      ·
 ├── scan   ·      ·
 │          table  abc@ba
 │          spans  /11-
 └── scan   ·      ·
·           table  abc@primary

query TTT
EXPLAIN SELECT a, b FROM abc ORDER BY b, c
----
nosort          ·      ·
 │              order  +b,+c
 └── render     ·      ·
      └── scan  ·      ·
·               table  abc@bc
·               spans  ALL

query TTTTT
EXPLAIN (VERBOSE) SELECT a, b FROM abc ORDER BY b, c
----
nosort          ·         ·                  (a, b)                 b!=NULL; +b
 │              order     +b,+c              ·                      ·
 └── render     ·         ·                  (a, b, c)              b!=NULL; c!=NULL; key(b,c); +b,+c
      │         render 0  test.public.abc.a  ·                      ·
      │         render 1  test.public.abc.b  ·                      ·
      │         render 2  test.public.abc.c  ·                      ·
      └── scan  ·         ·                  (a, b, c, d[omitted])  b!=NULL; c!=NULL; key(b,c); +b,+c
·               table     abc@bc             ·                      ·
·               spans     ALL                ·                      ·

query TTT
EXPLAIN SELECT a, b FROM abc ORDER BY b, c, a
----
nosort          ·      ·
 │              order  +b,+c,+a
 └── render     ·      ·
      └── scan  ·      ·
·               table  abc@bc
·               spans  ALL

query TTT
EXPLAIN SELECT a, b FROM abc ORDER BY b, c, a DESC
----
nosort          ·      ·
 │              order  +b,+c,-a
 └── render     ·      ·
      └── scan  ·      ·
·               table  abc@bc
·               spans  ALL

statement ok
SET tracing = on,kv,results; SELECT b, c FROM abc ORDER BY b, c; SET tracing = off

query T
SELECT message FROM [SHOW KV TRACE FOR SESSION]
 WHERE message LIKE 'fetched:%' OR message LIKE 'output row%'
----
fetched: /abc/bc/2/3 -> /1
output row: [2 3]
fetched: /abc/bc/5/6 -> /4
output row: [5 6]

statement ok
SET tracing = on,kv,results; SELECT a, b, c FROM abc ORDER BY b; SET tracing = off

query T
SELECT message FROM [SHOW KV TRACE FOR SESSION]
 WHERE message LIKE 'fetched:%' OR message LIKE 'output row%'
----
fetched: /abc/bc/2/3 -> /1
output row: [1 2 3]
fetched: /abc/bc/5/6 -> /4
output row: [4 5 6]

statement ok
SET tracing = on,kv,results; SELECT a FROM abc ORDER BY a DESC; SET tracing = off

query T
SELECT message FROM [SHOW KV TRACE FOR SESSION]
 WHERE message LIKE 'fetched:%' OR message LIKE 'output row%'
----
fetched: /abc/primary/4/5/6/d -> 'Two'
fetched: /abc/primary/4/5/6 -> NULL
output row: [4]
fetched: /abc/primary/1/2/3/d -> 'one'
fetched: /abc/primary/1/2/3 -> NULL
output row: [1]

query TTT
EXPLAIN SELECT a FROM abc ORDER BY a DESC
----
render        ·      ·
 └── revscan  ·      ·
·             table  abc@primary
·             spans  ALL

query TTT
EXPLAIN SELECT c FROM abc WHERE b = 2 ORDER BY c
----
render     ·      ·
 └── scan  ·      ·
·          table  abc@bc
·          spans  /2-/3

query TTT
EXPLAIN SELECT c FROM abc WHERE b = 2 ORDER BY c DESC
----
render        ·      ·
 └── revscan  ·      ·
·             table  abc@bc
·             spans  /2-/3

# Verify that the ordering of the primary index is still used for the outer sort.
query TTTTT
EXPLAIN (VERBOSE) SELECT * FROM (SELECT b, c FROM abc WHERE a=1 ORDER BY a,b) ORDER BY b,c
----
nosort          ·         ·                  (b, c)                          b!=NULL; c!=NULL; key(b,c); +b,+c
 │              order     +b,+c              ·                               ·
 └── render     ·         ·                  (b, c, a[omitted])              a=CONST; b!=NULL; c!=NULL; key(b,c); +b,+c
      │         render 0  test.public.abc.b  ·                               ·
      │         render 1  test.public.abc.c  ·                               ·
      │         render 2  NULL               ·                               ·
      └── scan  ·         ·                  (a[omitted], b, c, d[omitted])  a=CONST; b!=NULL; c!=NULL; key(b,c); +b,+c
·               table     abc@primary        ·                               ·
·               spans     /1-/2              ·                               ·

statement ok
CREATE TABLE bar (id INT PRIMARY KEY, baz STRING, UNIQUE INDEX i_bar (baz))

query TTTTT
EXPLAIN (VERBOSE) SELECT * FROM bar ORDER BY baz, id
----
sort       ·      ·          (id, baz)  weak-key(baz); +baz,+id
 │         order  +baz,+id   ·          ·
 └── scan  ·      ·          (id, baz)  weak-key(baz); +baz
·          table  bar@i_bar  ·          ·
·          spans  ALL        ·          ·

statement ok
CREATE TABLE abcd (
  a INT PRIMARY KEY,
  b INT,
  c INT,
  d INT,
  INDEX abc (a, b, c)
)

# Verify that render expressions after sorts perform correctly. We need the
# rowsort as we're attempting to force a RENDER expression after the first
# ORDER BY, to ensure it renders correctly, but the outer query doesn't
# guarantee that it will preserve the order.

# The following tests verify we recognize that sorting is not necessary
query TTT
EXPLAIN SELECT a, b, c FROM abcd@abc WHERE (a, b) = (1, 4) ORDER BY c
----
render     ·      ·
 └── scan  ·      ·
·          table  abcd@abc
·          spans  /1/4-/1/5

query TTT
EXPLAIN SELECT a, b, c FROM abcd@abc WHERE (a, b) = (1, 4) ORDER BY c, b, a
----
render     ·      ·
 └── scan  ·      ·
·          table  abcd@abc
·          spans  /1/4-/1/5

query TTT
EXPLAIN SELECT a, b, c FROM abcd@abc WHERE (a, b) = (1, 4) ORDER BY b, a, c
----
render     ·      ·
 └── scan  ·      ·
·          table  abcd@abc
·          spans  /1/4-/1/5

query TTT
EXPLAIN SELECT a, b, c FROM abcd@abc WHERE (a, b) = (1, 4) ORDER BY b, c, a
----
render     ·      ·
 └── scan  ·      ·
·          table  abcd@abc
·          spans  /1/4-/1/5

statement ok
CREATE TABLE nan (id INT PRIMARY KEY, x REAL)

query TTTTT
EXPLAIN (VERBOSE) SELECT * FROM (SELECT * FROM (VALUES ('a'), ('b'), ('c')) AS c(x) ORDER BY x)
----
sort         ·              ·                 (x)  +x
 │           order          +x                ·    ·
 └── values  ·              ·                 (x)  ·
·            size           1 column, 3 rows  ·    ·
·            row 0, expr 0  'a'               ·    ·
·            row 1, expr 0  'b'               ·    ·
·            row 2, expr 0  'c'               ·    ·

query TTT
EXPLAIN SELECT * FROM (VALUES ('a'), ('b'), ('c')) WITH ORDINALITY ORDER BY ordinality ASC
----
ordinality   ·     ·
 └── values  ·     ·
·            size  1 column, 3 rows

query TTT
EXPLAIN SELECT * FROM (VALUES ('a'), ('b'), ('c')) WITH ORDINALITY ORDER BY ordinality DESC
----
sort              ·      ·
 │                order  -"ordinality"
 └── ordinality   ·      ·
      └── values  ·      ·
·                 size   1 column, 3 rows

query TTTTT
EXPLAIN (VERBOSE) SELECT * FROM (SELECT * FROM (VALUES ('a'), ('b'), ('c')) AS c(x)) WITH ORDINALITY
----
ordinality   ·              ·                 (x, "ordinality")  weak-key("ordinality")
 └── values  ·              ·                 (x)                ·
·            size           1 column, 3 rows  ·                  ·
·            row 0, expr 0  'a'               ·                  ·
·            row 1, expr 0  'b'               ·                  ·
·            row 2, expr 0  'c'               ·                  ·

query TTTTT
EXPLAIN (VERBOSE) SELECT * FROM (SELECT * FROM (VALUES ('a'), ('b'), ('c')) AS c(x) ORDER BY x) WITH ORDINALITY
----
ordinality        ·              ·                 (x, "ordinality")  weak-key("ordinality")
 └── sort         ·              ·                 (x)                +x
      │           order          +x                ·                  ·
      └── values  ·              ·                 (x)                ·
·                 size           1 column, 3 rows  ·                  ·
·                 row 0, expr 0  'a'               ·                  ·
·                 row 1, expr 0  'b'               ·                  ·
·                 row 2, expr 0  'c'               ·                  ·

# Check that the ordering of the source does not propagate blindly to RETURNING.
query TTTTT
EXPLAIN (VERBOSE) INSERT INTO t(a, b) SELECT * FROM (SELECT 1 AS x, 2 AS y) ORDER BY x RETURNING b
----
render                        ·         ·                (b)        ·
 │                            render 0  test.public.t.b  ·          ·
 └── run                      ·         ·                (a, b, c)  ·
      └── insert              ·         ·                (a, b, c)  ·
           │                  into      t(a, b)          ·          ·
           └── render         ·         ·                (x, y)     x=CONST; y=CONST
                │             render 0  1                ·          ·
                │             render 1  2                ·          ·
                └── emptyrow  ·         ·                ()         ·

query TTTTT
EXPLAIN (VERBOSE) DELETE FROM t WHERE a = 3 RETURNING b
----
render               ·         ·                (b)        key()
 │                   render 0  test.public.t.b  ·          ·
 └── run             ·         ·                (a, b, c)  a=CONST; key()
      └── delete     ·         ·                (a, b, c)  a=CONST; key()
           │         from      t                ·          ·
           └── scan  ·         ·                (a, b, c)  a=CONST; key()
·                    table     t@primary        ·          ·
·                    spans     /3-/3/#          ·          ·

query TTTTT
EXPLAIN (VERBOSE) UPDATE t SET c = TRUE RETURNING b
----
render                    ·         ·                (b)              ·
 │                        render 0  test.public.t.b  ·                ·
 └── run                  ·         ·                (a, b, c)        ·
      └── update          ·         ·                (a, b, c)        ·
           │              table     t                ·                ·
           │              set       c                ·                ·
           └── render     ·         ·                (a, b, c, bool)  bool=CONST; a!=NULL; key(a)
                │         render 0  test.public.t.a  ·                ·
                │         render 1  test.public.t.b  ·                ·
                │         render 2  test.public.t.c  ·                ·
                │         render 3  true             ·                ·
                └── scan  ·         ·                (a, b, c)        a!=NULL; key(a)
·                         table     t@primary        ·                ·
·                         spans     ALL              ·                ·

statement ok
CREATE TABLE uvwxyz (
  u INT,
  v INT,
  w INT,
  x INT,
  y INT,
  z INT,
  INDEX ywxz (y, w, x, z, u, v),
  INDEX ywz (y, w, z, x)
)

# Verify that the outer ordering is propagated to index selection and we choose
# the index that avoids any sorting.
query TTTTT
EXPLAIN (VERBOSE) SELECT * FROM (SELECT y, w, x FROM uvwxyz WHERE y = 1 ORDER BY w) ORDER BY w, x
----
render     ·         ·                     (y, w, x)                                                             y=CONST; +w,+x
 │         render 0  test.public.uvwxyz.y  ·                                                                     ·
 │         render 1  test.public.uvwxyz.w  ·                                                                     ·
 │         render 2  test.public.uvwxyz.x  ·                                                                     ·
 └── scan  ·         ·                     (u[omitted], v[omitted], w, x, y, z[omitted], rowid[hidden,omitted])  y=CONST; rowid!=NULL; weak-key(u,v,w,x,z,rowid); +w,+x
·          table     uvwxyz@ywxz           ·                                                                     ·
·          spans     /1-/2                 ·                                                                     ·


statement ok
CREATE TABLE blocks (
  block_id  INT,
  writer_id STRING,
  block_num INT,
  raw_bytes BYTES,
  PRIMARY KEY (block_id, writer_id, block_num)
)

# Test that ordering goes "through" a renderNode that has a duplicate render of
# an order-by column (#13696).
query TTTTT
EXPLAIN (VERBOSE) SELECT block_id,writer_id,block_num,block_id FROM blocks ORDER BY block_id, writer_id, block_num LIMIT 1
----
limit           ·         ·                             (block_id, writer_id, block_num, block_id)            block_id=block_id; block_id!=NULL; writer_id!=NULL; block_num!=NULL; key(block_id,writer_id,block_num); +block_id,+writer_id,+block_num
 │              count     1                             ·                                                     ·
 └── render     ·         ·                             (block_id, writer_id, block_num, block_id)            block_id=block_id; block_id!=NULL; writer_id!=NULL; block_num!=NULL; key(block_id,writer_id,block_num); +block_id,+writer_id,+block_num
      │         render 0  test.public.blocks.block_id   ·                                                     ·
      │         render 1  test.public.blocks.writer_id  ·                                                     ·
      │         render 2  test.public.blocks.block_num  ·                                                     ·
      │         render 3  test.public.blocks.block_id   ·                                                     ·
      └── scan  ·         ·                             (block_id, writer_id, block_num, raw_bytes[omitted])  block_id!=NULL; writer_id!=NULL; block_num!=NULL; key(block_id,writer_id,block_num); +block_id,+writer_id,+block_num
·               table     blocks@primary                ·                                                     ·
·               spans     ALL                           ·                                                     ·
·               limit     1                             ·                                                     ·

statement ok
CREATE TABLE foo(a INT, b CHAR)

# Check that sort by ordinal picks up the existing render.
query TTTTT
EXPLAIN (VERBOSE) SELECT b, a FROM foo ORDER BY @1
----
sort            ·         ·                  (b, a)                         +a
 │              order     +a                 ·                              ·
 └── render     ·         ·                  (b, a)                         ·
      │         render 0  test.public.foo.b  ·                              ·
      │         render 1  test.public.foo.a  ·                              ·
      └── scan  ·         ·                  (a, b, rowid[hidden,omitted])  rowid!=NULL; key(rowid)
·               table     foo@primary        ·                              ·
·               spans     ALL                ·                              ·

query TTTTT
EXPLAIN (VERBOSE) SELECT b, a FROM foo ORDER BY @2
----
sort            ·         ·                  (b, a)                         +b
 │              order     +b                 ·                              ·
 └── render     ·         ·                  (b, a)                         ·
      │         render 0  test.public.foo.b  ·                              ·
      │         render 1  test.public.foo.a  ·                              ·
      └── scan  ·         ·                  (a, b, rowid[hidden,omitted])  rowid!=NULL; key(rowid)
·               table     foo@primary        ·                              ·
·               spans     ALL                ·                              ·

# ------------------------------------------------------------------------------
# Check star expansion in ORDER BY.
# ------------------------------------------------------------------------------
statement ok
CREATE TABLE a(x, y) AS VALUES (1, 1), (2, 2)

query TTT
SELECT tree, field, description FROM [
EXPLAIN (VERBOSE) SELECT * FROM a ORDER BY a.*
]
----
sort            ·         ·
 │              order     +x,+y
 └── render     ·         ·
      │         render 0  test.public.a.x
      │         render 1  test.public.a.y
      └── scan  ·         ·
·               table     a@primary
·               spans     ALL

query TTT
SELECT tree, field, description FROM [
EXPLAIN (VERBOSE) SELECT * FROM a ORDER BY (a.*)
]
----
sort            ·         ·
 │              order     +x,+y
 └── render     ·         ·
      │         render 0  test.public.a.x
      │         render 1  test.public.a.y
      └── scan  ·         ·
·               table     a@primary
·               spans     ALL

# ------------------------------------------------------------------------------
# ORDER BY INDEX test cases.
# ------------------------------------------------------------------------------
subtest order_by_index

statement ok
CREATE TABLE kv(k INT PRIMARY KEY, v INT); CREATE INDEX foo ON kv(v DESC)

query TTTTT
EXPLAIN (VERBOSE) SELECT v FROM kv ORDER BY PRIMARY KEY kv
----
nosort          ·         ·                 (v)     ·
 │              order     +k                ·       ·
 └── render     ·         ·                 (v, k)  k!=NULL; key(k); +k
      │         render 0  test.public.kv.v  ·       ·
      │         render 1  test.public.kv.k  ·       ·
      └── scan  ·         ·                 (k, v)  k!=NULL; key(k); +k
·               table     kv@primary        ·       ·
·               spans     ALL               ·       ·

query TTTTT
EXPLAIN (VERBOSE) SELECT v FROM kv ORDER BY PRIMARY KEY kv ASC
----
nosort          ·         ·                 (v)     ·
 │              order     +k                ·       ·
 └── render     ·         ·                 (v, k)  k!=NULL; key(k); +k
      │         render 0  test.public.kv.v  ·       ·
      │         render 1  test.public.kv.k  ·       ·
      └── scan  ·         ·                 (k, v)  k!=NULL; key(k); +k
·               table     kv@primary        ·       ·
·               spans     ALL               ·       ·

query TTTTT
EXPLAIN (VERBOSE) SELECT v FROM kv ORDER BY PRIMARY KEY kv DESC
----
nosort             ·         ·                 (v)     ·
 │                 order     -k                ·       ·
 └── render        ·         ·                 (v, k)  k!=NULL; key(k); -k
      │            render 0  test.public.kv.v  ·       ·
      │            render 1  test.public.kv.k  ·       ·
      └── revscan  ·         ·                 (k, v)  k!=NULL; key(k); -k
·                  table     kv@primary        ·       ·
·                  spans     ALL               ·       ·

query TTTTT
EXPLAIN (VERBOSE) SELECT k FROM kv ORDER BY v, PRIMARY KEY kv, v-2
----
sort               ·         ·                     (k)                 k!=NULL
 │                 order     +v,+k,+"?column?"     ·                   ·
 └── render        ·         ·                     (k, v, "?column?")  k!=NULL; weak-key(k,v); +v
      │            render 0  test.public.kv.k      ·                   ·
      │            render 1  test.public.kv.v      ·                   ·
      │            render 2  test.public.kv.v - 2  ·                   ·
      └── revscan  ·         ·                     (k, v)              k!=NULL; weak-key(k,v); +v
·                  table     kv@foo                ·                   ·
·                  spans     ALL                   ·                   ·

query TTTTT
EXPLAIN (VERBOSE) SELECT k FROM kv ORDER BY INDEX kv@foo
----
nosort     ·      ·       (k)     k!=NULL
 │         order  -v,+k   ·       ·
 └── scan  ·      ·       (k, v)  k!=NULL; weak-key(k,v); -v,+k
·          table  kv@foo  ·       ·
·          spans  ALL     ·       ·

query TTTTT
EXPLAIN (VERBOSE) SELECT k FROM kv ORDER BY INDEX kv@foo ASC
----
nosort     ·      ·       (k)     k!=NULL
 │         order  -v,+k   ·       ·
 └── scan  ·      ·       (k, v)  k!=NULL; weak-key(k,v); -v,+k
·          table  kv@foo  ·       ·
·          spans  ALL     ·       ·

query TTTTT
EXPLAIN (VERBOSE) SELECT k FROM kv ORDER BY INDEX kv@foo DESC
----
nosort        ·      ·       (k)     k!=NULL
 │            order  +v,-k   ·       ·
 └── revscan  ·      ·       (k, v)  k!=NULL; weak-key(k,v); +v,-k
·             table  kv@foo  ·       ·
·             spans  ALL     ·       ·

query TTTTT
EXPLAIN (VERBOSE) SELECT k FROM kv ORDER BY INDEX kv@foo, k
----
nosort     ·      ·       (k)     k!=NULL
 │         order  -v,+k   ·       ·
 └── scan  ·      ·       (k, v)  k!=NULL; weak-key(k,v); -v,+k
·          table  kv@foo  ·       ·
·          spans  ALL     ·       ·

# Check the syntax can be used with joins.
#
# Note: an ORDER BY INDEX clause on the result of the join
# does not imply use of that index by the underlying scan.
#

query TTTTT
EXPLAIN (VERBOSE) SELECT k FROM kv JOIN (VALUES (1,2)) AS z(a,b) ON kv.k = z.a ORDER BY INDEX kv@foo
----
sort                   ·              ·                 (k)                             ·
 │                     order          -v,+k             ·                               ·
 └── render            ·              ·                 (k, v)                          ·
      │                render 0       test.public.kv.k  ·                               ·
      │                render 1       test.public.kv.v  ·                               ·
      └── join         ·              ·                 (k, v, a[omitted], b[omitted])  ·
           │           type           inner             ·                               ·
           │           equality       (k) = (a)         ·                               ·
           ├── scan    ·              ·                 (k, v)                          k!=NULL; key(k)
           │           table          kv@primary        ·                               ·
           │           spans          ALL               ·                               ·
           └── values  ·              ·                 (column1, column2[omitted])     ·
·                      size           2 columns, 1 row  ·                               ·
·                      row 0, expr 0  1                 ·                               ·

query TTTTT
EXPLAIN (VERBOSE) SELECT k FROM kv a NATURAL JOIN kv ORDER BY INDEX kv@foo
----
sort                 ·               ·                 (k)                    k!=NULL; key(k)
 │                   order           -v,+k             ·                      ·
 └── render          ·               ·                 (k, v, k)              k=k; k!=NULL; v!=NULL; key(k)
      │              render 0        a.k               ·                      ·
      │              render 1        test.public.kv.v  ·                      ·
      │              render 2        test.public.kv.k  ·                      ·
      └── join       ·               ·                 (k, v[omitted], k, v)  k=k; v=v; k!=NULL; v!=NULL; key(k)
           │         type            inner             ·                      ·
           │         equality        (k, v) = (k, v)   ·                      ·
           │         mergeJoinOrder  +"(k=k)"          ·                      ·
           ├── scan  ·               ·                 (k, v)                 k!=NULL; key(k); +k
           │         table           kv@primary        ·                      ·
           │         spans           ALL               ·                      ·
           └── scan  ·               ·                 (k, v)                 k!=NULL; key(k); +k
·                    table           kv@primary        ·                      ·
·                    spans           ALL               ·                      ·

# The underlying index can be forced manually, of course.
query TTTTT
EXPLAIN (VERBOSE) SELECT k FROM kv@foo a NATURAL JOIN kv@foo ORDER BY INDEX kv@foo
----
nosort               ·               ·                  (k)                    k!=NULL
 │                   order           -v,+k              ·                      ·
 └── render          ·               ·                  (k, v, k)              k=k; k!=NULL; v!=NULL; -v,+k
      │              render 0        a.k                ·                      ·
      │              render 1        test.public.kv.v   ·                      ·
      │              render 2        test.public.kv.k   ·                      ·
      └── join       ·               ·                  (k, v[omitted], k, v)  k=k; v=v; k!=NULL; v!=NULL; -v,+k
           │         type            inner              ·                      ·
           │         equality        (k, v) = (k, v)    ·                      ·
           │         mergeJoinOrder  -"(v=v)",+"(k=k)"  ·                      ·
           ├── scan  ·               ·                  (k, v)                 k!=NULL; weak-key(k,v); -v,+k
           │         table           kv@foo             ·                      ·
           │         spans           ALL                ·                      ·
           └── scan  ·               ·                  (k, v)                 k!=NULL; weak-key(k,v); -v,+k
·                    table           kv@foo             ·                      ·
·                    spans           ALL                ·                      ·
