Skip to content

Commit 892a02a

Browse files
author
kinash-varvara
authored
Merge bc58e72 into 3204f33
2 parents 3204f33 + bc58e72 commit 892a02a

File tree

3 files changed

+77
-4
lines changed

3 files changed

+77
-4
lines changed

ydb/library/yql/parser/pg_wrapper/arrow.cpp

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,14 +183,17 @@ std::shared_ptr<arrow::Array> PgDecimal128ConvertNumeric(const std::shared_ptr<a
183183
size_t length = data->length;
184184
arrow::BinaryBuilder builder;
185185

186+
bool error;
187+
Numeric high_bits_mul = numeric_mul_opt_error(int64_to_numeric(int64_t(1) << 62), int64_to_numeric(4), &error);
188+
186189
auto input = data->GetValues<arrow::Decimal128>(1);
187190
for (size_t i = 0; i < length; ++i) {
188191
if (value->IsNull(i)) {
189192
ARROW_OK(builder.AppendNull());
190193
continue;
191194
}
192195

193-
Numeric v = PgDecimal128ToNumeric(input[i].high_bits(), input[i].low_bits(), precision, scale);
196+
Numeric v = PgDecimal128ToNumeric(input[i], precision, scale, high_bits_mul);
194197

195198
auto datum = NumericGetDatum(v);
196199
auto ptr = (char*)datum;
@@ -204,8 +207,28 @@ std::shared_ptr<arrow::Array> PgDecimal128ConvertNumeric(const std::shared_ptr<a
204207
return ret;
205208
}
206209

207-
Numeric PgDecimal128ToNumeric(int64_t high_bits, uint64_t low_bits, int32_t precision, int32_t scale) {
208-
Numeric res = int64_div_fast_to_numeric(low_bits, scale);
210+
Numeric PgDecimal128ToNumeric(arrow::Decimal128 value, int32_t precision, int32_t scale, Numeric& high_bits_mul) {
211+
uint64_t low_bits = value.low_bits();
212+
int64 high_bits = value.high_bits();
213+
std::cout << high_bits << '\n';
214+
std::cout << low_bits << '\n';
215+
216+
bool error;
217+
Numeric res;
218+
219+
if (!(high_bits == 0 || high_bits == -1)) {
220+
if (low_bits > INT64_MAX){
221+
high_bits += 1;
222+
}
223+
Numeric high_bits_res = numeric_mul_opt_error(int64_div_fast_to_numeric(high_bits, scale), high_bits_mul, &error);
224+
Numeric low_bits_res = int64_div_fast_to_numeric(int64_t(low_bits), scale);
225+
226+
res = numeric_add_opt_error(high_bits_res, low_bits_res, &error);
227+
}
228+
else {
229+
res = int64_div_fast_to_numeric(low_bits, scale);
230+
}
231+
209232
return res;
210233
}
211234

ydb/library/yql/parser/pg_wrapper/arrow_impl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ extern "C" {
1111
namespace NYql {
1212

1313
Numeric PgFloatToNumeric(double item, ui64 scale, int digits);
14-
Numeric PgDecimal128ToNumeric(int64_t high_bits, uint64_t low_bits, int32_t precision, int32_t scale);
14+
Numeric PgDecimal128ToNumeric(arrow::Decimal128 val, int32_t precision, int32_t scale, Numeric& high_bits_mul);
1515
TColumnConverter BuildPgColumnConverter(const std::shared_ptr<arrow::DataType>& originalType, NKikimr::NMiniKQL::TPgType* targetType);
1616

1717
template<typename T>

ydb/library/yql/parser/pg_wrapper/ut/arrow_ut.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,56 @@ Y_UNIT_TEST(PgConvertNumericDecimal128Scale5) {
185185
checkResult<false>(expected, result, &reader, numeric_out);
186186
}
187187

188+
Y_UNIT_TEST(PgConvertNumericDecimal128BigScale3) {
189+
TArenaMemoryContext arena;
190+
191+
int32_t precision = 20;
192+
int32_t scale = 3;
193+
std::shared_ptr<arrow::DataType> type(new arrow::Decimal128Type(precision, scale));
194+
arrow::Decimal128Builder builder(type);
195+
196+
const char* expected[] = {
197+
"36893488147419103.245", "-36893488147419103.245", nullptr
198+
};
199+
200+
ARROW_OK(builder.Append(arrow::Decimal128::FromString("36893488147419103.245").ValueOrDie()));
201+
ARROW_OK(builder.Append(arrow::Decimal128::FromString("-36893488147419103.245").ValueOrDie()));
202+
ARROW_OK(builder.AppendNull());
203+
204+
std::shared_ptr<arrow::Array> array;
205+
ARROW_OK(builder.Finish(&array));
206+
207+
auto result = PgDecimal128ConvertNumeric(array, precision, scale);
208+
209+
NYql::NUdf::TStringBlockReader<arrow::BinaryType, true> reader;
210+
checkResult<false>(expected, result, &reader, numeric_out);
211+
}
212+
213+
/*Y_UNIT_TEST(PgConvertNumericDecimal128BigScale6) {
214+
TArenaMemoryContext arena;
215+
216+
int32_t precision = 24;
217+
int32_t scale = 5;
218+
std::shared_ptr<arrow::DataType> type(new arrow::Decimal128Type(precision, scale));
219+
arrow::Decimal128Builder builder(type);
220+
221+
const char* expected[] = {
222+
"3623458934881474191.03245", "-3623458934881474191.03245", nullptr
223+
};
224+
225+
ARROW_OK(builder.Append(arrow::Decimal128::FromString("3623458934881474191.03245").ValueOrDie()));
226+
ARROW_OK(builder.Append(arrow::Decimal128::FromString("-3623458934881474191.03245").ValueOrDie()));
227+
ARROW_OK(builder.AppendNull());
228+
229+
std::shared_ptr<arrow::Array> array;
230+
ARROW_OK(builder.Finish(&array));
231+
232+
auto result = PgDecimal128ConvertNumeric(array, precision, scale);
233+
234+
NYql::NUdf::TStringBlockReader<arrow::BinaryType, true> reader;
235+
checkResult<false>(expected, result, &reader, numeric_out);
236+
}*/
237+
188238
Y_UNIT_TEST(PgConvertNumericInt) {
189239
TArenaMemoryContext arena;
190240

0 commit comments

Comments
 (0)