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
41 changes: 10 additions & 31 deletions Orm/Xtensive.Orm/Orm/Providers/DomainHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ namespace Xtensive.Orm.Providers
/// </summary>
public abstract class DomainHandler : DomainBoundHandler
{
private static readonly OrderingCorrector OrderingCorrector = new OrderingCorrector(ResolveOrderingDescriptor);

private Dictionary<Type, IMemberCompilerProvider> memberCompilerProviders;

/// <summary>
Expand Down Expand Up @@ -93,16 +91,20 @@ protected virtual IPreCompiler CreatePreCompiler(CompilerConfiguration configura
{
var providerInfo = Handlers.ProviderInfo;

var applyCorrector = new ApplyProviderCorrector(
!providerInfo.Supports(ProviderFeatures.Apply));
var skipTakeCorrector = new SkipTakeCorrector(
providerInfo.Supports(ProviderFeatures.NativeTake),
providerInfo.Supports(ProviderFeatures.NativeSkip));
var applyCorrector = providerInfo.Supports(ProviderFeatures.Apply)
? ApplyProviderCorrector.SilentCorrector
: ApplyProviderCorrector.ExceptionThrowingCorrector;

var skipTakeCorrector = (providerInfo.Supports(ProviderFeatures.NativeTake | ProviderFeatures.NativeSkip))
? SkipTakeCorrector.FullPaginationSupportCorrector
: new SkipTakeCorrector(providerInfo.Supports(ProviderFeatures.NativeTake),
providerInfo.Supports(ProviderFeatures.NativeSkip));

return new CompositePreCompiler(
applyCorrector,
skipTakeCorrector,
RedundantColumnOptimizer.Instance,
OrderingCorrector);
OrderingCorrector.DefaultInstance);
}

/// <summary>
Expand Down Expand Up @@ -194,29 +196,6 @@ private void BuildQueryPreprocessors()
QueryPreprocessors = ordered ?? throw new InvalidOperationException(Strings.ExCyclicDependencyInQueryPreprocessorGraphIsDetected);
}

private static ProviderOrderingDescriptor ResolveOrderingDescriptor(CompilableProvider provider)
{
var isOrderSensitive = provider.Type is ProviderType.Skip
or ProviderType.Take
or ProviderType.Seek
or ProviderType.Paging
or ProviderType.RowNumber;
var preservesOrder = provider.Type is ProviderType.Skip
or ProviderType.Take
or ProviderType.Seek
or ProviderType.Paging
or ProviderType.RowNumber
or ProviderType.Distinct
or ProviderType.Alias;
var isOrderBreaker = provider.Type is ProviderType.Except
or ProviderType.Intersect
or ProviderType.Union
or ProviderType.Concat
or ProviderType.Existence;
var isSorter = provider.Type is ProviderType.Sort or ProviderType.Index;
return new ProviderOrderingDescriptor(isOrderSensitive, preservesOrder, isOrderBreaker, isSorter);
}

#endregion


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ namespace Xtensive.Orm.Rse.Transformation
/// </summary>
public sealed class ApplyProviderCorrector : IPreCompiler
{
public static ApplyProviderCorrector ExceptionThrowingCorrector { get; } = new ApplyProviderCorrector(true);
public static ApplyProviderCorrector SilentCorrector { get; } = new ApplyProviderCorrector(false);


private readonly bool throwOnCorrectionFault;

/// <inheritdoc/>
Expand Down
31 changes: 31 additions & 0 deletions Orm/Xtensive.Orm/Orm/Rse/Transformation/OrderingCorrector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ namespace Xtensive.Orm.Rse.Transformation
[Serializable]
public sealed class OrderingCorrector : IPreCompiler
{
public static OrderingCorrector DefaultInstance { get; } = new OrderingCorrector();


private readonly Func<CompilableProvider, ProviderOrderingDescriptor> orderingDescriptorResolver;

/// <inheritdoc/>
Expand All @@ -26,6 +29,29 @@ CompilableProvider IPreCompiler.Process(CompilableProvider rootProvider)
return OrderingRewriter.Rewrite(rootProvider, orderingDescriptorResolver);
}

private static ProviderOrderingDescriptor ResolveOrderingDescriptor(CompilableProvider provider)
{
var isOrderSensitive = provider.Type is ProviderType.Skip
or ProviderType.Take
or ProviderType.Seek
or ProviderType.Paging
or ProviderType.RowNumber;
var preservesOrder = provider.Type is ProviderType.Skip
or ProviderType.Take
or ProviderType.Seek
or ProviderType.Paging
or ProviderType.RowNumber
or ProviderType.Distinct
or ProviderType.Alias;
var isOrderBreaker = provider.Type is ProviderType.Except
or ProviderType.Intersect
or ProviderType.Union
or ProviderType.Concat
or ProviderType.Existence;
var isSorter = provider.Type is ProviderType.Sort or ProviderType.Index;
return new ProviderOrderingDescriptor(isOrderSensitive, preservesOrder, isOrderBreaker, isSorter);
}


// Constructors

Expand All @@ -38,5 +64,10 @@ public OrderingCorrector(Func<CompilableProvider, ProviderOrderingDescriptor> or
{
this.orderingDescriptorResolver = orderingDescriptorResolver ?? throw new ArgumentNullException(nameof(orderingDescriptorResolver));
}

private OrderingCorrector()
{
this.orderingDescriptorResolver = ResolveOrderingDescriptor;
}
}
}
2 changes: 2 additions & 0 deletions Orm/Xtensive.Orm/Orm/Rse/Transformation/SkipTakeCorrector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ namespace Xtensive.Orm.Rse.Transformation
[Serializable]
public sealed class SkipTakeCorrector : IPreCompiler
{
public static SkipTakeCorrector FullPaginationSupportCorrector { get; } = new(true, true);

private readonly bool takeSupported;
private readonly bool skipSupported;

Expand Down
Loading