Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: support nvl(ifnull) function #9284

Merged
merged 6 commits into from
Feb 26, 2024
Merged

feature: support nvl(ifnull) function #9284

merged 6 commits into from
Feb 26, 2024

Conversation

guojidan
Copy link
Contributor

Which issue does this PR close?

Closes #9261.

Rationale for this change

add a new function nvl

What changes are included in this PR?

Are these changes tested?

yes

Are there any user-facing changes?

yes

@guojidan guojidan marked this pull request as draft February 20, 2024 06:42
@github-actions github-actions bot added the sqllogictest SQL Logic Tests (.slt) label Feb 20, 2024
@guojidan guojidan marked this pull request as ready for review February 20, 2024 13:00
Co-authored-by: Jonah Gao <jonahgao@msn.com>
let size = lhs.len();
let mut current_value = rhs.to_array_of_size(size)?;
let remainder = BooleanArray::from(vec![true; size]);
let to_apply = and(&remainder, &is_not_null(lhs.as_ref())?)?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this "and" operation necessary, as the remainder is always true ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ohh, yes, "and" true is meaningless, thank you 👍

/// Currently supported types by the nvl/ifnull function.
/// The order of these types correspond to the order on which coercion applies
/// This should thus be from least informative to most informative
pub static SUPPORTED_NVL_TYPES: &[DataType] = &[
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub static SUPPORTED_NVL_TYPES: &[DataType] = &[
static SUPPORTED_NVL_TYPES: &[DataType] = &[

How about removing pub since it is only used within the current file?

let current_value = zip(&to_apply, lhs, &rhs)?;
Ok(ColumnarValue::Array(current_value))
}
(ColumnarValue::Scalar(lhs), ColumnarValue::Array(rhs)) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about merging the computation related to arrays together?
Cloning an ArrayRef should be cheap.

    let (lhs_array, rhs_array) = match (&args[0], &args[1]) {
        (ColumnarValue::Array(lhs), ColumnarValue::Scalar(rhs)) => {
            (lhs.clone(), rhs.to_array_of_size(lhs.len())?)
        }
        (ColumnarValue::Array(lhs), ColumnarValue::Array(rhs)) => {
            (lhs.clone(), rhs.clone())
        }
        (ColumnarValue::Scalar(lhs), ColumnarValue::Array(rhs)) => {
            (lhs.to_array_of_size(rhs.len())?, rhs.clone())
        }
        (ColumnarValue::Scalar(lhs), ColumnarValue::Scalar(rhs)) => {
            let mut current_value = lhs;
            if lhs.is_null() {
                current_value = rhs;
            }
            return Ok(ColumnarValue::Scalar(current_value.clone()));
        }
    };
    let to_apply = is_not_null(&lhs_array)?;
    let value = zip(&to_apply, &lhs_array, &rhs_array)?;
    Ok(ColumnarValue::Array(value))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks better than mine

Copy link
Member

@jonahgao jonahgao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

@guojidan
Copy link
Contributor Author

Looks good to me!

thank you @jonahgao 😄

@@ -569,6 +569,7 @@ trunc(numeric_expression[, decimal_places])

- [coalesce](#coalesce)
- [nullif](#nullif)
- [nvl/ifnull](#nvl/ifnull)
Copy link
Member

@jonahgao jonahgao Feb 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This link to nvl/ifnull seems broken.
https://github.com/apache/arrow-datafusion/blob/f6c6e385041974c4e501bbe9e3ab42284ddddfda/docs/source/user-guide/sql/scalar_functions.md#conditional-functions

[nvl/ifnull](#nvlifnull) should work.

The rest of this PR looks good to me. Good job 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not support /, I separated them, thank you again 😄

@github-actions github-actions bot added sql SQL Planner logical-expr Logical plan and expressions physical-expr Physical Expressions optimizer Optimizer rules core Core DataFusion crate labels Feb 26, 2024
@github-actions github-actions bot removed sql SQL Planner logical-expr Logical plan and expressions physical-expr Physical Expressions optimizer Optimizer rules core Core DataFusion crate labels Feb 26, 2024
Copy link
Contributor

@alamb alamb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @guojidan and @jonahgao for the review 🙏


fn return_type(&self, arg_types: &[DataType]) -> Result<DataType> {
// NVL has two args and they might get coerced, get a preview of this
let coerced_types = datafusion_expr::type_coercion::functions::data_types(arg_types, &self.signature);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't fully understand the need for this code to check coercion, but I know it follows the existing patterns elsewhere.

Maybe we can try to remove it in a follow on PR

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#9357 for anyone else following along

@@ -569,6 +569,8 @@ trunc(numeric_expression[, decimal_places])

- [coalesce](#coalesce)
- [nullif](#nullif)
- [nvl](#nvl)
- [ifnull](#ifnull)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

@alamb alamb merged commit b55d0ed into apache:main Feb 26, 2024
48 checks passed
@guojidan guojidan deleted the ifnull branch February 27, 2024 02:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
sqllogictest SQL Logic Tests (.slt)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

support IFNULL function
3 participants