-- Copyright 2004-2023 H2 Group. Multiple-Licensed under the MPL 2.0,
-- and the EPL 1.0 (https://h2database.com/html/license.html).
-- Initial Developer: H2 Group
--

SELECT
    NULL AND NULL, NULL AND FALSE, NULL AND TRUE,
    FALSE AND NULL, FALSE AND FALSE, FALSE AND TRUE,
    TRUE AND NULL, TRUE AND FALSE, TRUE AND TRUE;
> UNKNOWN FALSE UNKNOWN FALSE FALSE FALSE UNKNOWN FALSE TRUE
> ------- ----- ------- ----- ----- ----- ------- ----- ----
> null    FALSE null    FALSE FALSE FALSE null    FALSE TRUE
> rows: 1

SELECT
    NULL OR NULL, NULL OR FALSE, NULL OR TRUE,
    FALSE OR NULL, FALSE OR FALSE, FALSE OR TRUE,
    TRUE OR NULL, TRUE OR FALSE, TRUE OR TRUE;
> UNKNOWN UNKNOWN TRUE UNKNOWN FALSE TRUE TRUE TRUE TRUE
> ------- ------- ---- ------- ----- ---- ---- ---- ----
> null    null    TRUE null    FALSE TRUE TRUE TRUE TRUE
> rows: 1

SELECT NOT NULL, NOT FALSE, NOT TRUE;
> UNKNOWN TRUE FALSE
> ------- ---- -----
> null    TRUE FALSE
> rows: 1

SELECT 0 AND TRUE;
>> FALSE

SELECT TRUE AND 0;
>> FALSE

SELECT 1 OR FALSE;
>> TRUE

SELECT FALSE OR 1;
>> TRUE

SELECT NOT 0;
>> TRUE

SELECT NOT 1;
>> FALSE

CREATE TABLE TEST(B BOOLEAN, Z INT) AS VALUES (NULL, 0);
> ok

EXPLAIN SELECT NOT NOT B, NOT NOT Z FROM TEST;
>> SELECT "B", CAST("Z" AS BOOLEAN) FROM "PUBLIC"."TEST" /* PUBLIC.TEST.tableScan */

EXPLAIN SELECT TRUE AND B, B AND TRUE, TRUE AND Z, Z AND TRUE FROM TEST;
>> SELECT "B", "B", CAST("Z" AS BOOLEAN), CAST("Z" AS BOOLEAN) FROM "PUBLIC"."TEST" /* PUBLIC.TEST.tableScan */

EXPLAIN SELECT FALSE OR B, B OR FALSE, FALSE OR Z, Z OR FALSE FROM TEST;
>> SELECT "B", "B", CAST("Z" AS BOOLEAN), CAST("Z" AS BOOLEAN) FROM "PUBLIC"."TEST" /* PUBLIC.TEST.tableScan */

DROP TABLE TEST;
> ok

CREATE TABLE TEST(A INT, B INT);
> ok

EXPLAIN SELECT A FROM TEST WHERE (A, B) IS NOT DISTINCT FROM NULL;
>> SELECT "A" FROM "PUBLIC"."TEST" /* PUBLIC.TEST.tableScan */ WHERE ROW ("A", "B") IS NOT DISTINCT FROM NULL

EXPLAIN SELECT A FROM TEST WHERE (A, B) IS DISTINCT FROM NULL;
>> SELECT "A" FROM "PUBLIC"."TEST" /* PUBLIC.TEST.tableScan */ WHERE ROW ("A", "B") IS DISTINCT FROM NULL

EXPLAIN SELECT A IS DISTINCT FROM NULL, NULL IS DISTINCT FROM A FROM TEST;
>> SELECT "A" IS NOT NULL, "A" IS NOT NULL FROM "PUBLIC"."TEST" /* PUBLIC.TEST.tableScan */

EXPLAIN SELECT A IS NOT DISTINCT FROM NULL, NULL IS NOT DISTINCT FROM A FROM TEST;
>> SELECT "A" IS NULL, "A" IS NULL FROM "PUBLIC"."TEST" /* PUBLIC.TEST.tableScan */

DROP TABLE TEST;
> ok

CREATE TABLE TEST(A NULL);
> ok

SELECT 1 IN (SELECT A FROM TEST);
>> FALSE

INSERT INTO TEST VALUES NULL;
> update count: 1

SELECT 1 IN (SELECT A FROM TEST);
>> null

DROP TABLE TEST;
> ok

SELECT 1 IN (NULL);
>> null

SELECT 1 IN (SELECT NULL);
>> null

SELECT 1 IN (VALUES NULL);
>> null

SELECT 1 IN (SELECT * FROM TABLE(X NULL=()));
>> FALSE

SELECT (1, 1) IN (VALUES (1, NULL));
>> null

SELECT (1, 1) IN (VALUES (NULL, 1));
>> null

SELECT (1, 1) IN (SELECT * FROM TABLE(X INT=(), Y INT=()));
>> FALSE

VALUES FALSE OR NULL OR FALSE;
>> null

VALUES FALSE OR NULL OR TRUE;
>> TRUE

VALUES TRUE AND NULL AND TRUE;
>> null

VALUES TRUE AND NULL AND FALSE;
>> FALSE

SELECT * FROM (VALUES 1) T(C) WHERE NOT NOT CASE C WHEN 1 THEN TRUE WHEN 2 THEN FALSE ELSE NULL END;
>> 1

SELECT C AND C, NOT(C AND C) FROM (VALUES 'F') T(C);
> C AND C (NOT C) OR (NOT C)
> ------- ------------------
> FALSE   TRUE
> rows: 1

SELECT C != 2 AND C, NOT (C != 2 AND C) FROM (VALUES TRUE) T(C);
> exception TYPES_ARE_NOT_COMPARABLE_2

SELECT ROW(1) = ROW(ROW(1));
>> TRUE

SELECT ROW(1) = ROW(ROW(2));
>> FALSE

SELECT ROW(1) = ROW(ROW(1, 2));
> exception TYPES_ARE_NOT_COMPARABLE_2

SELECT ROW(1) = ROW(ROW(TIME '00:00:00'));
> exception TYPES_ARE_NOT_COMPARABLE_2

CREATE TABLE TEST(C1 BOOLEAN GENERATED ALWAYS AS (NOT C2), C2 BOOLEAN GENERATED ALWAYS AS (C1));
> exception COLUMN_NOT_FOUND_1

CREATE TABLE TEST(A INTEGER, B INTEGER, C INTEGER, D INTEGER) AS VALUES (1, 2, 3, 4);
> ok

EXPLAIN SELECT A = B OR A = C C1, B = A OR A = C C2, A = B OR C = A C3, B = A OR C = A C4 FROM TEST;
>> SELECT "A" IN("B", "C") AS "C1", "A" IN("B", "C") AS "C2", "A" IN("B", "C") AS "C3", "A" IN("B", "C") AS "C4" FROM "PUBLIC"."TEST" /* PUBLIC.TEST.tableScan */

EXPLAIN SELECT A = B OR A = C OR A = D C1, B = A OR A = C OR A = D C2, A = B OR C = A OR A = D C3,
    B = A OR C = A OR A = D C4, A = B OR A = C OR D = A C5, B = A OR A = C OR D = A C6, A = B OR C = A OR D = A C7,
    B = A OR C = A OR D = A C8 FROM TEST;
>> SELECT "A" IN("B", "C", "D") AS "C1", "A" IN("B", "C", "D") AS "C2", "A" IN("B", "C", "D") AS "C3", "A" IN("B", "C", "D") AS "C4", "A" IN("B", "C", "D") AS "C5", "A" IN("B", "C", "D") AS "C6", "A" IN("B", "C", "D") AS "C7", "A" IN("B", "C", "D") AS "C8" FROM "PUBLIC"."TEST" /* PUBLIC.TEST.tableScan */

DROP TABLE TEST;
> ok
