diff --git a/bolt/functions/sparksql/UnscaledValueFunction.cpp b/bolt/functions/sparksql/UnscaledValueFunction.cpp index 69fbc7cf5..d3b8a7e7c 100644 --- a/bolt/functions/sparksql/UnscaledValueFunction.cpp +++ b/bolt/functions/sparksql/UnscaledValueFunction.cpp @@ -47,15 +47,23 @@ class UnscaledValueFunction final : public exec::VectorFunction { args[0]->type()->isShortDecimal(), "Expect short decimal type, but got: {}", args[0]->type()); - exec::DecodedArgs decodedArgs(rows, args, context); - auto decimalVector = decodedArgs.at(0); - context.ensureWritable(rows, BIGINT(), result); - result->clearNulls(rows); - auto flatResult = - result->asUnchecked>()->mutableRawValues(); - rows.applyToSelected([&](auto row) { - flatResult[row] = decimalVector->valueAt(row); - }); + VectorPtr localResult; + const auto& arg = args[0]; + if (arg->isConstantEncoding()) { + auto value = arg->as>()->valueAt(0); + localResult = std::make_shared>( + context.pool(), rows.end(), false, BIGINT(), std::move(value)); + } else { + auto flatInput = arg->asFlatVector(); + localResult = std::make_shared>( + context.pool(), + BIGINT(), + nullptr, + rows.end(), + flatInput->values(), + std::vector()); + } + context.moveOrCopyResult(localResult, rows, result); } }; } // namespace diff --git a/bolt/functions/sparksql/tests/UnscaledValueFunctionTest.cpp b/bolt/functions/sparksql/tests/UnscaledValueFunctionTest.cpp index 5aa19cd64..311a9664d 100644 --- a/bolt/functions/sparksql/tests/UnscaledValueFunctionTest.cpp +++ b/bolt/functions/sparksql/tests/UnscaledValueFunctionTest.cpp @@ -37,18 +37,18 @@ namespace { class UnscaledValueFunctionTest : public SparkFunctionBaseTest {}; TEST_F(UnscaledValueFunctionTest, unscaledValue) { - auto testUnscaledValue = [&](const std::vector& unscaledValue, - const TypePtr& decimalType) { - auto input = makeFlatVector(unscaledValue, decimalType); - auto expected = makeFlatVector(unscaledValue); - auto result = evaluate("unscaled_value(c0)", makeRowVector({input})); - assertEqualVectors(expected, result); - }; + auto input = + makeFlatVector({1000, 2000, -3000, -4000}, DECIMAL(18, 3)); + auto expected = makeFlatVector({1000, 2000, -3000, -4000}); + auto invalidInput = makeFlatVector({0, 0, 0, 0}, DECIMAL(20, 3)); - testUnscaledValue({1000, 2000, -3000, -4000}, DECIMAL(18, 3)); + testEncodings( + makeTypedExpr("unscaled_value(c0)", ROW({"c0"}, {input->type()})), + {input}, + expected); - BOLT_ASSERT_THROW( - testUnscaledValue({1000, 2000, -3000, -4000}, DECIMAL(20, 3)), + BOLT_ASSERT_USER_THROW( + evaluate("unscaled_value(c0)", makeRowVector({invalidInput})), "Expect short decimal type, but got: DECIMAL(20, 3)"); }