aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/tests/s-expressions/suites/Join
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/s-expressions/suites/Join
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/s-expressions/suites/Join')
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/CommonJoinCore.yql53
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/CommonJoinCoreSortedLeft.yql54
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/CommonJoinCoreSortedLeft_Flow.yql54
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/CommonJoinCoreSortedRight.yql54
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/CommonJoinCoreSortedRight_Flow.yql54
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/CommonJoinCore_Flow.yql53
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/CommonJoinCore_FlowOfTuples.yql54
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/EmptyLeftJoin.yql23
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/InputSelf.txt8
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/InputSelf.txt.attr30
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/JoinInMem.yql34
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/JoinTypes.yql30
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/MapJoinCore.yql41
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/MapJoinCoreOnStrings.yql41
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/MapJoinCoreOnStrings_Flow.yql41
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/MapJoinCore_Flow.yql41
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/MapJoinCore_FlowOfTuples.yql41
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/default.cfg5
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/input1.txt4
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/input1.txt.attr30
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/input2.txt4
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/input2.txt.attr30
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/input3.txt4
-rw-r--r--yql/essentials/tests/s-expressions/suites/Join/input3.txt.attr30
24 files changed, 813 insertions, 0 deletions
diff --git a/yql/essentials/tests/s-expressions/suites/Join/CommonJoinCore.yql b/yql/essentials/tests/s-expressions/suites/Join/CommonJoinCore.yql
new file mode 100644
index 0000000000..8bf51c75d5
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/CommonJoinCore.yql
@@ -0,0 +1,53 @@
+(
+(let mr_source (DataSource 'yt 'plato))
+(let emptyInt32 (Nothing (OptionalType (DataType 'Int32))))
+(let emptyString (Nothing (OptionalType (DataType 'String))))
+(let list1 (AsList
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'A))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'B))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+))
+
+(let list2 (AsList
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'X))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'Y))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+))
+
+(let list12 (AsList
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'A))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'X))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'B))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'Y))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+))
+
+(let writeRes (lambda '(world list) (block '(
+(let joinInner (CommonJoinCore (Iterator list (DependsOn (String 'Inner))) 'Inner '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '() '_yql_table_index))
+(let joinLeft (CommonJoinCore (Iterator list (DependsOn (String 'Left))) 'Left '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '() '_yql_table_index))
+(let joinRight (CommonJoinCore (Iterator list (DependsOn (String 'Right))) 'Right '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '() '_yql_table_index))
+(let joinFull (CommonJoinCore (Iterator list (DependsOn (String 'Full))) 'Full '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '() '_yql_table_index))
+(let joinLeftOnly (CommonJoinCore (Iterator list (DependsOn (String 'LeftOnly))) 'LeftOnly '('key1 'value1) '() '() '('_yql_join_column_0) '() '_yql_table_index))
+(let joinLeftSemi (CommonJoinCore (Iterator list (DependsOn (String 'LeftSemi))) 'LeftSemi '('key1 'value1) '() '() '('_yql_join_column_0) '() '_yql_table_index))
+(let joinRightOnly (CommonJoinCore (Iterator list (DependsOn (String 'RightOnly))) 'RightOnly '() '('key2 'value2) '() '('_yql_join_column_0) '() '_yql_table_index))
+(let joinRightSemi (CommonJoinCore (Iterator list (DependsOn (String 'RightSemi))) 'RightSemi '() '('key2 'value2) '() '('_yql_join_column_0) '() '_yql_table_index))
+(let joinExclusion (CommonJoinCore (Iterator list (DependsOn (String 'Exclusion))) 'Exclusion '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '() '_yql_table_index))
+(let joinCross (CommonJoinCore (Iterator list (DependsOn (String 'Cross))) 'Cross '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '() '_yql_table_index))
+
+(let res_sink (DataSink 'result))
+(let world (Write! world res_sink (Key) (Collect joinInner) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeft) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinRight) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinFull) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftOnly) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftSemi) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinRightOnly) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinRightSemi) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinExclusion) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinCross) '('('type))))
+(let world (Commit! world res_sink))
+(return world)
+))))
+
+(let world (Apply writeRes world list1))
+(let world (Apply writeRes world list2))
+(let world (Apply writeRes world list12))
+(return world)
+)
diff --git a/yql/essentials/tests/s-expressions/suites/Join/CommonJoinCoreSortedLeft.yql b/yql/essentials/tests/s-expressions/suites/Join/CommonJoinCoreSortedLeft.yql
new file mode 100644
index 0000000000..3d7aacb4dc
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/CommonJoinCoreSortedLeft.yql
@@ -0,0 +1,54 @@
+(
+(let mr_source (DataSource 'yt 'plato))
+(let emptyInt32 (Nothing (OptionalType (DataType 'Int32))))
+(let emptyString (Nothing (OptionalType (DataType 'String))))
+
+(let list1 (AsList
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'A))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'B))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+))
+
+(let list2 (AsList
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'X))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'Y))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+))
+
+(let list12 (AsList
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'A))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'X))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'B))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'Y))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+))
+
+(let writeRes (lambda '(world list) (block '(
+(let joinInner (CommonJoinCore (Iterator list (DependsOn (String 'Inner))) 'Inner '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'left)) '_yql_table_index))
+(let joinLeft (CommonJoinCore (Iterator list (DependsOn (String 'Left))) 'Left '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'left)) '_yql_table_index))
+(let joinRight (CommonJoinCore (Iterator list (DependsOn (String 'Right))) 'Right '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'left)) '_yql_table_index))
+(let joinFull (CommonJoinCore (Iterator list (DependsOn (String 'Full))) 'Full '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'left)) '_yql_table_index))
+(let joinLeftOnly (CommonJoinCore (Iterator list (DependsOn (String 'LeftOnly))) 'LeftOnly '('key1 'value1) '() '() '('_yql_join_column_0) '('('sorted 'left)) '_yql_table_index))
+(let joinLeftSemi (CommonJoinCore (Iterator list (DependsOn (String 'LeftSemi))) 'LeftSemi '('key1 'value1) '() '() '('_yql_join_column_0) '('('sorted 'left)) '_yql_table_index))
+(let joinRightOnly (CommonJoinCore (Iterator list (DependsOn (String 'RightOnly))) 'RightOnly '() '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'left)) '_yql_table_index))
+(let joinRightSemi (CommonJoinCore (Iterator list (DependsOn (String 'RightSemi))) 'RightSemi '() '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'left)) '_yql_table_index))
+(let joinExclusion (CommonJoinCore (Iterator list (DependsOn (String 'Exclusion))) 'Exclusion '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'left)) '_yql_table_index))
+(let joinCross (CommonJoinCore (Iterator list (DependsOn (String 'Cross))) 'Cross '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'left)) '_yql_table_index))
+
+(let res_sink (DataSink 'result))
+(let world (Write! world res_sink (Key) (Collect joinInner) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeft) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinRight) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinFull) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftOnly) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftSemi) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinRightOnly) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinRightSemi) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinExclusion) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinCross) '('('type))))
+(let world (Commit! world res_sink))
+(return world)
+))))
+
+(let world (Apply writeRes world list1))
+(let world (Apply writeRes world list2))
+(let world (Apply writeRes world list12))
+(return world)
+)
diff --git a/yql/essentials/tests/s-expressions/suites/Join/CommonJoinCoreSortedLeft_Flow.yql b/yql/essentials/tests/s-expressions/suites/Join/CommonJoinCoreSortedLeft_Flow.yql
new file mode 100644
index 0000000000..5d4048a4ab
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/CommonJoinCoreSortedLeft_Flow.yql
@@ -0,0 +1,54 @@
+(
+(let mr_source (DataSource 'yt 'plato))
+(let emptyInt32 (Nothing (OptionalType (DataType 'Int32))))
+(let emptyString (Nothing (OptionalType (DataType 'String))))
+
+(let list1 (AsList
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'A))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'B))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+))
+
+(let list2 (AsList
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'X))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'Y))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+))
+
+(let list12 (AsList
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'A))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'X))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'B))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'Y))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+))
+
+(let writeRes (lambda '(world list) (block '(
+(let joinInner (CommonJoinCore (ToFlow list) 'Inner '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'left)) '_yql_table_index))
+(let joinLeft (CommonJoinCore (ToFlow list) 'Left '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'left)) '_yql_table_index))
+(let joinRight (CommonJoinCore (ToFlow list) 'Right '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'left)) '_yql_table_index))
+(let joinFull (CommonJoinCore (ToFlow list) 'Full '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'left)) '_yql_table_index))
+(let joinLeftOnly (CommonJoinCore (ToFlow list) 'LeftOnly '('key1 'value1) '() '() '('_yql_join_column_0) '('('sorted 'left)) '_yql_table_index))
+(let joinLeftSemi (CommonJoinCore (ToFlow list) 'LeftSemi '('key1 'value1) '() '() '('_yql_join_column_0) '('('sorted 'left)) '_yql_table_index))
+(let joinRightOnly (CommonJoinCore (ToFlow list) 'RightOnly '() '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'left)) '_yql_table_index))
+(let joinRightSemi (CommonJoinCore (ToFlow list) 'RightSemi '() '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'left)) '_yql_table_index))
+(let joinExclusion (CommonJoinCore (ToFlow list) 'Exclusion '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'left)) '_yql_table_index))
+(let joinCross (CommonJoinCore (ToFlow list) 'Cross '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'left)) '_yql_table_index))
+
+(let res_sink (DataSink 'result))
+(let world (Write! world res_sink (Key) (Collect joinInner) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeft) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinRight) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinFull) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftOnly) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftSemi) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinRightOnly) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinRightSemi) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinExclusion) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinCross) '('('type))))
+(let world (Commit! world res_sink))
+(return world)
+))))
+
+(let world (Apply writeRes world list1))
+(let world (Apply writeRes world list2))
+(let world (Apply writeRes world list12))
+(return world)
+)
diff --git a/yql/essentials/tests/s-expressions/suites/Join/CommonJoinCoreSortedRight.yql b/yql/essentials/tests/s-expressions/suites/Join/CommonJoinCoreSortedRight.yql
new file mode 100644
index 0000000000..64425dd37b
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/CommonJoinCoreSortedRight.yql
@@ -0,0 +1,54 @@
+(
+(let mr_source (DataSource 'yt 'plato))
+(let emptyInt32 (Nothing (OptionalType (DataType 'Int32))))
+(let emptyString (Nothing (OptionalType (DataType 'String))))
+
+(let list1 (AsList
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'A))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'B))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+))
+
+(let list2 (AsList
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'X))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'Y))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+))
+
+(let list12 (AsList
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'A))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'X))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'B))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'Y))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+))
+
+(let writeRes (lambda '(world list) (block '(
+(let joinInner (CommonJoinCore (Iterator list (DependsOn (String 'Inner))) 'Inner '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'right)) '_yql_table_index))
+(let joinLeft (CommonJoinCore (Iterator list (DependsOn (String 'Left))) 'Left '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'right)) '_yql_table_index))
+(let joinRight (CommonJoinCore (Iterator list (DependsOn (String 'Right))) 'Right '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'right)) '_yql_table_index))
+(let joinFull (CommonJoinCore (Iterator list (DependsOn (String 'Full))) 'Full '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'right)) '_yql_table_index))
+(let joinLeftOnly (CommonJoinCore (Iterator list (DependsOn (String 'LeftOnly))) 'LeftOnly '('key1 'value1) '() '() '('_yql_join_column_0) '('('sorted 'right)) '_yql_table_index))
+(let joinLeftSemi (CommonJoinCore (Iterator list (DependsOn (String 'LeftSemi))) 'LeftSemi '('key1 'value1) '() '() '('_yql_join_column_0) '('('sorted 'right)) '_yql_table_index))
+(let joinRightOnly (CommonJoinCore (Iterator list (DependsOn (String 'RightOnly))) 'RightOnly '() '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'right)) '_yql_table_index))
+(let joinRightSemi (CommonJoinCore (Iterator list (DependsOn (String 'RightSemi))) 'RightSemi '() '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'right)) '_yql_table_index))
+(let joinExclusion (CommonJoinCore (Iterator list (DependsOn (String 'Exclusion))) 'Exclusion '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'right)) '_yql_table_index))
+(let joinCross (CommonJoinCore (Iterator list (DependsOn (String 'Cross))) 'Cross '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'right)) '_yql_table_index))
+
+(let res_sink (DataSink 'result))
+(let world (Write! world res_sink (Key) (Collect joinInner) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeft) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinRight) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinFull) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftOnly) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftSemi) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinRightOnly) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinRightSemi) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinExclusion) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinCross) '('('type))))
+(let world (Commit! world res_sink))
+(return world)
+))))
+
+(let world (Apply writeRes world list1))
+(let world (Apply writeRes world list2))
+(let world (Apply writeRes world list12))
+(return world)
+)
diff --git a/yql/essentials/tests/s-expressions/suites/Join/CommonJoinCoreSortedRight_Flow.yql b/yql/essentials/tests/s-expressions/suites/Join/CommonJoinCoreSortedRight_Flow.yql
new file mode 100644
index 0000000000..a3d9b47ecf
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/CommonJoinCoreSortedRight_Flow.yql
@@ -0,0 +1,54 @@
+(
+(let mr_source (DataSource 'yt 'plato))
+(let emptyInt32 (Nothing (OptionalType (DataType 'Int32))))
+(let emptyString (Nothing (OptionalType (DataType 'String))))
+
+(let list1 (AsList
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'A))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'B))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+))
+
+(let list2 (AsList
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'X))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'Y))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+))
+
+(let list12 (AsList
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'A))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'X))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'B))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'Y))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+))
+
+(let writeRes (lambda '(world list) (block '(
+(let joinInner (CommonJoinCore (ToFlow list) 'Inner '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'right)) '_yql_table_index))
+(let joinLeft (CommonJoinCore (ToFlow list) 'Left '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'right)) '_yql_table_index))
+(let joinRight (CommonJoinCore (ToFlow list) 'Right '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'right)) '_yql_table_index))
+(let joinFull (CommonJoinCore (ToFlow list) 'Full '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'right)) '_yql_table_index))
+(let joinLeftOnly (CommonJoinCore (ToFlow list) 'LeftOnly '('key1 'value1) '() '() '('_yql_join_column_0) '('('sorted 'right)) '_yql_table_index))
+(let joinLeftSemi (CommonJoinCore (ToFlow list) 'LeftSemi '('key1 'value1) '() '() '('_yql_join_column_0) '('('sorted 'right)) '_yql_table_index))
+(let joinRightOnly (CommonJoinCore (ToFlow list) 'RightOnly '() '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'right)) '_yql_table_index))
+(let joinRightSemi (CommonJoinCore (ToFlow list) 'RightSemi '() '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'right)) '_yql_table_index))
+(let joinExclusion (CommonJoinCore (ToFlow list) 'Exclusion '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'right)) '_yql_table_index))
+(let joinCross (CommonJoinCore (ToFlow list) 'Cross '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '('('sorted 'right)) '_yql_table_index))
+
+(let res_sink (DataSink 'result))
+(let world (Write! world res_sink (Key) (Collect joinInner) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeft) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinRight) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinFull) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftOnly) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftSemi) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinRightOnly) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinRightSemi) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinExclusion) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinCross) '('('type))))
+(let world (Commit! world res_sink))
+(return world)
+))))
+
+(let world (Apply writeRes world list1))
+(let world (Apply writeRes world list2))
+(let world (Apply writeRes world list12))
+(return world)
+)
diff --git a/yql/essentials/tests/s-expressions/suites/Join/CommonJoinCore_Flow.yql b/yql/essentials/tests/s-expressions/suites/Join/CommonJoinCore_Flow.yql
new file mode 100644
index 0000000000..10b5abc6e7
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/CommonJoinCore_Flow.yql
@@ -0,0 +1,53 @@
+(
+(let mr_source (DataSource 'yt 'plato))
+(let emptyInt32 (Nothing (OptionalType (DataType 'Int32))))
+(let emptyString (Nothing (OptionalType (DataType 'String))))
+(let list1 (AsList
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'A))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'B))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+))
+
+(let list2 (AsList
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'X))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'Y))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+))
+
+(let list12 (AsList
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'A))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'X))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (Just (String 'B))) '('key2 emptyInt32) '('value2 emptyString) '('_yql_table_index (Uint32 '0)) '('_yql_join_column_0 (Just (Int32 '1))))
+ (AsStruct '('key1 emptyInt32) '('value1 emptyString) '('key2 (Just (Int32 '1))) '('value2 (Just (String 'Y))) '('_yql_table_index (Uint32 '1)) '('_yql_join_column_0 (Just (Int32 '1))))
+))
+
+(let writeRes (lambda '(world list) (block '(
+(let joinInner (CommonJoinCore (ToFlow list) 'Inner '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '() '_yql_table_index))
+(let joinLeft (CommonJoinCore (ToFlow list) 'Left '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '() '_yql_table_index))
+(let joinRight (CommonJoinCore (ToFlow list) 'Right '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '() '_yql_table_index))
+(let joinFull (CommonJoinCore (ToFlow list) 'Full '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '() '_yql_table_index))
+(let joinLeftOnly (CommonJoinCore (ToFlow list) 'LeftOnly '('key1 'value1) '() '() '('_yql_join_column_0) '() '_yql_table_index))
+(let joinLeftSemi (CommonJoinCore (ToFlow list) 'LeftSemi '('key1 'value1) '() '() '('_yql_join_column_0) '() '_yql_table_index))
+(let joinRightOnly (CommonJoinCore (ToFlow list) 'RightOnly '() '('key2 'value2) '() '('_yql_join_column_0) '() '_yql_table_index))
+(let joinRightSemi (CommonJoinCore (ToFlow list) 'RightSemi '() '('key2 'value2) '() '('_yql_join_column_0) '() '_yql_table_index))
+(let joinExclusion (CommonJoinCore (ToFlow list) 'Exclusion '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '() '_yql_table_index))
+(let joinCross (CommonJoinCore (ToFlow list) 'Cross '('key1 'value1) '('key2 'value2) '() '('_yql_join_column_0) '() '_yql_table_index))
+
+(let res_sink (DataSink 'result))
+(let world (Write! world res_sink (Key) (Collect joinInner) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeft) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinRight) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinFull) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftOnly) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftSemi) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinRightOnly) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinRightSemi) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinExclusion) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinCross) '('('type))))
+(let world (Commit! world res_sink))
+(return world)
+))))
+
+(let world (Apply writeRes world list1))
+(let world (Apply writeRes world list2))
+(let world (Apply writeRes world list12))
+(return world)
+)
diff --git a/yql/essentials/tests/s-expressions/suites/Join/CommonJoinCore_FlowOfTuples.yql b/yql/essentials/tests/s-expressions/suites/Join/CommonJoinCore_FlowOfTuples.yql
new file mode 100644
index 0000000000..bb15c6f634
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/CommonJoinCore_FlowOfTuples.yql
@@ -0,0 +1,54 @@
+(
+(let mr_source (DataSource 'yt 'plato))
+(let emptyInt32 (Nothing (OptionalType (DataType 'Int32))))
+(let emptyString (Nothing (OptionalType (DataType 'String))))
+(let list1 (AsList
+ '((Just (Int32 '1)) (Just (String 'A)) emptyInt32 emptyString (Uint32 '0) (Just (Int32 '1)))
+ '((Just (Int32 '1)) (Just (String 'B)) emptyInt32 emptyString (Uint32 '0) (Just (Int32 '1)))
+))
+
+(let list2 (AsList
+ '(emptyInt32 emptyString (Just (Int32 '1)) (Just (String 'X)) (Uint32 '1) (Just (Int32 '1)))
+ '(emptyInt32 emptyString (Just (Int32 '1)) (Just (String 'Y)) (Uint32 '1) (Just (Int32 '1)))
+))
+
+(let list12 (AsList
+ '((Just (Int32 '1)) (Just (String 'A)) emptyInt32 emptyString (Uint32 '0) (Just (Int32 '1)))
+ '(emptyInt32 emptyString (Just (Int32 '1)) (Just (String 'X)) (Uint32 '1) (Just (Int32 '1)))
+ '((Just (Int32 '1)) (Just (String 'B)) emptyInt32 emptyString (Uint32 '0) (Just (Int32 '1)))
+ '(emptyInt32 emptyString (Just (Int32 '1)) (Just (String 'Y)) (Uint32 '1) (Just (Int32 '1)))
+))
+
+(let writeRes (lambda '(world list) (block '(
+(let joinInner (CommonJoinCore (ToFlow list) 'Inner '('0 '1) '('2 '3) '() '('5) '() '4))
+(let joinLeft (CommonJoinCore (ToFlow list) 'Left '('0 '1) '('2 '3) '() '('5) '() '4))
+(let joinRight (CommonJoinCore (ToFlow list) 'Right '('0 '1) '('2 '3) '() '('5) '() '4))
+(let joinFull (CommonJoinCore (ToFlow list) 'Full '('0 '1) '('2 '3) '() '('5) '() '4))
+(let joinLeftOnly (CommonJoinCore (ToFlow list) 'LeftOnly '('0 '1) '() '() '('5) '() '4))
+(let joinLeftSemi (CommonJoinCore (ToFlow list) 'LeftSemi '('0 '1) '() '() '('5) '() '4))
+(let joinRightOnly (CommonJoinCore (ToFlow list) 'RightOnly '() '('2 '3) '() '('5) '() '4))
+(let joinRightSemi (CommonJoinCore (ToFlow list) 'RightSemi '() '('2 '3) '() '('5) '() '4))
+(let joinExclusion (CommonJoinCore (ToFlow list) 'Exclusion '('0 '1) '('2 '3) '() '('5) '() '4))
+(let joinCross (CommonJoinCore (ToFlow list) 'Cross '('0 '1) '('2 '3) '() '('5) '() '4))
+
+(let res_sink (DataSink 'result))
+(let world (Write! world res_sink (Key) (Collect joinInner) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeft) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinRight) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinFull) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftOnly) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftSemi) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinRightOnly) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinRightSemi) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinExclusion) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinCross) '('('type))))
+(let world (Commit! world res_sink))
+(return world)
+))))
+
+(let world (Apply writeRes world list1))
+(let world (Apply writeRes world list2))
+(let world (Apply writeRes world list12))
+(return world)
+)
+
diff --git a/yql/essentials/tests/s-expressions/suites/Join/EmptyLeftJoin.yql b/yql/essentials/tests/s-expressions/suites/Join/EmptyLeftJoin.yql
new file mode 100644
index 0000000000..78c4cbd20f
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/EmptyLeftJoin.yql
@@ -0,0 +1,23 @@
+(
+(let mr_source (DataSource 'yt 'plato))
+(let list1 (AsList
+ (AsStruct '('key1 (Just (String '1))) '('value1 (Just (String 'A))))
+))
+
+(let list2 (AsList
+ (AsStruct '('key2 (String '1)) '('value2 (Nothing (OptionalType (DataType 'String)))))
+))
+
+(let keyExtractor (lambda '(x) (Member x 'key2)))
+(let payloadExtractor (lambda '(x) x))
+
+(let dictOne (ToDict list2 keyExtractor payloadExtractor '('Hashed 'One 'Compact)))
+(let dictMany (ToDict list2 keyExtractor payloadExtractor '('Hashed 'Many 'Compact)))
+(let joinLeft (MapJoinCore (Iterator list1 (DependsOn (String 'Left))) dictMany 'Left '('key1) '('key2) '('key1 'a.key1) '('key2 'b.key2 'value2 'b.value2) '() '()))
+
+(let res_sink (DataSink 'result))
+(let world (Write! world res_sink (Key) (Collect joinLeft) '('('type))))
+
+(let world (Commit! world res_sink))
+(return world)
+)
diff --git a/yql/essentials/tests/s-expressions/suites/Join/InputSelf.txt b/yql/essentials/tests/s-expressions/suites/Join/InputSelf.txt
new file mode 100644
index 0000000000..8ed0317c19
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/InputSelf.txt
@@ -0,0 +1,8 @@
+{"key"="075";"subkey"=".";"value"="abc"};
+{"key"="911";"subkey"=".";"value"="kkk"};
+{"key"="023";"subkey"=".";"value"="075"};
+{"key"="527";"subkey"=".";"value"="bbb"};
+{"key"="037";"subkey"=".";"value"="ddd"};
+{"key"="761";"subkey"=".";"value"="023"};
+{"key"="200";"subkey"=".";"value"="qqq"};
+{"key"="150";"subkey"=".";"value"="zzz"};
diff --git a/yql/essentials/tests/s-expressions/suites/Join/InputSelf.txt.attr b/yql/essentials/tests/s-expressions/suites/Join/InputSelf.txt.attr
new file mode 100644
index 0000000000..b6100e5fd0
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/InputSelf.txt.attr
@@ -0,0 +1,30 @@
+{
+ "_yql_row_spec" = {
+ "Type" = [
+ "StructType";
+ [
+ [
+ "key";
+ [
+ "DataType";
+ "String"
+ ]
+ ];
+ [
+ "subkey";
+ [
+ "DataType";
+ "String"
+ ]
+ ];
+ [
+ "value";
+ [
+ "DataType";
+ "String"
+ ]
+ ]
+ ]
+ ]
+ }
+} \ No newline at end of file
diff --git a/yql/essentials/tests/s-expressions/suites/Join/JoinInMem.yql b/yql/essentials/tests/s-expressions/suites/Join/JoinInMem.yql
new file mode 100644
index 0000000000..aecec9aba2
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/JoinInMem.yql
@@ -0,0 +1,34 @@
+(
+(let config (DataSource 'config))
+(let world (Configure! world config 'PureDataSource 'yt))
+
+(let list1 (AsList
+ '((Int32 '1) (String 'A))
+ '((Int32 '7) (String 'B))
+ '((Int32 '4) (String 'C))
+ '((Int32 '4) (String 'D))
+))
+
+(let list2 (AsList
+ '((Int32 '9) (String 'Z))
+ '((Int32 '4) (String 'Y))
+ '((Int32 '3) (String 'X))
+ '((Int32 '4) (String 'W))
+ '((Int32 '8) (String 'V))
+))
+
+(let keyExtractor (lambda '(item) (Nth item '0)))
+(let joinInner (Join list1 list2 keyExtractor keyExtractor 'Inner))
+(let joinLeft (Join list1 list2 keyExtractor keyExtractor 'Left))
+(let joinRight (Join list1 list2 keyExtractor keyExtractor 'Right))
+(let joinFull (Join list1 list2 keyExtractor keyExtractor 'Full))
+
+(let res_sink (DataSink 'result))
+(let world (Write! world res_sink (Key) joinInner '()))
+(let world (Write! world res_sink (Key) joinLeft '()))
+(let world (Write! world res_sink (Key) joinRight '()))
+(let world (Write! world res_sink (Key) joinFull '()))
+
+(let world (Commit! world res_sink))
+(return world)
+)
diff --git a/yql/essentials/tests/s-expressions/suites/Join/JoinTypes.yql b/yql/essentials/tests/s-expressions/suites/Join/JoinTypes.yql
new file mode 100644
index 0000000000..dff7b4a5f8
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/JoinTypes.yql
@@ -0,0 +1,30 @@
+(
+(let mr_source (DataSource 'yt 'plato))
+(let x (Read! world mr_source
+ (Key '('table (String 'Input1)))
+ '('key 'subkey 'value) '()))
+(let world (Left! x))
+(let table1 (Right! x))
+
+(let table2 (Map table1 (lambda '(item) (block '(
+ (return (AsStruct
+ '('value (Member item 'key))
+ '('subkey (Member item 'subkey))
+ '('key (Member item 'value)))))
+))))
+
+(let keyExtractor (lambda '(item) (Member item 'key)))
+(let joinInner (Join table1 table2 keyExtractor keyExtractor 'Inner))
+(let joinLeft (Join table1 table2 keyExtractor keyExtractor 'Left))
+(let joinRight (Join table1 table2 keyExtractor keyExtractor 'Right))
+(let joinFull (Join table1 table2 keyExtractor keyExtractor 'Full))
+
+(let res_sink (DataSink 'result))
+(let world (Write! world res_sink (Key) (FormatType (TypeOf joinInner)) '()))
+(let world (Write! world res_sink (Key) (FormatType (TypeOf joinLeft)) '()))
+(let world (Write! world res_sink (Key) (FormatType (TypeOf joinRight)) '()))
+(let world (Write! world res_sink (Key) (FormatType (TypeOf joinFull)) '()))
+
+(let world (Commit! world res_sink))
+(return world)
+)
diff --git a/yql/essentials/tests/s-expressions/suites/Join/MapJoinCore.yql b/yql/essentials/tests/s-expressions/suites/Join/MapJoinCore.yql
new file mode 100644
index 0000000000..3111328024
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/MapJoinCore.yql
@@ -0,0 +1,41 @@
+(
+(let mr_source (DataSource 'yt 'plato))
+(let list1 (AsList
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (String 'A)))
+ (AsStruct '('key1 (Just (Int32 '7))) '('value1 (String 'B)))
+ (AsStruct '('key1 (Nothing (OptionalType (DataType 'Int32)))) '('value1 (String 'C)))
+ (AsStruct '('key1 (Just (Int32 '4))) '('value1 (String 'D)))
+ (AsStruct '('key1 (Just (Int32 '4))) '('value1 (String 'E)))
+))
+
+(let list2 (AsList
+ (AsStruct '('key2 (Int64 '9)) '('value2 (String 'Z)))
+ (AsStruct '('key2 (Int64 '4)) '('value2 (String 'Y)))
+ (AsStruct '('key2 (Int64 '3)) '('value2 (String 'X)))
+ (AsStruct '('key2 (Int64 '4)) '('value2 (String 'W)))
+ (AsStruct '('key2 (Int64 '8)) '('value2 (String 'V)))
+))
+
+(let keyExtractor (lambda '(x) (Member x 'key2)))
+(let payloadExtractor (lambda '(x) x))
+
+(let dictOne (ToDict list2 keyExtractor payloadExtractor '('Hashed 'One 'Compact)))
+(let dictMany (ToDict list2 keyExtractor payloadExtractor '('Hashed 'Many 'Compact)))
+(let joinLeftSemi (MapJoinCore (Iterator list1 (DependsOn (String 'LeftSemi))) dictOne 'LeftSemi '('key1) '('key2) '('key1 'a.key1 'value1 'a.value1) '() '() '()))
+(let joinLeftOnly (MapJoinCore (Iterator list1 (DependsOn (String 'LeftOnly))) dictOne 'LeftOnly '('key1) '('key2) '('key1 'a.key1 'key1 'another_key 'key1 'yet_another_key) '() '() '()))
+(let joinInnerUnique (MapJoinCore (Iterator list1 (DependsOn (String 'InnerU))) dictOne 'Inner '('key1) '('key2) '('key1 'a.key1 'value1 'a.value1) '('value2 'b.value2) '() '()))
+(let joinLeftUnique (MapJoinCore (Iterator list1 (DependsOn (String 'LeftU))) dictOne 'Left '('key1) '('key2) '('key1 'a.key1) '('key2 'b.key2 'value2 'b.value2) '() '()))
+(let joinInner (MapJoinCore (Iterator list1 (DependsOn (String 'Inner))) dictMany 'Inner '('key1) '('key2) '('key1 'a.key1 'value1 'a.value1) '('key2 'b.key2) '() '()))
+(let joinLeft (MapJoinCore (Iterator list1 (DependsOn (String 'Left))) dictMany 'Left '('key1) '('key2) '('key1 'a.key1) '('key2 'b.key2 'value2 'b.value2) '() '()))
+
+(let res_sink (DataSink 'result))
+(let world (Write! world res_sink (Key) (Collect joinLeftSemi) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftOnly) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinInnerUnique) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftUnique) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinInner) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeft) '('('type))))
+
+(let world (Commit! world res_sink))
+(return world)
+)
diff --git a/yql/essentials/tests/s-expressions/suites/Join/MapJoinCoreOnStrings.yql b/yql/essentials/tests/s-expressions/suites/Join/MapJoinCoreOnStrings.yql
new file mode 100644
index 0000000000..663bde4955
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/MapJoinCoreOnStrings.yql
@@ -0,0 +1,41 @@
+(
+(let mr_source (DataSource 'yt 'plato))
+(let list1 (AsList
+ (AsStruct '('key1 (Just (String '0123456789QWRTYUIOP1))) '('value1 (String 'A)))
+ (AsStruct '('key1 (Just (String '0123456789QWRTYUIOP7))) '('value1 (String 'B)))
+ (AsStruct '('key1 (Nothing (OptionalType (DataType 'String)))) '('value1 (String 'C)))
+ (AsStruct '('key1 (Just (String '0123456789QWRTYUIOP4))) '('value1 (String 'D)))
+ (AsStruct '('key1 (Just (String '0123456789QWRTYUIOP4))) '('value1 (String 'E)))
+))
+
+(let list2 (AsList
+ (AsStruct '('key2 (String '0123456789QWRTYUIOP9)) '('value2 (String 'Z)))
+ (AsStruct '('key2 (String '0123456789QWRTYUIOP4)) '('value2 (String 'Y)))
+ (AsStruct '('key2 (String '0123456789QWRTYUIOP3)) '('value2 (String 'X)))
+ (AsStruct '('key2 (String '0123456789QWRTYUIOP4)) '('value2 (String 'W)))
+ (AsStruct '('key2 (String '0123456789QWRTYUIOP8)) '('value2 (String 'V)))
+))
+
+(let keyExtractor (lambda '(x) (Member x 'key2)))
+(let payloadExtractor (lambda '(x) x))
+
+(let dictOne (ToDict list2 keyExtractor payloadExtractor '('Hashed 'One 'Compact)))
+(let dictMany (ToDict list2 keyExtractor payloadExtractor '('Hashed 'Many 'Compact)))
+(let joinLeftSemi (MapJoinCore (Iterator list1 (DependsOn (String 'LeftSemi))) dictOne 'LeftSemi '('key1) '('key2) '('key1 'a.key1 'value1 'a.value1) '() '() '()))
+(let joinLeftOnly (MapJoinCore (Iterator list1 (DependsOn (String 'LeftOnly))) dictOne 'LeftOnly '('key1) '('key2) '('key1 'a.key1 'key1 'another_key 'key1 'yet_another_key) '() '() '()))
+(let joinInnerUnique (MapJoinCore (Iterator list1 (DependsOn (String 'InnerU))) dictOne 'Inner '('key1) '('key2) '('key1 'a.key1 'value1 'a.value1) '('value2 'b.value2) '() '()))
+(let joinLeftUnique (MapJoinCore (Iterator list1 (DependsOn (String 'LeftU))) dictOne 'Left '('key1) '('key2) '('key1 'a.key1) '('key2 'b.key2 'value2 'b.value2) '() '()))
+(let joinInner (MapJoinCore (Iterator list1 (DependsOn (String 'Inner))) dictMany 'Inner '('key1) '('key2) '('key1 'a.key1 'value1 'a.value1) '('key2 'b.key2) '() '()))
+(let joinLeft (MapJoinCore (Iterator list1 (DependsOn (String 'Left))) dictMany 'Left '('key1) '('key2) '('key1 'a.key1) '('key2 'b.key2 'value2 'b.value2) '() '()))
+
+(let res_sink (DataSink 'result))
+(let world (Write! world res_sink (Key) (Collect joinLeftSemi) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftOnly) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinInnerUnique) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftUnique) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinInner) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeft) '('('type))))
+
+(let world (Commit! world res_sink))
+(return world)
+)
diff --git a/yql/essentials/tests/s-expressions/suites/Join/MapJoinCoreOnStrings_Flow.yql b/yql/essentials/tests/s-expressions/suites/Join/MapJoinCoreOnStrings_Flow.yql
new file mode 100644
index 0000000000..9c1ef15dfe
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/MapJoinCoreOnStrings_Flow.yql
@@ -0,0 +1,41 @@
+(
+(let mr_source (DataSource 'yt 'plato))
+(let list1 (AsList
+ (AsStruct '('key1 (Just (String '0123456789QWRTYUIOP1))) '('value1 (String 'A)))
+ (AsStruct '('key1 (Just (String '0123456789QWRTYUIOP7))) '('value1 (String 'B)))
+ (AsStruct '('key1 (Nothing (OptionalType (DataType 'String)))) '('value1 (String 'C)))
+ (AsStruct '('key1 (Just (String '0123456789QWRTYUIOP4))) '('value1 (String 'D)))
+ (AsStruct '('key1 (Just (String '0123456789QWRTYUIOP4))) '('value1 (String 'E)))
+))
+
+(let list2 (AsList
+ (AsStruct '('key2 (String '0123456789QWRTYUIOP9)) '('value2 (String 'Z)))
+ (AsStruct '('key2 (String '0123456789QWRTYUIOP4)) '('value2 (String 'Y)))
+ (AsStruct '('key2 (String '0123456789QWRTYUIOP3)) '('value2 (String 'X)))
+ (AsStruct '('key2 (String '0123456789QWRTYUIOP4)) '('value2 (String 'W)))
+ (AsStruct '('key2 (String '0123456789QWRTYUIOP8)) '('value2 (String 'V)))
+))
+
+(let keyExtractor (lambda '(x) (Member x 'key2)))
+(let payloadExtractor (lambda '(x) x))
+
+(let dictOne (ToDict list2 keyExtractor payloadExtractor '('Hashed 'One 'Compact)))
+(let dictMany (ToDict list2 keyExtractor payloadExtractor '('Hashed 'Many 'Compact)))
+(let joinLeftSemi (MapJoinCore (ToFlow list1) dictOne 'LeftSemi '('key1) '('key2) '('key1 'a.key1 'value1 'a.value1) '() '() '()))
+(let joinLeftOnly (MapJoinCore (ToFlow list1) dictOne 'LeftOnly '('key1) '('key2) '('key1 'a.key1 'key1 'another_key 'key1 'yet_another_key) '() '() '()))
+(let joinInnerUnique (MapJoinCore (ToFlow list1) dictOne 'Inner '('key1) '('key2) '('key1 'a.key1 'value1 'a.value1) '('value2 'b.value2) '() '()))
+(let joinLeftUnique (MapJoinCore (ToFlow list1) dictOne 'Left '('key1) '('key2) '('key1 'a.key1) '('key2 'b.key2 'value2 'b.value2) '() '()))
+(let joinInner (MapJoinCore (ToFlow list1) dictMany 'Inner '('key1) '('key2) '('key1 'a.key1 'value1 'a.value1) '('key2 'b.key2) '() '()))
+(let joinLeft (MapJoinCore (ToFlow list1) dictMany 'Left '('key1) '('key2) '('key1 'a.key1) '('key2 'b.key2 'value2 'b.value2) '() '()))
+
+(let res_sink (DataSink 'result))
+(let world (Write! world res_sink (Key) (Collect joinLeftSemi) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftOnly) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinInnerUnique) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftUnique) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinInner) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeft) '('('type))))
+
+(let world (Commit! world res_sink))
+(return world)
+)
diff --git a/yql/essentials/tests/s-expressions/suites/Join/MapJoinCore_Flow.yql b/yql/essentials/tests/s-expressions/suites/Join/MapJoinCore_Flow.yql
new file mode 100644
index 0000000000..61b150f5f8
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/MapJoinCore_Flow.yql
@@ -0,0 +1,41 @@
+(
+(let mr_source (DataSource 'yt 'plato))
+(let list1 (AsList
+ (AsStruct '('key1 (Just (Int32 '1))) '('value1 (String 'A)))
+ (AsStruct '('key1 (Just (Int32 '7))) '('value1 (String 'B)))
+ (AsStruct '('key1 (Nothing (OptionalType (DataType 'Int32)))) '('value1 (String 'C)))
+ (AsStruct '('key1 (Just (Int32 '4))) '('value1 (String 'D)))
+ (AsStruct '('key1 (Just (Int32 '4))) '('value1 (String 'E)))
+))
+
+(let list2 (AsList
+ (AsStruct '('key2 (Int64 '9)) '('value2 (String 'Z)))
+ (AsStruct '('key2 (Int64 '4)) '('value2 (String 'Y)))
+ (AsStruct '('key2 (Int64 '3)) '('value2 (String 'X)))
+ (AsStruct '('key2 (Int64 '4)) '('value2 (String 'W)))
+ (AsStruct '('key2 (Int64 '8)) '('value2 (String 'V)))
+))
+
+(let keyExtractor (lambda '(x) (Member x 'key2)))
+(let payloadExtractor (lambda '(x) x))
+
+(let dictOne (ToDict list2 keyExtractor payloadExtractor '('Hashed 'One 'Compact)))
+(let dictMany (ToDict list2 keyExtractor payloadExtractor '('Hashed 'Many 'Compact)))
+(let joinLeftSemi (MapJoinCore (ToFlow list1) dictOne 'LeftSemi '('key1) '('key2) '('key1 'a.key1 'value1 'a.value1) '() '() '()))
+(let joinLeftOnly (MapJoinCore (ToFlow list1) dictOne 'LeftOnly '('key1) '('key2) '('key1 'a.key1 'key1 'another_key 'key1 'yet_another_key) '() '() '()))
+(let joinInnerUnique (MapJoinCore (ToFlow list1) dictOne 'Inner '('key1) '('key2) '('key1 'a.key1 'value1 'a.value1) '('value2 'b.value2) '() '()))
+(let joinLeftUnique (MapJoinCore (ToFlow list1) dictOne 'Left '('key1) '('key2) '('key1 'a.key1) '('key2 'b.key2 'value2 'b.value2) '() '()))
+(let joinInner (MapJoinCore (ToFlow list1) dictMany 'Inner '('key1) '('key2) '('key1 'a.key1 'value1 'a.value1) '('key2 'b.key2) '() '()))
+(let joinLeft (MapJoinCore (ToFlow list1) dictMany 'Left '('key1) '('key2) '('key1 'a.key1) '('key2 'b.key2 'value2 'b.value2) '() '()))
+
+(let res_sink (DataSink 'result))
+(let world (Write! world res_sink (Key) (Collect joinLeftSemi) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftOnly) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinInnerUnique) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftUnique) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinInner) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeft) '('('type))))
+
+(let world (Commit! world res_sink))
+(return world)
+)
diff --git a/yql/essentials/tests/s-expressions/suites/Join/MapJoinCore_FlowOfTuples.yql b/yql/essentials/tests/s-expressions/suites/Join/MapJoinCore_FlowOfTuples.yql
new file mode 100644
index 0000000000..dbd0d1712d
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/MapJoinCore_FlowOfTuples.yql
@@ -0,0 +1,41 @@
+(
+(let mr_source (DataSource 'yt 'plato))
+(let list1 (AsList
+ '((Just (Int32 '1)) (String 'A))
+ '((Just (Int32 '7)) (String 'B))
+ '((Nothing (OptionalType (DataType 'Int32))) (String 'C))
+ '((Just (Int32 '4)) (String 'D))
+ '((Just (Int32 '4)) (String 'E))
+))
+
+(let list2 (AsList
+ '((Int64 '9) (String 'Z))
+ '((Int64 '4) (String 'Y))
+ '((Int64 '3) (String 'X))
+ '((Int64 '4) (String 'W))
+ '((Int64 '8) (String 'V))
+))
+
+(let keyExtractor (lambda '(x) (Nth x '0)))
+(let payloadExtractor (lambda '(x) x))
+
+(let dictOne (ToDict list2 keyExtractor payloadExtractor '('Hashed 'One 'Compact)))
+(let dictMany (ToDict list2 keyExtractor payloadExtractor '('Hashed 'Many 'Compact)))
+(let joinLeftSemi (MapJoinCore (ToFlow list1) dictOne 'LeftSemi '('0) '('0) '('0 '0 '1 '1) '() '() '()))
+(let joinLeftOnly (MapJoinCore (ToFlow list1) dictOne 'LeftOnly '('0) '('0) '('0 '0 '0 '1 '0 '2) '() '() '()))
+(let joinInnerUnique (MapJoinCore (ToFlow list1) dictOne 'Inner '('0) '('0) '('0 '2 '1 '1) '('1 '0) '() '()))
+(let joinLeftUnique (MapJoinCore (ToFlow list1) dictOne 'Left '('0) '('0) '('0 '0) '('0 '1 '1 '2) '() '()))
+(let joinInner (MapJoinCore (ToFlow list1) dictMany 'Inner '('0) '('0) '('0 '0 '1 '1) '('0 '2) '() '()))
+(let joinLeft (MapJoinCore (ToFlow list1) dictMany 'Left '('0) '('0) '('0 '2) '('0 '1 '1 '0) '() '()))
+
+(let res_sink (DataSink 'result))
+(let world (Write! world res_sink (Key) (Collect joinLeftSemi) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftOnly) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinInnerUnique) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeftUnique) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinInner) '('('type))))
+(let world (Write! world res_sink (Key) (Collect joinLeft) '('('type))))
+
+(let world (Commit! world res_sink))
+(return world)
+)
diff --git a/yql/essentials/tests/s-expressions/suites/Join/default.cfg b/yql/essentials/tests/s-expressions/suites/Join/default.cfg
new file mode 100644
index 0000000000..db91b7fd18
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/default.cfg
@@ -0,0 +1,5 @@
+res result.txt
+in InputSelf InputSelf.txt
+in Input1 input1.txt
+in Input2 input2.txt
+in Input3 input3.txt
diff --git a/yql/essentials/tests/s-expressions/suites/Join/input1.txt b/yql/essentials/tests/s-expressions/suites/Join/input1.txt
new file mode 100644
index 0000000000..f53757c309
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/input1.txt
@@ -0,0 +1,4 @@
+{"key"="075";"subkey"="1";"value"="abc"};
+{"key"="800";"subkey"="1";"value"="ddd"};
+{"key"="020";"subkey"="1";"value"="q"};
+{"key"="150";"subkey"="1";"value"="qzz"};
diff --git a/yql/essentials/tests/s-expressions/suites/Join/input1.txt.attr b/yql/essentials/tests/s-expressions/suites/Join/input1.txt.attr
new file mode 100644
index 0000000000..b6100e5fd0
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/input1.txt.attr
@@ -0,0 +1,30 @@
+{
+ "_yql_row_spec" = {
+ "Type" = [
+ "StructType";
+ [
+ [
+ "key";
+ [
+ "DataType";
+ "String"
+ ]
+ ];
+ [
+ "subkey";
+ [
+ "DataType";
+ "String"
+ ]
+ ];
+ [
+ "value";
+ [
+ "DataType";
+ "String"
+ ]
+ ]
+ ]
+ ]
+ }
+} \ No newline at end of file
diff --git a/yql/essentials/tests/s-expressions/suites/Join/input2.txt b/yql/essentials/tests/s-expressions/suites/Join/input2.txt
new file mode 100644
index 0000000000..07af3b4647
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/input2.txt
@@ -0,0 +1,4 @@
+{"key"="075";"subkey"="2";"value"="abc"};
+{"key"="800";"subkey"="2";"value"="ddd"};
+{"key"="020";"subkey"="2";"value"="q"};
+{"key"="150";"subkey"="2";"value"="qzz"};
diff --git a/yql/essentials/tests/s-expressions/suites/Join/input2.txt.attr b/yql/essentials/tests/s-expressions/suites/Join/input2.txt.attr
new file mode 100644
index 0000000000..b6100e5fd0
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/input2.txt.attr
@@ -0,0 +1,30 @@
+{
+ "_yql_row_spec" = {
+ "Type" = [
+ "StructType";
+ [
+ [
+ "key";
+ [
+ "DataType";
+ "String"
+ ]
+ ];
+ [
+ "subkey";
+ [
+ "DataType";
+ "String"
+ ]
+ ];
+ [
+ "value";
+ [
+ "DataType";
+ "String"
+ ]
+ ]
+ ]
+ ]
+ }
+} \ No newline at end of file
diff --git a/yql/essentials/tests/s-expressions/suites/Join/input3.txt b/yql/essentials/tests/s-expressions/suites/Join/input3.txt
new file mode 100644
index 0000000000..1dc1bcc60b
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/input3.txt
@@ -0,0 +1,4 @@
+{"key"="075";"subkey"="3";"value"="abd"};
+{"key"="800";"subkey"="3";"value"="ddd"};
+{"key"="021";"subkey"="3";"value"="q"};
+{"key"="151";"subkey"="3";"value"="qzz"};
diff --git a/yql/essentials/tests/s-expressions/suites/Join/input3.txt.attr b/yql/essentials/tests/s-expressions/suites/Join/input3.txt.attr
new file mode 100644
index 0000000000..b6100e5fd0
--- /dev/null
+++ b/yql/essentials/tests/s-expressions/suites/Join/input3.txt.attr
@@ -0,0 +1,30 @@
+{
+ "_yql_row_spec" = {
+ "Type" = [
+ "StructType";
+ [
+ [
+ "key";
+ [
+ "DataType";
+ "String"
+ ]
+ ];
+ [
+ "subkey";
+ [
+ "DataType";
+ "String"
+ ]
+ ];
+ [
+ "value";
+ [
+ "DataType";
+ "String"
+ ]
+ ]
+ ]
+ ]
+ }
+} \ No newline at end of file