mkql_variant_ut.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  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(TMiniKQLVariantTest) {
  7. Y_UNIT_TEST_LLVM(TestGuessTuple) {
  8. TSetup<LLVM> setup;
  9. TProgramBuilder& pb = *setup.PgmBuilder;
  10. const auto data1 = pb.NewDataLiteral<ui32>(1);
  11. const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
  12. const auto tupleType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id)});
  13. const auto varType = pb.NewVariantType(tupleType);
  14. const auto var1 = pb.NewVariant(data1, 0, varType);
  15. const auto var2 = pb.NewVariant(data2, 1, varType);
  16. std::vector<TRuntimeNode> tupleItems;
  17. tupleItems.push_back(pb.Guess(var1, 0));
  18. tupleItems.push_back(pb.Guess(var1, 1));
  19. tupleItems.push_back(pb.Guess(var2, 0));
  20. tupleItems.push_back(pb.Guess(var2, 1));
  21. const auto pgmReturn = pb.NewTuple(tupleItems);
  22. const auto graph = setup.BuildGraph(pgmReturn);
  23. const auto res = graph->GetValue();
  24. UNIT_ASSERT(res.GetElement(0));
  25. UNIT_ASSERT_VALUES_EQUAL(res.GetElement(0).template Get<ui32>(), 1);
  26. UNIT_ASSERT(!res.GetElement(1));
  27. UNIT_ASSERT(!res.GetElement(2));
  28. UNIT_ASSERT(res.GetElement(3));
  29. UNBOXED_VALUE_STR_EQUAL(res.GetElement(3), "abc");
  30. }
  31. Y_UNIT_TEST_LLVM(TestGuessTupleOpt) {
  32. TSetup<LLVM> setup;
  33. TProgramBuilder& pb = *setup.PgmBuilder;
  34. const auto data1 = pb.NewDataLiteral<ui32>(1);
  35. const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
  36. const auto tupleType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id)});
  37. const auto varType = pb.NewVariantType(tupleType);
  38. const auto var1 = pb.NewVariant(data1, 0, varType);
  39. const auto var2 = pb.NewVariant(data2, 1, varType);
  40. const auto jvar1 = pb.NewOptional(var1);
  41. const auto jvar2 = pb.NewOptional(var2);
  42. const auto nothing = pb.NewEmptyOptional(pb.NewOptionalType(varType));
  43. std::vector<TRuntimeNode> tupleItems;
  44. tupleItems.push_back(pb.Guess(jvar1, 0));
  45. tupleItems.push_back(pb.Guess(jvar1, 1));
  46. tupleItems.push_back(pb.Guess(jvar2, 0));
  47. tupleItems.push_back(pb.Guess(jvar2, 1));
  48. tupleItems.push_back(pb.Guess(nothing, 0));
  49. tupleItems.push_back(pb.Guess(nothing, 1));
  50. const auto pgmReturn = pb.NewTuple(tupleItems);
  51. const auto graph = setup.BuildGraph(pgmReturn);
  52. const auto res = graph->GetValue();
  53. UNIT_ASSERT(res.GetElement(0));
  54. UNIT_ASSERT_VALUES_EQUAL(res.GetElement(0).template Get<ui32>(), 1);
  55. UNIT_ASSERT(!res.GetElement(1));
  56. UNIT_ASSERT(!res.GetElement(2));
  57. UNIT_ASSERT(res.GetElement(3));
  58. UNBOXED_VALUE_STR_EQUAL(res.GetElement(3), "abc");
  59. UNIT_ASSERT(!res.GetElement(4));
  60. UNIT_ASSERT(!res.GetElement(5));
  61. }
  62. Y_UNIT_TEST_LLVM(TestGuessStruct) {
  63. TSetup<LLVM> setup;
  64. TProgramBuilder& pb = *setup.PgmBuilder;
  65. const auto data1 = pb.NewDataLiteral<ui32>(1);
  66. const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
  67. const auto structType = pb.NewStructType({{"x", pb.NewDataType(NUdf::TDataType<ui32>::Id)}, {"y", pb.NewDataType(NUdf::TDataType<char*>::Id)}});
  68. const auto varType = pb.NewVariantType(structType);
  69. const auto var1 = pb.NewVariant(data1, "x", varType);
  70. const auto var2 = pb.NewVariant(data2, "y", varType);
  71. std::vector<TRuntimeNode> tupleItems;
  72. tupleItems.push_back(pb.Guess(var1, "x"));
  73. tupleItems.push_back(pb.Guess(var1, "y"));
  74. tupleItems.push_back(pb.Guess(var2, "x"));
  75. tupleItems.push_back(pb.Guess(var2, "y"));
  76. const auto pgmReturn = pb.NewTuple(tupleItems);
  77. const auto graph = setup.BuildGraph(pgmReturn);
  78. const auto res = graph->GetValue();
  79. UNIT_ASSERT(res.GetElement(0));
  80. UNIT_ASSERT_VALUES_EQUAL(res.GetElement(0).template Get<ui32>(), 1);
  81. UNIT_ASSERT(!res.GetElement(1));
  82. UNIT_ASSERT(!res.GetElement(2));
  83. UNIT_ASSERT(res.GetElement(3));
  84. UNBOXED_VALUE_STR_EQUAL(res.GetElement(3), "abc");
  85. }
  86. Y_UNIT_TEST_LLVM(TestGuessStructOpt) {
  87. TSetup<LLVM> setup;
  88. TProgramBuilder& pb = *setup.PgmBuilder;
  89. const auto data1 = pb.NewDataLiteral<ui32>(1);
  90. const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
  91. const auto structType = pb.NewStructType({{"x", pb.NewDataType(NUdf::TDataType<ui32>::Id)}, {"y", pb.NewDataType(NUdf::TDataType<char*>::Id)}});
  92. const auto varType = pb.NewVariantType(structType);
  93. const auto var1 = pb.NewVariant(data1, "x", varType);
  94. const auto var2 = pb.NewVariant(data2, "y", varType);
  95. const auto jvar1 = pb.NewOptional(var1);
  96. const auto jvar2 = pb.NewOptional(var2);
  97. const auto nothing = pb.NewEmptyOptional(pb.NewOptionalType(varType));
  98. std::vector<TRuntimeNode> tupleItems;
  99. tupleItems.push_back(pb.Guess(jvar1, "x"));
  100. tupleItems.push_back(pb.Guess(jvar1, "y"));
  101. tupleItems.push_back(pb.Guess(jvar2, "x"));
  102. tupleItems.push_back(pb.Guess(jvar2, "y"));
  103. tupleItems.push_back(pb.Guess(nothing, "x"));
  104. tupleItems.push_back(pb.Guess(nothing, "y"));
  105. const auto pgmReturn = pb.NewTuple(tupleItems);
  106. const auto graph = setup.BuildGraph(pgmReturn);
  107. const auto res = graph->GetValue();
  108. UNIT_ASSERT(res.GetElement(0));
  109. UNIT_ASSERT_VALUES_EQUAL(res.GetElement(0).template Get<ui32>(), 1);
  110. UNIT_ASSERT(!res.GetElement(1));
  111. UNIT_ASSERT(!res.GetElement(2));
  112. UNIT_ASSERT(res.GetElement(3));
  113. UNBOXED_VALUE_STR_EQUAL(res.GetElement(3), "abc");
  114. UNIT_ASSERT(!res.GetElement(4));
  115. UNIT_ASSERT(!res.GetElement(5));
  116. }
  117. Y_UNIT_TEST_LLVM(TestVisitAllTuple) {
  118. TSetup<LLVM> setup;
  119. TProgramBuilder& pb = *setup.PgmBuilder;
  120. const auto data1 = pb.NewDataLiteral<ui32>(1);
  121. const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
  122. const auto at = pb.NewDataLiteral<NUdf::EDataSlot::String>("@");
  123. const auto tupleType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id)});
  124. const auto varType = pb.NewVariantType(tupleType);
  125. const auto var1 = pb.NewVariant(data1, 0, varType);
  126. const auto var2 = pb.NewVariant(data2, 1, varType);
  127. const auto list = pb.NewList(varType, {var1, var2});
  128. const auto pgmReturn = pb.Map(list, [&](TRuntimeNode item) {
  129. return pb.VisitAll(item, [&](ui32 index, TRuntimeNode item) {
  130. if (!index) {
  131. return pb.Concat(at, pb.ToString(item));
  132. } else {
  133. return pb.Concat(at, item);
  134. }
  135. });
  136. });
  137. const auto graph = setup.BuildGraph(pgmReturn);
  138. const auto res = graph->GetValue();
  139. UNBOXED_VALUE_STR_EQUAL(res.GetElement(0), "@1");
  140. UNBOXED_VALUE_STR_EQUAL(res.GetElement(1), "@abc");
  141. }
  142. Y_UNIT_TEST_LLVM(TestVisitAllStruct) {
  143. TSetup<LLVM> setup;
  144. TProgramBuilder& pb = *setup.PgmBuilder;
  145. const auto at = pb.NewDataLiteral<NUdf::EDataSlot::String>("@");
  146. const auto data1 = pb.NewDataLiteral<ui32>(1);
  147. const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
  148. const auto structType = pb.NewStructType({{"x", pb.NewDataType(NUdf::TDataType<ui32>::Id)}, {"y", pb.NewDataType(NUdf::TDataType<char*>::Id)}});
  149. const auto varType = pb.NewVariantType(structType);
  150. const auto var1 = pb.NewVariant(data1, "x", varType);
  151. const auto var2 = pb.NewVariant(data2, "y", varType);
  152. const auto list = pb.NewList(varType, {var1, var2});
  153. const auto xIndex = AS_TYPE(TStructType, structType)->GetMemberIndex("x");
  154. const auto pgmReturn = pb.Map(list, [&](TRuntimeNode item) {
  155. return pb.VisitAll(item, [&](ui32 index, TRuntimeNode item) {
  156. if (xIndex == index) {
  157. return pb.Concat(at, pb.ToString(item));
  158. } else {
  159. return pb.Concat(at, item);
  160. }
  161. });
  162. });
  163. const auto graph = setup.BuildGraph(pgmReturn);
  164. const auto res = graph->GetValue();
  165. UNBOXED_VALUE_STR_EQUAL(res.GetElement(0), "@1");
  166. UNBOXED_VALUE_STR_EQUAL(res.GetElement(1), "@abc");
  167. }
  168. Y_UNIT_TEST_LLVM(TestVisitAllTupleFlow) {
  169. TSetup<LLVM> setup;
  170. TProgramBuilder& pb = *setup.PgmBuilder;
  171. const auto at = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("@");
  172. const auto data1 = pb.NewDataLiteral<ui64>(3ULL);
  173. const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("abc");
  174. const auto tupleType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui64>::Id), pb.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id)});
  175. const auto varType = pb.NewVariantType(tupleType);
  176. const auto var1 = pb.NewVariant(data1, 0, varType);
  177. const auto var2 = pb.NewVariant(data2, 1, varType);
  178. const auto list = pb.NewList(varType, {var1, var2});
  179. const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(list), [&](TRuntimeNode item) {
  180. return pb.VisitAll(item, [&](ui32 index, TRuntimeNode item) {
  181. if (!index) {
  182. return pb.ToFlow(pb.Replicate(at, item, __FILE__, __LINE__, 0U));
  183. } else {
  184. return pb.ToFlow(pb.NewOptional(item));
  185. }
  186. });
  187. }));
  188. const auto graph = setup.BuildGraph(pgmReturn);
  189. const auto res = graph->GetValue();
  190. NUdf::TUnboxedValue item;
  191. UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
  192. UNBOXED_VALUE_STR_EQUAL(item, "@");
  193. UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
  194. UNBOXED_VALUE_STR_EQUAL(item, "@");
  195. UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
  196. UNBOXED_VALUE_STR_EQUAL(item, "@");
  197. UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
  198. UNBOXED_VALUE_STR_EQUAL(item, "abc");
  199. UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Finish);
  200. UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Finish);
  201. }
  202. Y_UNIT_TEST_LLVM(TestVisitAllStructFlow) {
  203. TSetup<LLVM> setup;
  204. TProgramBuilder& pb = *setup.PgmBuilder;
  205. const auto at = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("@");
  206. const auto data1 = pb.NewDataLiteral<ui64>(4ULL);
  207. const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("abc");
  208. const auto structType = pb.NewStructType({{"x", pb.NewDataType(NUdf::TDataType<ui64>::Id)}, {"y", pb.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id)}});
  209. const auto varType = pb.NewVariantType(structType);
  210. const auto var1 = pb.NewVariant(data1, "x", varType);
  211. const auto var2 = pb.NewVariant(data2, "y", varType);
  212. const auto list = pb.NewList(varType, {var2, var1, var2});
  213. const auto xIndex = AS_TYPE(TStructType, structType)->GetMemberIndex("x");
  214. const auto pgmReturn = pb.FromFlow(pb.FlatMap(pb.ToFlow(list), [&](TRuntimeNode item) {
  215. return pb.VisitAll(item, [&](ui32 index, TRuntimeNode item) {
  216. if (xIndex == index) {
  217. return pb.ToFlow(pb.Replicate(at, item, __FILE__, __LINE__, 0U));
  218. } else {
  219. return pb.ToFlow(pb.NewOptional(item));
  220. }
  221. });
  222. }));
  223. const auto graph = setup.BuildGraph(pgmReturn);
  224. const auto res = graph->GetValue();
  225. NUdf::TUnboxedValue item;
  226. UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
  227. UNBOXED_VALUE_STR_EQUAL(item, "abc");
  228. UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
  229. UNBOXED_VALUE_STR_EQUAL(item, "@");
  230. UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
  231. UNBOXED_VALUE_STR_EQUAL(item, "@");
  232. UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
  233. UNBOXED_VALUE_STR_EQUAL(item, "@");
  234. UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
  235. UNBOXED_VALUE_STR_EQUAL(item, "@");
  236. UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
  237. UNBOXED_VALUE_STR_EQUAL(item, "abc");
  238. UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Finish);
  239. UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Finish);
  240. }
  241. Y_UNIT_TEST_LLVM(TestVisitAllStructWideFlow) {
  242. TSetup<LLVM> setup;
  243. TProgramBuilder& pb = *setup.PgmBuilder;
  244. const auto at = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("@");
  245. const auto data1 = pb.NewDataLiteral<ui64>(4ULL);
  246. const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("abc");
  247. const auto structType = pb.NewStructType({{"x", pb.NewDataType(NUdf::TDataType<ui64>::Id)}, {"y", pb.NewDataType(NUdf::TDataType<NUdf::TUtf8>::Id)}});
  248. const auto varType = pb.NewVariantType(structType);
  249. const auto var1 = pb.NewVariant(data1, "x", varType);
  250. const auto var2 = pb.NewVariant(data2, "y", varType);
  251. const auto list = pb.NewList(varType, {var2, var1, var2});
  252. const auto xIndex = AS_TYPE(TStructType, structType)->GetMemberIndex("x");
  253. const auto pgmReturn = pb.FromFlow(pb.NarrowMap(pb.FlatMap(pb.ToFlow(list), [&](TRuntimeNode item) {
  254. return pb.VisitAll(item, [&](ui32 index, TRuntimeNode item) {
  255. if (xIndex == index) {
  256. return pb.ExpandMap(pb.ToFlow(pb.Replicate(at, item, __FILE__, __LINE__, 0U)), [&](TRuntimeNode x) -> TRuntimeNode::TList { return {x, pb.NewDataLiteral(i32(index))}; });
  257. } else {
  258. return pb.ExpandMap(pb.ToFlow(pb.NewOptional(item)), [&](TRuntimeNode x) -> TRuntimeNode::TList { return {x, pb.NewDataLiteral(-i32(index))}; });
  259. }
  260. });
  261. }),
  262. [&](TRuntimeNode::TList items) { return pb.NewTuple(items); }
  263. ));
  264. const auto graph = setup.BuildGraph(pgmReturn);
  265. const auto res = graph->GetValue();
  266. NUdf::TUnboxedValue item;
  267. UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
  268. UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "abc");
  269. UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), -1);
  270. UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
  271. UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "@");
  272. UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), 0);
  273. UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
  274. UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "@");
  275. UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), 0);
  276. UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
  277. UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "@");
  278. UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), 0);
  279. UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
  280. UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "@");
  281. UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), 0);
  282. UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Ok);
  283. UNBOXED_VALUE_STR_EQUAL(item.GetElement(0), "abc");
  284. UNIT_ASSERT_EQUAL(item.GetElement(1).Get<i32>(), -1);
  285. UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Finish);
  286. UNIT_ASSERT_EQUAL(res.Fetch(item), NUdf::EFetchStatus::Finish);
  287. }
  288. Y_UNIT_TEST_LLVM(TestWayTuple) {
  289. TSetup<LLVM> setup;
  290. TProgramBuilder& pb = *setup.PgmBuilder;
  291. const auto data1 = pb.NewDataLiteral<ui32>(1);
  292. const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
  293. const auto tupleType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id)});
  294. const auto varType = pb.NewVariantType(tupleType);
  295. const auto var1 = pb.NewVariant(data1, 0, varType);
  296. const auto var2 = pb.NewVariant(data2, 1, varType);
  297. const auto list = pb.NewList(varType, {var2, var1});
  298. const auto pgmReturn = pb.Map(list,
  299. [&](TRuntimeNode item) { return pb.Way(item); }
  300. );
  301. const auto graph = setup.BuildGraph(pgmReturn);
  302. const auto iterator = graph->GetValue().GetListIterator();
  303. NUdf::TUnboxedValue item;
  304. UNIT_ASSERT(iterator.Next(item));
  305. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1U);
  306. UNIT_ASSERT(iterator.Next(item));
  307. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0U);
  308. UNIT_ASSERT(!iterator.Next(item));
  309. UNIT_ASSERT(!iterator.Next(item));
  310. }
  311. Y_UNIT_TEST_LLVM(TestWayTupleOpt) {
  312. TSetup<LLVM> setup;
  313. TProgramBuilder& pb = *setup.PgmBuilder;
  314. const auto data1 = pb.NewDataLiteral<ui32>(1);
  315. const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
  316. const auto tupleType = pb.NewTupleType({pb.NewDataType(NUdf::TDataType<ui32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id)});
  317. const auto varType = pb.NewVariantType(tupleType);
  318. const auto var1 = pb.NewVariant(data1, 0, varType);
  319. const auto var2 = pb.NewVariant(data2, 1, varType);
  320. const auto jvar1 = pb.NewOptional(var1);
  321. const auto jvar2 = pb.NewOptional(var2);
  322. const auto optType = pb.NewOptionalType(varType);
  323. const auto nothing = pb.NewEmptyOptional(optType);
  324. const auto list = pb.NewList(optType, {jvar2, nothing, jvar1});
  325. const auto pgmReturn = pb.Map(list,
  326. [&](TRuntimeNode item) { return pb.Way(item); }
  327. );
  328. const auto graph = setup.BuildGraph(pgmReturn);
  329. const auto iterator = graph->GetValue().GetListIterator();
  330. NUdf::TUnboxedValue item;
  331. UNIT_ASSERT(iterator.Next(item));
  332. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 1U);
  333. UNIT_ASSERT(iterator.Next(item));
  334. UNIT_ASSERT(!item);
  335. UNIT_ASSERT(iterator.Next(item));
  336. UNIT_ASSERT_VALUES_EQUAL(item.template Get<ui32>(), 0U);
  337. UNIT_ASSERT(!iterator.Next(item));
  338. UNIT_ASSERT(!iterator.Next(item));
  339. }
  340. Y_UNIT_TEST_LLVM(TestWayStruct) {
  341. TSetup<LLVM> setup;
  342. TProgramBuilder& pb = *setup.PgmBuilder;
  343. const auto data1 = pb.NewDataLiteral<ui32>(1);
  344. const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
  345. const auto structType = pb.NewStructType({{"x", pb.NewDataType(NUdf::TDataType<ui32>::Id)}, {"y", pb.NewDataType(NUdf::TDataType<char*>::Id)}});
  346. const auto varType = pb.NewVariantType(structType);
  347. const auto var1 = pb.NewVariant(data1, "x", varType);
  348. const auto var2 = pb.NewVariant(data2, "y", varType);
  349. const auto list = pb.NewList(varType, {var2, var1});
  350. const auto pgmReturn = pb.Map(list,
  351. [&](TRuntimeNode item) { return pb.Way(item); }
  352. );
  353. const auto graph = setup.BuildGraph(pgmReturn);
  354. const auto iterator = graph->GetValue().GetListIterator();
  355. NUdf::TUnboxedValue item;
  356. UNIT_ASSERT(iterator.Next(item));
  357. UNBOXED_VALUE_STR_EQUAL(item, "y");
  358. UNIT_ASSERT(iterator.Next(item));
  359. UNBOXED_VALUE_STR_EQUAL(item, "x");
  360. UNIT_ASSERT(!iterator.Next(item));
  361. UNIT_ASSERT(!iterator.Next(item));
  362. }
  363. Y_UNIT_TEST_LLVM(TestWayStructOpt) {
  364. TSetup<LLVM> setup;
  365. TProgramBuilder& pb = *setup.PgmBuilder;
  366. const auto data1 = pb.NewDataLiteral<ui32>(1);
  367. const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>("abc");
  368. const auto structType = pb.NewStructType({{"x", pb.NewDataType(NUdf::TDataType<ui32>::Id)}, {"y", pb.NewDataType(NUdf::TDataType<char*>::Id)}});
  369. const auto varType = pb.NewVariantType(structType);
  370. const auto var1 = pb.NewVariant(data1, "x", varType);
  371. const auto var2 = pb.NewVariant(data2, "y", varType);
  372. const auto jvar1 = pb.NewOptional(var1);
  373. const auto jvar2 = pb.NewOptional(var2);
  374. const auto optType = pb.NewOptionalType(varType);
  375. const auto nothing = pb.NewEmptyOptional(optType);
  376. const auto list = pb.NewList(optType, {jvar2, nothing, jvar1});
  377. const auto pgmReturn = pb.Map(list,
  378. [&](TRuntimeNode item) { return pb.Way(item); }
  379. );
  380. const auto graph = setup.BuildGraph(pgmReturn);
  381. const auto iterator = graph->GetValue().GetListIterator();
  382. NUdf::TUnboxedValue item;
  383. UNIT_ASSERT(iterator.Next(item));
  384. UNBOXED_VALUE_STR_EQUAL(item, "y");
  385. UNIT_ASSERT(iterator.Next(item));
  386. UNIT_ASSERT(!item);
  387. UNIT_ASSERT(iterator.Next(item));
  388. UNBOXED_VALUE_STR_EQUAL(item, "x");
  389. UNIT_ASSERT(!iterator.Next(item));
  390. UNIT_ASSERT(!iterator.Next(item));
  391. }
  392. Y_UNIT_TEST_LLVM(TestItemInMap) {
  393. TSetup<LLVM> setup;
  394. TProgramBuilder& pb = *setup.PgmBuilder;
  395. const auto varType = pb.NewVariantType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id), pb.NewDataType(NUdf::TDataType<bool>::Id)}));
  396. const auto data0 = pb.NewVariant(pb.NewDataLiteral<i32>(77), 0, varType);
  397. const auto data1 = pb.NewVariant(pb.NewDataLiteral<NUdf::EDataSlot::String>("abc"), 1, varType);
  398. const auto data2 = pb.NewVariant(pb.NewDataLiteral<bool>(false), 2, varType);
  399. const auto data3 = pb.NewVariant(pb.NewDataLiteral<bool>(true), 2, varType);
  400. const auto data4 = pb.NewVariant(pb.NewDataLiteral<NUdf::EDataSlot::String>("DEF"), 1, varType);
  401. const auto data5 = pb.NewVariant(pb.NewDataLiteral<i32>(-1267), 0, varType);
  402. const auto list = pb.NewList(varType, {data0, data1, data2, data3, data4, data5});
  403. const auto pgmReturn = pb.Map(list,
  404. [&](TRuntimeNode item) {
  405. return pb.VariantItem(item);
  406. });
  407. const auto graph = setup.BuildGraph(pgmReturn);
  408. const auto iterator = graph->GetValue().GetListIterator();
  409. NUdf::TUnboxedValue item;
  410. UNIT_ASSERT(iterator.Next(item));
  411. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), 77);
  412. UNIT_ASSERT(iterator.Next(item));
  413. UNIT_ASSERT_VALUES_EQUAL(TStringBuf(item.AsStringRef()), "abc");
  414. UNIT_ASSERT(iterator.Next(item));
  415. UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), false);
  416. UNIT_ASSERT(iterator.Next(item));
  417. UNIT_ASSERT_VALUES_EQUAL(item.template Get<bool>(), true);
  418. UNIT_ASSERT(iterator.Next(item));
  419. UNIT_ASSERT_VALUES_EQUAL(TStringBuf(item.AsStringRef()), "DEF");
  420. UNIT_ASSERT(iterator.Next(item));
  421. UNIT_ASSERT_VALUES_EQUAL(item.template Get<i32>(), -1267);
  422. UNIT_ASSERT(!iterator.Next(item));
  423. UNIT_ASSERT(!iterator.Next(item));
  424. }
  425. Y_UNIT_TEST_LLVM(TestGuessInMap) {
  426. TSetup<LLVM> setup;
  427. TProgramBuilder& pb = *setup.PgmBuilder;
  428. const auto varType = pb.NewVariantType(pb.NewTupleType({pb.NewDataType(NUdf::TDataType<i32>::Id), pb.NewDataType(NUdf::TDataType<char*>::Id), pb.NewDataType(NUdf::TDataType<bool>::Id)}));
  429. const auto data0 = pb.NewVariant(pb.NewDataLiteral<i32>(77), 0, varType);
  430. const auto data1 = pb.NewVariant(pb.NewDataLiteral<NUdf::EDataSlot::String>("abc"), 1, varType);
  431. const auto data2 = pb.NewVariant(pb.NewDataLiteral<bool>(false), 2, varType);
  432. const auto data3 = pb.NewVariant(pb.NewDataLiteral<bool>(true), 2, varType);
  433. const auto data4 = pb.NewVariant(pb.NewDataLiteral<NUdf::EDataSlot::String>("DEF"), 1, varType);
  434. const auto data5 = pb.NewVariant(pb.NewDataLiteral<i32>(-1267), 0, varType);
  435. const auto list = pb.NewList(varType, {data0, data1, data2, data3, data4, data5});
  436. const auto pgmReturn = pb.Map(list,
  437. [&](TRuntimeNode item) {
  438. return pb.NewTuple({pb.Guess(item, 0), pb.Guess(item, 2)});
  439. });
  440. const auto graph = setup.BuildGraph(pgmReturn);
  441. const auto iterator = graph->GetValue().GetListIterator();
  442. NUdf::TUnboxedValue item;
  443. UNIT_ASSERT(iterator.Next(item));
  444. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), 77);
  445. UNIT_ASSERT(!item.GetElement(1));
  446. UNIT_ASSERT(iterator.Next(item));
  447. UNIT_ASSERT(!item.GetElement(0));
  448. UNIT_ASSERT(!item.GetElement(1));
  449. UNIT_ASSERT(iterator.Next(item));
  450. UNIT_ASSERT(!item.GetElement(0));
  451. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<bool>(), false);
  452. UNIT_ASSERT(iterator.Next(item));
  453. UNIT_ASSERT(!item.GetElement(0));
  454. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(1).template Get<bool>(), true);
  455. UNIT_ASSERT(iterator.Next(item));
  456. UNIT_ASSERT(!item.GetElement(0));
  457. UNIT_ASSERT(!item.GetElement(1));
  458. UNIT_ASSERT(iterator.Next(item));
  459. UNIT_ASSERT_VALUES_EQUAL(item.GetElement(0).template Get<i32>(), -1267);
  460. UNIT_ASSERT(!item.GetElement(1));
  461. UNIT_ASSERT(!iterator.Next(item));
  462. UNIT_ASSERT(!iterator.Next(item));
  463. }
  464. Y_UNIT_TEST(TestDynamicVariantTuple) {
  465. TSetup<false> setup;
  466. TProgramBuilder& pb = *setup.PgmBuilder;
  467. const TStringBuf str1 = "VERY LONG STRING!!!";
  468. const TStringBuf str2 = "SHORT";
  469. const auto data1 = pb.NewDataLiteral<NUdf::EDataSlot::String>(str1);
  470. const auto data2 = pb.NewDataLiteral<NUdf::EDataSlot::String>(str2);
  471. const auto data3 = pb.NewDataLiteral<NUdf::EDataSlot::String>("");
  472. const auto dataType = pb.NewDataType(NUdf::TDataType<char*>::Id);
  473. const auto tupleType = pb.NewTupleType({dataType, dataType});
  474. const auto varType = pb.NewVariantType(tupleType);
  475. const auto var1 = pb.DynamicVariant(data1, pb.NewDataLiteral<ui32>(0), varType);
  476. const auto var2 = pb.DynamicVariant(data2, pb.NewDataLiteral<ui32>(1), varType);
  477. const auto var3 = pb.DynamicVariant(data3, pb.NewDataLiteral<ui32>(2), varType);
  478. const auto list = pb.AsList({var1, var2, var3});
  479. const auto pgmReturn = list;
  480. const auto graph = setup.BuildGraph(pgmReturn);
  481. const auto iterator = graph->GetValue().GetListIterator();
  482. NUdf::TUnboxedValue item;
  483. UNIT_ASSERT(iterator.Next(item));
  484. UNIT_ASSERT(item);
  485. UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 0);
  486. auto itemVar1 = item.GetVariantItem();
  487. UNIT_ASSERT(itemVar1.IsString());
  488. UNIT_ASSERT_VALUES_EQUAL(TStringBuf(itemVar1.AsStringRef()), str1);
  489. UNIT_ASSERT(iterator.Next(item));
  490. UNIT_ASSERT(item);
  491. UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 1);
  492. auto itemVar2 = item.GetVariantItem();
  493. UNIT_ASSERT(itemVar2.IsEmbedded());
  494. UNIT_ASSERT_VALUES_EQUAL(TStringBuf(itemVar2.AsStringRef()), str2);
  495. UNIT_ASSERT(iterator.Next(item));
  496. UNIT_ASSERT(!item);
  497. UNIT_ASSERT(!iterator.Next(item));
  498. UNIT_ASSERT(!iterator.Next(item));
  499. }
  500. Y_UNIT_TEST(TestDynamicVariantStruct) {
  501. TSetup<false> setup;
  502. TProgramBuilder& pb = *setup.PgmBuilder;
  503. const auto data1 = pb.NewDataLiteral<ui32>(10);
  504. const auto data2 = pb.NewDataLiteral<ui32>(20);
  505. const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
  506. const auto structType = pb.NewStructType({{"x", dataType}, {"y", dataType }});
  507. const auto varType = pb.NewVariantType(structType);
  508. const auto var1 = pb.DynamicVariant(data1, pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("x"), varType);
  509. const auto var2 = pb.DynamicVariant(data2, pb.NewDataLiteral<NUdf::EDataSlot::Utf8>("z"), varType);
  510. const auto list = pb.AsList({var1, var2});
  511. const auto pgmReturn = list;
  512. const auto graph = setup.BuildGraph(pgmReturn);
  513. const auto iterator = graph->GetValue().GetListIterator();
  514. NUdf::TUnboxedValue item;
  515. UNIT_ASSERT(iterator.Next(item));
  516. UNIT_ASSERT(item);
  517. UNIT_ASSERT_VALUES_EQUAL(item.GetVariantIndex(), 0);
  518. UNIT_ASSERT_VALUES_EQUAL(item.GetVariantItem().template Get<ui32>(), 10U);
  519. UNIT_ASSERT(iterator.Next(item));
  520. UNIT_ASSERT(!item);
  521. UNIT_ASSERT(!iterator.Next(item));
  522. UNIT_ASSERT(!iterator.Next(item));
  523. }
  524. Y_UNIT_TEST(TestDynamicVariantStructWithNullIndex) {
  525. TSetup<false> setup;
  526. TProgramBuilder& pb = *setup.PgmBuilder;
  527. const auto data1 = pb.NewDataLiteral<ui32>(10);
  528. const auto dataType = pb.NewDataType(NUdf::TDataType<ui32>::Id);
  529. const auto structType = pb.NewStructType({{"x", dataType}, {"y", dataType }});
  530. const auto varType = pb.NewVariantType(structType);
  531. const auto var1 = pb.DynamicVariant(data1, pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<NUdf::TUtf8>::Id), varType);
  532. const auto list = pb.AsList({var1});
  533. const auto pgmReturn = list;
  534. const auto graph = setup.BuildGraph(pgmReturn);
  535. const auto iterator = graph->GetValue().GetListIterator();
  536. NUdf::TUnboxedValue item;
  537. UNIT_ASSERT(iterator.Next(item));
  538. UNIT_ASSERT(!item);
  539. UNIT_ASSERT(!iterator.Next(item));
  540. UNIT_ASSERT(!iterator.Next(item));
  541. }
  542. }
  543. }
  544. }