public static Expression Replace(Expression source, AliasGenerator aliasGenerator) { var aliasMap = DeclaredAliasGatherer.GatherDeclared(source).Reverse().ToDictionary(a => a, aliasGenerator.CloneAlias); AliasReplacer ap = new AliasReplacer(aliasMap); return(ap.Visit(source)); }
// <summary> // Constructs a new ObjectSpanRewriter that will attempt to apply spanning to the specified query // (represented as a DbExpression) when <see cref="RewriteQuery" /> is called. // </summary> // <param name="toRewrite"> // A <see cref="DbExpression" /> representing the query to span. // </param> internal ObjectSpanRewriter(DbCommandTree tree, DbExpression toRewrite, AliasGenerator aliasGenerator) { DebugCheck.NotNull(toRewrite); _toRewrite = toRewrite; _tree = tree; _aliasGenerator = aliasGenerator; }
/// <summary> /// Constructs a new ObjectSpanRewriter that will attempt to apply spanning to the specified query /// (represented as a DbExpression) when <see cref="RewriteQuery"/> is called. /// </summary> /// <param name="toRewrite">A <see cref="DbExpression"/> representing the query to span.</param> internal ObjectSpanRewriter(DbCommandTree tree, DbExpression toRewrite, AliasGenerator aliasGenerator) { Debug.Assert(toRewrite != null, "Expression to rewrite cannot be null"); _toRewrite = toRewrite; _tree = tree; _aliasGenerator = aliasGenerator; }
/// <summary> /// 创建 DELETE 命令 /// </summary> /// <param name="tree">查询语义</param> /// <param name="context">解析SQL命令上下文</param> /// <returns></returns> protected override DbRawCommand TranslateDeleteCommand <T>(DbQueryDeleteTree tree, ITranslateContext context) { ISqlBuilder builder = this.CreateSqlBuilder(context); var typeRuntime = TypeRuntimeInfoCache.GetRuntimeInfo <T>(); builder.Append("DELETE FROM "); builder.AppendTable(typeRuntime.TableSchema, typeRuntime.TableName, typeRuntime.IsTemporary); builder.Append(" t0 "); if (tree.Entity != null) { if (typeRuntime.KeyMembers == null || typeRuntime.KeyMembers.Count == 0) { throw new XFrameworkException("Delete<T>(T value) require entity must have key column."); } object entity = tree.Entity; builder.AppendNewLine(); builder.Append("WHERE "); foreach (FieldAccessorBase m in typeRuntime.KeyMembers) { var value = m.Invoke(entity); var sqlExpression = this.Constor.GetSqlValue(value, context, m.Column); builder.AppendMember("t0", m.Member, typeRuntime.Type); builder.Append(" = "); builder.Append(sqlExpression); builder.Append(" AND "); } builder.Length -= 5; } else if (tree.Select != null) { AliasGenerator ag = this.PrepareTableAlias(tree.Select, context.AliasPrefix); var cmd = new NpgDbSelectCommand(context, ag, DbExpressionType.Delete, tree.Select.SelectHasMany); if (tree.Select.Joins != null) { var visitor = new NpgJoinExpressionVisitor(ag, cmd.JoinFragment, DbExpressionType.Delete, cmd); visitor.Visit(tree.Select.Joins); } if (tree.Select.Wheres != null) { var visitor = new NpgWhereExpressionVisitor(ag, cmd.WhereFragment); visitor.Visit(tree.Select.Wheres); cmd.AddNavMembers(visitor.NavMembers); } builder.Append(cmd.CommandText); } builder.Append(';'); return(new DbRawCommand(builder.ToString(), builder.TranslateContext != null ? builder.TranslateContext.Parameters : null, System.Data.CommandType.Text)); }
public static Expression Rewrite(Expression expr, AliasGenerator generator) { if (!Schema.Current.Settings.IsPostgres) { return(expr); } return(new DuplicateHistory(generator).Visit(expr)); }
public static Expression Replace(Expression proj, AliasGenerator aliasGenerator) { AliasProjectionReplacer apr = new AliasProjectionReplacer( root: proj as ProjectionExpression, aliasGenerator: aliasGenerator ); return(apr.Visit(proj)); }
internal ObjectSpanRewriter( DbCommandTree tree, DbExpression toRewrite, AliasGenerator aliasGenerator) { this._toRewrite = toRewrite; this._tree = tree; this._aliasGenerator = aliasGenerator; }
public CachedLiteTable(ICacheLogicController controller, AliasGenerator aliasGenerator, string lastPartialJoin, string remainingJoins) : base(controller) { this.table = Schema.Current.Table(typeof(T)); this.lastPartialJoin = lastPartialJoin; this.remainingJoins = remainingJoins; this.currentAlias = aliasGenerator.NextTableAlias(table.Name.Name); if (!CacheLogic.WithSqlDependency) { semiCachedController = new SemiCachedController <T>(this); } }
private void InitializeAndAddFromElement(FromElement element, string className, string classAlias, IEntityPersister entityPersister, EntityType type, string tableAlias) { if (tableAlias == null) { AliasGenerator aliasGenerator = _fromClause.AliasGenerator; tableAlias = aliasGenerator.CreateName(entityPersister.EntityName); } element.InitializeEntity(_fromClause, className, entityPersister, type, classAlias, tableAlias); }
protected override void Act() { // Execute code under test _generator1 = new AliasGenerator("1_", useSharedState: true); _generator1.Reset(); _generator2 = new AliasGenerator("1_", useSharedState: true); _generator2.Reset(); _generator3 = new AliasGenerator("1_", useSharedState: true); _generator3.Reset(); _instanceGenerator = new AliasGenerator("1_", useSharedState: false); }
static internal ProjectionExpression Flatten(ProjectionExpression proj, AliasGenerator aliasGenerator) { var result = (ProjectionExpression) new ChildProjectionFlattener(aliasGenerator).Visit(proj); if (result == proj) { return(result); } Expression columnCleaned = UnusedColumnRemover.Remove(result); Expression subqueryCleaned = RedundantSubqueryRemover.Remove(columnCleaned); return((ProjectionExpression)subqueryCleaned); }
public CachedTableConstructor(CachedTableBase cachedTable, AliasGenerator aliasGenerator) { this.cachedTable = cachedTable; this.table = cachedTable.Table; if (aliasGenerator != null) { this.aliasGenerator = aliasGenerator; this.currentAlias = aliasGenerator.NextTableAlias(table.Name.Name); } this.tupleType = TupleReflection.TupleChainType(table.Columns.Values.Select(GetColumnType)); this.origin = Expression.Parameter(tupleType, "origin"); }
public override void Execute() { var aliasGenerator = new AliasGenerator(); Alias firstAlias = aliasGenerator.GetAlias("John Doe"); Assert.NotNull(firstAlias); Alias sameAlias = aliasGenerator.GetAlias("John Doe"); Assert.Equal(firstAlias, sameAlias); Alias anotherAlias = aliasGenerator.GetAlias("Jane Doe"); Assert.NotEqual(firstAlias, anotherAlias); }
public virtual ObjectQueryExecutionPlan Prepare( ObjectContext context, DbQueryCommandTree tree, Type elementType, MergeOption mergeOption, bool streaming, Span span, IEnumerable <Tuple <ObjectParameter, QueryParameterExpression> > compiledQueryParameters, AliasGenerator aliasGenerator) { TypeUsage resultType = tree.Query.ResultType; DbExpression newQuery; SpanIndex spanInfo; if (ObjectSpanRewriter.TryRewrite(tree, span, mergeOption, aliasGenerator, out newQuery, out spanInfo)) { tree = DbQueryCommandTree.FromValidExpression(tree.MetadataWorkspace, tree.DataSpace, newQuery, tree.UseDatabaseNullSemantics); } else { spanInfo = (SpanIndex)null; } EntityCommandDefinition commandDefinition = ObjectQueryExecutionPlanFactory.CreateCommandDefinition(context, tree); ShaperFactory resultShaperFactory = System.Data.Entity.Core.Common.Internal.Materialization.Translator.TranslateColumnMap(this._translator, elementType, commandDefinition.CreateColumnMap((DbDataReader)null), context.MetadataWorkspace, spanInfo, mergeOption, streaming, false); EntitySet singleEntitySet = (EntitySet)null; if (resultType.EdmType.BuiltInTypeKind == BuiltInTypeKind.CollectionType && commandDefinition.EntitySets != null) { foreach (EntitySet entitySet in commandDefinition.EntitySets) { if (entitySet != null && entitySet.ElementType.IsAssignableFrom(((CollectionType)resultType.EdmType).TypeUsage.EdmType)) { if (singleEntitySet == null) { singleEntitySet = entitySet; } else { singleEntitySet = (EntitySet)null; break; } } } } return(new ObjectQueryExecutionPlan((DbCommandDefinition)commandDefinition, resultShaperFactory, resultType, mergeOption, streaming, singleEntitySet, compiledQueryParameters)); }
internal ObjectFullSpanRewriter( DbCommandTree tree, DbExpression toRewrite, Span span, AliasGenerator aliasGenerator) : base(tree, toRewrite, aliasGenerator) { EntityType entityType = (EntityType)null; if (!ObjectFullSpanRewriter.TryGetEntityType(this.Query.ResultType, out entityType)) { throw new InvalidOperationException(Strings.ObjectQuery_Span_IncludeRequiresEntityOrEntityCollection); } ObjectFullSpanRewriter.SpanPathInfo parentInfo = new ObjectFullSpanRewriter.SpanPathInfo(entityType); foreach (Span.SpanPath span1 in span.SpanList) { this.AddSpanPath(parentInfo, span1.Navigations); } this._currentSpanPath.Push(parentInfo); }
internal protected virtual R Insert <R>(IQueryable query, LambdaExpression constructor, ITable table, Func <SqlPreCommandSimple, R> continuation, bool removeSelectRowCount = false) { AliasGenerator aliasGenerator = new AliasGenerator(); SqlPreCommandSimple cr; using (HeavyProfiler.Log("LINQ")) using (var log = HeavyProfiler.LogNoStackTrace("Clean")) { Expression cleaned = Clean(query.Expression, true, log) !; var binder = new QueryBinder(aliasGenerator); log.Switch("Bind"); CommandExpression insert = binder.BindInsert(cleaned, constructor, table); CommandExpression insertOprimized = (CommandExpression)Optimize(insert, binder, aliasGenerator, log); CommandExpression insertSimplified = CommandSimplifier.Simplify(insertOprimized, removeSelectRowCount, aliasGenerator); log.Switch("TR"); cr = TranslatorBuilder.BuildCommandResult(insertSimplified); } return(continuation(cr)); }
internal protected virtual R Update <R>(IUpdateable updateable, Func <SqlPreCommandSimple, R> continuation, bool removeSelectRowCount = false) { AliasGenerator aliasGenerator = new AliasGenerator(); SqlPreCommandSimple cr; using (HeavyProfiler.Log("LINQ")) using (var log = HeavyProfiler.LogNoStackTrace("Clean")) { Expression cleaned = Clean(updateable.Query.Expression, true, log) !; var binder = new QueryBinder(aliasGenerator); log.Switch("Bind"); CommandExpression update = binder.BindUpdate(cleaned, updateable.PartSelector, updateable.SetterExpressions); CommandExpression updateOptimized = (CommandExpression)Optimize(update, binder, aliasGenerator, log); CommandExpression updateSimplified = CommandSimplifier.Simplify(updateOptimized, removeSelectRowCount, aliasGenerator); log.Switch("TR"); cr = TranslatorBuilder.BuildCommandResult(updateSimplified); } return(continuation(cr)); }
internal protected virtual R Translate <R>(Expression expression, Func <ITranslateResult, R> continuation) //For debugging purposes { AliasGenerator aliasGenerator = new AliasGenerator(); ITranslateResult result; using (HeavyProfiler.Log("LINQ", () => expression.ToString())) using (var log = HeavyProfiler.LogNoStackTrace("Clean")) { Expression cleaned = Clean(expression, true, log) !; var binder = new QueryBinder(aliasGenerator); log.Switch("Bind"); ProjectionExpression binded = (ProjectionExpression)binder.BindQuery(cleaned); ProjectionExpression optimized = (ProjectionExpression)Optimize(binded, binder, aliasGenerator, log); log.Switch("ChPrjFlatt"); ProjectionExpression flat = ChildProjectionFlattener.Flatten(optimized, aliasGenerator); log.Switch("TB"); result = TranslatorBuilder.Build(flat); } return(continuation(result)); }
internal static Expression Optimize(Expression binded, QueryBinder binder, AliasGenerator aliasGenerator, HeavyProfiler.Tracer?log) { var isPostgres = Schema.Current.Settings.IsPostgres; log.Switch("Aggregate"); Expression rewriten = AggregateRewriter.Rewrite(binded); log.Switch("DupHistory"); Expression dupHistory = DuplicateHistory.Rewrite(rewriten, aliasGenerator); log.Switch("EntityCompleter"); Expression completed = EntityCompleter.Complete(dupHistory, binder); log.Switch("AliasReplacer"); Expression replaced = AliasProjectionReplacer.Replace(completed, aliasGenerator); log.Switch("OrderBy"); Expression orderRewrited = OrderByRewriter.Rewrite(replaced); log.Switch("OrderBy"); Expression lazyCastRemoved = SqlCastLazyRemover.Remove(orderRewrited); log.Switch("Rebinder"); Expression rebinded = QueryRebinder.Rebind(lazyCastRemoved); log.Switch("UnusedColumn"); Expression columnCleaned = UnusedColumnRemover.Remove(rebinded); log.Switch("Redundant"); Expression subqueryCleaned = RedundantSubqueryRemover.Remove(columnCleaned); log.Switch("Condition"); Expression rewriteConditions = isPostgres ? ConditionsRewriterPostgres.Rewrite(subqueryCleaned) : ConditionsRewriter.Rewrite(subqueryCleaned); log.Switch("Scalar"); Expression scalar = ScalarSubqueryRewriter.Rewrite(rewriteConditions); return(scalar); }
// Dependencies protected override void Act() { // Execute code under test var generator = new AliasGenerator("fltr_", useSharedState: true); generator.Reset(); _actualAliases = new HashSet <string>(StringComparer.InvariantCultureIgnoreCase); int i = 0; string firstAlias = null; while (i++ < 100000) { string nextAlias = generator.GetNextAlias(); if (firstAlias == null) { firstAlias = nextAlias; } if (!_actualAliases.Add(nextAlias)) { // If we looped around if (nextAlias == firstAlias && i == 26 * 26 * 26 + 1) { break; } Assert.Fail("Duplicate alias generated: '{0}'", nextAlias); } } if (i >= 100000) { Assert.Fail("Possible infinite loop detected in alias generation. Stopped at 100,000 aliases."); } }
internal static DbExpression FindNavigationExpression( DbExpression expression, AliasGenerator aliasGenerator, out ObjectSpanRewriter.NavigationInfo navInfo) { navInfo = (ObjectSpanRewriter.NavigationInfo)null; TypeUsage typeUsage = ((CollectionType)expression.ResultType.EdmType).TypeUsage; if (!TypeSemantics.IsEntityType(typeUsage) && !TypeSemantics.IsReferenceType(typeUsage)) { return(expression); } ObjectSpanRewriter.RelationshipNavigationVisitor navigationVisitor = new ObjectSpanRewriter.RelationshipNavigationVisitor(aliasGenerator); DbExpression dbExpression = navigationVisitor.Find(expression); if (object.ReferenceEquals((object)expression, (object)dbExpression)) { return(expression); } navInfo = new ObjectSpanRewriter.NavigationInfo(navigationVisitor._original, navigationVisitor._rewritten); return(dbExpression); }
internal static bool TryRewrite( DbQueryCommandTree tree, Span span, MergeOption mergeOption, AliasGenerator aliasGenerator, out DbExpression newQuery, out SpanIndex spanInfo) { newQuery = null; spanInfo = null; ObjectSpanRewriter rewriter = null; var requiresRelationshipSpan = Span.RequiresRelationshipSpan(mergeOption); // Potentially perform a rewrite for span. // Note that the public 'Span' property is NOT used to retrieve the Span instance // since this forces creation of a Span object that may not be required. if (span != null && span.SpanList.Count > 0) { rewriter = new ObjectFullSpanRewriter(tree, tree.Query, span, aliasGenerator); } else if (requiresRelationshipSpan) { rewriter = new ObjectSpanRewriter(tree, tree.Query, aliasGenerator); } if (rewriter != null) { rewriter.RelationshipSpan = requiresRelationshipSpan; newQuery = rewriter.RewriteQuery(); if (newQuery != null) { Debug.Assert( rewriter.SpanIndex != null || tree.Query.ResultType.EdmEquals(newQuery.ResultType), "Query was rewritten for Span but no SpanIndex was created?"); spanInfo = rewriter.SpanIndex; } } return(spanInfo != null); }
// Dependencies protected override void Act() { // Execute code under test var generator = new AliasGenerator("fltr_", useSharedState: false); generator.Reset(); _actualAliases = new HashSet <string>(StringComparer.InvariantCultureIgnoreCase); int i = 0; while (i++ < 100000) { string nextAlias = generator.GetNextAlias(); if (!_actualAliases.Add(nextAlias)) { Assert.Fail("Duplicate alias generated: '{0}'", nextAlias); } } Assert.Fail("Possible infinite loop detected in alias generation. Stopped at 100,000 aliases."); }
// Constructors public TranslatorContext(Session session, CompilerConfiguration rseCompilerConfiguration, Expression query, CompiledQueryProcessingScope compiledQueryScope) { ArgumentValidator.EnsureArgumentNotNull(session, nameof(session)); ArgumentValidator.EnsureArgumentNotNull(rseCompilerConfiguration, nameof(rseCompilerConfiguration)); ArgumentValidator.EnsureArgumentNotNull(query, nameof(query)); Domain = session.Domain; RseCompilerConfiguration = rseCompilerConfiguration; // Applying query preprocessors query = Domain.Handler.QueryPreprocessors .Aggregate(query, (current, preprocessor) => ApplyPreprocessor(preprocessor, session, current)); // Built-in preprocessors query = AggregateOptimizer.Rewrite(query); query = ClosureAccessRewriter.Rewrite(query, compiledQueryScope); query = EqualityRewriter.Rewrite(query); query = EntitySetAccessRewriter.Rewrite(query); query = SubqueryDefaultResultRewriter.Rewrite(query); Evaluator = new ExpressionEvaluator(query); query = PersistentIndexerRewriter.Rewrite(query, this); Query = query; resultAliasGenerator = AliasGenerator.Create("#{0}{1}"); columnAliasGenerator = AliasGenerator.Create(new[] { "c01umn" }); CustomCompilerProvider = Domain.Handler.GetMemberCompilerProvider <Expression>(); Model = Domain.Model; TypeIdRegistry = session.StorageNode.TypeIdRegistry; ProviderInfo = Domain.Handlers.ProviderInfo; Translator = new Translator(this, compiledQueryScope); ParameterExtractor = new ParameterExtractor(Evaluator); Bindings = new LinqBindingCollection(); applyParameters = new Dictionary <CompilableProvider, ApplyParameter>(); tupleParameters = new Dictionary <ParameterExpression, Parameter <Tuple> >(); boundItemProjectors = new Dictionary <ParameterExpression, ItemProjectorExpression>(); }
private RelationshipNavigationVisitor(AliasGenerator aliasGenerator) { _aliasGenerator = aliasGenerator; }
internal static DbExpression FindNavigationExpression(DbExpression expression, AliasGenerator aliasGenerator, out NavigationInfo navInfo) { Debug.Assert(TypeSemantics.IsCollectionType(expression.ResultType), "Non-collection input to projection?"); navInfo = null; TypeUsage elementType = ((CollectionType)expression.ResultType.EdmType).TypeUsage; if (!TypeSemantics.IsEntityType(elementType) && !TypeSemantics.IsReferenceType(elementType)) { return(expression); } RelationshipNavigationVisitor visitor = new RelationshipNavigationVisitor(aliasGenerator); DbExpression rewrittenExpression = visitor.Find(expression); if (!object.ReferenceEquals(expression, rewrittenExpression)) { Debug.Assert(visitor._original != null && visitor._rewritten != null, "Expression was rewritten but no navigation was found?"); navInfo = new NavigationInfo(visitor._original, visitor._rewritten); return(rewrittenExpression); } else { return(expression); } }
private void DereferenceEntityJoin(string classAlias, EntityType propertyType, bool impliedJoin, IASTNode parent) { _dereferenceType = DerefEntity; if (Log.IsDebugEnabled) { Log.Debug("dereferenceEntityJoin() : generating join for " + _propertyName + " in " + FromElement.ClassName + " " + ((classAlias == null) ? "{no alias}" : "(" + classAlias + ")") + " parent = " + ASTUtil.GetDebugstring(parent) ); } // Create a new FROM node for the referenced class. string associatedEntityName = propertyType.GetAssociatedEntityName(); string tableAlias = AliasGenerator.CreateName(associatedEntityName); string[] joinColumns = GetColumns(); string joinPath = Path; if (impliedJoin && Walker.IsInFrom) { _joinType = Walker.ImpliedJoinType; } FromClause currentFromClause = Walker.CurrentFromClause; FromElement elem = currentFromClause.FindJoinByPath(joinPath); /////////////////////////////////////////////////////////////////////////////// // // This is the piece which recognizes the condition where an implicit join path // resolved earlier in a correlated subquery is now being referenced in the // outer query. For 3.0final, we just let this generate a second join (which // is exactly how the old parser handles this). Eventually we need to add this // logic back in and complete the logic in FromClause.promoteJoin; however, // FromClause.promoteJoin has its own difficulties (see the comments in // FromClause.promoteJoin). // // if ( elem == null ) { // // see if this joinPath has been used in a "child" FromClause, and if so // // promote that element to the outer query // FromClause currentNodeOwner = getFromElement().getFromClause(); // FromClause currentJoinOwner = currentNodeOwner.locateChildFromClauseWithJoinByPath( joinPath ); // if ( currentJoinOwner != null && currentNodeOwner != currentJoinOwner ) { // elem = currentJoinOwner.findJoinByPathLocal( joinPath ); // if ( elem != null ) { // currentFromClause.promoteJoin( elem ); // // EARLY EXIT!!! // return; // } // } // } // /////////////////////////////////////////////////////////////////////////////// bool found = elem != null; // even though we might find a pre-existing element by join path, for FromElements originating in a from-clause // we should only ever use the found element if the aliases match (null != null here). Implied joins are // always (?) ok to reuse. bool useFoundFromElement = found && (elem.IsImplied || (AreSame(classAlias, elem.ClassAlias))); if (!useFoundFromElement) { // If this is an implied join in a from element, then use the impled join type which is part of the // tree parser's state (set by the gramamar actions). JoinSequence joinSequence = SessionFactoryHelper .CreateJoinSequence(impliedJoin, propertyType, tableAlias, _joinType, joinColumns); FromElementFactory factory = new FromElementFactory( currentFromClause, GetLhs().FromElement, joinPath, classAlias, joinColumns, impliedJoin ); elem = factory.CreateEntityJoin( associatedEntityName, tableAlias, joinSequence, _fetch, Walker.IsInFrom, propertyType ); } else { currentFromClause.AddDuplicateAlias(classAlias, elem); } SetImpliedJoin(elem); Walker.AddQuerySpaces(elem.EntityPersister.QuerySpaces); FromElement = elem; // This 'dot' expression now refers to the resulting from element. }
protected OrderByLifterBase(DbExpression root, AliasGenerator aliasGenerator) { _root = root; _aliasGenerator = aliasGenerator; }
internal PassthroughOrderByLifter(DbExpression source, AliasGenerator aliasGenerator) : base(source, aliasGenerator) { }
internal SortLifter(DbSortExpression sort, AliasGenerator aliasGenerator) : base(sort, aliasGenerator) { _sort = sort; _source = sort.Input.Expression; }