mkql_condense_ut.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. #include "mkql_computation_node_ut.h"
  2. #include <yql/essentials/minikql/mkql_node_cast.h>
  3. #include <yql/essentials/minikql/mkql_string_util.h>
  4. namespace NKikimr {
  5. namespace NMiniKQL {
  6. Y_UNIT_TEST_SUITE(TMiniKQLCondenseNodeTest) {
  7. Y_UNIT_TEST_LLVM(TestSqueeze) {
  8. TSetup<LLVM> setup;
  9. TProgramBuilder& pb = *setup.PgmBuilder;
  10. const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<double>::Id));
  11. const auto data1 = pb.NewOptional(pb.NewDataLiteral<double>(3.8));
  12. const auto data2 = pb.NewOptional(pb.NewDataLiteral<double>(-53.2));
  13. const auto data3 = pb.NewOptional(pb.NewDataLiteral<double>(233.8));
  14. const auto data4 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<double>::Id);
  15. const auto data0 = pb.NewOptional(pb.NewDataLiteral<double>(HUGE_VAL));
  16. const auto list = pb.NewList(dataType, {data4, data3, data2, data1});
  17. const auto pgmReturn = pb.Squeeze(pb.Iterator(list, {}), data0,
  18. [&](TRuntimeNode item, TRuntimeNode state) {
  19. return pb.AggrMin(item, state);
  20. }
  21. );
  22. const auto graph = setup.BuildGraph(pgmReturn);
  23. const auto iterator = graph->GetValue();
  24. NUdf::TUnboxedValue item;
  25. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  26. UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -53.2);
  27. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  28. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  29. }
  30. Y_UNIT_TEST_LLVM(TestSqueezeOnEmpty) {
  31. TSetup<LLVM> setup;
  32. TProgramBuilder& pb = *setup.PgmBuilder;
  33. const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<double>::Id));
  34. const auto data0 = pb.NewOptional(pb.NewDataLiteral<double>(HUGE_VAL));
  35. const auto list = pb.NewEmptyList(dataType);
  36. const auto pgmReturn = pb.Squeeze(pb.Iterator(list, {}), data0,
  37. [&](TRuntimeNode item, TRuntimeNode state) {
  38. return pb.AggrMin(item, state);
  39. }
  40. );
  41. const auto graph = setup.BuildGraph(pgmReturn);
  42. const auto iterator = graph->GetValue();
  43. NUdf::TUnboxedValue item;
  44. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  45. UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), HUGE_VAL);
  46. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  47. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  48. }
  49. Y_UNIT_TEST_LLVM(TestSqueeze1OverEmpty) {
  50. TSetup<LLVM> setup;
  51. TProgramBuilder& pb = *setup.PgmBuilder;
  52. const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
  53. const auto list = pb.NewEmptyList(dataType);
  54. const auto pgmReturn = pb.Squeeze1(pb.Iterator(list, {}),
  55. [&](TRuntimeNode item) {
  56. return pb.Minus(item);
  57. },
  58. [&](TRuntimeNode item, TRuntimeNode state) {
  59. return pb.Mul(item, state);
  60. }
  61. );
  62. const auto graph = setup.BuildGraph(pgmReturn);
  63. const auto iterator = graph->GetValue();
  64. NUdf::TUnboxedValue item;
  65. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  66. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  67. }
  68. Y_UNIT_TEST_LLVM(TestSqueeze1OverSingle) {
  69. TSetup<LLVM> setup;
  70. TProgramBuilder& pb = *setup.PgmBuilder;
  71. const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
  72. const auto data1 = pb.NewDataLiteral<i32>(1);
  73. const auto list = pb.NewList(dataType, {data1});
  74. const auto pgmReturn = pb.Squeeze1(pb.Iterator(list, {}),
  75. [&](TRuntimeNode item) {
  76. return pb.Minus(item);
  77. },
  78. [&](TRuntimeNode item, TRuntimeNode state) {
  79. return pb.Mul(item, state);
  80. }
  81. );
  82. const auto graph = setup.BuildGraph(pgmReturn);
  83. const auto iterator = graph->GetValue();
  84. NUdf::TUnboxedValue item;
  85. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  86. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1);
  87. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  88. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  89. }
  90. Y_UNIT_TEST_LLVM(TestSqueeze1OverMany) {
  91. TSetup<LLVM> setup;
  92. TProgramBuilder& pb = *setup.PgmBuilder;
  93. const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
  94. const auto data1 = pb.NewDataLiteral<i32>(1);
  95. const auto data2 = pb.NewDataLiteral<i32>(2);
  96. const auto data3 = pb.NewDataLiteral<i32>(7);
  97. const auto list = pb.NewList(dataType, {data1, data2, data3});
  98. const auto pgmReturn = pb.Squeeze1(pb.Iterator(list, {}),
  99. [&](TRuntimeNode item) {
  100. return pb.Minus(item);
  101. },
  102. [&](TRuntimeNode item, TRuntimeNode state) {
  103. return pb.Mul(item, state);
  104. }
  105. );
  106. const auto graph = setup.BuildGraph(pgmReturn);
  107. const auto iterator = graph->GetValue();
  108. NUdf::TUnboxedValue item;
  109. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  110. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -14);
  111. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  112. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  113. }
  114. Y_UNIT_TEST_LLVM(TestCondense) {
  115. TSetup<LLVM> setup;
  116. TProgramBuilder& pb = *setup.PgmBuilder;
  117. const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<double>::Id));
  118. const auto data0 = pb.NewOptional(pb.NewDataLiteral<double>(0.0));
  119. const auto data1 = pb.NewOptional(pb.NewDataLiteral<double>(3.8));
  120. const auto data2 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<double>::Id);
  121. const auto data3 = pb.NewOptional(pb.NewDataLiteral<double>(-53.2));
  122. const auto data4 = pb.NewOptional(pb.NewDataLiteral<double>(233.8));
  123. const auto data5 = pb.NewOptional(pb.NewDataLiteral<double>(3.14));
  124. const auto data6 = pb.NewOptional(pb.NewDataLiteral<double>(-73.12));
  125. const auto data7 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<double>::Id);
  126. const auto data8 = pb.NewOptional(pb.NewDataLiteral<double>(233.8));
  127. const auto data9 = pb.NewOptional(pb.NewDataLiteral<double>(1221.8));
  128. const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
  129. const auto pgmReturn = pb.Condense(pb.Iterator(list, {}), data0,
  130. [&](TRuntimeNode item, TRuntimeNode state) {
  131. return pb.Or({pb.Not(pb.Exists(item)), pb.Less(state, data0)});
  132. },
  133. [&](TRuntimeNode item, TRuntimeNode state) {
  134. return pb.AggrAdd(item, state);
  135. }
  136. );
  137. const auto graph = setup.BuildGraph(pgmReturn);
  138. const auto iterator = graph->GetValue();
  139. NUdf::TUnboxedValue item;
  140. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  141. UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 3.8);
  142. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  143. UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -53.2);
  144. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  145. UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 163.82);
  146. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  147. UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 1455.6);
  148. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  149. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  150. }
  151. Y_UNIT_TEST_LLVM(TestCondense1) {
  152. TSetup<LLVM> setup;
  153. TProgramBuilder& pb = *setup.PgmBuilder;
  154. const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
  155. const auto data0 = pb.NewDataLiteral<i32>(-1);
  156. const auto data1 = pb.NewDataLiteral<i32>(2);
  157. const auto data2 = pb.NewDataLiteral<i32>(0);
  158. const auto data3 = pb.NewDataLiteral<i32>(7);
  159. const auto data4 = pb.NewDataLiteral<i32>(5);
  160. const auto data5 = pb.NewDataLiteral<i32>(-7);
  161. const auto data6 = pb.NewDataLiteral<i32>(-6);
  162. const auto data7 = pb.NewDataLiteral<i32>(4);
  163. const auto data8 = pb.NewDataLiteral<i32>(8);
  164. const auto data9 = pb.NewDataLiteral<i32>(9);
  165. const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
  166. const auto pgmReturn = pb.Condense1(pb.Iterator(list, {}),
  167. [&](TRuntimeNode item) {
  168. return pb.Minus(item);
  169. },
  170. [&](TRuntimeNode item, TRuntimeNode state) {
  171. return pb.LessOrEqual(item, state);
  172. },
  173. [&](TRuntimeNode item, TRuntimeNode state) {
  174. return pb.Mul(item, state);
  175. }
  176. );
  177. const auto graph = setup.BuildGraph(pgmReturn);
  178. const auto iterator = graph->GetValue();
  179. NUdf::TUnboxedValue item;
  180. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  181. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 2);
  182. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  183. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 0);
  184. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  185. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
  186. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  187. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 6);
  188. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  189. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -288);
  190. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  191. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  192. }
  193. Y_UNIT_TEST_LLVM(TestCondenseOverList) {
  194. TSetup<LLVM> setup;
  195. TProgramBuilder& pb = *setup.PgmBuilder;
  196. const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<double>::Id));
  197. const auto data0 = pb.NewOptional(pb.NewDataLiteral<double>(0.0));
  198. const auto data1 = pb.NewOptional(pb.NewDataLiteral<double>(3.8));
  199. const auto data2 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<double>::Id);
  200. const auto data3 = pb.NewOptional(pb.NewDataLiteral<double>(-53.2));
  201. const auto data4 = pb.NewOptional(pb.NewDataLiteral<double>(233.8));
  202. const auto data5 = pb.NewOptional(pb.NewDataLiteral<double>(3.14));
  203. const auto data6 = pb.NewOptional(pb.NewDataLiteral<double>(-73.12));
  204. const auto data7 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<double>::Id);
  205. const auto data8 = pb.NewOptional(pb.NewDataLiteral<double>(233.8));
  206. const auto data9 = pb.NewOptional(pb.NewDataLiteral<double>(1221.8));
  207. const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
  208. const auto pgmReturn = pb.Condense(list, data0,
  209. [&](TRuntimeNode item, TRuntimeNode state) {
  210. return pb.Or({pb.Not(pb.Exists(item)), pb.Less(state, data0)});
  211. },
  212. [&](TRuntimeNode item, TRuntimeNode state) {
  213. return pb.AggrAdd(item, state);
  214. }
  215. );
  216. const auto graph = setup.BuildGraph(pgmReturn);
  217. const auto iterator = graph->GetValue().GetListIterator();
  218. NUdf::TUnboxedValue item;
  219. UNIT_ASSERT(iterator.Next(item));
  220. UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 3.8);
  221. UNIT_ASSERT(iterator.Next(item));
  222. UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), -53.2);
  223. UNIT_ASSERT(iterator.Next(item));
  224. UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 163.82);
  225. UNIT_ASSERT(iterator.Next(item));
  226. UNIT_ASSERT_VALUES_EQUAL(item.template Get<double>(), 1455.6);
  227. UNIT_ASSERT(!iterator.Next(item));
  228. UNIT_ASSERT(!iterator.Next(item));
  229. }
  230. Y_UNIT_TEST_LLVM(TestCondense1OverList) {
  231. TSetup<LLVM> setup;
  232. TProgramBuilder& pb = *setup.PgmBuilder;
  233. const auto dataType = pb.NewDataType(NUdf::TDataType<i32>::Id);
  234. const auto data0 = pb.NewDataLiteral<i32>(-1);
  235. const auto data1 = pb.NewDataLiteral<i32>(2);
  236. const auto data2 = pb.NewDataLiteral<i32>(0);
  237. const auto data3 = pb.NewDataLiteral<i32>(7);
  238. const auto data4 = pb.NewDataLiteral<i32>(5);
  239. const auto data5 = pb.NewDataLiteral<i32>(-7);
  240. const auto data6 = pb.NewDataLiteral<i32>(-6);
  241. const auto data7 = pb.NewDataLiteral<i32>(4);
  242. const auto data8 = pb.NewDataLiteral<i32>(8);
  243. const auto data9 = pb.NewDataLiteral<i32>(9);
  244. const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6, data7, data8, data9});
  245. const auto pgmReturn = pb.Condense1(list,
  246. [&](TRuntimeNode item) {
  247. return pb.Minus(item);
  248. },
  249. [&](TRuntimeNode item, TRuntimeNode state) {
  250. return pb.LessOrEqual(item, state);
  251. },
  252. [&](TRuntimeNode item, TRuntimeNode state) {
  253. return pb.Mul(item, state);
  254. }
  255. );
  256. const auto graph = setup.BuildGraph(pgmReturn);
  257. const auto iterator = graph->GetValue().GetListIterator();
  258. NUdf::TUnboxedValue item;
  259. UNIT_ASSERT(iterator.Next(item));
  260. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 2);
  261. UNIT_ASSERT(iterator.Next(item));
  262. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 0);
  263. UNIT_ASSERT(iterator.Next(item));
  264. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 7);
  265. UNIT_ASSERT(iterator.Next(item));
  266. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 6);
  267. UNIT_ASSERT(iterator.Next(item));
  268. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -288);
  269. UNIT_ASSERT(!iterator.Next(item));
  270. UNIT_ASSERT(!iterator.Next(item));
  271. }
  272. Y_UNIT_TEST_LLVM(TestCondenseInterrupt) {
  273. TSetup<LLVM> setup;
  274. TProgramBuilder& pb = *setup.PgmBuilder;
  275. const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<bool>::Id));
  276. const auto data0 = pb.NewOptional(pb.NewDataLiteral<bool>(false));
  277. const auto data1 = pb.NewOptional(pb.NewDataLiteral<bool>(false));
  278. const auto data2 = pb.NewOptional(pb.NewDataLiteral<bool>(false));
  279. const auto data3 = pb.NewOptional(pb.NewDataLiteral<bool>(false));
  280. const auto data4 = pb.NewOptional(pb.NewDataLiteral<bool>(true));
  281. const auto data5 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id);
  282. const auto data6 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id);
  283. const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6});
  284. const auto pgmReturn = pb.FromFlow(pb.Condense(pb.ToFlow(list), pb.NewDataLiteral<bool>(false),
  285. [&](TRuntimeNode, TRuntimeNode state) {
  286. return pb.If(state, pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id), pb.NewDataLiteral<bool>(false));
  287. },
  288. [&](TRuntimeNode item, TRuntimeNode state) {
  289. return pb.Or({pb.Unwrap(item, pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0), state});
  290. }
  291. ));
  292. const auto graph = setup.BuildGraph(pgmReturn);
  293. const auto iterator = graph->GetValue();
  294. NUdf::TUnboxedValue item;
  295. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  296. UNIT_ASSERT(item.template Get<bool>());
  297. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  298. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  299. }
  300. Y_UNIT_TEST_LLVM(TestCondense1Interrupt) {
  301. TSetup<LLVM> setup;
  302. TProgramBuilder& pb = *setup.PgmBuilder;
  303. const auto dataType = pb.NewOptionalType(pb.NewDataType(NUdf::TDataType<bool>::Id));
  304. const auto data0 = pb.NewOptional(pb.NewDataLiteral<bool>(true));
  305. const auto data1 = pb.NewOptional(pb.NewDataLiteral<bool>(true));
  306. const auto data2 = pb.NewOptional(pb.NewDataLiteral<bool>(true));
  307. const auto data3 = pb.NewOptional(pb.NewDataLiteral<bool>(true));
  308. const auto data4 = pb.NewOptional(pb.NewDataLiteral<bool>(false));
  309. const auto data5 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id);
  310. const auto data6 = pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id);
  311. const auto list = pb.NewList(dataType, {data0, data1, data2, data3, data4, data5, data6});
  312. const auto pgmReturn = pb.FromFlow(pb.Condense1(pb.ToFlow(list),
  313. [&](TRuntimeNode item) {
  314. return pb.Unwrap(item, pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0);
  315. },
  316. [&](TRuntimeNode, TRuntimeNode state) {
  317. return pb.If(state, pb.NewDataLiteral<bool>(false), pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id));
  318. },
  319. [&](TRuntimeNode item, TRuntimeNode state) {
  320. return pb.And({pb.Unwrap(item, pb.NewDataLiteral<NUdf::EDataSlot::String>(""), "", 0, 0), state});
  321. }
  322. ));
  323. const auto graph = setup.BuildGraph(pgmReturn);
  324. const auto iterator = graph->GetValue();
  325. NUdf::TUnboxedValue item;
  326. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  327. UNIT_ASSERT(!item.template Get<bool>());
  328. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  329. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  330. }
  331. Y_UNIT_TEST_LLVM(TestCondenseInterruptEndlessStream) {
  332. TSetup<LLVM> setup;
  333. TProgramBuilder& pb = *setup.PgmBuilder;
  334. const auto pgmReturn = pb.Condense(pb.SourceOf(pb.NewStreamType(pb.NewNull().GetStaticType())), pb.NewDataLiteral<ui32>(0U),
  335. [&](TRuntimeNode, TRuntimeNode state) {
  336. return pb.If(pb.AggrLess(state, pb.NewDataLiteral<ui32>(123456U)), pb.NewDataLiteral<bool>(false), pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id));
  337. },
  338. [&](TRuntimeNode, TRuntimeNode state) {
  339. return pb.AggrAdd(pb.NewDataLiteral<ui32>(1U), state);
  340. }
  341. );
  342. const auto graph = setup.BuildGraph(pgmReturn);
  343. const auto iterator = graph->GetValue();
  344. NUdf::TUnboxedValue item;
  345. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  346. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 123456U);
  347. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  348. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  349. }
  350. Y_UNIT_TEST_LLVM(TestCondense1InterruptEndlessFlow) {
  351. TSetup<LLVM> setup;
  352. TProgramBuilder& pb = *setup.PgmBuilder;
  353. const auto pgmReturn = pb.FromFlow(pb.Condense1(pb.SourceOf(pb.NewFlowType(pb.NewNull().GetStaticType())),
  354. [&](TRuntimeNode) {
  355. return pb.NewDataLiteral<ui32>(0U);
  356. },
  357. [&](TRuntimeNode, TRuntimeNode state) {
  358. return pb.If(pb.AggrLess(state, pb.NewDataLiteral<ui32>(123456U)), pb.NewDataLiteral<bool>(false), pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<bool>::Id));
  359. },
  360. [&](TRuntimeNode, TRuntimeNode state) {
  361. return pb.AggrAdd(pb.NewDataLiteral<ui32>(1U), state);
  362. }
  363. ));
  364. const auto graph = setup.BuildGraph(pgmReturn);
  365. const auto iterator = graph->GetValue();
  366. NUdf::TUnboxedValue item;
  367. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Ok, iterator.Fetch(item));
  368. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 123456U);
  369. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  370. UNIT_ASSERT_VALUES_EQUAL(NUdf::EFetchStatus::Finish, iterator.Fetch(item));
  371. }
  372. Y_UNIT_TEST_LLVM(TestCondenseListeralListInMap) {
  373. TSetup<LLVM> setup;
  374. TProgramBuilder& pb = *setup.PgmBuilder;
  375. const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("other");
  376. const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("foo");
  377. const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("bar");
  378. const auto type = pb.NewDataType(NUdf::EDataSlot::String);
  379. const auto list2 = pb.NewList(type, {data1, data2});
  380. const auto list0 = pb.NewList(type, {data1, data2, data0});
  381. const auto pgmReturn = pb.Map(list0,
  382. [&](TRuntimeNode item) {
  383. return pb.Head(pb.Condense(list2,
  384. pb.NewDataLiteral(false),
  385. [&](TRuntimeNode, TRuntimeNode) { return pb.NewDataLiteral(false); },
  386. [&](TRuntimeNode it, TRuntimeNode state) { return pb.Or({state, pb.AggrEquals(item, it)}); }
  387. ));
  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(item.Get<bool>());
  394. UNIT_ASSERT(iterator.Next(item));
  395. UNIT_ASSERT(item.Get<bool>());
  396. UNIT_ASSERT(iterator.Next(item));
  397. UNIT_ASSERT(!item.Get<bool>());
  398. UNIT_ASSERT(!iterator.Next(item));
  399. UNIT_ASSERT(!iterator.Next(item));
  400. }
  401. Y_UNIT_TEST_LLVM(TestCondense1ListeralListInMap) {
  402. TSetup<LLVM> setup;
  403. TProgramBuilder& pb = *setup.PgmBuilder;
  404. const auto data0 = pb.NewDataLiteral<NUdf::EDataSlot::String>("other");
  405. const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>("foo");
  406. const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("bar");
  407. const auto type = pb.NewDataType(NUdf::EDataSlot::String);
  408. const auto list2 = pb.NewList(type, {data1, data2});
  409. const auto list0 = pb.NewList(type, {data1, data2, data0});
  410. const auto pgmReturn = pb.Map(list0,
  411. [&](TRuntimeNode item) {
  412. return pb.Head(pb.Condense1(list2,
  413. [&](TRuntimeNode it) { return pb.AggrEquals(item, it); },
  414. [&](TRuntimeNode, TRuntimeNode) { return pb.NewDataLiteral(false); },
  415. [&](TRuntimeNode it, TRuntimeNode state) { return pb.Or({state, pb.AggrEquals(item, it)}); }
  416. ));
  417. });
  418. const auto graph = setup.BuildGraph(pgmReturn);
  419. const auto iterator = graph->GetValue().GetListIterator();
  420. NUdf::TUnboxedValue item;
  421. UNIT_ASSERT(iterator.Next(item));
  422. UNIT_ASSERT(item.Get<bool>());
  423. UNIT_ASSERT(iterator.Next(item));
  424. UNIT_ASSERT(item.Get<bool>());
  425. UNIT_ASSERT(iterator.Next(item));
  426. UNIT_ASSERT(!item.Get<bool>());
  427. UNIT_ASSERT(!iterator.Next(item));
  428. UNIT_ASSERT(!iterator.Next(item));
  429. }
  430. }
  431. }
  432. }