# LogicTest: local

statement ok
CREATE TABLE xyz (
  x INT,
  y INT,
  z INT,
  pk1 INT,
  pk2 INT,
  PRIMARY KEY (pk1, pk2)
)

statement ok
CREATE TABLE abc (
  a STRING,
  b STRING,
  c STRING,
  PRIMARY KEY (a, b, c)
)

##################
# Simple queries #
##################

# 3/3 columns

query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON (x, y, z) x, y, z FROM xyz
----
distinct        ·            ·                  (x, y, z)                              weak-key(x,y,z)
 │              distinct on  x, y, z            ·                                      ·
 └── render     ·            ·                  (x, y, z)                              ·
      │         render 0     test.public.xyz.x  ·                                      ·
      │         render 1     test.public.xyz.y  ·                                      ·
      │         render 2     test.public.xyz.z  ·                                      ·
      └── scan  ·            ·                  (x, y, z, pk1[omitted], pk2[omitted])  pk1!=NULL; pk2!=NULL; key(pk1,pk2)
·               table        xyz@primary        ·                                      ·
·               spans        ALL                ·                                      ·

query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON (z, x, y) x FROM xyz
----
render               ·            ·                  (x)                                    ·
 │                   render 0     x                  ·                                      ·
 └── distinct        ·            ·                  (x, z, y)                              weak-key(x,z,y)
      │              distinct on  x, z, y            ·                                      ·
      └── render     ·            ·                  (x, z, y)                              ·
           │         render 0     test.public.xyz.x  ·                                      ·
           │         render 1     test.public.xyz.z  ·                                      ·
           │         render 2     test.public.xyz.y  ·                                      ·
           └── scan  ·            ·                  (x, y, z, pk1[omitted], pk2[omitted])  pk1!=NULL; pk2!=NULL; key(pk1,pk2)
·                    table        xyz@primary        ·                                      ·
·                    spans        ALL                ·                                      ·

query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON (b, c, a) a, c, b FROM abc
----
render     ·         ·                  (a, c, b)  a!=NULL; c!=NULL; b!=NULL; key(a,c,b)
 │         render 0  test.public.abc.a  ·          ·
 │         render 1  test.public.abc.c  ·          ·
 │         render 2  test.public.abc.b  ·          ·
 └── scan  ·         ·                  (a, b, c)  a!=NULL; b!=NULL; c!=NULL; key(a,b,c)
·          table     abc@primary        ·          ·
·          spans     ALL                ·          ·

# Distinct node should be elided since we have a strong key.
query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON (b, c, a) a FROM abc
----
render     ·         ·            (a)        a!=NULL
 │         render 0  a            ·          ·
 └── scan  ·         ·            (a, b, c)  a!=NULL; b!=NULL; c!=NULL; key(a,b,c)
·          table     abc@primary  ·          ·
·          spans     ALL          ·          ·

# Distinct node should be elided since we have a strong key.
query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON (c, a, b) b FROM abc ORDER BY b
----
render               ·         ·                  (b)                          b!=NULL; +b
 │                   render 0  b                  ·                            ·
 └── sort            ·         ·                  (b, c[omitted], a[omitted])  b!=NULL; c!=NULL; a!=NULL; key(b,c,a); +b
      │              order     +b                 ·                            ·
      └── render     ·         ·                  (b, c[omitted], a[omitted])  b!=NULL; c!=NULL; a!=NULL; key(b,c,a)
           │         render 0  test.public.abc.b  ·                            ·
           │         render 1  NULL               ·                            ·
           │         render 2  NULL               ·                            ·
           └── scan  ·         ·                  (a[omitted], b, c[omitted])  a!=NULL; b!=NULL; c!=NULL; key(a,b,c)
·                    table     abc@primary        ·                            ·
·                    spans     ALL                ·                            ·


# 2/3 columns

query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON (x, y) y, x FROM xyz
----
distinct        ·            ·                  (y, x)                                          weak-key(y,x)
 │              distinct on  y, x               ·                                               ·
 └── render     ·            ·                  (y, x)                                          ·
      │         render 0     test.public.xyz.y  ·                                               ·
      │         render 1     test.public.xyz.x  ·                                               ·
      └── scan  ·            ·                  (x, y, z[omitted], pk1[omitted], pk2[omitted])  pk1!=NULL; pk2!=NULL; key(pk1,pk2)
·               table        xyz@primary        ·                                               ·
·               spans        ALL                ·                                               ·

query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON (y, x) x FROM xyz
----
render               ·            ·                  (x)                                             ·
 │                   render 0     x                  ·                                               ·
 └── distinct        ·            ·                  (x, y)                                          weak-key(x,y)
      │              distinct on  x, y               ·                                               ·
      └── render     ·            ·                  (x, y)                                          ·
           │         render 0     test.public.xyz.x  ·                                               ·
           │         render 1     test.public.xyz.y  ·                                               ·
           └── scan  ·            ·                  (x, y, z[omitted], pk1[omitted], pk2[omitted])  pk1!=NULL; pk2!=NULL; key(pk1,pk2)
·                    table        xyz@primary        ·                                               ·
·                    spans        ALL                ·                                               ·

query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON (y, x, x, y, x) x, y FROM xyz
----
distinct        ·            ·                  (x, y)                                          weak-key(x,y)
 │              distinct on  x, y               ·                                               ·
 └── render     ·            ·                  (x, y)                                          ·
      │         render 0     test.public.xyz.x  ·                                               ·
      │         render 1     test.public.xyz.y  ·                                               ·
      └── scan  ·            ·                  (x, y, z[omitted], pk1[omitted], pk2[omitted])  pk1!=NULL; pk2!=NULL; key(pk1,pk2)
·               table        xyz@primary        ·                                               ·
·               spans        ALL                ·                                               ·

query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON(pk1, x) pk1, x FROM xyz ORDER BY pk1
----
distinct        ·            ·                    (pk1, x)                                        pk1!=NULL; weak-key(pk1,x); +pk1
 │              distinct on  pk1, x               ·                                               ·
 │              order key    pk1                  ·                                               ·
 └── render     ·            ·                    (pk1, x)                                        pk1!=NULL; +pk1
      │         render 0     test.public.xyz.pk1  ·                                               ·
      │         render 1     test.public.xyz.x    ·                                               ·
      └── scan  ·            ·                    (x, y[omitted], z[omitted], pk1, pk2[omitted])  pk1!=NULL; pk2!=NULL; key(pk1,pk2); +pk1
·               table        xyz@primary          ·                                               ·
·               spans        ALL                  ·                                               ·

query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON (a, c) a, b FROM abc
----
render          ·            ·            (a, b)     a!=NULL; b!=NULL; +a
 │              render 0     a            ·          ·
 │              render 1     b            ·          ·
 └── distinct   ·            ·            (a, b, c)  a!=NULL; b!=NULL; c!=NULL; key(a,c); +a
      │         distinct on  a, c         ·          ·
      │         order key    a            ·          ·
      └── scan  ·            ·            (a, b, c)  a!=NULL; b!=NULL; c!=NULL; key(a,b,c); +a
·               table        abc@primary  ·          ·
·               spans        ALL          ·          ·

query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON (c, a) b, c, a FROM abc
----
distinct        ·            ·                  (b, c, a)  b!=NULL; c!=NULL; a!=NULL; key(c,a); +a
 │              distinct on  c, a               ·          ·
 │              order key    a                  ·          ·
 └── render     ·            ·                  (b, c, a)  b!=NULL; c!=NULL; a!=NULL; key(b,c,a); +a
      │         render 0     test.public.abc.b  ·          ·
      │         render 1     test.public.abc.c  ·          ·
      │         render 2     test.public.abc.a  ·          ·
      └── scan  ·            ·                  (a, b, c)  a!=NULL; b!=NULL; c!=NULL; key(a,b,c); +a
·               table        abc@primary        ·          ·
·               spans        ALL                ·          ·


# 1/3 columns

# Check that distinct propagates the smaller, tighter key (pk1) as opposed to
# the original key (pk1, pk2).
query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON (pk1) pk1, pk2 FROM xyz
----
distinct        ·            ·                    (pk1, pk2)                                      pk1!=NULL; pk2!=NULL; key(pk1); +pk1
 │              distinct on  pk1                  ·                                               ·
 │              order key    pk1                  ·                                               ·
 └── render     ·            ·                    (pk1, pk2)                                      pk1!=NULL; pk2!=NULL; key(pk1,pk2); +pk1
      │         render 0     test.public.xyz.pk1  ·                                               ·
      │         render 1     test.public.xyz.pk2  ·                                               ·
      └── scan  ·            ·                    (x[omitted], y[omitted], z[omitted], pk1, pk2)  pk1!=NULL; pk2!=NULL; key(pk1,pk2); +pk1
·               table        xyz@primary          ·                                               ·
·               spans        ALL                  ·                                               ·

# Ensure order simplification on DISTINCT ON columns does not simplifying out
# an explicit order from ORDER BY.
# Note that the -c ordering was reduced after the distinct: this is because
# we have a strong key on 'a' so ordering after '+a' is unnecessary.
query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON (a) a, c FROM abc ORDER BY a, c DESC, b
----
distinct             ·            ·                  (a, c)     a!=NULL; c!=NULL; key(a); +a
 │                   distinct on  a                  ·          ·
 │                   order key    a                  ·          ·
 └── sort            ·            ·                  (a, c)     a!=NULL; c!=NULL; +a,-c
      │              order        +a,-c,+b           ·          ·
      └── render     ·            ·                  (a, c, b)  a!=NULL; c!=NULL; b!=NULL; key(a,c,b); +a
           │         render 0     test.public.abc.a  ·          ·
           │         render 1     test.public.abc.c  ·          ·
           │         render 2     test.public.abc.b  ·          ·
           └── scan  ·            ·                  (a, b, c)  a!=NULL; b!=NULL; c!=NULL; key(a,b,c); +a
·                    table        abc@primary        ·          ·
·                    spans        ALL                ·          ·

#################
# With ORDER BY #
#################

query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON (x) x FROM xyz ORDER BY x DESC
----
distinct             ·            ·                  (x)                                                      weak-key(x); -x
 │                   distinct on  x                  ·                                                        ·
 │                   order key    x                  ·                                                        ·
 └── sort            ·            ·                  (x)                                                      -x
      │              order        -x                 ·                                                        ·
      └── render     ·            ·                  (x)                                                      ·
           │         render 0     test.public.xyz.x  ·                                                        ·
           └── scan  ·            ·                  (x, y[omitted], z[omitted], pk1[omitted], pk2[omitted])  pk1!=NULL; pk2!=NULL; key(pk1,pk2)
·                    table        xyz@primary        ·                                                        ·
·                    spans        ALL                ·                                                        ·

query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON (x, z) y, z, x FROM xyz ORDER BY z
----
distinct             ·            ·                  (y, z, x)                              weak-key(z,x); +z
 │                   distinct on  z, x               ·                                      ·
 │                   order key    z                  ·                                      ·
 └── sort            ·            ·                  (y, z, x)                              +z
      │              order        +z                 ·                                      ·
      └── render     ·            ·                  (y, z, x)                              ·
           │         render 0     test.public.xyz.y  ·                                      ·
           │         render 1     test.public.xyz.z  ·                                      ·
           │         render 2     test.public.xyz.x  ·                                      ·
           └── scan  ·            ·                  (x, y, z, pk1[omitted], pk2[omitted])  pk1!=NULL; pk2!=NULL; key(pk1,pk2)
·                    table        xyz@primary        ·                                      ·
·                    spans        ALL                ·                                      ·

query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON (x) y, z, x FROM xyz ORDER BY x ASC, z DESC, y DESC
----
distinct             ·            ·                  (y, z, x)                              weak-key(x); +x,-z,-y
 │                   distinct on  x                  ·                                      ·
 │                   order key    x                  ·                                      ·
 └── sort            ·            ·                  (y, z, x)                              +x,-z,-y
      │              order        +x,-z,-y           ·                                      ·
      └── render     ·            ·                  (y, z, x)                              ·
           │         render 0     test.public.xyz.y  ·                                      ·
           │         render 1     test.public.xyz.z  ·                                      ·
           │         render 2     test.public.xyz.x  ·                                      ·
           └── scan  ·            ·                  (x, y, z, pk1[omitted], pk2[omitted])  pk1!=NULL; pk2!=NULL; key(pk1,pk2)
·                    table        xyz@primary        ·                                      ·
·                    spans        ALL                ·                                      ·

#####################
# With aggregations #
#####################

query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON (max(y)) max(x) FROM xyz
----
render                    ·            ·                  (max)                                           ·
 │                        render 0     max                ·                                               ·
 └── distinct             ·            ·                  (max, max)                                      weak-key(max)
      │                   distinct on  max                ·                                               ·
      └── group           ·            ·                  (max, max)                                      ·
           │              aggregate 0  max(x)             ·                                               ·
           │              aggregate 1  max(y)             ·                                               ·
           │              scalar       ·                  ·                                               ·
           └── render     ·            ·                  (x, y)                                          ·
                │         render 0     test.public.xyz.x  ·                                               ·
                │         render 1     test.public.xyz.y  ·                                               ·
                └── scan  ·            ·                  (x, y, z[omitted], pk1[omitted], pk2[omitted])  pk1!=NULL; pk2!=NULL; key(pk1,pk2)
·                         table        xyz@primary        ·                                               ·
·                         spans        ALL                ·                                               ·

query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON(min(a), max(b), min(c)) max(a) FROM abc
----
render               ·            ·              (max)                 ·
 │                   render 0     max            ·                     ·
 └── distinct        ·            ·              (max, min, max, min)  weak-key(min,max,min)
      │              distinct on  min, max, min  ·                     ·
      └── group      ·            ·              (max, min, max, min)  ·
           │         aggregate 0  max(a)         ·                     ·
           │         aggregate 1  min(a)         ·                     ·
           │         aggregate 2  max(b)         ·                     ·
           │         aggregate 3  min(c)         ·                     ·
           │         scalar       ·              ·                     ·
           └── scan  ·            ·              (a, b, c)             a!=NULL; b!=NULL; c!=NULL; key(a,b,c)
·                    table        abc@primary    ·                     ·
·                    spans        ALL            ·                     ·

#################
# With GROUP BY #
#################

# TODO(richardwu): we can elide the DISTINCT ON since its key is equivalent
# to the group key.
query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON(y) min(x) FROM xyz GROUP BY y
----
render                    ·            ·                  (min)                                           ·
 │                        render 0     min                ·                                               ·
 └── distinct             ·            ·                  (min, y)                                        weak-key(y)
      │                   distinct on  y                  ·                                               ·
      └── group           ·            ·                  (min, y)                                        weak-key(y)
           │              aggregate 0  min(x)             ·                                               ·
           │              aggregate 1  y                  ·                                               ·
           │              group by     @1                 ·                                               ·
           └── render     ·            ·                  (y, x)                                          ·
                │         render 0     test.public.xyz.y  ·                                               ·
                │         render 1     test.public.xyz.x  ·                                               ·
                └── scan  ·            ·                  (x, y, z[omitted], pk1[omitted], pk2[omitted])  pk1!=NULL; pk2!=NULL; key(pk1,pk2)
·                         table        xyz@primary        ·                                               ·
·                         spans        ALL                ·                                               ·

query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON(min(x)) min(x) FROM xyz GROUP BY y HAVING min(x) = 1
----
distinct                  ·            ·                  (min)                                           min=CONST; key()
 │                        distinct on  min                ·                                               ·
 └── filter               ·            ·                  (min)                                           min=CONST
      │                   filter       agg0 = 1           ·                                               ·
      └── group           ·            ·                  (min)                                           ·
           │              aggregate 0  min(x)             ·                                               ·
           │              group by     @1                 ·                                               ·
           └── render     ·            ·                  (y, x)                                          ·
                │         render 0     test.public.xyz.y  ·                                               ·
                │         render 1     test.public.xyz.x  ·                                               ·
                └── scan  ·            ·                  (x, y, z[omitted], pk1[omitted], pk2[omitted])  pk1!=NULL; pk2!=NULL; key(pk1,pk2)
·                         table        xyz@primary        ·                                               ·
·                         spans        ALL                ·                                               ·

#########################
# With window functions #
#########################

query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON(row_number() OVER()) y FROM xyz
----
render                    ·            ·                     (y)                                                      ·
 │                        render 0     y                     ·                                                        ·
 └── distinct             ·            ·                     (y, row_number)                                          weak-key(row_number)
      │                   distinct on  row_number            ·                                                        ·
      └── window          ·            ·                     (y, row_number)                                          ·
           │              window 0     row_number() OVER ()  ·                                                        ·
           │              render 1     row_number() OVER ()  ·                                                        ·
           └── render     ·            ·                     (y)                                                      ·
                │         render 0     test.public.xyz.y     ·                                                        ·
                └── scan  ·            ·                     (x[omitted], y, z[omitted], pk1[omitted], pk2[omitted])  pk1!=NULL; pk2!=NULL; key(pk1,pk2)
·                         table        xyz@primary           ·                                                        ·
·                         spans        ALL                   ·                                                        ·

###########################
# With ordinal references #
###########################

query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON (1) x, y, z FROM xyz
----
distinct        ·            ·                  (x, y, z)                              weak-key(x)
 │              distinct on  x                  ·                                      ·
 └── render     ·            ·                  (x, y, z)                              ·
      │         render 0     test.public.xyz.x  ·                                      ·
      │         render 1     test.public.xyz.y  ·                                      ·
      │         render 2     test.public.xyz.z  ·                                      ·
      └── scan  ·            ·                  (x, y, z, pk1[omitted], pk2[omitted])  pk1!=NULL; pk2!=NULL; key(pk1,pk2)
·               table        xyz@primary        ·                                      ·
·               spans        ALL                ·                                      ·

# Distinct node elided because of strong key.
query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON (1,2,3) a, b, c FROM abc
----
scan  ·      ·            (a, b, c)  a!=NULL; b!=NULL; c!=NULL; key(a,b,c)
·     table  abc@primary  ·          ·
·     spans  ALL          ·          ·

#########################
# With alias references #
#########################

# This should priortize alias (use 'x' as the key).
query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON(y) x AS y, y AS x FROM xyz
----
distinct        ·            ·                  (y, x)                                          weak-key(y)
 │              distinct on  y                  ·                                               ·
 └── render     ·            ·                  (y, x)                                          ·
      │         render 0     test.public.xyz.x  ·                                               ·
      │         render 1     test.public.xyz.y  ·                                               ·
      └── scan  ·            ·                  (x, y, z[omitted], pk1[omitted], pk2[omitted])  pk1!=NULL; pk2!=NULL; key(pk1,pk2)
·               table        xyz@primary        ·                                               ·
·               spans        ALL                ·                                               ·

# Ignores the alias.
query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON(x) x AS y FROM xyz
----
distinct        ·            ·                  (y)                                                      weak-key(y)
 │              distinct on  y                  ·                                                        ·
 └── render     ·            ·                  (y)                                                      ·
      │         render 0     test.public.xyz.x  ·                                                        ·
      └── scan  ·            ·                  (x, y[omitted], z[omitted], pk1[omitted], pk2[omitted])  pk1!=NULL; pk2!=NULL; key(pk1,pk2)
·               table        xyz@primary        ·                                                        ·
·               spans        ALL                ·                                                        ·

##################################
# With nested parentheses/tuples #
##################################

query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON(((x)), (x, y)) x, y FROM xyz
----
distinct        ·            ·                  (x, y)                                          weak-key(x,y)
 │              distinct on  x, y               ·                                               ·
 └── render     ·            ·                  (x, y)                                          ·
      │         render 0     test.public.xyz.x  ·                                               ·
      │         render 1     test.public.xyz.y  ·                                               ·
      └── scan  ·            ·                  (x, y, z[omitted], pk1[omitted], pk2[omitted])  pk1!=NULL; pk2!=NULL; key(pk1,pk2)
·               table        xyz@primary        ·                                               ·
·               spans        ALL                ·                                               ·

################################
# Hybrid PK and non-PK queries #
################################

# Distinct elided because of strong key presence.
query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON(pk1, pk2, x, y) x, y, z FROM xyz ORDER BY x, y
----
render          ·         ·            (x, y, z)                              +x,+y
 │              render 0  x            ·                                      ·
 │              render 1  y            ·                                      ·
 │              render 2  z            ·                                      ·
 └── sort       ·         ·            (x, y, z, pk1[omitted], pk2[omitted])  pk1!=NULL; pk2!=NULL; key(pk1,pk2); +x,+y
      │         order     +x,+y        ·                                      ·
      └── scan  ·         ·            (x, y, z, pk1[omitted], pk2[omitted])  pk1!=NULL; pk2!=NULL; key(pk1,pk2)
·               table     xyz@primary  ·                                      ·
·               spans     ALL          ·                                      ·

# Ordering only propagates up until distinctNode.
# pk1 ordering does not propagate at all since it's not explicitly needed.
query TTTTT
EXPLAIN (VERBOSE) SELECT DISTINCT ON (x, y, z) pk1 FROM xyz ORDER BY x
----
render                    ·            ·                    (pk1)                         pk1!=NULL
 │                        render 0     pk1                  ·                             ·
 └── distinct             ·            ·                    (pk1, x, y, z)                pk1!=NULL; weak-key(x,y,z); +x
      │                   distinct on  x, y, z              ·                             ·
      │                   order key    x                    ·                             ·
      └── sort            ·            ·                    (pk1, x, y, z)                pk1!=NULL; +x
           │              order        +x                   ·                             ·
           └── render     ·            ·                    (pk1, x, y, z)                pk1!=NULL
                │         render 0     test.public.xyz.pk1  ·                             ·
                │         render 1     test.public.xyz.x    ·                             ·
                │         render 2     test.public.xyz.y    ·                             ·
                │         render 3     test.public.xyz.z    ·                             ·
                └── scan  ·            ·                    (x, y, z, pk1, pk2[omitted])  pk1!=NULL; pk2!=NULL; key(pk1,pk2)
·                         table        xyz@primary          ·                             ·
·                         spans        ALL                  ·                             ·
