mkql_wide_chopper_ut.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. #include "mkql_computation_node_ut.h"
  2. #include <yql/essentials/minikql/mkql_runtime_version.h>
  3. namespace NKikimr {
  4. namespace NMiniKQL {
  5. #if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
  6. Y_UNIT_TEST_SUITE(TMiniKQLWideChopperTest) {
  7. Y_UNIT_TEST_LLVM(TestConcatKeyToItems) {
  8. TSetup<LLVM> setup;
  9. TProgramBuilder& pb = *setup.PgmBuilder;
  10. const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
  11. const auto tupleType = pb.NewTupleType({dataType, dataType});
  12. const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
  13. const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
  14. const auto longKeyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key one");
  15. const auto longKeyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key two");
  16. const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 1");
  17. const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 2");
  18. const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 3");
  19. const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 4");
  20. const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 5");
  21. const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 6");
  22. const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 7");
  23. const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 8");
  24. const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long value 9");
  25. const auto data1 = pb.NewTuple(tupleType, {keyOne, value1});
  26. const auto data2 = pb.NewTuple(tupleType, {keyTwo, value2});
  27. const auto data3 = pb.NewTuple(tupleType, {keyTwo, value3});
  28. const auto data4 = pb.NewTuple(tupleType, {longKeyOne, value4});
  29. const auto data5 = pb.NewTuple(tupleType, {longKeyTwo, value5});
  30. const auto data6 = pb.NewTuple(tupleType, {longKeyTwo, value6});
  31. const auto data7 = pb.NewTuple(tupleType, {longKeyTwo, value7});
  32. const auto data8 = pb.NewTuple(tupleType, {longKeyTwo, value8});
  33. const auto data9 = pb.NewTuple(tupleType, {longKeyTwo, value9});
  34. const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
  35. const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChopper(pb.ExpandMap(pb.ToFlow(list),
  36. [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
  37. [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
  38. return {pb.Substring(items.front(), pb.Sub(pb.Size(items.front()), pb.NewDataLiteral<ui32>(4U)), pb.NewDataLiteral<ui32>(4U))};
  39. },
  40. [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) {
  41. return pb.AggrNotEquals(keys.front(), items.front());
  42. },
  43. [&](TRuntimeNode::TList keys, TRuntimeNode input) {
  44. return pb.WideMap(input, [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
  45. return {pb.AggrConcat(items.back(), keys.front())};
  46. });
  47. }),
  48. [&](TRuntimeNode::TList items) { return items.front(); }
  49. ));
  50. const auto graph = setup.BuildGraph(pgmReturn);
  51. const auto iterator = graph->GetValue().GetListIterator();
  52. NUdf::TUnboxedValue item;
  53. UNIT_ASSERT(iterator.Next(item));
  54. UNBOXED_VALUE_STR_EQUAL(item, "very long value 1 one");
  55. UNIT_ASSERT(iterator.Next(item));
  56. UNBOXED_VALUE_STR_EQUAL(item, "very long value 2 two");
  57. UNIT_ASSERT(iterator.Next(item));
  58. UNBOXED_VALUE_STR_EQUAL(item, "very long value 3 two");
  59. UNIT_ASSERT(iterator.Next(item));
  60. UNBOXED_VALUE_STR_EQUAL(item, "very long value 4 one");
  61. UNIT_ASSERT(iterator.Next(item));
  62. UNBOXED_VALUE_STR_EQUAL(item, "very long value 5 two");
  63. UNIT_ASSERT(iterator.Next(item));
  64. UNBOXED_VALUE_STR_EQUAL(item, "very long value 6 two");
  65. UNIT_ASSERT(iterator.Next(item));
  66. UNBOXED_VALUE_STR_EQUAL(item, "very long value 7 two");
  67. UNIT_ASSERT(iterator.Next(item));
  68. UNBOXED_VALUE_STR_EQUAL(item, "very long value 8 two");
  69. UNIT_ASSERT(iterator.Next(item));
  70. UNBOXED_VALUE_STR_EQUAL(item, "very long value 9 two");
  71. UNIT_ASSERT(!iterator.Next(item));
  72. UNIT_ASSERT(!iterator.Next(item));
  73. }
  74. Y_UNIT_TEST_LLVM(TestCollectKeysOnly) {
  75. TSetup<LLVM> setup;
  76. TProgramBuilder& pb = *setup.PgmBuilder;
  77. const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
  78. const auto tupleType = pb.NewTupleType({dataType, dataType});
  79. const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
  80. const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
  81. const auto longKeyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key one");
  82. const auto longKeyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key two");
  83. const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
  84. const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
  85. const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
  86. const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
  87. const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
  88. const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 6");
  89. const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 7");
  90. const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 8");
  91. const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 9");
  92. const auto data1 = pb.NewTuple(tupleType, {keyOne, value1});
  93. const auto data2 = pb.NewTuple(tupleType, {keyTwo, value2});
  94. const auto data3 = pb.NewTuple(tupleType, {keyTwo, value3});
  95. const auto data4 = pb.NewTuple(tupleType, {longKeyOne, value4});
  96. const auto data5 = pb.NewTuple(tupleType, {longKeyTwo, value5});
  97. const auto data6 = pb.NewTuple(tupleType, {longKeyTwo, value6});
  98. const auto data7 = pb.NewTuple(tupleType, {longKeyTwo, value7});
  99. const auto data8 = pb.NewTuple(tupleType, {longKeyTwo, value8});
  100. const auto data9 = pb.NewTuple(tupleType, {longKeyTwo, value9});
  101. const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
  102. const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChopper(pb.ExpandMap(pb.ToFlow(list),
  103. [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
  104. [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
  105. return {items.front()};
  106. },
  107. [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) {
  108. return pb.AggrNotEquals(keys.front(), items.front());
  109. },
  110. [&](TRuntimeNode::TList keys, TRuntimeNode) {
  111. return pb.ExpandMap(pb.ToFlow(pb.NewOptional(keys.front())), [&](TRuntimeNode item) -> TRuntimeNode::TList {
  112. return {item};
  113. } );
  114. }),
  115. [&](TRuntimeNode::TList items) { return items.front(); }
  116. ));
  117. const auto graph = setup.BuildGraph(pgmReturn);
  118. const auto iterator = graph->GetValue().GetListIterator();
  119. NUdf::TUnboxedValue item;
  120. UNIT_ASSERT(iterator.Next(item));
  121. UNBOXED_VALUE_STR_EQUAL(item, "key one");
  122. UNIT_ASSERT(iterator.Next(item));
  123. UNBOXED_VALUE_STR_EQUAL(item, "key two");
  124. UNIT_ASSERT(iterator.Next(item));
  125. UNBOXED_VALUE_STR_EQUAL(item, "very long key one");
  126. UNIT_ASSERT(iterator.Next(item));
  127. UNBOXED_VALUE_STR_EQUAL(item, "very long key two");
  128. UNIT_ASSERT(!iterator.Next(item));
  129. UNIT_ASSERT(!iterator.Next(item));
  130. }
  131. Y_UNIT_TEST_LLVM(TestGetPart) {
  132. TSetup<LLVM> setup;
  133. TProgramBuilder& pb = *setup.PgmBuilder;
  134. const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
  135. const auto tupleType = pb.NewTupleType({dataType, dataType});
  136. const auto keyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("key one");
  137. const auto keyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("key two");
  138. const auto longKeyOne = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key one");
  139. const auto longKeyTwo = pb.NewDataLiteral<NUdf::EDataSlot::String>("very long key two");
  140. const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
  141. const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
  142. const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
  143. const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
  144. const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
  145. const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 6");
  146. const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 7");
  147. const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 8");
  148. const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 9");
  149. const auto data1 = pb.NewTuple(tupleType, {keyOne, value1});
  150. const auto data2 = pb.NewTuple(tupleType, {keyTwo, value2});
  151. const auto data3 = pb.NewTuple(tupleType, {keyTwo, value3});
  152. const auto data4 = pb.NewTuple(tupleType, {longKeyOne, value4});
  153. const auto data5 = pb.NewTuple(tupleType, {longKeyOne, value5});
  154. const auto data6 = pb.NewTuple(tupleType, {longKeyOne, value6});
  155. const auto data7 = pb.NewTuple(tupleType, {longKeyOne, value7});
  156. const auto data8 = pb.NewTuple(tupleType, {longKeyOne, value8});
  157. const auto data9 = pb.NewTuple(tupleType, {longKeyTwo, value9});
  158. const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
  159. const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChopper(pb.ExpandMap(pb.ToFlow(list),
  160. [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U)}; }),
  161. [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
  162. return {items.front()};
  163. },
  164. [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) {
  165. return pb.AggrNotEquals(keys.front(), items.front());
  166. },
  167. [&](TRuntimeNode::TList, TRuntimeNode input) {
  168. return pb.Take(pb.Skip(input, pb.NewDataLiteral<ui64>(1ULL)), pb.NewDataLiteral<ui64>(3ULL));
  169. }),
  170. [&](TRuntimeNode::TList items) { return items.back(); }
  171. ));
  172. const auto graph = setup.BuildGraph(pgmReturn);
  173. const auto iterator = graph->GetValue().GetListIterator();
  174. NUdf::TUnboxedValue item;
  175. UNIT_ASSERT(iterator.Next(item));
  176. UNBOXED_VALUE_STR_EQUAL(item, "value 3");
  177. UNIT_ASSERT(iterator.Next(item));
  178. UNBOXED_VALUE_STR_EQUAL(item, "value 5");
  179. UNIT_ASSERT(iterator.Next(item));
  180. UNBOXED_VALUE_STR_EQUAL(item, "value 6");
  181. UNIT_ASSERT(iterator.Next(item));
  182. UNBOXED_VALUE_STR_EQUAL(item, "value 7");
  183. UNIT_ASSERT(!iterator.Next(item));
  184. UNIT_ASSERT(!iterator.Next(item));
  185. }
  186. Y_UNIT_TEST_LLVM(TestSwitchByBoolFieldAndDontUseKey) {
  187. TSetup<LLVM> setup;
  188. TProgramBuilder& pb = *setup.PgmBuilder;
  189. const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
  190. const auto boolType = pb.NewDataType(NUdf::TDataType<bool>::Id);
  191. const auto tupleType = pb.NewTupleType({pb.NewOptionalType(dataType), dataType, boolType});
  192. const auto key0 = pb.NewEmptyOptional(pb.NewOptionalType(dataType));
  193. const auto key1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("one"));
  194. const auto key2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("two"));
  195. const auto trueVal = pb.NewDataLiteral<bool>(true);
  196. const auto falseVal = pb.NewDataLiteral<bool>(false);
  197. const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
  198. const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
  199. const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
  200. const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
  201. const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
  202. const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 6");
  203. const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 7");
  204. const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 8");
  205. const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 9");
  206. const auto data1 = pb.NewTuple(tupleType, {key0, value1, trueVal});
  207. const auto data2 = pb.NewTuple(tupleType, {key1, value2, falseVal});
  208. const auto data3 = pb.NewTuple(tupleType, {key2, value3, falseVal});
  209. const auto data4 = pb.NewTuple(tupleType, {key0, value4, trueVal});
  210. const auto data5 = pb.NewTuple(tupleType, {key1, value5, falseVal});
  211. const auto data6 = pb.NewTuple(tupleType, {key2, value6, falseVal});
  212. const auto data7 = pb.NewTuple(tupleType, {key0, value7, falseVal});
  213. const auto data8 = pb.NewTuple(tupleType, {key1, value8, falseVal});
  214. const auto data9 = pb.NewTuple(tupleType, {key2, value9, trueVal});
  215. const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
  216. const auto landmine = pb.NewDataLiteral<NUdf::EDataSlot::String>("ACHTUNG MINEN!");
  217. const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChopper(pb.ExpandMap(pb.ToFlow(list),
  218. [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
  219. [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
  220. return {pb.Unwrap(items.front(), landmine, __FILE__, __LINE__, 0)};
  221. },
  222. [&](TRuntimeNode::TList, TRuntimeNode::TList items) {
  223. return items.back();
  224. },
  225. [&](TRuntimeNode::TList, TRuntimeNode input) {
  226. return pb.Take(input, pb.NewDataLiteral<ui64>(2ULL));
  227. }),
  228. [&](TRuntimeNode::TList items) { return items[1U]; }
  229. ));
  230. const auto graph = setup.BuildGraph(pgmReturn);
  231. const auto iterator = graph->GetValue().GetListIterator();
  232. NUdf::TUnboxedValue item;
  233. UNIT_ASSERT(iterator.Next(item));
  234. UNBOXED_VALUE_STR_EQUAL(item, "value 1");
  235. UNIT_ASSERT(iterator.Next(item));
  236. UNBOXED_VALUE_STR_EQUAL(item, "value 2");
  237. UNIT_ASSERT(iterator.Next(item));
  238. UNBOXED_VALUE_STR_EQUAL(item, "value 4");
  239. UNIT_ASSERT(iterator.Next(item));
  240. UNBOXED_VALUE_STR_EQUAL(item, "value 5");
  241. UNIT_ASSERT(iterator.Next(item));
  242. UNBOXED_VALUE_STR_EQUAL(item, "value 9");
  243. UNIT_ASSERT(!iterator.Next(item));
  244. UNIT_ASSERT(!iterator.Next(item));
  245. }
  246. Y_UNIT_TEST_LLVM(TestCollectKeysIfPresent) {
  247. TSetup<LLVM> setup;
  248. TProgramBuilder& pb = *setup.PgmBuilder;
  249. const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
  250. const auto boolType = pb.NewDataType(NUdf::TDataType<bool>::Id);
  251. const auto tupleType = pb.NewTupleType({pb.NewOptionalType(dataType), dataType, boolType});
  252. const auto key0 = pb.NewEmptyOptional(pb.NewOptionalType(dataType));
  253. const auto key1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("one"));
  254. const auto key2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("two"));
  255. const auto trueVal = pb.NewDataLiteral<bool>(true);
  256. const auto falseVal = pb.NewDataLiteral<bool>(false);
  257. const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
  258. const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
  259. const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
  260. const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
  261. const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
  262. const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 6");
  263. const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 7");
  264. const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 8");
  265. const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 9");
  266. const auto data1 = pb.NewTuple(tupleType, {key1, value1, trueVal});
  267. const auto data2 = pb.NewTuple(tupleType, {key1, value2, falseVal});
  268. const auto data3 = pb.NewTuple(tupleType, {key1, value3, falseVal});
  269. const auto data4 = pb.NewTuple(tupleType, {key0, value4, trueVal});
  270. const auto data5 = pb.NewTuple(tupleType, {key0, value5, falseVal});
  271. const auto data6 = pb.NewTuple(tupleType, {key2, value6, falseVal});
  272. const auto data7 = pb.NewTuple(tupleType, {key0, value7, falseVal});
  273. const auto data8 = pb.NewTuple(tupleType, {key0, value8, falseVal});
  274. const auto data9 = pb.NewTuple(tupleType, {key0, value9, trueVal});
  275. const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
  276. const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChopper(pb.ExpandMap(pb.ToFlow(list),
  277. [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
  278. [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
  279. return {items.front()};
  280. },
  281. [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) {
  282. return pb.AggrNotEquals(keys.front(), items.front());
  283. },
  284. [&](TRuntimeNode::TList keys, TRuntimeNode part) {
  285. return pb.IfPresent(keys,
  286. [&](TRuntimeNode::TList keys) { return pb.ExpandMap(pb.ToFlow(pb.NewList(dataType, keys)), [&](TRuntimeNode item) -> TRuntimeNode::TList { return {item}; } ); },
  287. pb.WideMap(part, [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items[1U]}; } ));
  288. }),
  289. [&](TRuntimeNode::TList items) { return items.front(); }
  290. ));
  291. const auto graph = setup.BuildGraph(pgmReturn);
  292. const auto iterator = graph->GetValue().GetListIterator();
  293. NUdf::TUnboxedValue item;
  294. UNIT_ASSERT(iterator.Next(item));
  295. UNBOXED_VALUE_STR_EQUAL(item, "one");
  296. UNIT_ASSERT(iterator.Next(item));
  297. UNBOXED_VALUE_STR_EQUAL(item, "value 4");
  298. UNIT_ASSERT(iterator.Next(item));
  299. UNBOXED_VALUE_STR_EQUAL(item, "value 5");
  300. UNIT_ASSERT(iterator.Next(item));
  301. UNBOXED_VALUE_STR_EQUAL(item, "two");
  302. UNIT_ASSERT(iterator.Next(item));
  303. UNBOXED_VALUE_STR_EQUAL(item, "value 7");
  304. UNIT_ASSERT(iterator.Next(item));
  305. UNBOXED_VALUE_STR_EQUAL(item, "value 8");
  306. UNIT_ASSERT(iterator.Next(item));
  307. UNBOXED_VALUE_STR_EQUAL(item, "value 9");
  308. UNIT_ASSERT(!iterator.Next(item));
  309. UNIT_ASSERT(!iterator.Next(item));
  310. }
  311. Y_UNIT_TEST_LLVM(TestConditionalByKeyPart) {
  312. TSetup<LLVM> setup;
  313. TProgramBuilder& pb = *setup.PgmBuilder;
  314. const auto dataType = pb.NewDataType(NUdf::TDataType<const char*>::Id);
  315. const auto boolType = pb.NewDataType(NUdf::TDataType<bool>::Id);
  316. const auto tupleType = pb.NewTupleType({pb.NewOptionalType(dataType), dataType, boolType});
  317. const auto key0 = pb.NewEmptyOptional(pb.NewOptionalType(dataType));
  318. const auto key1 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("one"));
  319. const auto key2 = pb.NewOptional(pb.NewDataLiteral<NUdf::EDataSlot::String>("two"));
  320. const auto trueVal = pb.NewDataLiteral<bool>(true);
  321. const auto falseVal = pb.NewDataLiteral<bool>(false);
  322. const auto value1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 1");
  323. const auto value2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 2");
  324. const auto value3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 3");
  325. const auto value4 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 4");
  326. const auto value5 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 5");
  327. const auto value6 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 6");
  328. const auto value7 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 7");
  329. const auto value8 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 8");
  330. const auto value9 = pb.NewDataLiteral<NUdf::EDataSlot::String>("value 9");
  331. const auto data1 = pb.NewTuple(tupleType, {key1, value1, trueVal});
  332. const auto data2 = pb.NewTuple(tupleType, {key1, value2, trueVal});
  333. const auto data3 = pb.NewTuple(tupleType, {key1, value3, falseVal});
  334. const auto data4 = pb.NewTuple(tupleType, {key1, value4, falseVal});
  335. const auto data5 = pb.NewTuple(tupleType, {key2, value5, falseVal});
  336. const auto data6 = pb.NewTuple(tupleType, {key2, value6, falseVal});
  337. const auto data7 = pb.NewTuple(tupleType, {key2, value7, trueVal});
  338. const auto data8 = pb.NewTuple(tupleType, {key0, value8, trueVal});
  339. const auto data9 = pb.NewTuple(tupleType, {key0, value9, falseVal});
  340. const auto list = pb.NewList(tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
  341. const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChopper(pb.ExpandMap(pb.ToFlow(list),
  342. [&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth(item, 0U), pb.Nth(item, 1U), pb.Nth(item, 2U)}; }),
  343. [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
  344. return {items.front(), items.back()};
  345. },
  346. [&](TRuntimeNode::TList keys, TRuntimeNode::TList items) {
  347. return pb.Or({pb.AggrNotEquals(keys.front(), items.front()), pb.AggrNotEquals(keys.back(), items.back())});
  348. },
  349. [&](TRuntimeNode::TList keys, TRuntimeNode part) {
  350. return pb.If(keys.back(),
  351. pb.ExpandMap(pb.ToFlow(keys.front()), [&](TRuntimeNode item) -> TRuntimeNode::TList { return {item}; } ),
  352. pb.WideMap(part, [&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items[1U]}; } ));
  353. }),
  354. [&](TRuntimeNode::TList items) { return items.front(); }
  355. ));
  356. const auto graph = setup.BuildGraph(pgmReturn);
  357. const auto iterator = graph->GetValue().GetListIterator();
  358. NUdf::TUnboxedValue item;
  359. UNIT_ASSERT(iterator.Next(item));
  360. UNBOXED_VALUE_STR_EQUAL(item, "one");
  361. UNIT_ASSERT(iterator.Next(item));
  362. UNBOXED_VALUE_STR_EQUAL(item, "value 3");
  363. UNIT_ASSERT(iterator.Next(item));
  364. UNBOXED_VALUE_STR_EQUAL(item, "value 4");
  365. UNIT_ASSERT(iterator.Next(item));
  366. UNBOXED_VALUE_STR_EQUAL(item, "value 5");
  367. UNIT_ASSERT(iterator.Next(item));
  368. UNBOXED_VALUE_STR_EQUAL(item, "value 6");
  369. UNIT_ASSERT(iterator.Next(item));
  370. UNBOXED_VALUE_STR_EQUAL(item, "two");
  371. UNIT_ASSERT(iterator.Next(item));
  372. UNBOXED_VALUE_STR_EQUAL(item, "value 9");
  373. UNIT_ASSERT(!iterator.Next(item));
  374. UNIT_ASSERT(!iterator.Next(item));
  375. }
  376. Y_UNIT_TEST_LLVM(TestThinAllLambdas) {
  377. TSetup<LLVM> setup;
  378. TProgramBuilder& pb = *setup.PgmBuilder;
  379. const auto tupleType = pb.NewTupleType({});
  380. const auto data = pb.NewTuple({});
  381. const auto list = pb.NewList(tupleType, {data, data, data, data});
  382. const auto pgmReturn = pb.Collect(pb.NarrowMap(pb.WideChopper(pb.ExpandMap(pb.ToFlow(list),
  383. [](TRuntimeNode) -> TRuntimeNode::TList { return {}; }),
  384. [](TRuntimeNode::TList items) { return items; },
  385. [&](TRuntimeNode::TList, TRuntimeNode::TList) { return pb.NewDataLiteral<bool>(true); },
  386. [&](TRuntimeNode::TList, TRuntimeNode input) { return pb.WideMap(input, [](TRuntimeNode::TList items) { return items; }); }),
  387. [&](TRuntimeNode::TList) { return pb.NewTuple({}); }
  388. ));
  389. const auto graph = setup.BuildGraph(pgmReturn);
  390. const auto iterator = graph->GetValue().GetListIterator();
  391. NUdf::TUnboxedValue item;
  392. UNIT_ASSERT(iterator.Next(item));
  393. UNIT_ASSERT(iterator.Next(item));
  394. UNIT_ASSERT(iterator.Next(item));
  395. UNIT_ASSERT(iterator.Next(item));
  396. UNIT_ASSERT(!iterator.Next(item));
  397. UNIT_ASSERT(!iterator.Next(item));
  398. }
  399. }
  400. #endif
  401. }
  402. }