Skip to content

Commit

Permalink
[GLUTEN-1273] Support casting decimal as int (facebookincubator#177)
Browse files Browse the repository at this point in the history
  • Loading branch information
jinchengchenghh authored and zhejiangxiaomai committed Apr 20, 2023
1 parent f24d7b0 commit 9d9dd6d
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 25 deletions.
34 changes: 21 additions & 13 deletions velox/expression/tests/CastExprTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,12 @@ TEST_F(CastExprTest, toString) {
ASSERT_EQ("cast((a) as ARRAY<VARCHAR>)", exprSet.exprs()[1]->toString());
}

TEST_F(CastExprTest, decimalToInt) {
// short to short, scale up.
auto longFlat = makeLongDecimalFlatVector({8976067200}, DECIMAL(21, 6));
testComplexCast("c0", longFlat, makeFlatVector<int32_t>({8976}));
}

TEST_F(CastExprTest, decimalToDecimal) {
// short to short, scale up.
auto shortFlat =
Expand Down Expand Up @@ -932,22 +938,24 @@ TEST_F(CastExprTest, integerToDecimal) {

TEST_F(CastExprTest, varcharToDecimal) {
// varchar to short decimal
// auto input = makeFlatVector<StringView>({"-3", "177"});
// testComplexCast(
// "c0", input, makeShortDecimalFlatVector({-300, 17700}, DECIMAL(6, 2)));

// // varchar to long decimal
// auto input2 = makeFlatVector<StringView>(
// {"-300000001234567891234.5", "1771234.5678912345678"});
// testComplexCast(
// "c0", input2, makeLongDecimalFlatVector({-300, 17700}, DECIMAL(32, 7)));
// auto input = makeFlatVector<StringView>({"-3", "177"});
// testComplexCast(
// "c0", input, makeShortDecimalFlatVector({-300, 17700}, DECIMAL(6,
// 2)));

// // varchar to long decimal
// auto input2 = makeFlatVector<StringView>(
// {"-300000001234567891234.5", "1771234.5678912345678"});
// testComplexCast(
// "c0", input2, makeLongDecimalFlatVector({-300, 17700}, DECIMAL(32,
// 7)));

auto input3 = makeFlatVector<StringView>({"9999999999.99", "9999999999.99"});
testComplexCast(
"c0", input3, makeLongDecimalFlatVector(
{-30'000'000'000,
-20'000'000'000},
DECIMAL(12, 2)));
"c0",
input3,
makeLongDecimalFlatVector(
{-30'000'000'000, -20'000'000'000}, DECIMAL(12, 2)));
}

TEST_F(CastExprTest, castInTry) {
Expand Down
54 changes: 42 additions & 12 deletions velox/type/Conversions.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,11 @@ struct Converter<TypeKind::BOOLEAN> {
}

static T cast(const UnscaledLongDecimal& d, bool& nullOutput) {
VELOX_UNSUPPORTED(
"Conversion of UnscaledLongDecimal to Boolean is not supported");
return folly::to<T>(d.unscaledValue());
}

static T cast(const UnscaledShortDecimal& d, bool& nullOutput) {
VELOX_UNSUPPORTED(
"Conversion of UnscaledShortDecimal to Boolean is not supported");
return folly::to<T>(d.unscaledValue());
}
};

Expand All @@ -113,6 +111,40 @@ struct Converter<
VELOX_NYI();
}

static T cast(
const UnscaledLongDecimal& d,
bool& nullOutput,
const TypePtr& fromType) {
const auto& decimalType = fromType->asLongDecimal();
auto scale0Decimal = DecimalUtil::
rescaleWithRoundUp<UnscaledLongDecimal, UnscaledLongDecimal>(
d,
decimalType.precision(),
decimalType.scale(),
decimalType.precision(),
0,
false,
false);
return cast(scale0Decimal.value().unscaledValue(), nullOutput);
}

static T cast(
const UnscaledShortDecimal& d,
bool& nullOutput,
const TypePtr& fromType) {
const auto& decimalType = fromType->asShortDecimal();
auto scale0Decimal = DecimalUtil::
rescaleWithRoundUp<UnscaledShortDecimal, UnscaledShortDecimal>(
d,
decimalType.precision(),
decimalType.scale(),
decimalType.precision(),
0,
false,
false);
return cast(scale0Decimal.value().unscaledValue(), nullOutput);
}

template <typename From>
static T cast(const From& v, bool& nullOutput) {
VELOX_UNSUPPORTED(
Expand Down Expand Up @@ -318,14 +350,12 @@ struct Converter<
}
}

static T cast(const UnscaledLongDecimal& d, bool& nullOutput) {
VELOX_UNSUPPORTED(
"Conversion of UnscaledLongDecimal to Boolean is not supported");
}

static T cast(const UnscaledShortDecimal& d, bool& nullOutput) {
VELOX_UNSUPPORTED(
"Conversion of UnscaledShortDecimal to Boolean is not supported");
static T cast(const int128_t& v, bool& nullOutput) {
if constexpr (TRUNCATE) {
return T(v);
} else {
return static_cast<T>(v);
}
}
};

Expand Down

0 comments on commit 9d9dd6d

Please sign in to comment.