aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/tests/sql/suites/compute_range
diff options
context:
space:
mode:
authorMaxim Yurchuk <maxim-yurchuk@ydb.tech>2024-11-20 17:37:57 +0000
committerGitHub <noreply@github.com>2024-11-20 17:37:57 +0000
commitf76323e9b295c15751e51e3443aa47a36bee8023 (patch)
tree4113c8cad473a33e0f746966e0cf087252fa1d7a /yql/essentials/tests/sql/suites/compute_range
parent753ecb8d410a4cb459c26f3a0082fb2d1724fe63 (diff)
parenta7b9a6afea2a9d7a7bfac4c5eb4c1a8e60adb9e6 (diff)
downloadydb-f76323e9b295c15751e51e3443aa47a36bee8023.tar.gz
Merge pull request #11788 from ydb-platform/mergelibs-241120-1113
Library import 241120-1113
Diffstat (limited to 'yql/essentials/tests/sql/suites/compute_range')
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/adjacent_to_point.sql85
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/decimal.sql13
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/default.cfg1
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/huge_in.sql14
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/in.sql58
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/in2.sql29
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/in3.sql78
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/in_literal_nulls.sql13
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/merge_adjacent.sql43
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/multiply_limit.sql31
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/multiply_limit_for_single_key.sql15
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/multiply_limit_with_dups.sql32
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/multiply_limit_with_nulls.sql13
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/norange.sql21
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/pg_compare.sql35
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/pg_equal.sql22
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/pg_exists.sql20
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/pg_sqlin.sql23
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/pg_startswith.sql36
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/preserve_rest_predicates_order.sql17
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/repeated_keyranges_in_and.sql13
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/startswith.sql80
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/tuples_compare.sql46
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/tztypes.sql48
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/yql-12941.sql19
-rw-r--r--yql/essentials/tests/sql/suites/compute_range/yql-13489.sql18
26 files changed, 823 insertions, 0 deletions
diff --git a/yql/essentials/tests/sql/suites/compute_range/adjacent_to_point.sql b/yql/essentials/tests/sql/suites/compute_range/adjacent_to_point.sql
new file mode 100644
index 0000000000..15a272bea6
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/adjacent_to_point.sql
@@ -0,0 +1,85 @@
+/* syntax version 1 */
+/* postgres can not */
+/* yt can not */
+
+pragma warning("disable", "4510");
+
+-- [10, 11) -> [10, 10]
+select YQL::RangeComputeFor(
+ Struct<x:UInt32>,
+ ($row) -> ($row.x >= 10 and $row.x < 11),
+ AsTuple(AsAtom("x"))
+);
+
+-- (10, 11] -> [11, 11]
+select YQL::RangeComputeFor(
+ Struct<x:UInt32>,
+ ($row) -> ($row.x > 10 and $row.x <= 11),
+ AsTuple(AsAtom("x"))
+);
+
+-- dates
+select YQL::RangeComputeFor(
+ Struct<x:Date??>,
+ ($row) -> (($row.x > Date("2021-09-08") and $row.x <= Date("2021-09-09")) ?? false),
+ AsTuple(AsAtom("x"))
+)
+, YQL::RangeComputeFor(
+ Struct<x:Date32??>,
+ ($row) -> (($row.x > Date("2021-09-08") and $row.x <= Date("2021-09-09")) ?? false),
+ AsTuple(AsAtom("x"))
+)
+, YQL::RangeComputeFor(
+ Struct<x:Date??>,
+ ($row) -> (($row.x > Date32("2021-09-08") and $row.x <= Date32("2021-09-09")) ?? false),
+ AsTuple(AsAtom("x"))
+)
+, YQL::RangeComputeFor(
+ Struct<x:Date32??>,
+ ($row) -> (($row.x > Date32("-1-12-31") and $row.x <= Date32("1-01-01")) ?? false),
+ AsTuple(AsAtom("x"))
+);
+
+-- datetimes
+select YQL::RangeComputeFor(
+ Struct<x:Datetime?>,
+ ($row) -> (($row.x > Datetime("2021-09-09T12:00:00Z") and $row.x <= Datetime("2021-09-09T12:00:01Z")) ?? false),
+ AsTuple(AsAtom("x"))
+)
+, YQL::RangeComputeFor(
+ Struct<x:Datetime64?>,
+ ($row) -> (($row.x > Datetime("2021-09-09T12:00:00Z") and $row.x <= Datetime("2021-09-09T12:00:01Z")) ?? false),
+ AsTuple(AsAtom("x"))
+)
+, YQL::RangeComputeFor(
+ Struct<x:Datetime?>,
+ ($row) -> (($row.x > Datetime64("2021-09-09T12:00:00Z") and $row.x <= Datetime64("2021-09-09T12:00:01Z")) ?? false),
+ AsTuple(AsAtom("x"))
+)
+, YQL::RangeComputeFor(
+ Struct<x:Datetime64?>,
+ ($row) -> (($row.x > Datetime64("-1-12-31T23:59:59Z") and $row.x <= Datetime64("1-01-01T00:00:00Z")) ?? false),
+ AsTuple(AsAtom("x"))
+);
+
+-- timestamps
+select YQL::RangeComputeFor(
+ Struct<x:Timestamp??>,
+ ($row) -> (($row.x > Timestamp("2021-09-09T12:00:00.000000Z") and $row.x <= Timestamp("2021-09-09T12:00:00.000001Z")) ?? false),
+ AsTuple(AsAtom("x"))
+)
+, YQL::RangeComputeFor(
+ Struct<x:Timestamp64??>,
+ ($row) -> (($row.x > Timestamp("2021-09-09T12:00:00.000000Z") and $row.x <= Timestamp("2021-09-09T12:00:00.000001Z")) ?? false),
+ AsTuple(AsAtom("x"))
+)
+, YQL::RangeComputeFor(
+ Struct<x:Timestamp??>,
+ ($row) -> (($row.x > Timestamp64("2021-09-09T12:00:00.000000Z") and $row.x <= Timestamp64("2021-09-09T12:00:00.000001Z")) ?? false),
+ AsTuple(AsAtom("x"))
+)
+, YQL::RangeComputeFor(
+ Struct<x:Timestamp64??>,
+ ($row) -> (($row.x > Timestamp64("-1-12-31T23:59:59.999999Z") and $row.x <= Timestamp64("1-01-01T00:00:00.000000Z")) ?? false),
+ AsTuple(AsAtom("x"))
+);
diff --git a/yql/essentials/tests/sql/suites/compute_range/decimal.sql b/yql/essentials/tests/sql/suites/compute_range/decimal.sql
new file mode 100644
index 0000000000..b6869a3661
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/decimal.sql
@@ -0,0 +1,13 @@
+/* syntax version 1 */
+/* postgres can not */
+/* yt can not */
+
+pragma warning("disable", "4510");
+
+$opt_type = Struct<x:Decimal(15,10)?>;
+$keys = AsTuple(AsAtom("x"));
+
+$pred = ($row) -> (($row.x < Decimal("-inf",15,10)) ?? false);
+
+select YQL::RangeComputeFor($opt_type, $pred, $keys);
+
diff --git a/yql/essentials/tests/sql/suites/compute_range/default.cfg b/yql/essentials/tests/sql/suites/compute_range/default.cfg
new file mode 100644
index 0000000000..bb349dd8ab
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/default.cfg
@@ -0,0 +1 @@
+providers yt
diff --git a/yql/essentials/tests/sql/suites/compute_range/huge_in.sql b/yql/essentials/tests/sql/suites/compute_range/huge_in.sql
new file mode 100644
index 0000000000..188a77494d
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/huge_in.sql
@@ -0,0 +1,14 @@
+/* syntax version 1 */
+/* postgres can not */
+/* yt can not */
+
+pragma warning("disable", "4510");
+pragma warning("disable", "1108");
+
+select YQL::RangeComputeFor(
+ Struct<x:Int32>,
+ ($row) -> ($row.x IN ListFromRange(100000000, 0, -1)),
+ AsTuple(AsAtom("x"))
+);
+
+
diff --git a/yql/essentials/tests/sql/suites/compute_range/in.sql b/yql/essentials/tests/sql/suites/compute_range/in.sql
new file mode 100644
index 0000000000..1c1f3dbee0
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/in.sql
@@ -0,0 +1,58 @@
+/* syntax version 1 */
+/* postgres can not */
+/* yt can not */
+
+pragma warning("disable", "4510");
+pragma warning("disable", "1108");
+
+-- basic IN
+select YQL::RangeComputeFor(
+ Struct<x:UInt32>,
+ ($row) -> ($row.x IN (1, 2, -1)),
+ AsTuple(AsAtom("x"))
+);
+
+-- opaque collection
+select YQL::RangeComputeFor(
+ Struct<x:UInt32>,
+ ($row) -> ($row.x IN ListFromRange(-1, 3)),
+ AsTuple(AsAtom("x"))
+);
+
+-- optional collection
+select YQL::RangeComputeFor(
+ Struct<x:UInt32>,
+ ($row) -> (($row.x IN Just(AsSet(-1, 1, 2))) ?? false),
+ AsTuple(AsAtom("x"))
+);
+
+-- optional items
+select YQL::RangeComputeFor(
+ Struct<x:UInt32>,
+ ($row) -> (($row.x IN (-1, 10u, 20, 1/0)) ?? false),
+ AsTuple(AsAtom("x"))
+);
+
+-- tuple
+select YQL::RangeComputeFor(
+ Struct<x:UInt32, y:Uint32, z:Uint32>,
+ ($row) -> (($row.y, $row.x, $row.z) IN [(1,2,3), (100,200,300)]),
+ AsTuple(AsAtom("x"), AsAtom("y"), AsAtom("z"))
+);
+
+
+-- tuple partial
+select YQL::RangeComputeFor(
+ Struct<x:UInt32, y:Uint32, z:Uint32>,
+ ($row) -> (($row.y, $row.x, $row.z) IN [Just(Just((1,2,3))), (100,200,300), null]),
+ AsTuple(AsAtom("x"), AsAtom("y"))
+);
+
+
+-- tuple with implicit nulls
+select YQL::RangeComputeFor(
+ Struct<x:UInt32, y:Uint32, z:Uint32>,
+ ($row) -> (($row.y, $row.x) IN ((1,2,3), (100, 200, 300))),
+ AsTuple(AsAtom("x"), AsAtom("y"))
+);
+
diff --git a/yql/essentials/tests/sql/suites/compute_range/in2.sql b/yql/essentials/tests/sql/suites/compute_range/in2.sql
new file mode 100644
index 0000000000..7ef922e930
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/in2.sql
@@ -0,0 +1,29 @@
+/* syntax version 1 */
+/* postgres can not */
+/* dq can not */
+/* dqfile can not */
+/* yt can not */
+pragma warning("disable", "4510");
+pragma warning("disable", "1108");
+
+-- tuple
+select YQL::RangeComputeFor(
+ Struct<x:UInt32, y:Uint32, z:Uint32>,
+ ($row) -> (($row.y, $row.x, $row.z) IN ((1,2,3), (100,200,300))),
+ AsTuple(AsAtom("x"), AsAtom("y"), AsAtom("z"))
+);
+
+-- tuple with single element
+select YQL::RangeComputeFor(
+ Struct<x:UInt32>,
+ ($row) -> (($row.x,) IN ((1,), (100,))),
+ AsTuple(AsAtom("x"))
+);
+
+-- key prefix tuples
+select YQL::RangeComputeFor(
+ Struct<x:UInt32, y:Uint32, z:Uint32>,
+ ($row) -> (($row.y, $row.x) IN ((1,2), (2,2))),
+ AsTuple(AsAtom("x"), AsAtom("y"), AsAtom("z"))
+);
+
diff --git a/yql/essentials/tests/sql/suites/compute_range/in3.sql b/yql/essentials/tests/sql/suites/compute_range/in3.sql
new file mode 100644
index 0000000000..e1e02cbe7e
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/in3.sql
@@ -0,0 +1,78 @@
+/* syntax version 1 */
+/* postgres can not */
+/* dq can not */
+/* dqfile can not */
+/* yt can not */
+pragma warning("disable", "4510");
+pragma warning("disable", "1108");
+
+$Input = [(4, 100), (5, 100)];
+select YQL::RangeComputeFor(
+ Struct<
+ a:Int32?,
+ b:Int32?,
+ c:Int32?,
+ d:Int32?,
+ e:Int32?,
+ >,
+
+ ($row) -> (((
+ $row.a,
+ $row.d)
+ IN $Input) ?? false),
+ AsTuple(
+ AsAtom("a"),
+ AsAtom("b"),
+ AsAtom("c"),
+ AsAtom("d"),
+ )
+);
+
+$Input2 = [(30, 20, 88), (31, 21, 99)];
+select YQL::RangeComputeFor(
+ Struct<
+ a:Int32?,
+ b:Int32?,
+ c:Int32?,
+ d:Int32?,
+ e:Int32?,
+ >,
+
+ ($row) -> ((((
+ $row.c,
+ $row.b,
+ $row.e)
+ IN $Input2) AND $row.a == 10) ?? false),
+ AsTuple(
+ AsAtom("a"),
+ AsAtom("b"),
+ AsAtom("c"),
+ AsAtom("d"),
+ AsAtom("e"),
+ )
+);
+
+$Input3 = [(20, 10, 30, 99), (21, 10, 31, 88)];
+select YQL::RangeComputeFor(
+ Struct<
+ a:Int32?,
+ b:Int32?,
+ c:Int32?,
+ d:Int32?,
+ e:Int32?,
+ >,
+
+ ($row) -> ((($row.c = 33 AND $row.d = 44 AND (
+ $row.b,
+ $row.a,
+ $row.b,
+ $row.e)
+ IN $Input3)) ?? false),
+ AsTuple(
+ AsAtom("a"),
+ AsAtom("b"),
+ AsAtom("c"),
+ AsAtom("d"),
+ AsAtom("e"),
+ )
+);
diff --git a/yql/essentials/tests/sql/suites/compute_range/in_literal_nulls.sql b/yql/essentials/tests/sql/suites/compute_range/in_literal_nulls.sql
new file mode 100644
index 0000000000..71946ffc02
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/in_literal_nulls.sql
@@ -0,0 +1,13 @@
+/* syntax version 1 */
+/* postgres can not */
+/* dq can not */
+/* dqfile can not */
+/* yt can not */
+pragma warning("disable", "4510");
+pragma warning("disable", "1108");
+
+select YQL::RangeComputeFor(
+ Struct<x:Int32?>,
+ ($row) -> (($row.x IN (1,2,5,null)) ?? false),
+ AsTuple(AsAtom("x"))
+);
diff --git a/yql/essentials/tests/sql/suites/compute_range/merge_adjacent.sql b/yql/essentials/tests/sql/suites/compute_range/merge_adjacent.sql
new file mode 100644
index 0000000000..d8d534b501
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/merge_adjacent.sql
@@ -0,0 +1,43 @@
+/* syntax version 1 */
+/* postgres can not */
+/* yt can not */
+
+pragma warning("disable", "4510");
+pragma warning("disable", "1108");
+
+-- basic in
+select YQL::RangeComputeFor(
+ Struct<x:UInt32>,
+ ($row) -> ($row.x in ListFromRange(-100, 100)),
+ AsTuple(AsAtom("x"))
+);
+
+-- maxint
+select YQL::RangeComputeFor(
+ Struct<x:Int32?>,
+ ($row) -> (($row.x in ListFromRange(2147483547ul, 2147483648ul)) ?? false),
+ AsTuple(AsAtom("x"))
+);
+
+-- date
+select YQL::RangeComputeFor(
+ Struct<x:Date>,
+ ($row) -> ($row.x in ListFromRange(Date("2105-01-01"), Date("2105-12-31")) or $row.x == Date("2105-12-31")),
+ AsTuple(AsAtom("x"))
+);
+
+-- datetime
+select YQL::RangeComputeFor(
+ Struct<x:Datetime>,
+ ($row) -> ($row.x == Datetime("2105-12-31T23:59:58Z") or $row.x == Datetime("2105-12-31T23:59:59Z")),
+ AsTuple(AsAtom("x"))
+);
+
+
+-- timestamp
+select YQL::RangeComputeFor(
+ Struct<x:Timestamp>,
+ ($row) -> ($row.x == Timestamp("2105-12-31T23:59:59.999998Z") or $row.x == Timestamp("2105-12-31T23:59:59.999999Z")),
+ AsTuple(AsAtom("x"))
+);
+
diff --git a/yql/essentials/tests/sql/suites/compute_range/multiply_limit.sql b/yql/essentials/tests/sql/suites/compute_range/multiply_limit.sql
new file mode 100644
index 0000000000..a8967ea763
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/multiply_limit.sql
@@ -0,0 +1,31 @@
+/* syntax version 1 */
+/* postgres can not */
+/* dq can not */
+/* dqfile can not */
+/* yt can not */
+pragma warning("disable", "4510");
+pragma warning("disable", "1108");
+
+-- single over limit
+select YQL::RangeComputeFor(
+ Struct<x:String, y:String>,
+ ($row) -> ($row.x IN CAST(ListFromRange(0, 10001) AS List<String>)),
+ AsTuple(AsAtom("x"), AsAtom("y"))
+);
+
+
+-- multiply over limit
+select YQL::RangeComputeFor(
+ Struct<x:String, y:String>,
+ ($row) -> ($row.x IN CAST(ListFromRange(0, 101) AS List<String>) and $row.y IN CAST(ListFromRange(0, 101) AS List<String>)),
+ AsTuple(AsAtom("x"), AsAtom("y"))
+);
+
+-- fuzing predicates
+-- TODO: currently the result is (-inf, +inf) here. Optimally, it should be [0, +inf)
+select YQL::RangeComputeFor(
+ Struct<x:Int32>,
+ ($row) -> ($row.x IN ListFromRange(0, 20000)),
+ AsTuple(AsAtom("x"))
+);
+
diff --git a/yql/essentials/tests/sql/suites/compute_range/multiply_limit_for_single_key.sql b/yql/essentials/tests/sql/suites/compute_range/multiply_limit_for_single_key.sql
new file mode 100644
index 0000000000..d7c3cedc10
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/multiply_limit_for_single_key.sql
@@ -0,0 +1,15 @@
+/* syntax version 1 */
+/* postgres can not */
+/* dq can not */
+/* dqfile can not */
+/* yt can not */
+pragma warning("disable", "4510");
+pragma warning("disable", "1108");
+
+-- single over limit
+select YQL::RangeComputeFor(
+ Struct<x:String, y:String>,
+ ($row) -> ($row.x IN CAST(ListFromRange(0, 10001) AS List<String>)),
+ AsTuple(AsAtom("x"))
+);
+
diff --git a/yql/essentials/tests/sql/suites/compute_range/multiply_limit_with_dups.sql b/yql/essentials/tests/sql/suites/compute_range/multiply_limit_with_dups.sql
new file mode 100644
index 0000000000..312e173e08
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/multiply_limit_with_dups.sql
@@ -0,0 +1,32 @@
+/* syntax version 1 */
+/* postgres can not */
+/* dq can not */
+/* dqfile can not */
+/* yt can not */
+pragma warning("disable", "4510");
+pragma warning("disable", "1108");
+
+$lst = ListExtend(
+ ListFromRange(0, 5000),
+ ListFromRange(0, 5000),
+ ListFromRange(5000, 10000)
+);
+
+$lst = ListMap($lst, ($x)->(AsTuple(cast($x as String), $x)));
+
+select YQL::RangeComputeFor(
+ Struct<
+ a:Int32?,
+ b:String,
+ >,
+
+ ($row) -> (((
+ $row.b,
+ $row.a)
+ IN $lst) ?? false),
+ AsTuple(
+ AsAtom("a"),
+ AsAtom("b"),
+ )
+);
+
diff --git a/yql/essentials/tests/sql/suites/compute_range/multiply_limit_with_nulls.sql b/yql/essentials/tests/sql/suites/compute_range/multiply_limit_with_nulls.sql
new file mode 100644
index 0000000000..74ec8616f3
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/multiply_limit_with_nulls.sql
@@ -0,0 +1,13 @@
+/* syntax version 1 */
+/* postgres can not */
+/* dq can not */
+/* dqfile can not */
+/* yt can not */
+pragma warning("disable", "4510");
+pragma warning("disable", "1108");
+
+select YQL::RangeComputeFor(
+ Struct<x:Uint32>,
+ ($row) -> ($row.x IN ListFromRange(-1,10001)),
+ AsTuple(AsAtom("x"))
+);
diff --git a/yql/essentials/tests/sql/suites/compute_range/norange.sql b/yql/essentials/tests/sql/suites/compute_range/norange.sql
new file mode 100644
index 0000000000..825f9e8921
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/norange.sql
@@ -0,0 +1,21 @@
+/* syntax version 1 */
+/* postgres can not */
+/* yt can not */
+
+pragma warning("disable", "4510");
+
+$opt_type = Struct<x:Int32?, y:Int32?, z:String?, t:String?>;
+$xy_keys = AsTuple(AsAtom("x"), AsAtom("y"));
+
+$range_for = ($pred) -> (YQL::RangeComputeFor($opt_type, $pred, $xy_keys));
+
+$pred1 = ($row) -> (($row.x + $row.y > 0) ?? false);
+$pred2 = ($row) -> (($row.x > 0 or $row.y > 0) ?? false);
+$pred3 = ($row) -> (($row.x > 0 or $row.z == "test") ?? false);
+
+
+select
+ $range_for($pred1) is null,
+ $range_for($pred2) is null,
+ $range_for($pred3) is null,
+;
diff --git a/yql/essentials/tests/sql/suites/compute_range/pg_compare.sql b/yql/essentials/tests/sql/suites/compute_range/pg_compare.sql
new file mode 100644
index 0000000000..4bb2a3f805
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/pg_compare.sql
@@ -0,0 +1,35 @@
+/* syntax version 1 */
+/* postgres can not */
+/* dq can not */
+/* dqfile can not */
+/* yt can not */
+pragma warning("disable", "4510");
+pragma warning("disable", "1108");
+
+-- a > 2
+select YQL::RangeComputeFor(
+ Struct<a:PgInt4,b:PgText>,
+ ($row) -> (FromPg(PgOp(">", $row.a, 2p)) ?? false),
+ AsTuple(AsAtom("a"))
+);
+
+-- a >= 2
+select YQL::RangeComputeFor(
+ Struct<a:PgInt4,b:PgText>,
+ ($row) -> (($row.a >= 2p) ?? false),
+ AsTuple(AsAtom("a"))
+);
+
+-- b < 2
+select YQL::RangeComputeFor(
+ Struct<a:PgInt4,b:PgText>,
+ ($row) -> (('2'p > $row.b) ?? false),
+ AsTuple(AsAtom("b"))
+);
+
+-- b <= 2
+select YQL::RangeComputeFor(
+ Struct<a:PgInt4,b:PgText>,
+ ($row) -> (FromPg(PgOp(">=", '2'p, $row.b)) ?? false),
+ AsTuple(AsAtom("b"))
+);
diff --git a/yql/essentials/tests/sql/suites/compute_range/pg_equal.sql b/yql/essentials/tests/sql/suites/compute_range/pg_equal.sql
new file mode 100644
index 0000000000..595e01bde3
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/pg_equal.sql
@@ -0,0 +1,22 @@
+/* syntax version 1 */
+/* postgres can not */
+/* dq can not */
+/* dqfile can not */
+/* yt can not */
+pragma warning("disable", "4510");
+pragma warning("disable", "1108");
+
+-- a != 2
+select YQL::RangeComputeFor(
+ Struct<a:PgFloat8,b:PgText>,
+ ($row) -> (FromPg(PgOp("<>", $row.a, 2.0pf8)) ?? false),
+ AsTuple(AsAtom("a"))
+);
+
+-- b == 'foo'
+select YQL::RangeComputeFor(
+ Struct<a:PgInt4,b:PgText>,
+ ($row) -> (($row.b == 'foo'p) ?? false),
+ AsTuple(AsAtom("b"))
+);
+
diff --git a/yql/essentials/tests/sql/suites/compute_range/pg_exists.sql b/yql/essentials/tests/sql/suites/compute_range/pg_exists.sql
new file mode 100644
index 0000000000..5c368e9f35
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/pg_exists.sql
@@ -0,0 +1,20 @@
+/* syntax version 1 */
+/* postgres can not */
+/* dq can not */
+/* dqfile can not */
+/* yt can not */
+pragma warning("disable", "4510");
+pragma warning("disable", "1108");
+
+select YQL::RangeComputeFor(
+ Struct<a:PgFloat8,b:PgText>,
+ ($row) -> ($row.a is not null),
+ AsTuple(AsAtom("a"))
+);
+
+select YQL::RangeComputeFor(
+ Struct<a:PgInt4,b:PgText>,
+ ($row) -> ($row.b is null),
+ AsTuple(AsAtom("b"))
+);
+
diff --git a/yql/essentials/tests/sql/suites/compute_range/pg_sqlin.sql b/yql/essentials/tests/sql/suites/compute_range/pg_sqlin.sql
new file mode 100644
index 0000000000..0e991c92ae
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/pg_sqlin.sql
@@ -0,0 +1,23 @@
+/* syntax version 1 */
+/* postgres can not */
+/* dq can not */
+/* dqfile can not */
+/* yt can not */
+pragma warning("disable", "4510");
+pragma warning("disable", "1108");
+pragma AnsiInForEmptyOrNullableItemsCollections;
+
+-- a != 2
+select YQL::RangeComputeFor(
+ Struct<a:PgInt4,b:PgText>,
+ ($row) -> (($row.a in (3p,2p,1p)) ?? false),
+ AsTuple(AsAtom("a"))
+);
+
+-- b == 'foo'
+select YQL::RangeComputeFor(
+ Struct<a:PgInt4,b:PgText>,
+ ($row) -> (($row.b in ('foo'p, 'bar'p, 'baz'p)) ?? false),
+ AsTuple(AsAtom("b"))
+);
+
diff --git a/yql/essentials/tests/sql/suites/compute_range/pg_startswith.sql b/yql/essentials/tests/sql/suites/compute_range/pg_startswith.sql
new file mode 100644
index 0000000000..0ed99c65c0
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/pg_startswith.sql
@@ -0,0 +1,36 @@
+/* syntax version 1 */
+/* postgres can not */
+/* dq can not */
+/* dqfile can not */
+/* yt can not */
+pragma warning("disable", "4510");
+pragma warning("disable", "1108");
+
+-- like 'aaaa'
+select YQL::RangeComputeFor(
+ Struct<a:PgInt4,b:PgText>,
+ ($row) -> (StartsWith(FromPg($row.b), 'aaaa') ?? false),
+ AsTuple(AsAtom("b"))
+);
+
+-- not like 'aaaa'
+select YQL::RangeComputeFor(
+ Struct<a:PgInt4,b:PgText>,
+ ($row) -> (not (StartsWith(FromPg($row.b), 'aaaa') ?? true)),
+ AsTuple(AsAtom("b"))
+);
+
+
+-- like <invalid utf8>
+select YQL::RangeComputeFor(
+ Struct<a:PgInt4,b:PgText>,
+ ($row) -> (StartsWith(FromPg($row.b), 'a\xf5') ?? false),
+ AsTuple(AsAtom("b"))
+);
+
+-- not like <invalid utf8>
+select YQL::RangeComputeFor(
+ Struct<a:PgInt4,b:PgText>,
+ ($row) -> (not (StartsWith(FromPg($row.b), 'a\xf5') ?? true)),
+ AsTuple(AsAtom("b"))
+);
diff --git a/yql/essentials/tests/sql/suites/compute_range/preserve_rest_predicates_order.sql b/yql/essentials/tests/sql/suites/compute_range/preserve_rest_predicates_order.sql
new file mode 100644
index 0000000000..efd5ec2fb3
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/preserve_rest_predicates_order.sql
@@ -0,0 +1,17 @@
+/* syntax version 1 */
+/* postgres can not */
+/* yt can not */
+
+pragma warning("disable", "4510");
+pragma warning("disable", "1108");
+
+select YQL::RangeComputeFor(
+ Struct<x:String, y:String, z:String>,
+ ($row) -> (
+ ($row.x, $row.y, $row.z) > ("a", "b", "c") and
+ ($row.x, $row.y, $row.z) < ("d", "e", "f") and
+ $row.z IN AsList("t", "u", "v") and
+ $row.y IN AsList("x", "y", "z") and
+ (len($row.z) == 1 OR len($row.z || 'x') == 2)),
+ AsTuple(AsAtom("x"), AsAtom("y"), AsAtom("z"))
+);
diff --git a/yql/essentials/tests/sql/suites/compute_range/repeated_keyranges_in_and.sql b/yql/essentials/tests/sql/suites/compute_range/repeated_keyranges_in_and.sql
new file mode 100644
index 0000000000..b8c98f6382
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/repeated_keyranges_in_and.sql
@@ -0,0 +1,13 @@
+/* syntax version 1 */
+/* postgres can not */
+/* yt can not */
+
+pragma warning("disable", "4510");
+pragma warning("disable", "1108");
+
+select YQL::RangeComputeFor(
+ Struct<x:Int32, y:UInt32, z:Uint64>,
+ ($row) -> ($row.x == 1 and ($row.y = 2 and $row.z > 0 and $row.z < 10 or
+ $row.y = 2 and $row.z > 8 and $row.z < 20)),
+ AsTuple(AsAtom("x"), AsAtom("y"), AsAtom("z"))
+);
diff --git a/yql/essentials/tests/sql/suites/compute_range/startswith.sql b/yql/essentials/tests/sql/suites/compute_range/startswith.sql
new file mode 100644
index 0000000000..b5c31298cb
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/startswith.sql
@@ -0,0 +1,80 @@
+/* syntax version 1 */
+/* postgres can not */
+/* dq can not */
+/* dqfile can not */
+/* yt can not */
+pragma warning("disable", "4510");
+
+-- string/string
+select YQL::RangeComputeFor(
+ Struct<x:String>,
+ ($row) -> (StartsWith($row.x, 'foo')),
+ AsTuple(AsAtom("x"))
+);
+
+
+select YQL::RangeComputeFor(
+ Struct<x:String>,
+ ($row) -> (not StartsWith($row.x, 'foo')),
+ AsTuple(AsAtom("x"))
+);
+
+
+select YQL::RangeComputeFor(
+ Struct<x:String>,
+ ($row) -> (StartsWith($row.x, '\xff\xff')),
+ AsTuple(AsAtom("x"))
+);
+
+select YQL::RangeComputeFor(
+ Struct<x:String>,
+ ($row) -> (not StartsWith($row.x, '\xff\xff')),
+ AsTuple(AsAtom("x"))
+);
+
+-- optional string/string
+select YQL::RangeComputeFor(
+ Struct<x:String?>,
+ ($row) -> ((not StartsWith($row.x, 'foo')) ?? false),
+ AsTuple(AsAtom("x"))
+);
+
+-- optional string/optional string
+select YQL::RangeComputeFor(
+ Struct<x:String?>,
+ ($row) -> (StartsWith($row.x, if(1 > 2, 'void')) ?? false),
+ AsTuple(AsAtom("x"))
+);
+
+--utf8/string
+select YQL::RangeComputeFor(
+ Struct<x:Utf8>,
+ ($row) -> (StartsWith($row.x, 'тест')),
+ AsTuple(AsAtom("x"))
+);
+
+select YQL::RangeComputeFor(
+ Struct<x:Utf8>,
+ ($row) -> (StartsWith($row.x, 'тест\xf5')),
+ AsTuple(AsAtom("x"))
+);
+
+--optional utf8/utf8
+select YQL::RangeComputeFor(
+ Struct<x:Utf8?>,
+ ($row) -> ((not StartsWith($row.x, 'тест'u)) ?? false),
+ AsTuple(AsAtom("x"))
+);
+
+select YQL::RangeComputeFor(
+ Struct<x:Utf8?>,
+ ($row) -> (StartsWith($row.x, '\xf4\x8f\xbf\xbf'u) ?? false),
+ AsTuple(AsAtom("x"))
+);
+
+-- optional utf8/string
+select YQL::RangeComputeFor(
+ Struct<x:Utf8?>,
+ ($row) -> ((not StartsWith($row.x, 'тест\xf5')) ?? false),
+ AsTuple(AsAtom("x"))
+);
diff --git a/yql/essentials/tests/sql/suites/compute_range/tuples_compare.sql b/yql/essentials/tests/sql/suites/compute_range/tuples_compare.sql
new file mode 100644
index 0000000000..a9fae38085
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/tuples_compare.sql
@@ -0,0 +1,46 @@
+/* syntax version 1 */
+/* postgres can not */
+/* yt can not */
+
+pragma warning("disable", "4510");
+
+$type = Struct<x:Int32, y:Int32, z:Int32>;
+$keys = AsTuple(AsAtom("x"), AsAtom("y"), AsAtom("z"));
+
+$range_for = ($pred) -> (YQL::RangeComputeFor($type, $pred, $keys));
+
+$pred1 = ($row) -> (($row.x, $row.y, $row.z) >= (11, 22, 33));
+$pred2 = ($row) -> (($row.x, $row.y, $row.z) > (11, 22, 33));
+
+$pred3 = ($row) -> (($row.x, $row.y, $row.z) < (11, 22, 33));
+$pred4 = ($row) -> (($row.x, $row.y, $row.z) <= (11, 22, 33));
+
+$pred5 = ($row) -> (($row.x, $row.y, $row.z) > (111, 222, 333) and ($row.x, $row.y, $row.z) <= (111, 333, 444));
+$pred6 = ($row) -> (($row.x, $row.y, $row.z) >= (111, 222, 333) and ($row.x, $row.y, $row.z) < (111, 222, 333));
+
+select
+ $range_for($pred1),
+ $range_for($pred2),
+ $range_for($pred3),
+ $range_for($pred4),
+ $range_for($pred5),
+ $range_for($pred6),
+;
+
+$pred1 = ($row) -> (($row.x, $row.y) >= (11, 22));
+$pred2 = ($row) -> (($row.x, $row.y) > (11, 22));
+
+$pred3 = ($row) -> (($row.x, $row.y) < (11, 22));
+$pred4 = ($row) -> (($row.x, $row.y) <= (11, 22));
+
+$pred5 = ($row) -> (($row.x, $row.y) > (111, 222) and ($row.x, $row.y) <= (111, 333));
+$pred6 = ($row) -> (($row.x, $row.y) >= (111, 222) and ($row.x, $row.y) < (111, 222));
+
+select
+ $range_for($pred1),
+ $range_for($pred2),
+ $range_for($pred3),
+ $range_for($pred4),
+ $range_for($pred5),
+ $range_for($pred6),
+;
diff --git a/yql/essentials/tests/sql/suites/compute_range/tztypes.sql b/yql/essentials/tests/sql/suites/compute_range/tztypes.sql
new file mode 100644
index 0000000000..915d2d94db
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/tztypes.sql
@@ -0,0 +1,48 @@
+/* syntax version 1 */
+/* postgres can not */
+/* yt can not */
+
+pragma warning("disable", "4510");
+
+-- ==
+select YQL::RangeComputeFor(
+ Struct<x:TzDate>,
+ ($row) -> ($row.x == TzDate('2000-01-01,Europe/Moscow')),
+ AsTuple(AsAtom("x"))
+);
+
+-- !=
+select YQL::RangeComputeFor(
+ Struct<x:TzDate>,
+ ($row) -> ($row.x != TzDate('2000-01-01,Europe/Moscow')),
+ AsTuple(AsAtom("x"))
+);
+
+-- >
+select YQL::RangeComputeFor(
+ Struct<x:TzDatetime>,
+ ($row) -> ($row.x > TzDatetime('2000-01-01T00:00:00,Europe/Moscow')),
+ AsTuple(AsAtom("x"))
+);
+
+-- >=
+select YQL::RangeComputeFor(
+ Struct<x:TzDatetime>,
+ ($row) -> ($row.x >= TzDatetime('2000-01-01T00:00:00,Europe/Moscow')),
+ AsTuple(AsAtom("x"))
+);
+
+-- <
+select YQL::RangeComputeFor(
+ Struct<x:TzTimestamp>,
+ ($row) -> ($row.x < TzTimestamp('2000-01-01T00:00:00.000000,Europe/Moscow')),
+ AsTuple(AsAtom("x"))
+);
+
+-- <=
+select YQL::RangeComputeFor(
+ Struct<x:TzTimestamp>,
+ ($row) -> ($row.x <= TzTimestamp('2000-01-01T00:00:00.000000,Europe/Moscow')),
+ AsTuple(AsAtom("x"))
+);
+
diff --git a/yql/essentials/tests/sql/suites/compute_range/yql-12941.sql b/yql/essentials/tests/sql/suites/compute_range/yql-12941.sql
new file mode 100644
index 0000000000..63e2a586bc
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/yql-12941.sql
@@ -0,0 +1,19 @@
+/* syntax version 1 */
+/* postgres can not */
+/* yt can not */
+
+pragma warning("disable", "4510");
+
+$opt_type = Struct<x:UInt32?, y:Int32?>;
+$xy_keys = AsTuple(AsAtom("x"), AsAtom("y"));
+
+$range_for = ($pred) -> (YQL::RangeComputeFor($opt_type, $pred, $xy_keys));
+
+$pred1 = ($row) -> (($row.x == 3u and ($row.y > 300 or $row.y == 100)) ?? false);
+$pred2 = ($row) -> (($row.y > 300 and $row.x == 3u or $row.x == 3u and $row.y == 100) ?? false);
+
+
+select
+ $range_for($pred1),
+ $range_for($pred2),
+;
diff --git a/yql/essentials/tests/sql/suites/compute_range/yql-13489.sql b/yql/essentials/tests/sql/suites/compute_range/yql-13489.sql
new file mode 100644
index 0000000000..2f2f153cb7
--- /dev/null
+++ b/yql/essentials/tests/sql/suites/compute_range/yql-13489.sql
@@ -0,0 +1,18 @@
+/* syntax version 1 */
+/* postgres can not */
+/* yt can not */
+
+pragma warning("disable", "4510");
+
+select YQL::RangeComputeFor(
+ Struct<x:Int32, y:Int32>,
+ ($row) -> ($row.x > 2 or ($row.x == 2 and $row.y >= 10) or ($row.x == 0 and $row.y < 10)),
+ AsTuple(AsAtom("x"))
+);
+
+select YQL::RangeComputeFor(
+ Struct<x:Int32, y:Int32>,
+ ($row) -> (($row.x > 10 and $row.y > 1) or $row.x < 5),
+ AsTuple(AsAtom("x"), AsAtom("y"))
+);
+