Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public RelationalQueryTranslationPostprocessor(
: base(dependencies, queryCompilationContext)
{
RelationalDependencies = relationalDependencies;
RelationalQueryCompilationContext = queryCompilationContext;
_sqlAliasManager = queryCompilationContext.SqlAliasManager;
_useRelationalNulls = RelationalOptionsExtension.Extract(queryCompilationContext.ContextOptions).UseRelationalNulls;
}
Expand All @@ -36,31 +37,49 @@ public RelationalQueryTranslationPostprocessor(
/// </summary>
protected virtual RelationalQueryTranslationPostprocessorDependencies RelationalDependencies { get; }

/// <summary>
/// The query compilation context object for current compilation.
/// </summary>
protected virtual RelationalQueryCompilationContext RelationalQueryCompilationContext { get; }

/// <inheritdoc />
public override Expression Process(Expression query)
{
var query1 = base.Process(query);
var query2 = new SelectExpressionProjectionApplyingExpressionVisitor(
((RelationalQueryCompilationContext)QueryCompilationContext).QuerySplittingBehavior).Visit(query1);
var query3 = Prune(query2);
var afterBase = base.Process(query);
var afterTypeMappings = ProcessTypeMappings(afterBase);
var afterProjectionApplication = new SelectExpressionProjectionApplyingExpressionVisitor(
((RelationalQueryCompilationContext)QueryCompilationContext).QuerySplittingBehavior)
.Visit(afterTypeMappings);
var afterPruning = Prune(afterProjectionApplication);

// TODO: This - and all the verifications below - should happen after all visitors have run, including provider-specific ones.
var query4 = _sqlAliasManager.PostprocessAliases(query3);
var afterAliases = _sqlAliasManager.PostprocessAliases(afterPruning);

#if DEBUG
// Verifies that all SelectExpression are marked as immutable after this point.
new SelectExpressionMutableVerifyingExpressionVisitor().Visit(query4);
new SelectExpressionMutableVerifyingExpressionVisitor().Visit(afterAliases);
#endif

var query5 = new SqlExpressionSimplifyingExpressionVisitor(RelationalDependencies.SqlExpressionFactory, _useRelationalNulls)
.Visit(query4);
var query6 = new RelationalValueConverterCompensatingExpressionVisitor(RelationalDependencies.SqlExpressionFactory).Visit(query5);
var afterSimplification = new SqlExpressionSimplifyingExpressionVisitor(
RelationalDependencies.SqlExpressionFactory, _useRelationalNulls)
.Visit(afterAliases);
var afterValueConverterCompensation =
new RelationalValueConverterCompensatingExpressionVisitor(RelationalDependencies.SqlExpressionFactory)
.Visit(afterSimplification);

return query6;
return afterValueConverterCompensation;
}

/// <summary>
/// Prunes unnecessarily objects from the SQL tree, e.g. tables which aren't referenced by any column.
/// Performs various postprocessing related to type mappings, e.g. applies inferred type mappings for queryable constants/parameters
/// and verifies that all <see cref="SqlExpression" /> have a type mapping.
/// </summary>
/// <param name="expression">The query expression to process.</param>
protected virtual Expression ProcessTypeMappings(Expression expression)
=> new RelationalTypeMappingPostprocessor(Dependencies, RelationalDependencies, RelationalQueryCompilationContext).Process(expression);

/// <summary>
/// Prunes unnecessary objects from the SQL tree, e.g. tables which aren't referenced by any column.
/// Can be overridden by providers for provider-specific pruning.
/// </summary>
protected virtual Expression Prune(Expression query)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,20 @@ public sealed record RelationalQueryTranslationPostprocessorDependencies
/// </remarks>
[EntityFrameworkInternal]
public RelationalQueryTranslationPostprocessorDependencies(
ISqlExpressionFactory sqlExpressionFactory)
ISqlExpressionFactory sqlExpressionFactory,
IRelationalTypeMappingSource typeMappingSource)
{
SqlExpressionFactory = sqlExpressionFactory;
TypeMappingSource = typeMappingSource;
}

/// <summary>
/// The SQL expression factory.
/// </summary>
public ISqlExpressionFactory SqlExpressionFactory { get; init; }

/// <summary>
/// The SQL expression factory.
/// </summary>
public IRelationalTypeMappingSource TypeMappingSource { get; init; }
}
Loading