mkql_block_exists_ut.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #include "mkql_computation_node_ut.h"
  2. #include <yql/essentials/minikql/computation/mkql_computation_node_holders.h>
  3. #include <yql/essentials/minikql/computation/mkql_block_builder.h>
  4. namespace NKikimr {
  5. namespace NMiniKQL {
  6. namespace {
  7. void DoBlockExistsOffset(size_t length, size_t offset) {
  8. TSetup<false> setup;
  9. TProgramBuilder& pb = *setup.PgmBuilder;
  10. const auto ui64Type = pb.NewDataType(NUdf::TDataType<ui64>::Id);
  11. const auto optui64Type = pb.NewOptionalType(ui64Type);
  12. const auto boolType = pb.NewDataType(NUdf::TDataType<bool>::Id);
  13. const auto inputTupleType = pb.NewTupleType({ui64Type, optui64Type, optui64Type, optui64Type});
  14. const auto outputTupleType = pb.NewTupleType({ui64Type, boolType, boolType, boolType});
  15. TRuntimeNode::TList input;
  16. TVector<bool> isNull;
  17. static_assert(MaxBlockSizeInBytes % 4 == 0);
  18. const auto drng = CreateDeterministicRandomProvider(std::time(nullptr));
  19. for (size_t i = 0; i < length; i++) {
  20. const ui64 randomValue = drng->GenRand();
  21. const auto maybeNull = (randomValue % 2)
  22. ? pb.NewOptional(pb.NewDataLiteral<ui64>(randomValue / 2))
  23. : pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui64>::Id);
  24. const auto inputTuple = pb.NewTuple(inputTupleType, {
  25. pb.NewDataLiteral<ui64>(i),
  26. maybeNull,
  27. pb.NewEmptyOptionalDataLiteral(NUdf::TDataType<ui64>::Id),
  28. pb.NewOptional(pb.NewDataLiteral<ui64>(i))
  29. });
  30. input.push_back(inputTuple);
  31. isNull.push_back((randomValue % 2) != 0);
  32. }
  33. const auto list = pb.NewList(inputTupleType, std::move(input));
  34. auto node = pb.ToFlow(list);
  35. node = pb.ExpandMap(node, [&](TRuntimeNode item) -> TRuntimeNode::TList {
  36. return {
  37. pb.Nth(item, 0),
  38. pb.Nth(item, 1),
  39. pb.Nth(item, 2),
  40. pb.Nth(item, 3)
  41. };
  42. });
  43. node = pb.WideToBlocks(node);
  44. if (offset > 0) {
  45. node = pb.WideSkipBlocks(node, pb.NewDataLiteral<ui64>(offset));
  46. }
  47. node = pb.WideMap(node, [&](TRuntimeNode::TList items) -> TRuntimeNode::TList {
  48. return {
  49. items[0],
  50. pb.BlockExists(items[1]),
  51. pb.BlockExists(items[2]),
  52. pb.BlockExists(items[3]),
  53. items[4],
  54. };
  55. });
  56. node = pb.ToFlow(pb.WideFromBlocks(pb.FromFlow(node)));
  57. node = pb.NarrowMap(node, [&](TRuntimeNode::TList items) -> TRuntimeNode {
  58. return pb.NewTuple(outputTupleType, {items[0], items[1], items[2], items[3]});
  59. });
  60. const auto pgmReturn = pb.Collect(node);
  61. const auto graph = setup.BuildGraph(pgmReturn);
  62. const auto iterator = graph->GetValue().GetListIterator();
  63. for (size_t i = 0; i < length; i++) {
  64. if (i < offset) {
  65. continue;
  66. }
  67. NUdf::TUnboxedValue outputTuple;
  68. UNIT_ASSERT(iterator.Next(outputTuple));
  69. const ui32 key = outputTuple.GetElement(0).Get<ui64>();
  70. const bool maybeNull = outputTuple.GetElement(1).Get<bool>();
  71. const bool alwaysNull = outputTuple.GetElement(2).Get<bool>();
  72. const bool neverNull = outputTuple.GetElement(3).Get<bool>();
  73. UNIT_ASSERT_VALUES_EQUAL(key, i);
  74. UNIT_ASSERT_VALUES_EQUAL(maybeNull, isNull[i]);
  75. UNIT_ASSERT_VALUES_EQUAL(alwaysNull, false);
  76. UNIT_ASSERT_VALUES_EQUAL(neverNull, true);
  77. }
  78. NUdf::TUnboxedValue outputTuple;
  79. UNIT_ASSERT(!iterator.Next(outputTuple));
  80. UNIT_ASSERT(!iterator.Next(outputTuple));
  81. }
  82. } //namespace
  83. Y_UNIT_TEST_SUITE(TMiniKQLBlockExistsTest) {
  84. Y_UNIT_TEST(ExistsWithOffset) {
  85. const size_t length = 20;
  86. for (size_t offset = 0; offset < length; offset++) {
  87. DoBlockExistsOffset(length, offset);
  88. }
  89. }
  90. } // Y_UNIT_TEST_SUITE
  91. } // namespace NMiniKQL
  92. } // namespace NKikimr