Skip to content

Commit 3dc3ebe

Browse files
author
B Vadlamani
committed
add_tests
1 parent 548fd18 commit 3dc3ebe

3 files changed

Lines changed: 61 additions & 16 deletions

File tree

datafusion/spark/src/function/math/ceil.rs

Lines changed: 56 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@ use arrow::array::{
2222
Int32Array, Int64Array,
2323
};
2424
use arrow::compute::kernels::arity::unary;
25-
use arrow::datatypes::DataType;
26-
use datafusion_common::{DataFusionError, ScalarValue};
25+
use arrow::datatypes::{DataType, Field, FieldRef};
26+
use datafusion_common::{DataFusionError, ScalarValue, internal_err};
2727
use datafusion_expr::{
28-
ColumnarValue, ScalarFunctionArgs, ScalarUDFImpl, Signature, Volatility,
28+
ColumnarValue, ReturnFieldArgs, ScalarFunctionArgs, ScalarUDFImpl, Signature,
29+
Volatility,
2930
};
3031
use std::any::Any;
3132
use std::sync::Arc;
@@ -62,17 +63,32 @@ pub fn spark_ceil(args: &[ColumnarValue]) -> Result<ColumnarValue, DataFusionErr
6263
Ok(ColumnarValue::Array(result?))
6364
}
6465
DataType::Int8 => {
65-
let input = array.as_any().downcast_ref::<Int8Array>().unwrap();
66+
let input =
67+
array.as_any().downcast_ref::<Int8Array>().ok_or_else(|| {
68+
DataFusionError::Internal(
69+
"Failed to downcast to Int8Array".to_string(),
70+
)
71+
})?;
6672
let result: Int64Array = unary(input, |x| x as i64);
6773
Ok(ColumnarValue::Array(Arc::new(result)))
6874
}
6975
DataType::Int16 => {
70-
let input = array.as_any().downcast_ref::<Int16Array>().unwrap();
76+
let input =
77+
array.as_any().downcast_ref::<Int16Array>().ok_or_else(|| {
78+
DataFusionError::Internal(
79+
"Failed to downcast to Int16Array".to_string(),
80+
)
81+
})?;
7182
let result: Int64Array = unary(input, |x| x as i64);
7283
Ok(ColumnarValue::Array(Arc::new(result)))
7384
}
7485
DataType::Int32 => {
75-
let input = array.as_any().downcast_ref::<Int32Array>().unwrap();
86+
let input =
87+
array.as_any().downcast_ref::<Int32Array>().ok_or_else(|| {
88+
DataFusionError::Internal(
89+
"Failed to downcast to Int32Array".to_string(),
90+
)
91+
})?;
7692
let result: Int64Array = unary(input, |x| x as i64);
7793
Ok(ColumnarValue::Array(Arc::new(result)))
7894
}
@@ -147,26 +163,43 @@ fn decimal_ceil_f(scale: i8) -> impl Fn(i128) -> i128 {
147163
}
148164
}
149165

166+
/// Spark-compatible `ceil` function.
167+
///
168+
/// Returns the smallest integer greater than or equal to the input.
169+
/// Unlike standard DataFusion ceil, this returns Int64 for float/integer
170+
/// inputs (matching Spark behavior).
171+
///
172+
/// # Supported types
173+
/// - Float32, Float64 → Int64
174+
/// - Int8, Int16, Int32, Int64 → Int64
175+
/// - Decimal128(p, s) → Decimal128(p, s) (preserves scale)
176+
///
177+
/// # Examples
178+
/// ```sql
179+
/// SELECT ceil(1.5); -- Returns 2 (Int64)
180+
/// SELECT ceil(-1.5); -- Returns -1 (Int64)
181+
/// SELECT ceil(5); -- Returns 5 (Int64)
182+
/// ```
150183
#[derive(Debug, PartialEq, Eq, Hash)]
151-
pub struct SparkCiel {
184+
pub struct SparkCeil {
152185
signature: Signature,
153186
}
154187

155-
impl Default for SparkCiel {
188+
impl Default for SparkCeil {
156189
fn default() -> Self {
157190
Self::new()
158191
}
159192
}
160193

161-
impl SparkCiel {
194+
impl SparkCeil {
162195
pub fn new() -> Self {
163196
Self {
164197
signature: Signature::numeric(1, Volatility::Immutable),
165198
}
166199
}
167200
}
168201

169-
impl ScalarUDFImpl for SparkCiel {
202+
impl ScalarUDFImpl for SparkCeil {
170203
fn as_any(&self) -> &dyn Any {
171204
self
172205
}
@@ -183,7 +216,19 @@ impl ScalarUDFImpl for SparkCiel {
183216
&self,
184217
_arg_types: &[DataType],
185218
) -> datafusion_common::Result<DataType> {
186-
Ok(DataType::Int64)
219+
internal_err!("return_field_from_args should be called instead")
220+
}
221+
222+
fn return_field_from_args(
223+
&self,
224+
args: ReturnFieldArgs,
225+
) -> datafusion_common::Result<FieldRef> {
226+
let nullable = args.arg_fields.iter().any(|f| f.is_nullable());
227+
let return_type = match args.arg_fields[0].data_type() {
228+
DataType::Decimal128(p, s) => DataType::Decimal128(*p, *s),
229+
_ => DataType::Int64,
230+
};
231+
Ok(Arc::new(Field::new(self.name(), return_type, nullable)))
187232
}
188233

189234
fn invoke_with_args(

datafusion/spark/src/function/math/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
// under the License.
1717

1818
pub mod abs;
19-
mod ceil;
19+
pub mod ceil;
2020
pub mod expm1;
2121
pub mod factorial;
2222
pub mod hex;
@@ -43,7 +43,7 @@ make_udf_function!(width_bucket::SparkWidthBucket, width_bucket);
4343
make_udf_function!(trigonometry::SparkCsc, csc);
4444
make_udf_function!(trigonometry::SparkSec, sec);
4545
make_udf_function!(negative::SparkNegative, negative);
46-
make_udf_function!(ceil::SparkCiel, ceil);
46+
make_udf_function!(ceil::SparkCeil, ceil);
4747

4848
pub mod expr_fn {
4949
use datafusion_functions::export_functions;

datafusion/sqllogictest/test_files/spark/math/ceil.slt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ SELECT ceil(127::tinyint);
144144
127
145145

146146
query I
147-
SELECT ceil(-128::tinyint);
147+
SELECT ceil(CAST(-128 AS tinyint));
148148
----
149149
-128
150150

@@ -170,7 +170,7 @@ SELECT ceil(32767::smallint);
170170
32767
171171

172172
query I
173-
SELECT ceil(-32768::smallint);
173+
SELECT ceil(CAST(-32768 AS smallint));
174174
----
175175
-32768
176176

@@ -212,7 +212,7 @@ SELECT ceil(9223372036854775807::bigint);
212212
9223372036854775807
213213

214214
query I
215-
SELECT ceil(-9223372036854775808::bigint);
215+
SELECT ceil(CAST(-9223372036854775808 AS bigint));
216216
----
217217
-9223372036854775808
218218

0 commit comments

Comments
 (0)