# LogicTest: local local-opt local-parallel-stmts fakedist fakedist-opt fakedist-metadata fakedist-disk

statement ok
CREATE TABLE tb(unused INT); INSERT INTO tb VALUES (1)

subtest empty_tuple

query B
SELECT 1 IN (SELECT * FROM tb LIMIT 0)
----
false

query B
SELECT 1 IN ()
----
false

query B
SELECT 1 = ANY ()
----
false

subtest unlabeled_tuple

# TODO(bram): We don't pretty print tuples the same way as postgres. See #25522.
query TT colnames
SELECT (1, 2, 'hello', NULL, NULL) AS t, (true, NULL, (false, 6.6, false)) AS u FROM tb
----
t              u
(1,2,hello,,)  (t,,"(f,6.6,f)")

query T
SELECT (1, e'hello\nworld')
----
(1,"hello
world")

query BBBBBBBBB colnames
SELECT
  (2, 2) < (1, 1) AS a,
  (2, 2) < (1, 2) AS b,
  (2, 2) < (1, 3) AS c,
  (2, 2) < (2, 1) AS d,
  (2, 2) < (2, 2) AS e,
  (2, 2) < (2, 3) AS f,
  (2, 2) < (3, 1) AS g,
  (2, 2) < (3, 2) AS h,
  (2, 2) < (3, 3) AS i
  FROM tb
----
a      b      c      d      e      f     g     h     i
false  false  false  false  false  true  true  true  true

query BBBBBBBBB colnames
SELECT
  (2, 2) > (1, 1) AS a,
  (2, 2) > (1, 2) AS b,
  (2, 2) > (1, 3) AS c,
  (2, 2) > (2, 1) AS d,
  (2, 2) > (2, 2) AS e,
  (2, 2) > (2, 3) AS f,
  (2, 2) > (3, 1) AS g,
  (2, 2) > (3, 2) AS h,
  (2, 2) > (3, 3) AS i
  FROM tb
----
a     b     c     d     e      f      g      h      i
true  true  true  true  false  false  false  false  false

query BBBBBBBBB colnames
SELECT
  (2, 2) <= (1, 1) AS a,
  (2, 2) <= (1, 2) AS b,
  (2, 2) <= (1, 3) AS c,
  (2, 2) <= (2, 1) AS d,
  (2, 2) <= (2, 2) AS e,
  (2, 2) <= (2, 3) AS f,
  (2, 2) <= (3, 1) AS g,
  (2, 2) <= (3, 2) AS h,
  (2, 2) <= (3, 3) AS i
  FROM tb
----
a      b      c      d      e     f     g     h     i
false  false  false  false  true  true  true  true  true

query BBBBBBBBB colnames
SELECT
  (2, 2) >= (1, 1) AS a,
  (2, 2) >= (1, 2) AS b,
  (2, 2) >= (1, 3) AS c,
  (2, 2) >= (2, 1) AS d,
  (2, 2) >= (2, 2) AS e,
  (2, 2) >= (2, 3) AS f,
  (2, 2) >= (3, 1) AS g,
  (2, 2) >= (3, 2) AS h,
  (2, 2) >= (3, 3) AS i
  FROM tb
----
a     b     c     d     e     f      g      h      i
true  true  true  true  true  false  false  false  false

query BBBBBBBBB colnames
SELECT
  (2, 2) = (1, 1) AS a,
  (2, 2) = (1, 2) AS b,
  (2, 2) = (1, 3) AS c,
  (2, 2) = (2, 1) AS d,
  (2, 2) = (2, 2) AS e,
  (2, 2) = (2, 3) AS f,
  (2, 2) = (3, 1) AS g,
  (2, 2) = (3, 2) AS h,
  (2, 2) = (3, 3) AS i
  FROM tb
----
a      b      c      d      e     f      g      h      i
false  false  false  false  true  false  false  false  false

query BBBBBBBBB colnames
SELECT
  (2, 2) != (1, 1) AS a,
  (2, 2) != (1, 2) AS b,
  (2, 2) != (1, 3) AS c,
  (2, 2) != (2, 1) AS d,
  (2, 2) != (2, 2) AS e,
  (2, 2) != (2, 3) AS f,
  (2, 2) != (3, 1) AS g,
  (2, 2) != (3, 2) AS h,
  (2, 2) != (3, 3) AS i
  FROM tb
----
a     b     c     d     e      f     g     h     i
true  true  true  true  false  true  true  true  true

query BBBB colnames
SELECT
  (1, 1) > (0, NULL) AS a,
  (1, 1) > (1, NULL) AS b,
  (1, 1) > (2, NULL) AS c,
  (1, 1) > (NULL, 0) AS d
  FROM tb
----
a     b     c      d
true  NULL  false  NULL

statement error pq: tuples \(1, 2\), \(1, 'hi'\) are not comparable at index 2: unsupported comparison operator
SELECT (1, 2) > (1, 'hi') FROM tb

statement error pq: expected tuple \(1, 2, 3\) to have a length of 2
SELECT (1, 2) > (1, 2, 3) FROM tb

statement ok
CREATE TABLE t (a int, b int, c int)

statement ok
INSERT INTO t VALUES (1, 2, 3), (2, 3, 1), (3, 1, 2)

query III colnames
SELECT * FROM t ORDER BY a, b, c
----
a b c
1 2 3
2 3 1
3 1 2

query III colnames
SELECT * FROM t WHERE (a, b, c) > (1, 2, 3) AND (a, b, c) < (8, 9, 10) ORDER BY a, b, c
----
a b c
2 3 1
3 1 2

query T colnames,rowsort
SELECT (t.*) AS a FROM t
----
a
(2,3,1)
(3,1,2)
(1,2,3)

query BB colnames
SELECT ((1, 2), 'equal') = ((1, 2.0), 'equal') AS a,
       ((1, 2), 'equal') = ((1, 2.0), 'not equal') AS b
	   FROM tb
----
a     b
true  false

query B colnames
SELECT ((1, 2), 'equal') = ((1, 2.1), 'equal') AS a
  FROM tb
----
a
false

query B colnames
SELECT (ROW(pow(1, 10.0) + 9), 'a' || 'b') = (ROW(sqrt(100.0)), 'ab') AS a
  FROM tb
----
a
true

query B colnames
SELECT (ROW(sqrt(100.0)), 'ab') = (ROW(pow(1, 10.0) + 9), 'a' || 'b') AS a
  FROM tb
----
a
true

query error pq: tuples \(\(1, 2\), 'equal'\), \(\(1, 'huh'\), 'equal'\) are not comparable at index 1: tuples \(1, 2\), \(1, 'huh'\) are not comparable at index 2: unsupported comparison operator
SELECT ((1, 2), 'equal') = ((1, 'huh'), 'equal') FROM tb

# Issue #3568

statement ok
CREATE TABLE kv (
  k INT PRIMARY KEY,
  v INT
)

statement ok
INSERT INTO kv VALUES (1, 2)

query II colnames
SELECT k, v FROM kv WHERE (k, v) = (1, 100)
----
k  v

query II colnames
SELECT k, v FROM kv WHERE (k, v) IN ((1, 100))
----
k  v

statement ok
DROP TABLE kv

# Issue #12295

query B colnames
SELECT 'foo' IN (x, 'aaa') AS r FROM (SELECT 'foo' AS x FROM tb)
----
r
true

query B colnames
SELECT 'foo' IN (x, 'zzz') AS r FROM (SELECT 'foo' AS x FROM tb)
----
r
true

# Subquery tuples are already sorted

query B colnames
SELECT 3 IN (SELECT c FROM t ORDER BY 1 ASC) AS r
----
r
true

query B colnames
SELECT 4 IN (SELECT c FROM t ORDER BY 1 DESC) AS r
----
r
false

query B colnames
SELECT (1, 2) IN (SELECT a, b FROM t ORDER BY 1 ASC, 2 ASC) AS r
----
r
true

query B colnames
SELECT (1, 2) IN (SELECT a, b FROM t ORDER BY 1 DESC, 2 DESC) AS r
----
r
true

statement ok
DROP TABLE t

# Issue #12302

query B colnames
SELECT 1 IN (2, NULL) AS r
  FROM tb
----
r
NULL

query B colnames
SELECT 1 IN (2, x) AS r FROM (SELECT NULL AS x FROM tb)
----
r
NULL

# Issue 10407: tuple comparisons should not require homogeneous types
query B colnames
SELECT (now(), 2) = (now() :: timestamp, 2) AS r
  FROM tb
----
r
true

query B colnames
SELECT (1, 2) > (1.0, 2.0) AS r
  FROM tb
----
r
false

statement ok
CREATE TABLE uvw (
  u INT,
  v INT,
  w INT,
  INDEX (u,v,w)
)

statement ok
INSERT INTO uvw SELECT u, v, w FROM
  generate_series(0, 3) AS u,
  generate_series(0, 3) AS v,
  generate_series(0, 3) AS w;
UPDATE uvw SET u = NULL WHERE u = 0;
UPDATE uvw SET v = NULL WHERE v = 0;
UPDATE uvw SET w = NULL WHERE w = 0

query III colnames
SELECT * FROM uvw ORDER BY u, v, w
----
u     v     w
NULL  NULL  NULL
NULL  NULL  1
NULL  NULL  2
NULL  NULL  3
NULL  1     NULL
NULL  1     1
NULL  1     2
NULL  1     3
NULL  2     NULL
NULL  2     1
NULL  2     2
NULL  2     3
NULL  3     NULL
NULL  3     1
NULL  3     2
NULL  3     3
1     NULL  NULL
1     NULL  1
1     NULL  2
1     NULL  3
1     1     NULL
1     1     1
1     1     2
1     1     3
1     2     NULL
1     2     1
1     2     2
1     2     3
1     3     NULL
1     3     1
1     3     2
1     3     3
2     NULL  NULL
2     NULL  1
2     NULL  2
2     NULL  3
2     1     NULL
2     1     1
2     1     2
2     1     3
2     2     NULL
2     2     1
2     2     2
2     2     3
2     3     NULL
2     3     1
2     3     2
2     3     3
3     NULL  NULL
3     NULL  1
3     NULL  2
3     NULL  3
3     1     NULL
3     1     1
3     1     2
3     1     3
3     2     NULL
3     2     1
3     2     2
3     2     3
3     3     NULL
3     3     1
3     3     2
3     3     3

query III colnames
SELECT * FROM uvw WHERE (u, v, w) >= (1, 2, 3) ORDER BY u, v, w
----
u  v     w
1  2     3
1  3     NULL
1  3     1
1  3     2
1  3     3
2  NULL  NULL
2  NULL  1
2  NULL  2
2  NULL  3
2  1     NULL
2  1     1
2  1     2
2  1     3
2  2     NULL
2  2     1
2  2     2
2  2     3
2  3     NULL
2  3     1
2  3     2
2  3     3
3  NULL  NULL
3  NULL  1
3  NULL  2
3  NULL  3
3  1     NULL
3  1     1
3  1     2
3  1     3
3  2     NULL
3  2     1
3  2     2
3  2     3
3  3     NULL
3  3     1
3  3     2
3  3     3

query III colnames
SELECT * FROM uvw WHERE (u, v, w) > (2, 1, 1) ORDER BY u, v, w
----
u  v     w
2  1     2
2  1     3
2  2     NULL
2  2     1
2  2     2
2  2     3
2  3     NULL
2  3     1
2  3     2
2  3     3
3  NULL  NULL
3  NULL  1
3  NULL  2
3  NULL  3
3  1     NULL
3  1     1
3  1     2
3  1     3
3  2     NULL
3  2     1
3  2     2
3  2     3
3  3     NULL
3  3     1
3  3     2
3  3     3

query III colnames
SELECT * FROM uvw WHERE (u, v, w) <= (2, 3, 1) ORDER BY u, v, w
----
u  v     w
1  NULL  NULL
1  NULL  1
1  NULL  2
1  NULL  3
1  1     NULL
1  1     1
1  1     2
1  1     3
1  2     NULL
1  2     1
1  2     2
1  2     3
1  3     NULL
1  3     1
1  3     2
1  3     3
2  1     NULL
2  1     1
2  1     2
2  1     3
2  2     NULL
2  2     1
2  2     2
2  2     3
2  3     1

query III colnames
SELECT * FROM uvw WHERE (u, v, w) < (2, 2, 2) ORDER BY u, v, w
----
u  v     w
1  NULL  NULL
1  NULL  1
1  NULL  2
1  NULL  3
1  1     NULL
1  1     1
1  1     2
1  1     3
1  2     NULL
1  2     1
1  2     2
1  2     3
1  3     NULL
1  3     1
1  3     2
1  3     3
2  1     NULL
2  1     1
2  1     2
2  1     3
2  2     1

query III colnames
SELECT * FROM uvw WHERE (u, v, w) != (1, 2, 3) ORDER BY u, v, w
----
u     v     w
NULL  NULL  1
NULL  NULL  2
NULL  1     NULL
NULL  1     1
NULL  1     2
NULL  1     3
NULL  2     1
NULL  2     2
NULL  3     NULL
NULL  3     1
NULL  3     2
NULL  3     3
1     NULL  1
1     NULL  2
1     1     NULL
1     1     1
1     1     2
1     1     3
1     2     1
1     2     2
1     3     NULL
1     3     1
1     3     2
1     3     3
2     NULL  NULL
2     NULL  1
2     NULL  2
2     NULL  3
2     1     NULL
2     1     1
2     1     2
2     1     3
2     2     NULL
2     2     1
2     2     2
2     2     3
2     3     NULL
2     3     1
2     3     2
2     3     3
3     NULL  NULL
3     NULL  1
3     NULL  2
3     NULL  3
3     1     NULL
3     1     1
3     1     2
3     1     3
3     2     NULL
3     2     1
3     2     2
3     2     3
3     3     NULL
3     3     1
3     3     2
3     3     3

query III colnames
SELECT * FROM uvw WHERE (u, v, w) >= (1, NULL, 3) ORDER BY u, v, w
----
u  v     w
2  NULL  NULL
2  NULL  1
2  NULL  2
2  NULL  3
2  1     NULL
2  1     1
2  1     2
2  1     3
2  2     NULL
2  2     1
2  2     2
2  2     3
2  3     NULL
2  3     1
2  3     2
2  3     3
3  NULL  NULL
3  NULL  1
3  NULL  2
3  NULL  3
3  1     NULL
3  1     1
3  1     2
3  1     3
3  2     NULL
3  2     1
3  2     2
3  2     3
3  3     NULL
3  3     1
3  3     2
3  3     3

query III colnames
SELECT * FROM uvw WHERE (u, v, w) < (2, NULL, 3) ORDER BY u, v, w
----
u  v     w
1  NULL  NULL
1  NULL  1
1  NULL  2
1  NULL  3
1  1     NULL
1  1     1
1  1     2
1  1     3
1  2     NULL
1  2     1
1  2     2
1  2     3
1  3     NULL
1  3     1
1  3     2
1  3     3

statement ok
DROP TABLE uvw

subtest tuple_placeholders

statement ok
PREPARE x AS SELECT $1 = (1,2) AS r FROM tb

statement ok
PREPARE y AS SELECT (1,2) = $1 AS r FROM tb

query B colnames
EXECUTE x((1,2))
----
r
true

query B colnames
EXECUTE y((1,2))
----
r
true

query error expected EXECUTE parameter expression to have type tuple\{int, int\}, but '\(1, 2, 3\)' has type tuple\{int, int, int\}
EXECUTE x((1,2,3))

subtest labeled_tuple

# Selecting two tuples
query TT colnames
SELECT ((1, 2, 'hello', NULL, NULL) AS a1, b2, c3, d4, e5) AS r,
       ((true, NULL, (false, 6.6, false)) AS a1, b2, c3) AS s
  FROM tb
----
r              s
(1,2,hello,,)  (t,,"(f,6.6,f)")

# Comparing tuples
query BBB colnames
SELECT ((2, 2) AS a, b) < ((1, 1) AS c, d) AS r
      ,((2, 2) AS a, b) < (1, 2) AS s
      ,(2, 2) < ((1, 3) AS c, d) AS t
 FROM tb
----
r      s      t
false  false  false

statement error pq: tuples \(\(1, 2\) AS a, b\), \(\(1, 'hi'\) AS c, d\) are not comparable at index 2: unsupported comparison operator: <int> > <string>
SELECT ((1, 2) AS a, b) > ((1, 'hi') AS c, d) FROM tb

statement error pq: expected tuple \(\(1, 2, 3\) AS a, b, c\) to have a length of 2
SELECT ((1, 2) AS a, b, c) > ((1, 2, 3) AS a, b, c) FROM tb

query BBBBBBBBBBBBBBBB colnames
SELECT ((((1, 2) AS a, b), 'value') AS c, d) = ((((1, 2) AS e, f), 'value') AS g, h) AS nnnn
      ,((((1, 2) AS a, b), 'value') AS c, d) = (((1, 2) AS e, f), 'value')           AS nnnu
      ,((((1, 2) AS a, b), 'value') AS c, d) = (((1, 2), 'value') AS g, h)           AS nnun
      ,((((1, 2) AS a, b), 'value') AS c, d) = ((1, 2), 'value')                     AS nnuu
      ,(((1, 2) AS a, b), 'value')           = ((((1, 2) AS e, f), 'value') AS g, h) AS nunn
      ,(((1, 2) AS a, b), 'value')           = (((1, 2) AS e, f), 'value')           AS nunu
      ,(((1, 2) AS a, b), 'value')           = (((1, 2), 'value') AS g, h)           AS nuun
      ,(((1, 2) AS a, b), 'value')           = ((1, 2), 'value')                     AS nuuu
      ,(((1, 2), 'value') AS c, d)           = ((((1, 2) AS e, f), 'value') AS g, h) AS unnn
      ,(((1, 2), 'value') AS c, d)           = (((1, 2) AS e, f), 'value')           AS unnu
      ,(((1, 2), 'value') AS c, d)           = (((1, 2), 'value') AS g, h)           AS unun
      ,(((1, 2), 'value') AS c, d)           = ((1, 2), 'value')                     AS unuu
      ,((1, 2), 'value')                     = ((((1, 2) AS e, f), 'value') AS g, h) AS uunn
      ,((1, 2), 'value')                     = (((1, 2) AS e, f), 'value')           AS uunu
      ,((1, 2), 'value')                     = (((1, 2), 'value') AS g, h)           AS uuun
      ,((1, 2), 'value')                     = ((1, 2), 'value')                     AS uuuu
 FROM tb
----
nnnn  nnnu  nnun  nnuu  nunn  nunu  nuun  nuuu  unnn  unnu  unun  unuu  uunn  uunu  uuun  uuuu
true  true  true  true  true  true  true  true  true  true  true  true  true  true  true  true

query BB colnames
SELECT (((ROW(pow(1, 10.0) + 9) AS t1), 'a' || 'b') AS t2, t3) = (((ROW(sqrt(100.0)) AS t4), 'ab') AS t5, t6) AS a
      ,(ROW(pow(1, 10.0) + 9), 'a' || 'b') = (((ROW(sqrt(100.0)) AS t4), 'ab') AS t5, t6) AS b
 FROM tb
----
a     b
true  true

subtest labeled_tuple_errors

query error pq: tuples \(\(\(\(1, 2\) AS a, b\), 'equal'\) AS c, d\), \(\(\(\(1, 'huh'\) AS e, f\), 'equal'\) AS g, h\) are not comparable at index 1: tuples \(\(1, 2\) AS a, b\), \(\(1, 'huh'\) AS e, f\) are not comparable at index 2: unsupported comparison operator: <int> = <string>
SELECT ((((1, 2) AS a, b), 'equal') AS c, d) = ((((1, 'huh') AS e, f), 'equal') AS g, h) FROM tb

# Ensure the number of labels matches the number of expressions
query error pq: mismatch in tuple definition: 2 expressions, 1 labels
SELECT ((1, '2') AS a) FROM tb

query error pq: mismatch in tuple definition: 1 expressions, 2 labels
SELECT (ROW(1) AS a, b) FROM tb

# Tuple labels must be different
query error pq: found duplicate tuple label: "a"
SELECT ((1, '2') AS a, a) FROM tb

query error pq: found duplicate tuple label: "a"
SELECT ((1, '2', true) AS a, a, b) FROM tb

query error pq: found duplicate tuple label: "a"
SELECT ((1, '2', true) AS a, b, a) FROM tb

query error pq: found duplicate tuple label: "a"
SELECT ((1, '2', true) AS b, a, a) FROM tb

# But inner tuples can reuse labels
query T colnames
SELECT ((
         (
          (((1, '2', 3) AS a, b, c),
           ((4,'5') AS a, b),
		   (ROW(6) AS a))
		   AS a, b, c),
		 ((7, 8) AS a, b),
		 (ROW('9') AS a))
		 AS a, b, c
		) AS r
 FROM tb
----
r
("(""(1,2,3)"",""(4,5)"",""(6)"")","(7,8)","(9)")

subtest labeled_tuple_column_access

## base working case

# Accessing a specific column
query error pq: could not identify column "x" in tuple{int AS a, int AS b, int AS c}
SELECT (((1,2,3) AS a,b,c)).x FROM tb

query ITBITB colnames
SELECT (((1,'2',true) AS a,b,c)).a
      ,(((1,'2',true) AS a,b,c)).b
      ,(((1,'2',true) AS a,b,c)).c
      ,((ROW(1,'2',true) AS a,b,c)).a
      ,((ROW(1,'2',true) AS a,b,c)).b
      ,((ROW(1,'2',true) AS a,b,c)).c
 FROM tb
----
a  b  c     a  b  c
1  2  true  1  2  true

subtest labeled_tuple_column_access_errors

# column doesn't exist
query error pq: could not identify column "x" in tuple{int AS a, int AS b, int AS c}
SELECT (((1,2,3) AS a,b,c)).x FROM tb

# Missing extra parentheses
query error pq: syntax error at or near "."
SELECT ((1,2,3) AS a,b,c).x FROM tb

query error pq: syntax error at or near "."
SELECT ((1,2,3) AS a,b,c).* FROM tb

# No labels
query error pq: type tuple{int, int, int} is not composite
SELECT ((1,2,3)).x FROM tb

query error pq: type tuple{int, int, int} is not composite
SELECT ((1,2,3)).* FROM tb

# Accessing all the columns

query ITB colnames
SELECT (((1,'2',true) AS a,b,c)).* FROM tb
----
a  b  c
1  2  true

query ITB colnames
SELECT ((ROW(1,'2',true) AS a,b,c)).* FROM tb
----
a  b  c
1  2  true

query T
SELECT (((ROW(1,'2',true) AS a,b,c)).*, 456) FROM tb
----
("(1,2,t)",456)

query I colnames
SELECT ((ROW(1) AS a)).* FROM tb
----
a
1


subtest literal_labeled_tuple_in_subquery

query ITB colnames
SELECT (x).e, (x).f, (x).g
FROM (
  SELECT ((1,'2',true) AS e,f,g) AS x FROM tb
)
----
e  f  g
1  2  true

query ITB colnames
SELECT (x).*
FROM (
  SELECT ((1,'2',true) AS e,f,g) AS x FROM tb
)
----
e  f  g
1  2  true

subtest labeled_tuples_derived_from_relational_subquery_schema

query IT
  SELECT (x).a, (x).b
    FROM (SELECT (ROW(a, b) AS a, b) AS x FROM (VALUES (1, 'one')) AS t(a, b))
----
1 one

statement ok
CREATE TABLE t (a int, b string)

statement ok
INSERT INTO t VALUES (1, 'one'), (2, 'two')

query IT
  SELECT (x).a, (x).b
    FROM (SELECT (ROW(a, b) AS a, b) AS x FROM t)
ORDER BY 1
   LIMIT 1
----
1 one

subtest labeled_column_access_from_table

query IT colnames
SELECT (t.*).* FROM t ORDER BY 1,2
----
a  b
1  one
2  two


# Pending #26719
query error pq: column "t" does not exist
SELECT (t).a FROM t

statement ok
DROP TABLE t

query B
SELECT (1, 2, 3) IS NULL AS r
----
false

subtest regression_for_34262

query B
SELECT () = ()
----
true
