You are viewing a plain text version of this content. The canonical link for it is here.
Posted to github@datafusion.apache.org by "coderfender (via GitHub)" <gi...@apache.org> on 2026/03/11 00:53:29 UTC
[PR] feat: [datafusion]
coderfender opened a new pull request, #20860:
URL: https://github.com/apache/datafusion/pull/20860
## Which issue does this PR close?
Part of https://github.com/apache/datafusion/issues/15914
<!--
We generally require a GitHub issue to be filed for all bug fixes and enhancements and this helps us generate change logs for our releases. You can link an issue to this PR using the GitHub syntax. For example `Closes #123` indicates that this PR will close issue #123.
-->
## Rationale for this change
Spark compatible semantics for `floor` function
<!--
Why are you proposing this change? If this is already explained clearly in the issue then this section is not needed.
Explaining clearly why changes are proposed helps reviewers understand your changes and offer better suggestions for fixes.
-->
## What changes are included in this PR?
Implements SparkFloor UDF with Spark-compatible return types:
- Float/Integer inputs -> Int64
- Decimal128(p, s) -> Decimal128(p-s+1, 0)
<!--
There is no need to duplicate the description in the issue here but it is sometimes worth providing a summary of the individual changes in this PR.
-->
## Are these changes tested?
Yes . Added unit tests and SLT tests
<!--
We typically require tests for all PRs in order to:
1. Prevent the code from being accidentally broken by subsequent changes
2. Serve as another way to document the expected behavior of the code
If tests are not included in your PR, please explain why (for example, are they covered by existing tests)?
-->
## Are there any user-facing changes?
<!--
If there are user-facing changes then we may require documentation to be updated before approving the PR.
-->
<!--
If there are any breaking changes to public APIs, please add the `api change` label.
-->
--
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.
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For additional commands, e-mail: github-help@datafusion.apache.org
Re: [PR] feat: suport spark compatible floor function [datafusion]
Posted by "coderfender (via GitHub)" <gi...@apache.org>.
coderfender closed pull request #20860: feat: suport spark compatible floor function
URL: https://github.com/apache/datafusion/pull/20860
--
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.
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For additional commands, e-mail: github-help@datafusion.apache.org
Re: [PR] feat: suport spark compatible floor function [datafusion]
Posted by "xanderbailey (via GitHub)" <gi...@apache.org>.
xanderbailey commented on PR #20860:
URL: https://github.com/apache/datafusion/pull/20860#issuecomment-4038055445
Is this a duplicate of https://github.com/apache/datafusion/pull/20594?
--
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.
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For additional commands, e-mail: github-help@datafusion.apache.org
Re: [PR] feat: suport spark compatible floor function [datafusion]
Posted by "coderfender (via GitHub)" <gi...@apache.org>.
coderfender commented on PR #20860:
URL: https://github.com/apache/datafusion/pull/20860#issuecomment-4039781974
https://github.com/apache/datafusion/pull/20593
--
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.
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For additional commands, e-mail: github-help@datafusion.apache.org
Re: [PR] feat: suport spark compatible floor function [datafusion]
Posted by "athlcode (via GitHub)" <gi...@apache.org>.
athlcode commented on PR #20860:
URL: https://github.com/apache/datafusion/pull/20860#issuecomment-4332427447
@coderfender I can work on this if its okay
--
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.
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For additional commands, e-mail: github-help@datafusion.apache.org
Re: [PR] feat: suport spark compatible floor function [datafusion]
Posted by "coderfender (via GitHub)" <gi...@apache.org>.
coderfender commented on PR #20860:
URL: https://github.com/apache/datafusion/pull/20860#issuecomment-4039778516
Yeah , I initially though since @shivbhatia10 implemented ceil function , I would go for other math function but turns out we have 4 pending PRs from his side and I started reviewing his implementations to help the effort and take one for the team :)
--
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.
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For additional commands, e-mail: github-help@datafusion.apache.org
Re: [PR] feat: suport spark compatible floor function [datafusion]
Posted by "coderfender (via GitHub)" <gi...@apache.org>.
coderfender commented on PR #20860:
URL: https://github.com/apache/datafusion/pull/20860#issuecomment-4321338864
Sounds good to me @Jefffrey . I will rebase this PR and add more tests to this PR
--
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.
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For additional commands, e-mail: github-help@datafusion.apache.org
Re: [PR] feat: suport spark compatible floor function [datafusion]
Posted by "shivbhatia10 (via GitHub)" <gi...@apache.org>.
shivbhatia10 commented on PR #20860:
URL: https://github.com/apache/datafusion/pull/20860#issuecomment-4335977108
Hey @coderfender @athlcode sorry about blocking this one with my other PR, I missed that this already existed - I've closed that one, I don't have the bandwidth to work on it at the moment
--
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.
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For additional commands, e-mail: github-help@datafusion.apache.org
Re: [PR] feat: suport spark compatible floor function [datafusion]
Posted by "Jefffrey (via GitHub)" <gi...@apache.org>.
Jefffrey commented on code in PR #20860:
URL: https://github.com/apache/datafusion/pull/20860#discussion_r3143026236
##########
datafusion/spark/src/function/math/floor.rs:
##########
@@ -0,0 +1,455 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use arrow::array::cast::AsArray;
+use arrow::array::types::Decimal128Type;
+use arrow::array::{ArrowNativeTypeOp, Decimal128Array, Int64Array};
+use arrow::compute::kernels::arity::unary;
+use arrow::datatypes::{DataType, Field, FieldRef};
+use datafusion_common::{DataFusionError, ScalarValue, exec_err, internal_err};
+use datafusion_expr::{
+ ColumnarValue, ReturnFieldArgs, ScalarFunctionArgs, ScalarUDFImpl, Signature,
+ Volatility,
+};
+use std::any::Any;
+use std::sync::Arc;
+
+/// Spark-compatible `floor` function.
+///
+/// Differences from DataFusion's floor:
+/// - Returns Int64 for float and integer inputs (while DataFusion preserves input type)
+/// - For Decimal128(p, s), returns Decimal128(p-s+1, 0) with scale 0
+/// (DataFusion preserves original precision and scale)
+///
+/// <https://spark.apache.org/docs/latest/api/sql/index.html#floor>
+#[derive(Debug, PartialEq, Eq, Hash)]
+pub struct SparkFloor {
+ signature: Signature,
+}
+
+impl Default for SparkFloor {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl SparkFloor {
+ pub fn new() -> Self {
+ Self {
+ signature: Signature::numeric(1, Volatility::Immutable),
+ }
+ }
+}
+
+impl ScalarUDFImpl for SparkFloor {
+ fn as_any(&self) -> &dyn Any {
+ self
+ }
+
+ fn name(&self) -> &str {
+ "floor"
+ }
+
+ fn signature(&self) -> &Signature {
+ &self.signature
+ }
+
+ fn return_type(
+ &self,
+ _arg_types: &[DataType],
+ ) -> datafusion_common::Result<DataType> {
+ internal_err!("return_field_from_args should be called instead")
+ }
+
+ fn return_field_from_args(
+ &self,
+ args: ReturnFieldArgs,
+ ) -> datafusion_common::Result<FieldRef> {
+ let nullable = args.arg_fields.iter().any(|f| f.is_nullable());
+ let return_type = match args.arg_fields[0].data_type() {
+ DataType::Decimal128(p, s) if *s > 0 => {
+ let new_p = (*p - *s as u8 + 1).clamp(1, 38);
+ DataType::Decimal128(new_p, 0)
+ }
+ DataType::Decimal128(p, s) => DataType::Decimal128(*p, *s),
+ DataType::Float32 | DataType::Float64 => DataType::Int64,
+ DataType::Int8 | DataType::Int16 | DataType::Int32 | DataType::Int64 => {
+ DataType::Int64
+ }
+ _ => exec_err!(
+ "found unsupported return type {:?}",
+ args.arg_fields[0].data_type()
+ )?,
+ };
+ Ok(Arc::new(Field::new(self.name(), return_type, nullable)))
+ }
+
+ fn invoke_with_args(
+ &self,
+ args: ScalarFunctionArgs,
+ ) -> datafusion_common::Result<ColumnarValue> {
+ spark_floor(&args.args, args.return_field.data_type())
+ }
+}
+
+macro_rules! apply_int64 {
+ ($value:expr, $arr_type:ty, $scalar_variant:path, $f:expr) => {
+ match $value {
+ ColumnarValue::Array(array) => {
+ let result: Int64Array = unary(array.as_primitive::<$arr_type>(), $f);
+ Ok(ColumnarValue::Array(Arc::new(result)))
+ }
+ ColumnarValue::Scalar($scalar_variant(v)) => {
+ Ok(ColumnarValue::Scalar(ScalarValue::Int64(v.map($f))))
+ }
+ other => internal_err!(
+ "floor: expected {} but got {:?}",
+ stringify!($scalar_variant),
+ other.data_type()
+ ),
+ }
+ };
+}
+
+fn spark_floor(
+ args: &[ColumnarValue],
+ return_type: &DataType,
+) -> Result<ColumnarValue, DataFusionError> {
+ let value = &args[0];
+ match value.data_type() {
+ DataType::Float32 => apply_int64!(
+ value,
+ arrow::datatypes::Float32Type,
+ ScalarValue::Float32,
+ |x| x.floor() as i64
+ ),
+ DataType::Float64 => apply_int64!(
+ value,
+ arrow::datatypes::Float64Type,
+ ScalarValue::Float64,
+ |x| x.floor() as i64
+ ),
+ DataType::Int8 => {
+ apply_int64!(value, arrow::datatypes::Int8Type, ScalarValue::Int8, |x| x
+ as i64)
+ }
+ DataType::Int16 => apply_int64!(
+ value,
+ arrow::datatypes::Int16Type,
+ ScalarValue::Int16,
+ |x| x as i64
+ ),
+ DataType::Int32 => apply_int64!(
+ value,
+ arrow::datatypes::Int32Type,
+ ScalarValue::Int32,
+ |x| x as i64
+ ),
+ DataType::Int64 => Ok(value.clone()),
+ DataType::Decimal128(_, scale) if scale > 0 => {
+ let divisor = 10_i128.pow_wrapping(scale as u32);
+ let floor_decimal = |x: i128| {
+ let (d, r) = (x / divisor, x % divisor);
+ if r < 0 { d - 1 } else { d }
+ };
+ match value {
+ ColumnarValue::Array(array) => {
+ let result: Decimal128Array =
+ unary(array.as_primitive::<Decimal128Type>(), floor_decimal);
+ Ok(ColumnarValue::Array(Arc::new(
+ result.with_data_type(return_type.clone()),
+ )))
+ }
+ ColumnarValue::Scalar(ScalarValue::Decimal128(v, _, _)) => {
+ let DataType::Decimal128(new_p, new_s) = return_type else {
+ return internal_err!(
+ "floor: expected Decimal128 return type but got {:?}",
+ return_type
+ );
+ };
+ Ok(ColumnarValue::Scalar(ScalarValue::Decimal128(
+ v.map(floor_decimal),
+ *new_p,
+ *new_s,
+ )))
+ }
+ other => internal_err!(
+ "floor: expected Decimal128 scalar but got {:?}",
+ other.data_type()
+ ),
+ }
+ }
+ DataType::Decimal128(_, _) => Ok(value.clone()),
+ other => exec_err!("Unsupported data type {other:?} for function floor"),
+ }
+}
+
+#[cfg(test)]
+mod tests {
Review Comment:
Could we move all these tests to SLTs?
##########
datafusion/spark/src/function/math/floor.rs:
##########
@@ -0,0 +1,455 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use arrow::array::cast::AsArray;
+use arrow::array::types::Decimal128Type;
+use arrow::array::{ArrowNativeTypeOp, Decimal128Array, Int64Array};
+use arrow::compute::kernels::arity::unary;
+use arrow::datatypes::{DataType, Field, FieldRef};
+use datafusion_common::{DataFusionError, ScalarValue, exec_err, internal_err};
+use datafusion_expr::{
+ ColumnarValue, ReturnFieldArgs, ScalarFunctionArgs, ScalarUDFImpl, Signature,
+ Volatility,
+};
+use std::any::Any;
+use std::sync::Arc;
+
+/// Spark-compatible `floor` function.
+///
+/// Differences from DataFusion's floor:
+/// - Returns Int64 for float and integer inputs (while DataFusion preserves input type)
+/// - For Decimal128(p, s), returns Decimal128(p-s+1, 0) with scale 0
+/// (DataFusion preserves original precision and scale)
+///
+/// <https://spark.apache.org/docs/latest/api/sql/index.html#floor>
+#[derive(Debug, PartialEq, Eq, Hash)]
+pub struct SparkFloor {
+ signature: Signature,
+}
+
+impl Default for SparkFloor {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl SparkFloor {
+ pub fn new() -> Self {
+ Self {
+ signature: Signature::numeric(1, Volatility::Immutable),
+ }
+ }
+}
+
+impl ScalarUDFImpl for SparkFloor {
+ fn as_any(&self) -> &dyn Any {
+ self
+ }
+
+ fn name(&self) -> &str {
+ "floor"
+ }
+
+ fn signature(&self) -> &Signature {
+ &self.signature
+ }
+
+ fn return_type(
+ &self,
+ _arg_types: &[DataType],
+ ) -> datafusion_common::Result<DataType> {
+ internal_err!("return_field_from_args should be called instead")
+ }
+
+ fn return_field_from_args(
+ &self,
+ args: ReturnFieldArgs,
+ ) -> datafusion_common::Result<FieldRef> {
+ let nullable = args.arg_fields.iter().any(|f| f.is_nullable());
+ let return_type = match args.arg_fields[0].data_type() {
+ DataType::Decimal128(p, s) if *s > 0 => {
+ let new_p = (*p - *s as u8 + 1).clamp(1, 38);
+ DataType::Decimal128(new_p, 0)
+ }
+ DataType::Decimal128(p, s) => DataType::Decimal128(*p, *s),
+ DataType::Float32 | DataType::Float64 => DataType::Int64,
+ DataType::Int8 | DataType::Int16 | DataType::Int32 | DataType::Int64 => {
+ DataType::Int64
+ }
Review Comment:
```suggestion
DataType::Float32 | DataType::Float64 | DataType::Int8 | DataType::Int16 | DataType::Int32 | DataType::Int64 => {
DataType::Int64
}
```
--
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.
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For additional commands, e-mail: github-help@datafusion.apache.org
Re: [PR] feat: suport spark compatible floor function [datafusion]
Posted by "athlcode (via GitHub)" <gi...@apache.org>.
athlcode commented on PR #20860:
URL: https://github.com/apache/datafusion/pull/20860#issuecomment-4346164488
@coderfender I have the PR up with the comments resolved as well: https://github.com/apache/datafusion/pull/21933
--
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.
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For additional commands, e-mail: github-help@datafusion.apache.org
Re: [PR] feat: suport spark compatible floor function [datafusion]
Posted by "coderfender (via GitHub)" <gi...@apache.org>.
coderfender commented on PR #20860:
URL: https://github.com/apache/datafusion/pull/20860#issuecomment-4332525488
Sure ! Always happy to get help on this. Please tag me once you have the PR up
--
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.
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscribe@datafusion.apache.org
For additional commands, e-mail: github-help@datafusion.apache.org