Skip to content

[C++] Why arrow decimal divide precision and scale is not correct? #39875

Description

@godliness

Describe the usage question you have. Please include as many useful details as possible.

select 1.00/id from test;
id is decimal(15,2) which is 16906.24
1.00 is decimal(3,2)
but the result is decimal(3, 0);

code is that


expr: 1727_2arrowfunc_divide(1.00, 0)
ARROW_ASSIGN_OR_RAISE(auto res, arrow::compute::ExecuteScalarExpression(
expr, arrow::compute::ExecBatch(*batch), &exec_context));

before we execute the scalar, we will bind the expr, it always go to the DispatchExct step not DispatchBest

image

and this

#0 arrow::compute::internal::(anonymous namespace)::ResolveDecimalDivisionOutput (types=std::vector of length -3918358451798, capacity 157086 = {...}) at /home/gpadmin/Projects/arrow/cpp/src/arrow/compute/kernels/scalar_arithmetic.cc:528
#1 0x00007f6374e52f29 in arrow::compute::OutputType::Resolve (this=0x558788ba0d58, ctx=0x7fffed4eb580, types=std::vector of length 2, capacity 2 = {...}) at /home/gpadmin/Projects/arrow/cpp/src/arrow/compute/kernel.cc:447
#2 0x00007f6374e1067d in arrow::compute::(anonymous namespace)::BindNonRecursive (call=..., insert_implicit_casts=true, exec_context=0x7fffed4eba70) at /home/gpadmin/Projects/arrow/cpp/src/arrow/compute/expression.cc:587
#3 0x00007f6374e1e0ba in arrow::compute::(anonymous namespace)::BindImpl<arrow::Schema> (expr=..., in=..., exec_context=0x7fffed4eba70) at /home/gpadmin/Projects/arrow/cpp/src/arrow/compute/expression.cc:619
#4 0x00007f6374e1db20 in arrow::compute::(anonymous namespace)::BindImpl<arrow::Schema> (expr=..., in=..., exec_context=0x0) at /home/gpadmin/Projects/arrow/cpp/src/arrow/compute/expression.cc:598
#5 0x00007f6374e10b6b in arrow::compute::Expression::Bind (this=0x558788f60570, in_schema=..., exec_context=0x0) at /home/gpadmin/Projects/arrow/cpp/src/arrow/compute/expression.cc:631

looks like it's follow the rule that is
rule1

Result<TypeHolder> ResolveDecimalDivisionOutput(KernelContext*,
const std::vector<TypeHolder>& types) {
return ResolveDecimalBinaryOperationOutput(
types, [](int32_t p1, int32_t s1, int32_t p2, int32_t s2) {
DCHECK_GE(s1, s2);
const int32_t scale = s1 - s2;
const int32_t precision = p1;
return std::make_pair(precision, scale);
});
}

but the document is show that
rule 2:

scale = max(4, s1 + p2 - s2 + 1)
precision = p1 - s1 + s2 + scale

How could i use the second rule?

Component(s)

C++

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions