Skip to content

Commit d3aca76

Browse files
author
Bhargava Vadlamani
committed
decimal_types_bool_cast_native_support
1 parent 0d2c5fc commit d3aca76

4 files changed

Lines changed: 32 additions & 4 deletions

File tree

docs/source/user-guide/latest/compatibility.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ The following cast operations are generally compatible with Spark except for the
195195
| double | long | |
196196
| double | float | |
197197
| double | string | There can be differences in precision. For example, the input "1.4E-45" will produce 1.0E-45 instead of 1.4E-45 |
198+
| decimal | boolean | |
198199
| decimal | byte | |
199200
| decimal | short | |
200201
| decimal | integer | |

native/spark-expr/src/conversion_funcs/cast.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::utils::array_with_timezone;
1919
use crate::{timezone, BinaryOutputStyle};
2020
use crate::{EvalMode, SparkError, SparkResult};
2121
use arrow::array::builder::StringBuilder;
22-
use arrow::array::{DictionaryArray, GenericByteArray, StringArray, StructArray};
22+
use arrow::array::{BooleanBuilder, DictionaryArray, GenericByteArray, StringArray, StructArray};
2323
use arrow::compute::can_cast_types;
2424
use arrow::datatypes::{
2525
ArrowDictionaryKeyType, ArrowNativeType, DataType, GenericBinaryType, Schema,
@@ -50,7 +50,7 @@ use datafusion::physical_expr::PhysicalExpr;
5050
use datafusion::physical_plan::ColumnarValue;
5151
use num::{
5252
cast::AsPrimitive, integer::div_floor, traits::CheckedNeg, CheckedSub, Integer, Num,
53-
ToPrimitive,
53+
ToPrimitive, Zero,
5454
};
5555
use regex::Regex;
5656
use std::str::FromStr;
@@ -1015,6 +1015,7 @@ fn cast_array(
10151015
{
10161016
spark_cast_nonintegral_numeric_to_integral(&array, eval_mode, from_type, to_type)
10171017
}
1018+
(Decimal128(_p, _s), Boolean) => spark_cast_decimal_to_boolean(&array, from_type, to_type),
10181019
(Utf8View, Utf8) => Ok(cast_with_options(&array, to_type, &CAST_OPTIONS)?),
10191020
(Struct(_), Utf8) => Ok(casts_struct_to_string(array.as_struct(), cast_options)?),
10201021
(Struct(_), Struct(_)) => Ok(cast_struct_to_struct(
@@ -1528,6 +1529,32 @@ where
15281529
Ok(Arc::new(output_array))
15291530
}
15301531

1532+
fn spark_cast_decimal_to_boolean(
1533+
array: &dyn Array,
1534+
from_type: &DataType,
1535+
to_type: &DataType,
1536+
) -> SparkResult<ArrayRef> {
1537+
match (from_type, to_type) {
1538+
(DataType::Decimal128(_p, _s), DataType::Boolean) => {
1539+
let decimal_array = array.as_primitive::<Decimal128Type>();
1540+
let mut result = BooleanBuilder::with_capacity(decimal_array.len());
1541+
for i in 0..decimal_array.len() {
1542+
if decimal_array.is_null(i) {
1543+
result.append_null()
1544+
} else if decimal_array.value(i).is_zero() {
1545+
result.append_value(false);
1546+
} else {
1547+
result.append_value(true);
1548+
}
1549+
}
1550+
Ok(Arc::new(result.finish()))
1551+
}
1552+
_ => panic!(
1553+
"{}",
1554+
format!("invalid cast from decimal type: {from_type} to boolean type: {to_type}")
1555+
),
1556+
}
1557+
}
15311558
fn spark_cast_nonintegral_numeric_to_integral(
15321559
array: &dyn Array,
15331560
eval_mode: EvalMode,

spark/src/main/scala/org/apache/comet/expressions/CometCast.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ object CometCast extends CometExpressionSerde[Cast] with CometExprShim {
325325

326326
private def canCastFromDecimal(toType: DataType): SupportLevel = toType match {
327327
case DataTypes.FloatType | DataTypes.DoubleType | DataTypes.ByteType | DataTypes.ShortType |
328-
DataTypes.IntegerType | DataTypes.LongType =>
328+
DataTypes.IntegerType | DataTypes.LongType | DataTypes.BooleanType =>
329329
Compatible()
330330
case _ => Unsupported(Some(s"Cast from DecimalType to $toType is not supported"))
331331
}

spark/src/test/scala/org/apache/comet/CometCastSuite.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ class CometCastSuite extends CometTestBase with AdaptiveSparkPlanHelper {
505505

506506
// CAST from DecimalType(10,2)
507507

508-
ignore("cast DecimalType(10,2) to BooleanType") {
508+
test("cast DecimalType(10,2) to BooleanType") {
509509
// Arrow error: Cast error: Casting from Decimal128(38, 18) to Boolean not supported
510510
castTest(generateDecimalsPrecision10Scale2(), DataTypes.BooleanType)
511511
}

0 commit comments

Comments
 (0)