# Tests for predicates with OR expressions.

# Atom filters

predtest vars=(a bool)
a
=>
a OR a
----
true
└── remaining filters: none

predtest vars=(a bool, b bool)
a
=>
a OR b
----
true
└── remaining filters: a

predtest vars=(a bool, b bool)
b
=>
a OR b
----
true
└── remaining filters: b

predtest vars=(a int, b int)
(a, b) = (1, 2)
=>
a = 1 OR b = 2
----
true
└── remaining filters: (a = 1) AND (b = 2)

predtest vars=(a bool, b bool)
NOT b
=>
a OR b
----
false

predtest vars=(a int)
a IN (1, 2)
=>
a = 1 OR a = 2
----
true
└── remaining filters: none

predtest vars=(a int)
a IN (1)
=>
a = 1 OR a = 2
----
true
└── remaining filters: a = 1

predtest vars=(a int)
a IN (1, 2, 3)
=>
a IN (1, 2) OR a = 3
----
true
└── remaining filters: none

# Regression tests for #54649. Atoms that are contradictions, like NULL, should
# not cause panics.
predtest vars=(a bool)
a
=>
(a OR NULL) OR a
----
true
└── remaining filters: a

predtest vars=(a bool, b bool)
a
=>
(b OR NULL) OR b
----
false

predtest vars=(a int, b int, c int)
a = b
=>
a IS NOT NULL OR c > 0
----
true
└── remaining filters: a = b

# Conjunction filters

predtest vars=(a bool, b bool)
a AND b
=>
a OR a
----
true
└── remaining filters: b

predtest vars=(a bool, b bool)
a AND b
=>
a OR b
----
true
└── remaining filters: a AND b

predtest vars=(a bool, b bool)
a AND b
=>
b OR a
----
true
└── remaining filters: a AND b

predtest vars=(a bool, b bool, c bool)
a AND b AND c
=>
a OR c
----
true
└── remaining filters: (a AND b) AND c

predtest vars=(a bool, b bool, c bool)
a AND b AND c
=>
a OR b
----
true
└── remaining filters: (a AND b) AND c

predtest vars=(a bool, b bool, c bool)
a AND b AND c
=>
c OR a OR b
----
true
└── remaining filters: (a AND b) AND c

predtest vars=(a int, b int)
a > 10 AND b < 20
=>
a > 0 OR b < 30
----
true
└── remaining filters: (a > 10) AND (b < 20)

predtest vars=(a int)
a IN (1) OR a IN (2)
=>
a = 1 OR a = 2
----
true
└── remaining filters: none

predtest vars=(a int, b int)
a IN (1, 2)
=>
a IN (1, 2) OR b = 3
----
true
└── remaining filters: a IN (1, 2)

predtest vars=(a bool, b bool)
a AND b
=>
NOT a OR NOT b
----
false

predtest vars=(a bool, b bool, c bool)
a AND b
=>
NOT a OR c
----
false

predtest vars=(a int, b int)
a > 10 AND b < 20
=>
a > 11 OR b < 19
----
false

predtest vars=(a int, b int, c int)
c > 0 AND a = b
=>
a IS NOT NULL OR c > 0
----
true
└── remaining filters: (c > 0) AND (a = b)

# Range filters

predtest vars=(a int)
a > 10 AND a < 100
=>
a > 10 OR a < 100
----
true
└── remaining filters: (a > 10) AND (a < 100)

predtest vars=(a int)
a > 10 AND a < 100
=>
a < 100 OR a > 10
----
true
└── remaining filters: (a > 10) AND (a < 100)

predtest vars=(a int)
a > 10 AND a < 100
=>
a > 0 OR a < 90
----
true
└── remaining filters: (a > 10) AND (a < 100)

predtest vars=(a int, b bool)
a > 10 AND b AND a < 100
=>
a > 10 OR a < 100
----
true
└── remaining filters: ((a > 10) AND (a < 100)) AND b

predtest vars=(a int)
a > 0 AND a < 90
=>
a > 10 OR a < 100
----
true
└── remaining filters: (a > 0) AND (a < 90)

predtest vars=(a int)
a > 0 AND a < 90
=>
a < 10 OR a > 100
----
false

# Disjunction filters

predtest vars=(a bool)
a OR a
=>
a OR a
----
true
└── remaining filters: none

predtest vars=(a int)
a < 10 OR a > 100
=>
a < 20 OR a > 80
----
true
└── remaining filters: (a < 10) OR (a > 100)

predtest vars=(a bool, b bool)
a OR b
=>
a OR b
----
true
└── remaining filters: none

# These filters could, in theory, be reduced to "none". However, doing so is
# difficult because we don't remove exact expression matches inside Or
# expressions in the predicate or filters. See the docs for
# FilterImpliesPredicate for more details.
predtest vars=(a bool, b bool)
a OR b
=>
b OR a
----
true
└── remaining filters: a OR b

predtest vars=(a bool, b bool, c bool)
a OR b
=>
a OR b OR c
----
true
└── remaining filters: a OR b

predtest vars=(a bool, b bool, c bool)
a OR b
=>
c OR a OR b
----
true
└── remaining filters: a OR b

predtest vars=(a bool, b bool, c bool)
a OR b
=>
a OR c
----
false

predtest vars=(a int, b int, c int, d int)
a > b OR c > d
=>
b < a OR d < c
----
true
└── remaining filters: (a > b) OR (c > d)

predtest vars=(a int, b int, c int)
c > 0 OR a = b
=>
a IS NOT NULL OR c > 0
----
true
└── remaining filters: (c > 0) OR (a = b)

# Combination conjunction and disjunction filters

predtest vars=(a int)
(a > 10 OR a < 0) AND (a > 11 OR a < 0)
=>
a > 10 OR a < 0
----
true
└── remaining filters: (a > 11) OR (a < 0)

predtest vars=(a int)
(a > 10 OR a < 0) AND (a > 11 OR a < 0)
=>
a > 5 OR a < 1
----
true
└── remaining filters: ((a > 10) OR (a < 0)) AND ((a > 11) OR (a < 0))

predtest vars=(a bool, b bool, c bool)
a OR (b AND c)
=>
a OR c
----
true
└── remaining filters: a OR (b AND c)

predtest vars=(a bool, b bool, c bool)
(a OR b) AND c
=>
a OR b
----
true
└── remaining filters: c

predtest vars=(a bool, b bool, c bool)
(a OR b) AND (a OR c)
=>
a OR b
----
true
└── remaining filters: a OR c

# These filters could, in theory, be reduced to "a OR c". However, doing so is
# difficult because we don't remove exact expression matches inside Or
# expressions in the predicate or filters. See the docs for
# FilterImpliesPredicate for more details.
predtest vars=(a bool, b bool, c bool)
(b OR a) AND (a OR c)
=>
a OR b
----
true
└── remaining filters: (b OR a) AND (a OR c)

predtest vars=(a bool, b bool, c bool, d bool)
a OR (b AND c) OR d
=>
a OR c OR d
----
true
└── remaining filters: (a OR (b AND c)) OR d
