-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
Query: SqlExpression.Type is non-nullable even when it could be null #20637
Comments
Am not a big query honcho, but definitely seems like Type should be nullable if it can take null values - but not in other cases (so your first suggestion, not your second). Unless I'm mistaken a lot of our logic already works in this way, right? If so, is it accurate to say this is a bug specifically in the handling of SqlUnary (or even certain types of SqlUnary)? Or is this a larger issue in our pipeline?
That makes sense to me. It's the same as the situation in pure C# LINQ - an expression tree can have nullable types even where the tree structure doesn't allow actual null values to appear (e.g. because of a previous null check). Type information is independent of actual possible values in a given node. |
C# LINQ null types are less about if there would be actual null data and more about how generic methods interact. The larger issue in pipeline is this,
Our logic which is partially correct only worked because we never cared about types. In rare case it can add duplicate columns in projection if types don't match. #20633 would also make it important that we have accurate type. 2nd proposal is about changing semantics of type somewhat. sqlExpression.Type being non-null does not imply anything if we will receive null value or not. We always assume nullable except for ColumnExpression anyway. So Sql tree becomes, every node can take null value even if type is non-null. The type is there because Expression requires it. Otherwise for a properly typeMapped sql tree, the SqlExpression.Type should be same as RelationalTypeMapping.ClrType. |
…alue type To align with structure of TypeMapping Resolves #20637
For relational providers, |
When we make ColumnExpression nullable, we mark it's type as nullable. But when we do Average over it, we generate SqlUnary (for int/long), which ends up taking Type from typeMapping, which makes it non-null.
Design I am thinking is
SqlExpression.Type would be a nullable type if can take null values. In a way it would be superset of null semantics. e.g. Certain things won't be null in tree due to other conditions but still have nullable type.
Another alternative is to make all Types non-null so SQL tree becomes null-agnostic, any SqlExpression can take null value in database. This may require some changes when materializing to know if we need to make null check. (I believe we make null check for everything other than basic SqlConstant/SqlParameter/Column already).
Identified during #20635
The issue arises because a nullable type SqlUnaryExpression got converted to non-null SqlUnary since the TypeMapping's clrType is non-null.
The text was updated successfully, but these errors were encountered: