arrow_ut.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. #include "../pg_compat.h"
  2. #include <arrow/api.h>
  3. #include <arrow/array.h>
  4. #include <library/cpp/testing/unittest/registar.h>
  5. #include "arrow.h"
  6. #include "arrow_impl.h"
  7. extern "C" {
  8. #include "utils/fmgrprotos.h"
  9. }
  10. namespace {
  11. template <bool IsFixedSizeReader>
  12. void checkResult(const char ** expected, auto result, NYql::NUdf::IBlockReader* reader, auto out_fun) {
  13. const auto& data = result->data();
  14. for (int i = 0; i < data->length; i++) {
  15. if (result->IsNull(i)) {
  16. UNIT_ASSERT(expected[i] == nullptr);
  17. } else {
  18. UNIT_ASSERT(expected[i] != nullptr);
  19. Datum item;
  20. if constexpr (IsFixedSizeReader) {
  21. item = reader->GetItem(*data, i).template As<Datum>();
  22. } else {
  23. item = Datum(reader->GetItem(*data, i).AsStringRef().Data() + sizeof(void*));
  24. }
  25. UNIT_ASSERT_VALUES_EQUAL(
  26. TString(DatumGetCString(DirectFunctionCall1(out_fun, item))),
  27. expected[i]
  28. );
  29. }
  30. }
  31. }
  32. } // namespace {
  33. namespace NYql {
  34. Y_UNIT_TEST_SUITE(TArrowUtilsTests) {
  35. Y_UNIT_TEST(TestPgFloatToNumeric) {
  36. TArenaMemoryContext arena;
  37. auto n = PgFloatToNumeric(711.56, 1000000000000LL, 12);
  38. auto value = TString(DatumGetCString(DirectFunctionCall1(numeric_out, NumericGetDatum(n))));
  39. UNIT_ASSERT_VALUES_EQUAL(value, "711.56");
  40. n = PgFloatToNumeric(-711.56, 1000000000000LL, 12);
  41. value = TString(DatumGetCString(DirectFunctionCall1(numeric_out, NumericGetDatum(n))));
  42. UNIT_ASSERT_VALUES_EQUAL(value, "-711.56");
  43. n = PgFloatToNumeric(711.56f, 100000LL, 5);
  44. value = TString(DatumGetCString(DirectFunctionCall1(numeric_out, NumericGetDatum(n))));
  45. UNIT_ASSERT_VALUES_EQUAL(value, "711.56");
  46. n = PgFloatToNumeric(-711.56f, 100000LL, 5);
  47. value = TString(DatumGetCString(DirectFunctionCall1(numeric_out, NumericGetDatum(n))));
  48. UNIT_ASSERT_VALUES_EQUAL(value, "-711.56");
  49. }
  50. Y_UNIT_TEST(PgConvertNumericDouble) {
  51. TArenaMemoryContext arena;
  52. arrow::DoubleBuilder builder;
  53. ARROW_OK(builder.Append(1.1));
  54. ARROW_OK(builder.Append(31.37));
  55. ARROW_OK(builder.AppendNull());
  56. ARROW_OK(builder.Append(-1.337));
  57. ARROW_OK(builder.Append(0.0));
  58. std::shared_ptr<arrow::Array> array;
  59. ARROW_OK(builder.Finish(&array));
  60. auto result = PgConvertNumeric<double>(array);
  61. const char* expected[] = {
  62. "1.1", "31.37", nullptr, "-1.337", "0", "1.234111"
  63. };
  64. NYql::NUdf::TStringBlockReader<arrow::BinaryType, true> reader;
  65. checkResult<false>(expected, result, &reader, numeric_out);
  66. }
  67. Y_UNIT_TEST(PgConvertNumericDecimal128Scale1) {
  68. TArenaMemoryContext arena;
  69. int32_t precision = 6;
  70. int32_t scale = 1;
  71. std::shared_ptr<arrow::DataType> type(new arrow::Decimal128Type(precision, scale));
  72. arrow::Decimal128Builder builder(type);
  73. const char* expected[] = {
  74. "12345.0", "-12345.0", nullptr
  75. };
  76. ARROW_OK(builder.Append(arrow::Decimal128::FromString("12345.0").ValueOrDie()));
  77. ARROW_OK(builder.Append(arrow::Decimal128::FromString("-12345.0").ValueOrDie()));
  78. ARROW_OK(builder.AppendNull());
  79. std::shared_ptr<arrow::Array> array;
  80. ARROW_OK(builder.Finish(&array));
  81. auto result = PgDecimal128ConvertNumeric(array, precision, scale);
  82. NYql::NUdf::TStringBlockReader<arrow::BinaryType, true> reader;
  83. checkResult<false>(expected, result, &reader, numeric_out);
  84. }
  85. Y_UNIT_TEST(PgConvertNumericDecimal128ScaleNegative) {
  86. TArenaMemoryContext arena;
  87. int32_t precision = 8;
  88. int32_t scale = -3;
  89. std::shared_ptr<arrow::DataType> type(new arrow::Decimal128Type(precision, scale));
  90. arrow::Decimal128Builder builder(type);
  91. const char* expected[] = {
  92. "12345678000", "-12345678000", nullptr
  93. };
  94. ARROW_OK(builder.Append(arrow::Decimal128::FromString("12345678").ValueOrDie()));
  95. ARROW_OK(builder.Append(arrow::Decimal128::FromString("-12345678").ValueOrDie()));
  96. ARROW_OK(builder.AppendNull());
  97. std::shared_ptr<arrow::Array> array;
  98. ARROW_OK(builder.Finish(&array));
  99. auto result = PgDecimal128ConvertNumeric(array, precision, scale);
  100. NYql::NUdf::TStringBlockReader<arrow::BinaryType, true> reader;
  101. checkResult<false>(expected, result, &reader, numeric_out);
  102. }
  103. Y_UNIT_TEST(PgConvertNumericDecimal128Scale2) {
  104. TArenaMemoryContext arena;
  105. int32_t precision = 5;
  106. int32_t scale = 2;
  107. std::shared_ptr<arrow::DataType> type(new arrow::Decimal128Type(precision, scale));
  108. arrow::Decimal128Builder builder(type);
  109. const char* expected[] = {
  110. "123.45", "-123.45", nullptr
  111. };
  112. ARROW_OK(builder.Append(arrow::Decimal128::FromString("123.45").ValueOrDie()));
  113. ARROW_OK(builder.Append(arrow::Decimal128::FromString("-123.45").ValueOrDie()));
  114. ARROW_OK(builder.AppendNull());
  115. std::shared_ptr<arrow::Array> array;
  116. ARROW_OK(builder.Finish(&array));
  117. auto result = PgDecimal128ConvertNumeric(array, precision, scale);
  118. NYql::NUdf::TStringBlockReader<arrow::BinaryType, true> reader;
  119. checkResult<false>(expected, result, &reader, numeric_out);
  120. }
  121. Y_UNIT_TEST(PgConvertNumericDecimal128Scale3) {
  122. TArenaMemoryContext arena;
  123. int32_t precision = 3;
  124. int32_t scale = 3;
  125. std::shared_ptr<arrow::DataType> type(new arrow::Decimal128Type(precision, scale));
  126. arrow::Decimal128Builder builder(type);
  127. const char* expected[] = {
  128. "0.123", "-0.123", nullptr
  129. };
  130. ARROW_OK(builder.Append(arrow::Decimal128::FromString("0.123").ValueOrDie()));
  131. ARROW_OK(builder.Append(arrow::Decimal128::FromString("-0.123").ValueOrDie()));
  132. ARROW_OK(builder.AppendNull());
  133. std::shared_ptr<arrow::Array> array;
  134. ARROW_OK(builder.Finish(&array));
  135. auto result = PgDecimal128ConvertNumeric(array, precision, scale);
  136. NYql::NUdf::TStringBlockReader<arrow::BinaryType, true> reader;
  137. checkResult<false>(expected, result, &reader, numeric_out);
  138. }
  139. Y_UNIT_TEST(PgConvertNumericDecimal128Scale4) {
  140. TArenaMemoryContext arena;
  141. int32_t precision = 7;
  142. int32_t scale = 4;
  143. std::shared_ptr<arrow::DataType> type(new arrow::Decimal128Type(precision, scale));
  144. arrow::Decimal128Builder builder(type);
  145. const char* expected[] = {
  146. "123.4567", "-123.4567", nullptr
  147. };
  148. ARROW_OK(builder.Append(arrow::Decimal128::FromString("123.4567").ValueOrDie()));
  149. ARROW_OK(builder.Append(arrow::Decimal128::FromString("-123.4567").ValueOrDie()));
  150. ARROW_OK(builder.AppendNull());
  151. std::shared_ptr<arrow::Array> array;
  152. ARROW_OK(builder.Finish(&array));
  153. auto result = PgDecimal128ConvertNumeric(array, precision, scale);
  154. NYql::NUdf::TStringBlockReader<arrow::BinaryType, true> reader;
  155. checkResult<false>(expected, result, &reader, numeric_out);
  156. }
  157. Y_UNIT_TEST(PgConvertNumericDecimal128Scale5) {
  158. TArenaMemoryContext arena;
  159. int32_t precision = 7;
  160. int32_t scale = 5;
  161. std::shared_ptr<arrow::DataType> type(new arrow::Decimal128Type(precision, scale));
  162. arrow::Decimal128Builder builder(type);
  163. const char* expected[] = {
  164. "12.34567", "-12.34567", nullptr
  165. };
  166. ARROW_OK(builder.Append(arrow::Decimal128::FromReal(12.34567, precision, scale).ValueOrDie()));
  167. ARROW_OK(builder.Append(arrow::Decimal128::FromReal(-12.34567, precision, scale).ValueOrDie()));
  168. ARROW_OK(builder.AppendNull());
  169. std::shared_ptr<arrow::Array> array;
  170. ARROW_OK(builder.Finish(&array));
  171. auto result = PgDecimal128ConvertNumeric(array, precision, scale);
  172. NYql::NUdf::TStringBlockReader<arrow::BinaryType, true> reader;
  173. checkResult<false>(expected, result, &reader, numeric_out);
  174. }
  175. Y_UNIT_TEST(PgConvertNumericDecimal128BigScale3) {
  176. TArenaMemoryContext arena;
  177. int32_t precision = 20;
  178. int32_t scale = 3;
  179. std::shared_ptr<arrow::DataType> type(new arrow::Decimal128Type(precision, scale));
  180. arrow::Decimal128Builder builder(type);
  181. const char* expected[] = {
  182. "36893488147419103.245", "-36893488147419103.245",
  183. "46116860184273879.041", "-46116860184273879.041",
  184. nullptr
  185. };
  186. ARROW_OK(builder.Append(arrow::Decimal128::FromString("36893488147419103.245").ValueOrDie()));
  187. ARROW_OK(builder.Append(arrow::Decimal128::FromString("-36893488147419103.245").ValueOrDie()));
  188. ARROW_OK(builder.Append(arrow::Decimal128::FromString("46116860184273879.041").ValueOrDie()));
  189. ARROW_OK(builder.Append(arrow::Decimal128::FromString("-46116860184273879.041").ValueOrDie()));
  190. ARROW_OK(builder.AppendNull());
  191. std::shared_ptr<arrow::Array> array;
  192. ARROW_OK(builder.Finish(&array));
  193. auto result = PgDecimal128ConvertNumeric(array, precision, scale);
  194. NYql::NUdf::TStringBlockReader<arrow::BinaryType, true> reader;
  195. checkResult<false>(expected, result, &reader, numeric_out);
  196. }
  197. Y_UNIT_TEST(PgConvertNumericDecimal128BigScale1) {
  198. TArenaMemoryContext arena;
  199. int32_t precision = 26;
  200. int32_t scale = 1;
  201. std::shared_ptr<arrow::DataType> type(new arrow::Decimal128Type(precision, scale));
  202. arrow::Decimal128Builder builder(type);
  203. const char* expected[] = {
  204. "3868562622766813359059763.2", "-3868562622766813359059763.2", nullptr
  205. };
  206. ARROW_OK(builder.Append(arrow::Decimal128::FromString("3868562622766813359059763.2").ValueOrDie()));
  207. ARROW_OK(builder.Append(arrow::Decimal128::FromString("-3868562622766813359059763.2").ValueOrDie()));
  208. ARROW_OK(builder.AppendNull());
  209. std::shared_ptr<arrow::Array> array;
  210. ARROW_OK(builder.Finish(&array));
  211. auto result = PgDecimal128ConvertNumeric(array, precision, scale);
  212. NYql::NUdf::TStringBlockReader<arrow::BinaryType, true> reader;
  213. checkResult<false>(expected, result, &reader, numeric_out);
  214. }
  215. Y_UNIT_TEST(PgConvertNumericInt) {
  216. TArenaMemoryContext arena;
  217. arrow::Int64Builder builder;
  218. ARROW_OK(builder.Append(11));
  219. ARROW_OK(builder.Append(3137));
  220. ARROW_OK(builder.AppendNull());
  221. ARROW_OK(builder.Append(-1337));
  222. ARROW_OK(builder.Append(0));
  223. std::shared_ptr<arrow::Array> array;
  224. ARROW_OK(builder.Finish(&array));
  225. auto result = PgConvertNumeric<i64>(array);
  226. const auto& data = result->data();
  227. const char* expected[] = {
  228. "11", "3137", nullptr, "-1337", "0"
  229. };
  230. NYql::NUdf::TStringBlockReader<arrow::BinaryType, true> reader;
  231. checkResult<false>(expected, result, &reader, numeric_out);
  232. }
  233. Y_UNIT_TEST(PgConvertDate32Date) {
  234. TArenaMemoryContext arena;
  235. arrow::Date32Builder builder;
  236. ARROW_OK(builder.Append(10227));
  237. ARROW_OK(builder.AppendNull());
  238. ARROW_OK(builder.Append(11323));
  239. ARROW_OK(builder.Append(10227));
  240. ARROW_OK(builder.Append(10958));
  241. ARROW_OK(builder.Append(11688));
  242. std::shared_ptr<arrow::Array> array;
  243. ARROW_OK(builder.Finish(&array));
  244. NKikimr::NMiniKQL::TScopedAlloc alloc(__LOCATION__);
  245. NKikimr::NMiniKQL::TTypeEnvironment typeEnv(alloc);
  246. auto* targetType = NKikimr::NMiniKQL::TPgType::Create(DATEOID, typeEnv);
  247. auto converter = BuildPgColumnConverter(std::shared_ptr<arrow::DataType>(new arrow::Date32Type), targetType);
  248. auto result = converter(array);
  249. UNIT_ASSERT_VALUES_EQUAL(result->length(), 6);
  250. const char* expected[] = {
  251. "1998-01-01", nullptr, "2001-01-01", "1998-01-01", "2000-01-02", "2002-01-01"
  252. };
  253. NUdf::TFixedSizeBlockReader<ui64, true> reader;
  254. checkResult<true>(expected, result, &reader, date_out);
  255. }
  256. } // Y_UNIT_TEST_SUITE(TArrowUtilsTests)
  257. } // namespace NYql