# LogicTest: local-opt fakedist-opt

statement ok
CREATE TABLE t (k INT PRIMARY KEY, str STRING);
CREATE TABLE u (l INT PRIMARY KEY, str2 STRING);
CREATE TABLE v (m INT PRIMARY KEY, str3 STRING);
INSERT INTO t SELECT i, to_english(i) FROM generate_series(1, 5) AS g(i);
INSERT INTO u SELECT i, to_english(i) FROM generate_series(1, 5) AS g(i);
INSERT INTO v SELECT i, to_english(i) FROM generate_series(1, 5) AS g(i);

statement ok
SET allow_prepare_as_opt_plan = ON

# InnerJoinApply tests.

statement ok
PREPARE a AS OPT PLAN '
(Root
  (InnerJoinApply
    (Scan [(Table "t") (Cols "k,str") ])
    (Select
      (Scan [(Table "u") (Cols "l,str2") ])
      [ (Eq (Var "k") (Var "l") )]
     )
    []
    []
  )
  (Presentation "k,str,l,str2")
  (NoOrdering)
)'

query ITIT rowsort
EXECUTE a
----
1  one    1  one
2  two    2  two
3  three  3  three
4  four   4  four
5  five   5  five

# LeftJoinApply tests.

statement ok
PREPARE b AS OPT PLAN '
(Root
  (LeftJoinApply
    (Scan [(Table "t") (Cols "k,str") ])
    (Select
      (Scan [(Table "u") (Cols "l,str2") ])
      [ (Eq (Plus (Var "k") (Const 1)) (Var "l") )]
     )
    []
    []
  )
  (Presentation "k,str,l,str2")
  (NoOrdering)
)'

query ITIT rowsort
EXECUTE b
----
1  one      2  two
2  two      3  three
3  three    4  four
4  four     5  five
5  five     NULL NULL

# SemiJoinApply tests.

statement ok
PREPARE c AS OPT PLAN '
(Root
  (SemiJoinApply
    (Scan [(Table "t") (Cols "k,str") ])
    (Select
      (Scan [(Table "u") (Cols "l,str2") ])
      [ (Eq (Plus (Var "k") (Const 1)) (Var "l") )]
     )
    []
    []
  )
  (Presentation "k,str")
  (NoOrdering)
)'

query IT rowsort
EXECUTE c
----
1  one
2  two
3  three
4  four

# AntiJoinApply tests.

statement ok
PREPARE d AS OPT PLAN '
(Root
  (AntiJoinApply
    (Scan [(Table "t") (Cols "k,str") ])
    (Select
      (Scan [(Table "u") (Cols "l,str2") ])
      [ (Eq (Plus (Var "k") (Const 1)) (Var "l") )]
     )
    []
    []
  )
  (Presentation "k,str")
  (NoOrdering)
)'

query IT rowsort
EXECUTE d
----
5  five

# Nested Apply, with outer columns of the outer apply on the left and right of
# the inner apply.

statement ok
PREPARE e AS OPT PLAN '
(Root
  (InnerJoinApply
    (Scan [(Table "t") (Cols "k,str") ])
    (InnerJoinApply
      (Select
        (Scan [(Table "u") (Cols "l,str2") ])
        [ (Eq (Var "k") (Var "l") )]
      )
      (Select
        (Scan [(Table "v") (Cols "m,str3") ])
        [ (Eq (Var "k") (Var "m") )]
      )
      [ (Eq (Var "k") (Var "l")) ]
      []
    )
    []
    []
  )
  (Presentation "k,str,l,str2,m,str3")
  (NoOrdering)
)'

query ITITIT rowsort
EXECUTE e
----
1  one    1  one    1  one
2  two    2  two    2  two
3  three  3  three  3  three
4  four   4  four   4  four
5  five   5  five   5  five

# Test subqueries within an apply join.

statement ok
PREPARE f AS OPT PLAN '
(Root
  (InnerJoinApply
    (Scan [(Table "t") (Cols "k,str") ])
    (Select
      (Scan [(Table "u") (Cols "l,str2") ])
      [ (Eq (Plus (Var "k")
                  (Subquery (Values [(Tuple [(Const 1)] "tuple{int}") ]
                                    [(Cols [(NewColumn "z" "int")] )])
                            []))
            (Var "l") )]
     )
    []
    []
  )
  (Presentation "k,str,l,str2")
  (NoOrdering)
)'

query ITIT rowsort
EXECUTE f
----
1  one    2  two
2  two    3  three
3  three  4  four
4  four   5  five

# Another test of subqueries within an apply join.

query I
SELECT
	(SELECT * FROM (VALUES ((SELECT x FROM (VALUES (1)) AS s (x)) + y)))
FROM
	(VALUES (1), (2), (3)) AS t (y)
----
2
3
4


# Regression test for #36197: 0-col applyjoin RHS doesn't panic

statement ok
CREATE TABLE table9 (
    _bool BOOL,
    _bytes BYTES,
    _date DATE,
    _decimal DECIMAL,
    _float4 FLOAT4,
    _float8 FLOAT8,
    _inet INET,
    _int4 INT4,
    _int8 INT8,
    _interval INTERVAL,
    _jsonb JSONB,
    _string STRING,
    _time TIME,
    _timestamp TIMESTAMP,
    _timestamptz TIMESTAMPTZ,
    _uuid UUID
); INSERT INTO table9 DEFAULT VALUES;

query B
SELECT
  true
FROM
    table9 AS tab_27927
WHERE
    EXISTS(
        SELECT
            tab_27929._string AS col_85223
        FROM
            table9 AS tab_27928,
            table9 AS tab_27929,
            table9 AS tab_27930
            RIGHT JOIN table9 AS tab_27931
            ON
                NOT
                    (
                        tab_27927._float8
                        IN (
                                CASE
                                WHEN NULL
                                THEN div(
                                    tab_27927._float4::FLOAT8,
                                    tab_27927._float4::FLOAT8
                                )::FLOAT8
                                ELSE tab_27927._float4
                                END,
                                tab_27927._float4,
                                tab_27927._float8::FLOAT8
                                + NULL::FLOAT8,
                                tab_27927._float4
                            )
                    )
        WHERE
            EXISTS(
                SELECT
                    2470039497:::OID AS col_85224
                FROM
                    table9 AS tab_27932
                ORDER BY
                    tab_27932._string ASC,
                    tab_27932._interval DESC,
                    tab_27932._uuid DESC
                LIMIT
                    37:::INT8
            )
        LIMIT
            11:::INT8
    )
LIMIT
    89:::INT8;
----
true
