Skip to content

Commit

Permalink
Query: Remove EntityQueryableExpressionVisitor and integrate function…
Browse files Browse the repository at this point in the history
…ality in QueryableMethodTranslatingVisitor

Issue:
We did 2 pass in ExpressionTree to convert entityQueryables to shapedQueries and then translate/compose over them.
Since we mutate the ShapedQueryExpression.QueryExpression in place,
(reference to query expression are in shaper expression so it is not easy to make it immutable)
if we try to translate something and fail then there is no way for us to try translating smaller part since we already mutated the ET.
By integrating functionality in translation pipeline, if we fail to translate, our initial expression would still be intact (since it does not contain shapedQuery

This is required for supporting collections/single non-scalar in projection.
  • Loading branch information
smitpatel committed Jun 27, 2019
1 parent 9026770 commit 0230b7f
Show file tree
Hide file tree
Showing 19 changed files with 87 additions and 274 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ public static IServiceCollection AddEntityFrameworkCosmos([NotNull] this IServic
.TryAdd<ITypeMappingSource, CosmosTypeMappingSource>()

// New Query pipeline
.TryAdd<IEntityQueryableTranslatorFactory, CosmosEntityQueryableTranslatorFactory>()
.TryAdd<IQueryableMethodTranslatingExpressionVisitorFactory, CosmosQueryableMethodTranslatingExpressionVisitorFactory>()
.TryAdd<IShapedQueryCompilingExpressionVisitorFactory, CosmosShapedQueryCompilingExpressionVisitorFactory>()

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Query.Pipeline;
using Microsoft.EntityFrameworkCore.Storage;

namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Pipeline
{
public class CosmosQueryableMethodTranslatingExpressionVisitor : QueryableMethodTranslatingExpressionVisitor
{
private readonly IModel _model;
private readonly ISqlExpressionFactory _sqlExpressionFactory;
private readonly CosmosSqlTranslatingExpressionVisitor _sqlTranslator;
private readonly CosmosProjectionBindingExpressionVisitor _projectionBindingExpressionVisitor;
Expand All @@ -22,6 +24,7 @@ public CosmosQueryableMethodTranslatingExpressionVisitor(
IMemberTranslatorProvider memberTranslatorProvider,
IMethodCallTranslatorProvider methodCallTranslatorProvider)
{
_model = model;
_sqlExpressionFactory = sqlExpressionFactory;
_sqlTranslator = new CosmosSqlTranslatingExpressionVisitor(
model,
Expand All @@ -36,6 +39,22 @@ public override ShapedQueryExpression TranslateSubquery(Expression expression)
throw new NotImplementedException();
}

protected override ShapedQueryExpression CreateShapedQueryExpression(Type elementType)
{
var entityType = _model.FindEntityType(elementType);
var selectExpression = _sqlExpressionFactory.Select(entityType);

return new ShapedQueryExpression(
selectExpression,
new EntityShaperExpression(
entityType,
new ProjectionBindingExpression(
selectExpression,
new ProjectionMember(),
typeof(ValueBuffer)),
false));
}

protected override ShapedQueryExpression TranslateAll(ShapedQueryExpression source, LambdaExpression predicate)
{
throw new NotImplementedException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ public static IServiceCollection AddEntityFrameworkInMemoryDatabase([NotNull] th
// New Query pipeline
.TryAdd<IShapedQueryCompilingExpressionVisitorFactory, InMemoryShapedQueryCompilingExpressionVisitorFactory>()
.TryAdd<IQueryableMethodTranslatingExpressionVisitorFactory, InMemoryQueryableMethodTranslatingExpressionVisitorFactory>()
.TryAdd<IEntityQueryableTranslatorFactory, InMemoryEntityQueryableTranslatorFactory>()
.TryAdd<IShapedQueryOptimizerFactory, InMemoryShapedQueryOptimizerFactory>()

.TryAdd<ISingletonOptions, IInMemorySingletonOptions>(p => p.GetService<IInMemorySingletonOptions>())
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Query.Pipeline;
using Microsoft.EntityFrameworkCore.Storage;

Expand All @@ -14,18 +15,36 @@ public class InMemoryQueryableMethodTranslatingExpressionVisitor : QueryableMeth
{
private readonly InMemoryExpressionTranslatingExpressionVisitor _expressionTranslator;
private readonly InMemoryProjectionBindingExpressionVisitor _projectionBindingExpressionVisitor;
private readonly IModel _model;

public InMemoryQueryableMethodTranslatingExpressionVisitor()
public InMemoryQueryableMethodTranslatingExpressionVisitor(IModel model)
{
_expressionTranslator = new InMemoryExpressionTranslatingExpressionVisitor();
_projectionBindingExpressionVisitor = new InMemoryProjectionBindingExpressionVisitor(_expressionTranslator);
_model = model;
}

public override ShapedQueryExpression TranslateSubquery(Expression expression)
{
throw new NotImplementedException();
}

protected override ShapedQueryExpression CreateShapedQueryExpression(Type elementType)
{
var entityType = _model.FindEntityType(elementType);
var queryExpression = new InMemoryQueryExpression(entityType);

return new ShapedQueryExpression(
queryExpression,
new EntityShaperExpression(
entityType,
new ProjectionBindingExpression(
queryExpression,
new ProjectionMember(),
typeof(ValueBuffer)),
false));
}

protected override ShapedQueryExpression TranslateAll(ShapedQueryExpression source, LambdaExpression predicate)
{
var inMemoryQueryExpression = (InMemoryQueryExpression)source.QueryExpression;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class InMemoryQueryableMethodTranslatingExpressionVisitorFactory : IQuery
{
public QueryableMethodTranslatingExpressionVisitor Create(IModel model)
{
return new InMemoryQueryableMethodTranslatingExpressionVisitor();
return new InMemoryQueryableMethodTranslatingExpressionVisitor(model);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,6 @@ public override EntityFrameworkServicesBuilder TryAddCoreServices()
TryAdd<IQueryableMethodTranslatingExpressionVisitorFactory, RelationalQueryableMethodTranslatingExpressionVisitorFactory>();
TryAdd<IMethodCallTranslatorProvider, RelationalMethodCallTranslatorProvider>();
TryAdd<IMemberTranslatorProvider, RelationalMemberTranslatorProvider>();
TryAdd<IEntityQueryableTranslatorFactory, RelationalEntityQueryableTranslatorFactory>();
TryAdd<IShapedQueryOptimizerFactory, RelationalShapedQueryOptimizerFactory>();
TryAdd<IRelationalSqlTranslatingExpressionVisitorFactory, RelationalSqlTranslatingExpressionVisitorFactory>();
TryAdd<ISqlExpressionFactory, SqlExpressionFactory>();
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,19 @@ private RelationalQueryableMethodTranslatingExpressionVisitor(
_sqlExpressionFactory = sqlExpressionFactory;
}

protected override Expression VisitMethodCall(MethodCallExpression methodCallExpression)
{
if (methodCallExpression.Method.DeclaringType == typeof(RelationalQueryableExtensions)
&& methodCallExpression.Method.Name == nameof(RelationalQueryableExtensions.FromSqlOnQueryable))
{
var sql = (string)((ConstantExpression)methodCallExpression.Arguments[1]).Value;
var queryable = (IQueryable)((ConstantExpression)methodCallExpression.Arguments[0]).Value;
return CreateShapedQueryExpression(queryable.ElementType, sql, methodCallExpression.Arguments[2]);
}

return base.VisitMethodCall(methodCallExpression);
}

public override ShapedQueryExpression TranslateSubquery(Expression expression)
{
return (ShapedQueryExpression)new RelationalQueryableMethodTranslatingExpressionVisitor(
Expand All @@ -55,6 +68,35 @@ public override ShapedQueryExpression TranslateSubquery(Expression expression)

}

protected override ShapedQueryExpression CreateShapedQueryExpression(Type elementType)
{
var entityType = _model.FindEntityType(elementType);
var queryExpression = _sqlExpressionFactory.Select(entityType);

return CreateShapedQueryExpression(entityType, queryExpression);
}

private ShapedQueryExpression CreateShapedQueryExpression(Type elementType, string sql, Expression arguments)
{
var entityType = _model.FindEntityType(elementType);
var queryExpression = _sqlExpressionFactory.Select(entityType, sql, arguments);

return CreateShapedQueryExpression(entityType, queryExpression);
}

private ShapedQueryExpression CreateShapedQueryExpression(IEntityType entityType, SelectExpression selectExpression)
{
return new ShapedQueryExpression(
selectExpression,
new EntityShaperExpression(
entityType,
new ProjectionBindingExpression(
selectExpression,
new ProjectionMember(),
typeof(ValueBuffer)),
false));
}

protected override ShapedQueryExpression TranslateAll(ShapedQueryExpression source, LambdaExpression predicate)
{
var translation = TranslateLambdaExpression(source, predicate);
Expand Down
Loading

0 comments on commit 0230b7f

Please sign in to comment.