You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Comparisons (BinaryExprs) to literal NULL don't work #1179
Bug is that datafusion SQL treats a literal NULL as though it is typed ScalarValue::Utf8(None)
So then if you try to compare null to a column that is not a scalar DataFusion goes 💥
To Reproduce
(I love the new VALUES feature that @jimexist added)
>select*from (VALUES (1, 'foo' ,2.3), (2, 'bar', 5.4)) as t;
+---------+---------+---------+
| column1 | column2 | column3 |
+---------+---------+---------+
| 1 | foo | 2.3 |
| 2 | bar | 5.4 |
+---------+---------+---------+2 rows inset. Query took 0.004 seconds.
>select column1 <nullfrom (VALUES (1, 'foo' ,2.3), (2, 'bar', 5.4)) as t;
Plan("'Int64 < Utf8' can't be evaluated because there isn't a common type to coerce the types to")
>select column2 <nullfrom (VALUES (1, 'foo' ,2.3), (2, 'bar', 5.4)) as t;
ArrowError(ExternalError(Internal("compute_utf8_op_scalar for 'lt' failed to cast literal value NULL")))
>select column3 <nullfrom (VALUES (1, 'foo' ,2.3), (2, 'bar', 5.4)) as t;
Plan("'Float64 < Utf8' can't be evaluated because there isn't a common type to coerce the types to")
Expected behavior
All three queries should return 1 column, 2 rows with all values null;
result
NULL
NULL
Additional context
This came up in the context of IOx where we are doing partial evaluation (on something that is like at the partition level) where references to columns may be rewritten into nulls. See more details on https://github.com/influxdata/influxdb_iox/issues/883
Hey @alamb did you start working on this?
I might otherwise check it out how this is handled - maybe before / in the weekend.
Thanks @Dandandan and @jimexist -- yes I have started working on this, and came up with something simple (#1181) and uncovered a bunch of other work
To introduce ScalarValue::Null and use that instead for Value::Null.
Return DataType::Null as type for ScalarValue::Null
Implement the rest of changes in coercion as needed.
Yes I agree that would be the ideal solution -- I tried a variant of that (basically made ScalarValue::get_datatype() return DataType::Null if ScalarValue::is_null() and taught the coercion logic about it for binary operators). However, I have since abandoned that approach in the near term.
The biggest problem I hit was that the arrow-rs cast kernels doesn't support casting from Null -> other_type -- I will be filing a ticket shortly for that.
I also found that functions and binary expressions don't share the same coercion logic and that many other expressions / operators don't actually try to coerce their arguments at all (e.g. try running a query like select case when NULL then 'foo' else 'bar' end;)
I'll also be filing tickets for those items as well
🤔 well I thought #1181 was ready but apparently it is not -- I am about out of time to work on this issue today, so I am going to spend the rest of my time writing up tickets.
Activity
alamb commentedon Oct 26, 2021
FYI here is what postgres does
jimexist commentedon Oct 27, 2021
FYI i put
\pset null ¤into~/.psqlrcso that null is explicitDandandan commentedon Oct 27, 2021
The source of the problem is here:
I would propose:
ScalarValue::Nulland use that instead forValue::Null.DataType::Nullas type forScalarValue::Nulljimexist commentedon Oct 27, 2021
i wonder how this line up with typed nulls for other enum cases.
or, could we actually get rid of the
Optionwrapping for other types, and keep this null enum case with wrapper type instead?alamb commentedon Oct 27, 2021
Thanks @Dandandan and @jimexist -- yes I have started working on this, and came up with something simple (#1181) and uncovered a bunch of other work
Yes I agree that would be the ideal solution -- I tried a variant of that (basically made
ScalarValue::get_datatype()return DataType::Null ifScalarValue::is_null()and taught the coercion logic about it for binary operators). However, I have since abandoned that approach in the near term.The biggest problem I hit was that the arrow-rs cast kernels doesn't support casting from
Null-> other_type -- I will be filing a ticket shortly for that.I also found that functions and binary expressions don't share the same coercion logic and that many other expressions / operators don't actually try to coerce their arguments at all (e.g. try running a query like
select case when NULL then 'foo' else 'bar' end;)I'll also be filing tickets for those items as well
[-]Comparisons to literal NULL don't work [/-][+]Comparisons (BinaryExprs) to literal NULL don't work [/+]alamb commentedon Oct 27, 2021
🤔 well I thought #1181 was ready but apparently it is not -- I am about out of time to work on this issue today, so I am going to spend the rest of my time writing up tickets.
feat: add support for array_remove expression (apache#1179)
Update how to dev instructions (apache#1179)