aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/parser/pg_wrapper/arrow_impl.h
blob: 707cd515d4504f10d0bc294e969f0df726153aed (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#pragma once

#include <arrow/array.h>
#include <arrow/array/builder_binary.h>
#include <yql/essentials/parser/pg_wrapper/interface/arrow.h>

extern "C" {
#include "utils/numeric.h"
}

namespace NYql {

Numeric Uint64ToPgNumeric(ui64 value);
Numeric DecimalToPgNumeric(const NUdf::TUnboxedValuePod& value, ui8 precision, ui8 scale);
Numeric DyNumberToPgNumeric(const NUdf::TUnboxedValuePod& value);
Numeric PgFloatToNumeric(double item, ui64 scale, int digits);
Numeric PgDecimal128ToNumeric(arrow::Decimal128 val, int32_t precision, int32_t scale, Numeric high_bits_mul);
TColumnConverter BuildPgColumnConverter(const std::shared_ptr<arrow::DataType>& originalType, NKikimr::NMiniKQL::TPgType* targetType);

template<typename T>
std::shared_ptr<arrow::Array> PgConvertNumeric(const std::shared_ptr<arrow::Array>& value) {
    TArenaMemoryContext arena;
    const auto& data = value->data();
    size_t length = data->length;
    arrow::BinaryBuilder builder;
    auto input = data->GetValues<T>(1);
    for (size_t i = 0; i < length; ++i) {
        if (value->IsNull(i)) {
            ARROW_OK(builder.AppendNull());
            continue;
        }
        T item = input[i];
        Numeric v;
        if constexpr(std::is_same_v<T, double>) {
            v = PgFloatToNumeric(item, 1000000000000LL, 12);
        } else if constexpr(std::is_same_v<T, float>) {
            v = PgFloatToNumeric(item, 1000000LL, 6);
        } else {
            v = int64_to_numeric(item);
        }
        auto datum = NumericGetDatum(v);
        auto ptr = (char*)datum;
        auto len = GetFullVarSize((const text*)datum);
        NUdf::ZeroMemoryContext(ptr);
        ARROW_OK(builder.Append(ptr - sizeof(void*), len + sizeof(void*)));
    }

    std::shared_ptr<arrow::BinaryArray> ret;
    ARROW_OK(builder.Finish(&ret));
    return ret;
}


std::shared_ptr<arrow::Array> PgDecimal128ConvertNumeric(const std::shared_ptr<arrow::Array>& value, int32_t precision, int32_t scale);

}