presort_ut.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679
  1. #include "presort.h"
  2. #include <yql/essentials/minikql/mkql_alloc.h>
  3. #include <yql/essentials/minikql/mkql_string_util.h>
  4. #include <yql/essentials/minikql/invoke_builtins/mkql_builtins.h>
  5. #include <yql/essentials/minikql/computation/mkql_computation_node_holders.h>
  6. #include <library/cpp/testing/unittest/registar.h>
  7. #include <util/string/hex.h>
  8. using namespace std::literals::string_view_literals;
  9. namespace NKikimr {
  10. namespace NMiniKQL {
  11. namespace {
  12. #define TYPE_MAP(XX) \
  13. XX(bool, Bool) \
  14. XX(ui8, Uint8) \
  15. XX(ui16, Uint16) \
  16. XX(ui32, Uint32) \
  17. XX(ui64, Uint64) \
  18. XX(i8, Int8) \
  19. XX(i16, Int16) \
  20. XX(i32, Int32) \
  21. XX(i64, Int64) \
  22. XX(float, Float) \
  23. XX(double, Double)
  24. #define ALL_VALUES(xType, xName) \
  25. xType xName;
  26. struct TSimpleTypes {
  27. TYPE_MAP(ALL_VALUES)
  28. };
  29. #undef ALL_VALUES
  30. #define ADD_TYPE(xType, xName) \
  31. codec.AddType(NUdf::EDataSlot::xName, isOptional, isDesc);
  32. void AddTypes(TPresortCodec& codec, bool isOptional, bool isDesc) {
  33. TYPE_MAP(ADD_TYPE)
  34. }
  35. #undef ADD_TYPE
  36. #define ENCODE(xType, xName) \
  37. encoder.Encode(NUdf::TUnboxedValuePod(values.xName));
  38. TStringBuf Encode(NKikimr::NMiniKQL::TPresortEncoder& encoder, const TSimpleTypes& values) {
  39. encoder.Start();
  40. TYPE_MAP(ENCODE)
  41. return encoder.Finish();
  42. }
  43. #undef ENCODE
  44. #define DECODE(xType, xName) \
  45. UNIT_ASSERT_EQUAL(decoder.Decode().Get<xType>(), values.xName);
  46. void Decode(TPresortDecoder& decoder, TStringBuf input, const TSimpleTypes& values) {
  47. decoder.Start(input);
  48. TYPE_MAP(DECODE)
  49. decoder.Finish();
  50. }
  51. #undef DECODE
  52. #undef TYPE_MAP
  53. struct TPresortTest {
  54. TScopedAlloc Alloc;
  55. TMemoryUsageInfo MemInfo;
  56. TPresortTest()
  57. : Alloc(__LOCATION__)
  58. , MemInfo("Memory")
  59. {}
  60. template <typename T>
  61. void ValidateEncoding(bool isDesc, T value, const TString& hex) {
  62. TPresortEncoder encoder;
  63. encoder.AddType(NUdf::TDataType<T>::Slot, false, isDesc);
  64. TPresortDecoder decoder;
  65. decoder.AddType(NUdf::TDataType<T>::Slot, false, isDesc);
  66. encoder.Start();
  67. encoder.Encode(NUdf::TUnboxedValuePod(value));
  68. auto bytes = encoder.Finish();
  69. UNIT_ASSERT_STRINGS_EQUAL(HexEncode(bytes.data(), bytes.size()), hex);
  70. decoder.Start(bytes);
  71. auto decoded = decoder.Decode().Get<T>();
  72. decoder.Finish();
  73. UNIT_ASSERT_EQUAL(decoded, value);
  74. };
  75. template <NUdf::EDataSlot Slot>
  76. void ValidateEncoding(bool isDesc, TStringBuf value, const TString& hex) {
  77. TPresortEncoder encoder;
  78. encoder.AddType(Slot, false, isDesc);
  79. TPresortDecoder decoder;
  80. decoder.AddType(Slot, false, isDesc);
  81. encoder.Start();
  82. encoder.Encode(NUdf::TUnboxedValue(MakeString(NUdf::TStringRef(value))));
  83. auto bytes = encoder.Finish();
  84. UNIT_ASSERT_STRINGS_EQUAL(HexEncode(bytes.data(), bytes.size()), hex);
  85. decoder.Start(bytes);
  86. auto uv = decoder.Decode();
  87. decoder.Finish();
  88. auto stringRef = uv.AsStringRef();
  89. auto decoded = TStringBuf(stringRef.Data(), stringRef.Size());
  90. UNIT_ASSERT_EQUAL(decoded, value);
  91. }
  92. template <NUdf::EDataSlot Slot, typename T>
  93. void ValidateEncoding(bool isDesc, const std::pair<T, ui16>& value, const TString& hex) {
  94. TPresortEncoder encoder;
  95. encoder.AddType(Slot, false, isDesc);
  96. TPresortDecoder decoder;
  97. decoder.AddType(Slot, false, isDesc);
  98. NUdf::TUnboxedValuePod uv(value.first);
  99. uv.SetTimezoneId(value.second);
  100. encoder.Start();
  101. encoder.Encode(uv);
  102. auto bytes = encoder.Finish();
  103. UNIT_ASSERT_STRINGS_EQUAL(HexEncode(bytes.data(), bytes.size()), hex);
  104. decoder.Start(bytes);
  105. auto decoded = decoder.Decode();
  106. decoder.Finish();
  107. UNIT_ASSERT_EQUAL(decoded.Get<T>(), value.first);
  108. UNIT_ASSERT_EQUAL(decoded.GetTimezoneId(), value.second);
  109. };
  110. void ValidateEncoding(bool isDesc, NYql::NDecimal::TInt128 value, const TString& hex) {
  111. TPresortEncoder encoder;
  112. encoder.AddType(NUdf::EDataSlot::Decimal, false, isDesc);
  113. TPresortDecoder decoder;
  114. decoder.AddType(NUdf::EDataSlot::Decimal, false, isDesc);
  115. encoder.Start();
  116. encoder.Encode(NUdf::TUnboxedValuePod(value));
  117. auto bytes = encoder.Finish();
  118. UNIT_ASSERT_STRINGS_EQUAL(HexEncode(bytes.data(), bytes.size()), hex);
  119. decoder.Start(bytes);
  120. auto decoded = decoder.Decode().GetInt128();
  121. decoder.Finish();
  122. UNIT_ASSERT_EQUAL(decoded, value);
  123. };
  124. template <typename T>
  125. void ValidateEncoding(const TVector<T>& values) {
  126. for (auto& value : values) {
  127. ValidateEncoding(false, std::get<0>(value), std::get<1>(value));
  128. ValidateEncoding(true, std::get<0>(value), std::get<2>(value));
  129. }
  130. }
  131. template <NUdf::EDataSlot Slot, typename T>
  132. void ValidateEncoding(const TVector<T>& values) {
  133. for (auto& value : values) {
  134. ValidateEncoding<Slot>(false, std::get<0>(value), std::get<1>(value));
  135. ValidateEncoding<Slot>(true, std::get<0>(value), std::get<2>(value));
  136. }
  137. }
  138. };
  139. }
  140. Y_UNIT_TEST_SUITE(TPresortCodecTest) {
  141. Y_UNIT_TEST(SimpleTypes) {
  142. TPresortTest test;
  143. TSimpleTypes values = {false, 1u, 2u, 3u, 4u, 5, 6, 7, 8, 9.f, 10.0};
  144. auto validateSimpleTypes = [&] (bool isOptional, bool isDesc) {
  145. TPresortEncoder encoder;
  146. AddTypes(encoder, isOptional, isDesc);
  147. TPresortDecoder decoder;
  148. AddTypes(decoder, isOptional, isDesc);
  149. auto bytes = Encode(encoder, values);
  150. Decode(decoder, bytes, values);
  151. };
  152. validateSimpleTypes(false, false);
  153. validateSimpleTypes(false, true);
  154. validateSimpleTypes(true, false);
  155. validateSimpleTypes(true, true);
  156. }
  157. Y_UNIT_TEST(Bool) {
  158. const TVector<std::tuple<bool, TString, TString>> values = {
  159. {false, "00", "FF"},
  160. {true, "01", "FE"}
  161. };
  162. TPresortTest().ValidateEncoding(values);
  163. }
  164. Y_UNIT_TEST(Int8) {
  165. const TVector<std::tuple<i8, TString, TString>> values = {
  166. {-0x80, "00", "FF"},
  167. {-1, "7F", "80"},
  168. {0, "80", "7F"},
  169. {1, "81", "7E"},
  170. {0x7F, "FF", "00"}
  171. };
  172. TPresortTest().ValidateEncoding(values);
  173. }
  174. Y_UNIT_TEST(Uint8) {
  175. const TVector<std::tuple<ui8, TString, TString>> values = {
  176. {0u, "00", "FF"},
  177. {0x80u, "80", "7F"},
  178. {0xFFu, "FF", "00"},
  179. };
  180. TPresortTest().ValidateEncoding(values);
  181. }
  182. Y_UNIT_TEST(Int16) {
  183. const TVector<std::tuple<i16, TString, TString>> values = {
  184. {-0x8000, "0000", "FFFF"},
  185. {-1, "7FFF", "8000"},
  186. {0, "8000", "7FFF"},
  187. {1, "8001", "7FFE"},
  188. {0x7FFF, "FFFF", "0000"}
  189. };
  190. TPresortTest().ValidateEncoding(values);
  191. }
  192. Y_UNIT_TEST(Uint16) {
  193. const TVector<std::tuple<ui16, TString, TString>> values = {
  194. {0, "0000", "FFFF"},
  195. {0x8000u, "8000", "7FFF"},
  196. {0xFFFFu, "FFFF", "0000"},
  197. };
  198. TPresortTest().ValidateEncoding(values);
  199. }
  200. Y_UNIT_TEST(Int32) {
  201. const TVector<std::tuple<i32, TString, TString>> values = {
  202. {-0x80000000, "00000000", "FFFFFFFF"},
  203. {-1, "7FFFFFFF", "80000000"},
  204. {0, "80000000", "7FFFFFFF"},
  205. {1, "80000001", "7FFFFFFE"},
  206. {0x7FFFFFFF, "FFFFFFFF", "00000000"}
  207. };
  208. TPresortTest().ValidateEncoding(values);
  209. }
  210. Y_UNIT_TEST(Uint32) {
  211. const TVector<std::tuple<ui32, TString, TString>> values = {
  212. {0u, "00000000", "FFFFFFFF"},
  213. {0x80000000u, "80000000", "7FFFFFFF"},
  214. {0xFFFFFFFFu, "FFFFFFFF", "00000000"},
  215. };
  216. TPresortTest().ValidateEncoding(values);
  217. }
  218. Y_UNIT_TEST(Int64) {
  219. const TVector<std::tuple<i64, TString, TString>> values = {
  220. {-0x8000000000000000, "0000000000000000", "FFFFFFFFFFFFFFFF"},
  221. {-1, "7FFFFFFFFFFFFFFF", "8000000000000000"},
  222. {0, "8000000000000000", "7FFFFFFFFFFFFFFF"},
  223. {1, "8000000000000001", "7FFFFFFFFFFFFFFE"},
  224. {0x7FFFFFFFFFFFFFFF, "FFFFFFFFFFFFFFFF", "0000000000000000"}
  225. };
  226. TPresortTest().ValidateEncoding(values);
  227. }
  228. Y_UNIT_TEST(Uint64) {
  229. const TVector<std::tuple<ui64, TString, TString>> values = {
  230. {0u, "0000000000000000", "FFFFFFFFFFFFFFFF"},
  231. {0x8000000000000000u, "8000000000000000", "7FFFFFFFFFFFFFFF"},
  232. {0xFFFFFFFFFFFFFFFFu, "FFFFFFFFFFFFFFFF", "0000000000000000"}
  233. };
  234. TPresortTest().ValidateEncoding(values);
  235. }
  236. Y_UNIT_TEST(Float) {
  237. using TLimits = std::numeric_limits<float>;
  238. const TVector<std::tuple<float, TString, TString>> values = {
  239. {-TLimits::infinity(), "00", "FF"},
  240. {-TLimits::max(), "0100800000", "FEFF7FFFFF"},
  241. {-1.f, "01407FFFFF", "FEBF800000"},
  242. {-TLimits::min(), "017F7FFFFF", "FE80800000"},
  243. {-TLimits::min()/8.f, "017FEFFFFF", "FE80100000"},
  244. {0.f, "02", "FD"},
  245. {TLimits::min()/8.f, "0300100000", "FCFFEFFFFF"},
  246. {TLimits::min(), "0300800000", "FCFF7FFFFF"},
  247. {1.f, "033F800000", "FCC07FFFFF"},
  248. {TLimits::max(), "037F7FFFFF", "FC80800000"},
  249. {TLimits::infinity(), "04", "FB"},
  250. };
  251. TPresortTest().ValidateEncoding(values);
  252. }
  253. Y_UNIT_TEST(Double) {
  254. using TLimits = std::numeric_limits<double>;
  255. const TVector<std::tuple<double, TString, TString>> values = {
  256. {-TLimits::infinity(), "00", "FF"},
  257. {-TLimits::max(), "010010000000000000", "FEFFEFFFFFFFFFFFFF"},
  258. {-1., "01400FFFFFFFFFFFFF", "FEBFF0000000000000"},
  259. {-TLimits::min(), "017FEFFFFFFFFFFFFF", "FE8010000000000000"},
  260. {-TLimits::min()/8., "017FFDFFFFFFFFFFFF", "FE8002000000000000"},
  261. {0., "02", "FD"},
  262. {TLimits::min()/8., "030002000000000000", "FCFFFDFFFFFFFFFFFF"},
  263. {TLimits::min(), "030010000000000000", "FCFFEFFFFFFFFFFFFF"},
  264. {1., "033FF0000000000000", "FCC00FFFFFFFFFFFFF"},
  265. {TLimits::max(), "037FEFFFFFFFFFFFFF", "FC8010000000000000"},
  266. {TLimits::infinity(), "04", "FB"},
  267. };
  268. TPresortTest().ValidateEncoding(values);
  269. }
  270. Y_UNIT_TEST(String) {
  271. const TVector<std::tuple<TStringBuf, TString, TString>> values = {
  272. {TStringBuf(""), "00", "FF"},
  273. {"\x00"sv, "1F00000000000000000000000000000001",
  274. "E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"},
  275. {"\x01", "1F01000000000000000000000000000001",
  276. "E0FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"},
  277. {"0", "1F30000000000000000000000000000001",
  278. "E0CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"},
  279. {"0123", "1F30313233000000000000000000000004",
  280. "E0CFCECDCCFFFFFFFFFFFFFFFFFFFFFFFB"},
  281. {"0123456789abcde", "1F3031323334353637383961626364650F",
  282. "E0CFCECDCCCBCAC9C8C7C69E9D9C9B9AF0"},
  283. {"a", "1F61000000000000000000000000000001",
  284. "E09EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"},
  285. {"a\x00"sv, "1F61000000000000000000000000000002",
  286. "E09EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD"},
  287. {"abc", "1F61626300000000000000000000000003",
  288. "E09E9D9CFFFFFFFFFFFFFFFFFFFFFFFFFC"},
  289. {"b", "1F62000000000000000000000000000001",
  290. "E09DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"},
  291. };
  292. TPresortTest().ValidateEncoding<NUdf::EDataSlot::String>(values);
  293. }
  294. Y_UNIT_TEST(Uuid) {
  295. const TVector<std::tuple<TStringBuf, TString, TString>> values = {
  296. {"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"sv,
  297. "00000000000000000000000000000000",
  298. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"},
  299. {"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1"sv,
  300. "00000000000000000000000000000001",
  301. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"},
  302. {"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff",
  303. "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
  304. "00000000000000000000000000000000"},
  305. };
  306. TPresortTest().ValidateEncoding<NUdf::EDataSlot::Uuid>(values);
  307. }
  308. Y_UNIT_TEST(TzDate) {
  309. const TVector<std::tuple<std::pair<ui16, ui16>, TString, TString>> values = {
  310. {{0u, 0u}, "00000000", "FFFFFFFF"},
  311. {{0u, 1u}, "00000001", "FFFFFFFE"},
  312. {{1u, 0u}, "00010000", "FFFEFFFF"},
  313. {{NUdf::MAX_DATE, 0u}, "C2090000", "3DF6FFFF"},
  314. };
  315. TPresortTest().ValidateEncoding<NUdf::EDataSlot::TzDate>(values);
  316. }
  317. Y_UNIT_TEST(TzDatetime) {
  318. const TVector<std::tuple<std::pair<ui32, ui16>, TString, TString>> values = {
  319. {{0u, 0u}, "000000000000", "FFFFFFFFFFFF"},
  320. {{0u, 1u}, "000000000001", "FFFFFFFFFFFE"},
  321. {{1u, 0u}, "000000010000", "FFFFFFFEFFFF"},
  322. {{NUdf::MAX_DATETIME, 0u}, "FFCEDD800000", "0031227FFFFF"},
  323. };
  324. TPresortTest().ValidateEncoding<NUdf::EDataSlot::TzDatetime>(values);
  325. }
  326. Y_UNIT_TEST(TzTimestamp) {
  327. const TVector<std::tuple<std::pair<ui64, ui16>, TString, TString>> values = {
  328. {{0u, 0u}, "00000000000000000000", "FFFFFFFFFFFFFFFFFFFF"},
  329. {{0u, 1u}, "00000000000000000001", "FFFFFFFFFFFFFFFFFFFE"},
  330. {{1u, 0u}, "00000000000000010000", "FFFFFFFFFFFFFFFEFFFF"},
  331. {{NUdf::MAX_TIMESTAMP, 0u}, "000F3F52435260000000", "FFF0C0ADBCAD9FFFFFFF"},
  332. };
  333. TPresortTest().ValidateEncoding<NUdf::EDataSlot::TzTimestamp>(values);
  334. }
  335. Y_UNIT_TEST(TzDate32) {
  336. const TVector<std::tuple<std::pair<i32, ui16>, TString, TString>> values = {
  337. {{0, 0u}, "800000000000", "7FFFFFFFFFFF"},
  338. {{0, 1u}, "800000000001", "7FFFFFFFFFFE"},
  339. {{1, 0u}, "800000010000", "7FFFFFFEFFFF"},
  340. {{NUdf::MIN_DATE32, 0u}, "7CD18CBF0000", "832E7340FFFF"},
  341. {{NUdf::MAX_DATE32, 0u}, "832E733F0000", "7CD18CC0FFFF"},
  342. };
  343. TPresortTest().ValidateEncoding<NUdf::EDataSlot::TzDate32>(values);
  344. }
  345. Y_UNIT_TEST(TzDatetime64) {
  346. const TVector<std::tuple<std::pair<i64, ui16>, TString, TString>> values = {
  347. {{0, 0u}, "80000000000000000000", "7FFFFFFFFFFFFFFFFFFF"},
  348. {{0, 1u}, "80000000000000000001", "7FFFFFFFFFFFFFFFFFFE"},
  349. {{1, 0u}, "80000000000000010000", "7FFFFFFFFFFFFFFEFFFF"},
  350. {{NUdf::MIN_DATETIME64, 0u}, "7FFFFBCE430DCE800000", "80000431BCF2317FFFFF"},
  351. {{NUdf::MAX_DATETIME64, 0u}, "80000431BCF0DFFF0000", "7FFFFBCE430F2000FFFF"},
  352. };
  353. TPresortTest().ValidateEncoding<NUdf::EDataSlot::TzDatetime64>(values);
  354. }
  355. Y_UNIT_TEST(TzTimestamp64) {
  356. const TVector<std::tuple<std::pair<i64, ui16>, TString, TString>> values = {
  357. {{0, 0u}, "80000000000000000000", "7FFFFFFFFFFFFFFFFFFF"},
  358. {{0, 1u}, "80000000000000000001", "7FFFFFFFFFFFFFFFFFFE"},
  359. {{1, 0u}, "80000000000000010000", "7FFFFFFFFFFFFFFEFFFF"},
  360. {{NUdf::MIN_TIMESTAMP64, 0u}, "40000EA96C30A0000000", "BFFFF15693CF5FFFFFFF"},
  361. {{NUdf::MAX_TIMESTAMP64, 0u}, "BFFFF14275F7FFFF0000", "40000EBD8A080000FFFF"},
  362. };
  363. TPresortTest().ValidateEncoding<NUdf::EDataSlot::TzTimestamp64>(values);
  364. }
  365. Y_UNIT_TEST(Decimal) {
  366. const TVector<std::tuple<NYql::NDecimal::TInt128, TString, TString>> values = {
  367. {-NYql::NDecimal::Inf(),
  368. "01",
  369. "FE"},
  370. {NYql::NDecimal::TInt128(-1),
  371. "7F",
  372. "8101"},
  373. {NYql::NDecimal::TInt128(0),
  374. "80",
  375. "80"},
  376. {NYql::NDecimal::TInt128(1),
  377. "8101",
  378. "7F"},
  379. {NYql::NDecimal::Inf(),
  380. "FE",
  381. "01"},
  382. {NYql::NDecimal::Nan(),
  383. "FF",
  384. "00"},
  385. };
  386. TPresortTest().ValidateEncoding(values);
  387. }
  388. Y_UNIT_TEST(GenericVoid) {
  389. TScopedAlloc alloc(__LOCATION__);
  390. TTypeEnvironment env(alloc);
  391. auto type = env.GetVoidLazy()->GetType();
  392. NUdf::TUnboxedValue value = NUdf::TUnboxedValuePod::Void();
  393. TGenericPresortEncoder encoder(type);
  394. auto buf = encoder.Encode(value, false);
  395. UNIT_ASSERT_NO_DIFF(buf, TStringBuf(""));
  396. }
  397. Y_UNIT_TEST(GenericBool) {
  398. TScopedAlloc alloc(__LOCATION__);
  399. TTypeEnvironment env(alloc);
  400. auto type = TDataType::Create(NUdf::TDataType<bool>::Id, env);
  401. NUdf::TUnboxedValue value = NUdf::TUnboxedValuePod(true);
  402. TGenericPresortEncoder encoder(type);
  403. auto buf = encoder.Encode(value, false);
  404. UNIT_ASSERT_NO_DIFF(buf, TStringBuf("\x01"));
  405. buf = encoder.Encode(value, true);
  406. UNIT_ASSERT_NO_DIFF(buf, TStringBuf("\xFE"));
  407. }
  408. Y_UNIT_TEST(GenericNumber) {
  409. TScopedAlloc alloc(__LOCATION__);
  410. TTypeEnvironment env(alloc);
  411. auto type = TDataType::Create(NUdf::TDataType<ui32>::Id, env);
  412. NUdf::TUnboxedValue value = NUdf::TUnboxedValuePod(ui32(1234));
  413. TGenericPresortEncoder encoder(type);
  414. auto buf = encoder.Encode(value, false);
  415. UNIT_ASSERT_NO_DIFF(buf, TStringBuf("\x00\x00\x04\xD2"sv));
  416. }
  417. Y_UNIT_TEST(GenericString) {
  418. TScopedAlloc alloc(__LOCATION__);
  419. TTypeEnvironment env(alloc);
  420. auto type = TDataType::Create(NUdf::TDataType<char*>::Id, env);
  421. NUdf::TUnboxedValue value = MakeString("ALongStringExample");
  422. TGenericPresortEncoder encoder(type);
  423. auto buf = encoder.Encode(value, false);
  424. UNIT_ASSERT_NO_DIFF(buf, TStringBuf("\x1F" "ALongStringExam\x1Fple\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03"sv));
  425. }
  426. Y_UNIT_TEST(GenericOptional) {
  427. TScopedAlloc alloc(__LOCATION__);
  428. TTypeEnvironment env(alloc);
  429. auto type = TOptionalType::Create(TDataType::Create(NUdf::TDataType<bool>::Id, env), env);
  430. NUdf::TUnboxedValue value = NUdf::TUnboxedValuePod(true);
  431. TGenericPresortEncoder encoder(type);
  432. auto buf = encoder.Encode(value, false);
  433. UNIT_ASSERT_NO_DIFF(buf, TStringBuf("\x01\x01"));
  434. value = {};
  435. buf = encoder.Encode(value, false);
  436. UNIT_ASSERT_NO_DIFF(buf, TStringBuf("\x00"sv));
  437. }
  438. Y_UNIT_TEST(NestedOptional) {
  439. TScopedAlloc alloc(__LOCATION__);
  440. TTypeEnvironment env(alloc);
  441. // Int32???
  442. auto type =
  443. TOptionalType::Create(TOptionalType::Create(TOptionalType::Create(TDataType::Create(NUdf::TDataType<i32>::Id, env), env), env), env);
  444. TGenericPresortEncoder encoder(type);
  445. NUdf::TUnboxedValue null = {};
  446. auto buf = encoder.Encode(null, false);
  447. UNIT_ASSERT_NO_DIFF(buf, TStringBuf("\x00"sv));
  448. auto justNull = null.MakeOptional();
  449. buf = encoder.Encode(justNull, false);
  450. UNIT_ASSERT_NO_DIFF(buf, TStringBuf("\x01\x00"sv));
  451. auto justJustNull = justNull.MakeOptional();
  452. buf = encoder.Encode(justJustNull, false);
  453. UNIT_ASSERT_NO_DIFF(buf, TStringBuf("\x01\x01\x00"sv));
  454. auto zero = NUdf::TUnboxedValuePod(0).MakeOptional().MakeOptional().MakeOptional();
  455. buf = encoder.Encode(zero, false);
  456. UNIT_ASSERT_NO_DIFF(buf, TStringBuf("\x01\x01\x01\x80\x00\x00\x00"sv));
  457. }
  458. Y_UNIT_TEST(GenericList) {
  459. TScopedAlloc alloc(__LOCATION__);
  460. TTypeEnvironment env(alloc);
  461. auto type = TListType::Create(TDataType::Create(NUdf::TDataType<bool>::Id, env), env);
  462. TMemoryUsageInfo memInfo("test");
  463. THolderFactory holderFactory(alloc.Ref(), memInfo);
  464. auto value = holderFactory.GetEmptyContainerLazy();
  465. TGenericPresortEncoder encoder(type);
  466. auto buf = encoder.Encode(value, false);
  467. UNIT_ASSERT_NO_DIFF(buf, TStringBuf("\x00"sv));
  468. NUdf::TUnboxedValue* items;
  469. value = holderFactory.CreateDirectArrayHolder(1, items);
  470. items[0] = NUdf::TUnboxedValuePod(true);
  471. buf = encoder.Encode(value, false);
  472. UNIT_ASSERT_NO_DIFF(buf, TStringBuf("\x01\x01\x00"sv));
  473. value = holderFactory.CreateDirectArrayHolder(2, items);
  474. items[0] = NUdf::TUnboxedValuePod(true);
  475. items[1] = NUdf::TUnboxedValuePod(false);
  476. buf = encoder.Encode(value, false);
  477. UNIT_ASSERT_NO_DIFF(buf, TStringBuf("\x01\x01\x01\x00\x00"sv));
  478. }
  479. Y_UNIT_TEST(GenericTuple) {
  480. TScopedAlloc alloc(__LOCATION__);
  481. TTypeEnvironment env(alloc);
  482. TType* tupleTypes[2];
  483. tupleTypes[0] = TDataType::Create(NUdf::TDataType<bool>::Id, env);
  484. tupleTypes[1] = TDataType::Create(NUdf::TDataType<ui32>::Id, env);
  485. auto type = TTupleType::Create(2, tupleTypes, env);
  486. TMemoryUsageInfo memInfo("test");
  487. THolderFactory holderFactory(alloc.Ref(), memInfo);
  488. NUdf::TUnboxedValue* items;
  489. auto value = holderFactory.CreateDirectArrayHolder(2, items);
  490. items[0] = NUdf::TUnboxedValuePod(true);
  491. items[1] = NUdf::TUnboxedValuePod(ui32(1234));
  492. TGenericPresortEncoder encoder(type);
  493. auto buf = encoder.Encode(value, false);
  494. UNIT_ASSERT_NO_DIFF(buf, TStringBuf("\x01\x00\x00\x04\xD2"sv));
  495. }
  496. Y_UNIT_TEST(GenericStruct) {
  497. TScopedAlloc alloc(__LOCATION__);
  498. TTypeEnvironment env(alloc);
  499. TStructMember structTypes[2];
  500. structTypes[0] = TStructMember("A", TDataType::Create(NUdf::TDataType<bool>::Id, env));
  501. structTypes[1] = TStructMember("B", TDataType::Create(NUdf::TDataType<ui32>::Id, env));
  502. auto type = TStructType::Create(2, structTypes, env);
  503. TMemoryUsageInfo memInfo("test");
  504. THolderFactory holderFactory(alloc.Ref(), memInfo);
  505. NUdf::TUnboxedValue* items;
  506. auto value = holderFactory.CreateDirectArrayHolder(2, items);
  507. items[0] = NUdf::TUnboxedValuePod(true);
  508. items[1] = NUdf::TUnboxedValuePod(ui32(1234));
  509. TGenericPresortEncoder encoder(type);
  510. auto buf = encoder.Encode(value, false);
  511. UNIT_ASSERT_NO_DIFF(buf, TStringBuf("\x01\x00\x00\x04\xD2"sv));
  512. }
  513. Y_UNIT_TEST(GenericTupleVariant) {
  514. TScopedAlloc alloc(__LOCATION__);
  515. TTypeEnvironment env(alloc);
  516. TType* tupleTypes[2];
  517. tupleTypes[0] = TDataType::Create(NUdf::TDataType<bool>::Id, env);
  518. tupleTypes[1] = TDataType::Create(NUdf::TDataType<ui32>::Id, env);
  519. auto underlying = TTupleType::Create(2, tupleTypes, env);
  520. auto type = TVariantType::Create(underlying, env);
  521. TMemoryUsageInfo memInfo("test");
  522. THolderFactory holderFactory(alloc.Ref(), memInfo);
  523. TGenericPresortEncoder encoder(type);
  524. auto value = holderFactory.CreateVariantHolder(NUdf::TUnboxedValuePod(true), 0);
  525. auto buf = encoder.Encode(value, false);
  526. UNIT_ASSERT_NO_DIFF(buf, TStringBuf("\x00\x01"sv));
  527. value = holderFactory.CreateVariantHolder(NUdf::TUnboxedValuePod(ui32(1234)), 1);
  528. buf = encoder.Encode(value, false);
  529. UNIT_ASSERT_NO_DIFF(buf, TStringBuf("\x01\x00\x00\x04\xD2"sv));
  530. }
  531. Y_UNIT_TEST(GenericStructVariant) {
  532. TScopedAlloc alloc(__LOCATION__);
  533. TTypeEnvironment env(alloc);
  534. TStructMember structTypes[2];
  535. structTypes[0] = TStructMember("A", TDataType::Create(NUdf::TDataType<bool>::Id, env));
  536. structTypes[1] = TStructMember("B", TDataType::Create(NUdf::TDataType<ui32>::Id, env));
  537. auto underlying = TStructType::Create(2, structTypes, env);
  538. auto type = TVariantType::Create(underlying, env);
  539. TMemoryUsageInfo memInfo("test");
  540. THolderFactory holderFactory(alloc.Ref(), memInfo);
  541. TGenericPresortEncoder encoder(type);
  542. auto value = holderFactory.CreateVariantHolder(NUdf::TUnboxedValuePod(true), 0);
  543. auto buf = encoder.Encode(value, false);
  544. UNIT_ASSERT_NO_DIFF(buf, TStringBuf("\x00\x01"sv));
  545. value = holderFactory.CreateVariantHolder(NUdf::TUnboxedValuePod(ui32(1234)), 1);
  546. buf = encoder.Encode(value, false);
  547. UNIT_ASSERT_NO_DIFF(buf, TStringBuf("\x01\x00\x00\x04\xD2"sv));
  548. }
  549. Y_UNIT_TEST(GenericDict) {
  550. TScopedAlloc alloc(__LOCATION__);
  551. TTypeEnvironment env(alloc);
  552. auto type = TDictType::Create(TDataType::Create(NUdf::TDataType<ui32>::Id, env),
  553. TDataType::Create(NUdf::TDataType<bool>::Id, env), env);
  554. TKeyTypes keyTypes;
  555. bool isTuple;
  556. bool encoded;
  557. bool useIHash;
  558. GetDictionaryKeyTypes(type->GetKeyType(), keyTypes, isTuple, encoded, useIHash);
  559. UNIT_ASSERT(!isTuple);
  560. UNIT_ASSERT(!encoded);
  561. UNIT_ASSERT(!useIHash);
  562. TMemoryUsageInfo memInfo("test");
  563. THolderFactory holderFactory(alloc.Ref(), memInfo);
  564. auto value = holderFactory.GetEmptyContainerLazy();
  565. TGenericPresortEncoder encoder(type);
  566. auto buf = encoder.Encode(value, false);
  567. UNIT_ASSERT_NO_DIFF(buf, TStringBuf("\x00"sv));
  568. value = holderFactory.CreateDirectHashedDictHolder([](TValuesDictHashMap& map) {
  569. map.emplace(NUdf::TUnboxedValuePod(ui32(1234)), NUdf::TUnboxedValuePod(true));
  570. }, keyTypes, false, true, nullptr, nullptr, nullptr);
  571. buf = encoder.Encode(value, false);
  572. UNIT_ASSERT_NO_DIFF(buf, TStringBuf("\x01\x00\x00\x04\xD2\x01\x00"sv));
  573. value = holderFactory.CreateDirectHashedDictHolder([](TValuesDictHashMap& map) {
  574. map.emplace(NUdf::TUnboxedValuePod(ui32(5678)), NUdf::TUnboxedValuePod(false));
  575. map.emplace(NUdf::TUnboxedValuePod(ui32(1234)), NUdf::TUnboxedValuePod(true));
  576. }, keyTypes, false, true, nullptr, nullptr, nullptr);
  577. buf = encoder.Encode(value, false);
  578. UNIT_ASSERT_NO_DIFF(buf, TStringBuf("\x01\x00\x00\x04\xD2\x01\x01\x00\x00\x16\x2E\x00\x00"sv));
  579. }
  580. }
  581. } // NMiniKQL
  582. } // NKikimr