-
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
_sqlAliasManager
unexpectedly null
in SelectExpression.PushdownIntoSubquery()
call after previous call of SelectExpression.Update()
#35192
Comments
Hey @lauxjpn 👋 Are you saying you call PushdownIntoSubquery at some point after in SqlNullabilityProcessor or afterwards, in your provider? That's not something we currently do elsewhere - can you provide a bit more context on where/why you need to do that? To give more context, SelectExpression (currently) has two modes: mutable and immutable; a SelectExpression is only mutable during the translation phase, as more operators get processed and the SelectExpression get mutated; right after translation it is made mutable. This is a design that I think is problematic in several ways, and I hope to be able to change in 10, so that our SQL tree is fully immutable. In any case, the SQL alias manager is currently only available in the mutable phase. Very concretely: rather than doing PushdownIntoSubquery(), which is meant to be used during the mutable phase, maybe it's possible to simply construct the new SelectExpression on top of the existing one (perform a "manual pushdown")? If not, I'll look into finding a solution for you. Unfortunately, this entire area is quite messy at the moment, and in a transitional phase... But I'm slowly trying to move us in a more sane direction. |
Yeah, we're back baby! Original postYes, we have a couple of expression visitors that we need to run as late as possible. I have now moved the one in question (the one that is doing the pushdown) into the post translation handling. The debugger shows though, that Since at this point, no call to Unfortunately, we can't be 100% sure that nobody has already called public static SelectExpression UpdateWithSqlAliasManager(
this SelectExpression selectExpression,
SqlAliasManager sqlAliasManager)
=> new(
selectExpression.Alias,
selectExpression.Tables.ToList(),
selectExpression.Predicate,
selectExpression.GroupBy.ToList(),
selectExpression.Having,
selectExpression.Projection.ToList(),
selectExpression.IsDistinct,
selectExpression.Orderings.ToList(),
selectExpression.Offset,
selectExpression.Limit,
selectExpression.Tags,
selectExpression.GetAnnotations().ToDictionary(a => a.Name, a => a),
sqlAliasManager,
false); We are still able to call this method in // In MySqlQueryTranslationPostprocessor.Process():
query = new MySqlHavingExpressionVisitor(
_sqlExpressionFactory,
((RelationalQueryCompilationContext)QueryCompilationContext).SqlAliasManager)
.Visit(query);
// In MySqlHavingExpressionVisitor.VisitSelect:
selectExpression = selectExpression.UpdateWithSqlAliasManager(_sqlAliasManager);
selectExpression.PushdownIntoSubquery(); The question is: Is it a bug that we are able to do this successfully in If we should not do this, we will either move the expression visitor to the end of the translation phase (but before (For context: The expression visitor in question has to do some weird syntax stuff for queries with I will reevaluate what we are doing with our HAVING expression visitor and come back to this, once I know in which direction we want to go with this. |
An existing
SelectExpression
is "updated" inSqlNullabilityProcessor.Visit(SelectExpression selectExpression, bool visitProjection)
via a call toSelectExpression.Update(...)
.On that resulting
SelectExpression
, we later callSelectExpression.PushdownIntoSubquery()
.Because
SelectExpression.PushdownIntoSubquery()
uses_sqlAliasManager
internally, andSelectExpression.Update(...)
does not retain theSqlAliasManager
instance of the originalSelectExpression
,_sqlAliasManager
isnull
in theSelectExpression.PushdownIntoSubquery()
call and an unexpected/implicit NRE is thrown.Include provider and version information
EF Core version: 9.0.0
Database provider: Pomelo.EntityFrameworkCore.MySql
The text was updated successfully, but these errors were encountered: