Is string equality not null safe in daft? ```col =...
# general
t
Is string equality not null safe in daft?
Copy code
col = "foo" # both c.foo and p.foo are all nulls
df.where(df[f"c.{col}"] == df[f"p.{col}"]).show()
returns 0 rows
Copy code
df.where(df[f"c.{col}"] != df[f"p.{col}"]).show()
also returns 0 rows
j
Equality actually falls back on
null
if either LHS/RHS is a
null
I believe. We should check what postgres behavior is and follow that cc @Kevin Wang
t
hmm, so I can't have the expression short circuited with a true values earlier in the expression?
Copy code
df.where(
    (col(f"p.{col_name}").is_null() & col(f"c.{col_name}").is_null())
    | (col(f"p.{col_name}").not_null() & col(f"c.{col_name}").not_null())
    | (col(f"p.{col_name}") == col(f"c.{col_name}"))
).show()
without the 3rd part of the expression (
==
), I get all rows as expected, but the inclusion of the 3rd part reverts it to 0 rows, which seems broken
k
That is correct, it propagates null values up. Could you try using fill_null instead?
(side note: I believe we already have logic in the Rust side for null-safe equality. we should expose that to our DataFrame API, will create an issue)
πŸ‘πŸ½ 1
t
OK will try fill_null, but isn't there a core issue here with boolean logic? df.where(True | False) should return everything
k
Hm, will investigate what standard behavior is among other libraries. The general rule we try to follow is to propagate nulls but I think this may be a case where it should not do that
thanks for pointing it out!
πŸ‘πŸ½ 1
Looks like you are right. Issue created here, will work on fixing it! https://github.com/Eventual-Inc/Daft/issues/3512
πŸ™πŸ½ 1
t
there's no type checking with
fill_null
? Not giving an error filling an int64 col with strings or vice versa
j
It does implicit supertype-casting (notice how the type changes from int32 to string in this example)
πŸ‘€ 1
Here’s the behavior with strings filled with an int (supertype-casted to strings as well)
πŸ‘πŸ½ 1
t
what's the trick for filling null on a decimal type?
Copy code
DaftCoreException: DaftError::External Unable to create logical plan node.
Due to: DaftError::TypeError Expected expr and fill_value arguments for fill_null to be castable to the same supertype, but received amount#Decimal(precision=10, scale=0) and literal#Decimal(precision=1, scale=0)
Copy code
df[f"c.{col}.amount"].fill_null(Decimal(-1.0)) != df[f"p.{col}.amount"].fill_null(Decimal(-1.0))
EDIT: nvm, realized what precision vs scale are. Need a 10 digit number and it works.
πŸ‘ 1