bkietz commented on a change in pull request #10364:
URL: https://github.com/apache/arrow/pull/10364#discussion_r646711505
##########
File path: cpp/src/arrow/compute/kernels/scalar_arithmetic.cc
##########
@@ -428,12 +524,69 @@ ArrayKernelExec ArithmeticExecFromOp(detail::GetTypeId
get_id) {
}
}
+// calculate output precision/scale and args rescaling per operation type
+Result<std::shared_ptr<DataType>> GetDecimalBinaryOutput(
+ const std::string& op, const std::vector<ValueDescr>& values,
+ std::vector<std::shared_ptr<DataType>>* replaced = nullptr) {
+ const auto& left_type = checked_pointer_cast<DecimalType>(values[0].type);
+ const auto& right_type = checked_pointer_cast<DecimalType>(values[1].type);
+
+ const int32_t p1 = left_type->precision(), s1 = left_type->scale();
+ const int32_t p2 = right_type->precision(), s2 = right_type->scale();
+ if (s1 < 0 || s2 < 0) {
+ return Status::NotImplemented("Decimals with negative scales not
supported");
+ }
+
+ int32_t out_prec, out_scale;
+ int32_t left_scaleup = 0, right_scaleup = 0;
+
+ // decimal upscaling behaviour references amazon redshift
+ //
https://docs.aws.amazon.com/redshift/latest/dg/r_numeric_computations201.html
+ if (op.find("add") == 0 || op.find("subtract") == 0) {
+ out_scale = std::max(s1, s2);
+ out_prec = std::max(p1 - s1, p2 - s2) + 1 + out_scale;
+ left_scaleup = out_scale - s1;
+ right_scaleup = out_scale - s2;
+ } else if (op.find("multiply") == 0) {
+ out_scale = s1 + s2;
+ out_prec = p1 + p2 + 1;
+ } else if (op.find("divide") == 0) {
+ out_scale = std::max(4, s1 + p2 - s2 + 1);
+ out_prec = p1 - s1 + s2 + out_scale; // >= p1 + p2 + 1
+ left_scaleup = out_prec - p1;
+ } else {
+ return Status::Invalid("Invalid decimal operation: ", op);
+ }
+
+ const auto id = left_type->id();
Review comment:
If you want to defer mixed width to a follow up that's acceptable, but
DispatchDecimal should fail gracefully for that case
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]