Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DLinq / Dlinq / SqlClient / Query / SqlLiftIndependentRowExpressions.cs / 1305376 / SqlLiftIndependentRowExpressions.cs
using System; using System.Collections.Generic; using System.Text; using System.Diagnostics.CodeAnalysis; namespace System.Data.Linq.SqlClient { ////// Find projection expressions on the right side of CROSS APPLY that do not /// depend exclusively on right side productions and move them outside of the /// CROSS APPLY by enclosing the CROSS APPLY with a new source. /// class SqlLiftIndependentRowExpressions { internal static SqlNode Lift(SqlNode node) { ColumnLifter cl = new ColumnLifter(); node = cl.Visit(node); return node; } private class ColumnLifter : SqlVisitor { SelectScope expressionSink; SqlAggregateChecker aggregateChecker; internal ColumnLifter() { this.aggregateChecker = new SqlAggregateChecker(); } class SelectScope { // Stack of projections lifted from the right to be pushed on the left. internal Stack> Lifted = new Stack
>(); internal IEnumerable
LeftProduction; internal HashSet ReferencedExpressions = new HashSet (); } internal override SqlSelect VisitSelect(SqlSelect select) { SelectScope s = expressionSink; // Don't lift through a TOP. if (select.Top != null) { expressionSink = null; } // Don't lift through a GROUP BY (or implicit GROUP BY). if (select.GroupBy.Count > 0 || this.aggregateChecker.HasAggregates(select)) { expressionSink = null; } // Don't lift through DISTINCT if (select.IsDistinct) { expressionSink = null; } if (expressionSink != null) { List keep = new List (); List lift = new List (); foreach (SqlColumn sc in select.Row.Columns) { bool referencesLeftsideAliases = SqlAliasesReferenced.ReferencesAny(sc.Expression, expressionSink.LeftProduction); bool isLockedExpression = expressionSink.ReferencedExpressions.Contains(sc); if (referencesLeftsideAliases && !isLockedExpression) { lift.Add(sc); } else { keep.Add(sc); } } select.Row.Columns.Clear(); select.Row.Columns.AddRange(keep); if (lift.Count > 0) { expressionSink.Lifted.Push(lift); } } SqlSelect sel = base.VisitSelect(select); expressionSink = s; return sel; } internal override SqlExpression VisitColumnRef(SqlColumnRef cref) { if (expressionSink!=null) { expressionSink.ReferencedExpressions.Add(cref.Column); } return cref; } internal override SqlSource VisitJoin(SqlJoin join) { if (join.JoinType == SqlJoinType.CrossApply) { // Visit the left side as usual. join.Left = this.VisitSource(join.Left); // Visit the condition as usual. join.Condition = this.VisitExpression(join.Condition); // Visit the right, with the expressionSink set. SelectScope s = expressionSink; expressionSink = new SelectScope(); expressionSink.LeftProduction = SqlGatherProducedAliases.Gather(join.Left); join.Right = this.VisitSource(join.Right); // Were liftable expressions found? SqlSource newSource = join; foreach (List cols in expressionSink.Lifted) { newSource = PushSourceDown(newSource, cols); } expressionSink = s; return newSource; } return base.VisitJoin(join); } [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")] private SqlSource PushSourceDown(SqlSource sqlSource, List cols) { SqlSelect ns = new SqlSelect(new SqlNop(cols[0].ClrType, cols[0].SqlType, sqlSource.SourceExpression), sqlSource, sqlSource.SourceExpression); ns.Row.Columns.AddRange(cols); return new SqlAlias(ns); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. using System; using System.Collections.Generic; using System.Text; using System.Diagnostics.CodeAnalysis; namespace System.Data.Linq.SqlClient { /// /// Find projection expressions on the right side of CROSS APPLY that do not /// depend exclusively on right side productions and move them outside of the /// CROSS APPLY by enclosing the CROSS APPLY with a new source. /// class SqlLiftIndependentRowExpressions { internal static SqlNode Lift(SqlNode node) { ColumnLifter cl = new ColumnLifter(); node = cl.Visit(node); return node; } private class ColumnLifter : SqlVisitor { SelectScope expressionSink; SqlAggregateChecker aggregateChecker; internal ColumnLifter() { this.aggregateChecker = new SqlAggregateChecker(); } class SelectScope { // Stack of projections lifted from the right to be pushed on the left. internal Stack> Lifted = new Stack
>(); internal IEnumerable
LeftProduction; internal HashSet ReferencedExpressions = new HashSet (); } internal override SqlSelect VisitSelect(SqlSelect select) { SelectScope s = expressionSink; // Don't lift through a TOP. if (select.Top != null) { expressionSink = null; } // Don't lift through a GROUP BY (or implicit GROUP BY). if (select.GroupBy.Count > 0 || this.aggregateChecker.HasAggregates(select)) { expressionSink = null; } // Don't lift through DISTINCT if (select.IsDistinct) { expressionSink = null; } if (expressionSink != null) { List keep = new List (); List lift = new List (); foreach (SqlColumn sc in select.Row.Columns) { bool referencesLeftsideAliases = SqlAliasesReferenced.ReferencesAny(sc.Expression, expressionSink.LeftProduction); bool isLockedExpression = expressionSink.ReferencedExpressions.Contains(sc); if (referencesLeftsideAliases && !isLockedExpression) { lift.Add(sc); } else { keep.Add(sc); } } select.Row.Columns.Clear(); select.Row.Columns.AddRange(keep); if (lift.Count > 0) { expressionSink.Lifted.Push(lift); } } SqlSelect sel = base.VisitSelect(select); expressionSink = s; return sel; } internal override SqlExpression VisitColumnRef(SqlColumnRef cref) { if (expressionSink!=null) { expressionSink.ReferencedExpressions.Add(cref.Column); } return cref; } internal override SqlSource VisitJoin(SqlJoin join) { if (join.JoinType == SqlJoinType.CrossApply) { // Visit the left side as usual. join.Left = this.VisitSource(join.Left); // Visit the condition as usual. join.Condition = this.VisitExpression(join.Condition); // Visit the right, with the expressionSink set. SelectScope s = expressionSink; expressionSink = new SelectScope(); expressionSink.LeftProduction = SqlGatherProducedAliases.Gather(join.Left); join.Right = this.VisitSource(join.Right); // Were liftable expressions found? SqlSource newSource = join; foreach (List cols in expressionSink.Lifted) { newSource = PushSourceDown(newSource, cols); } expressionSink = s; return newSource; } return base.VisitJoin(join); } [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")] private SqlSource PushSourceDown(SqlSource sqlSource, List cols) { SqlSelect ns = new SqlSelect(new SqlNop(cols[0].ClrType, cols[0].SqlType, sqlSource.SourceExpression), sqlSource, sqlSource.SourceExpression); ns.Row.Columns.AddRange(cols); return new SqlAlias(ns); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- FileStream.cs
- Geometry.cs
- WindowsListViewSubItem.cs
- LabelTarget.cs
- TextElementEnumerator.cs
- TextViewSelectionProcessor.cs
- EntityContainerRelationshipSet.cs
- counter.cs
- XmlDictionaryString.cs
- ArrayElementGridEntry.cs
- SchemaExporter.cs
- MouseEvent.cs
- DefaultAsyncDataDispatcher.cs
- CodeBlockBuilder.cs
- ToolBar.cs
- TypeToken.cs
- DateTimeHelper.cs
- ViewStateChangedEventArgs.cs
- SiteMapNode.cs
- SafeLocalMemHandle.cs
- _NestedMultipleAsyncResult.cs
- AdornerDecorator.cs
- TransformerInfoCollection.cs
- CheckBoxFlatAdapter.cs
- VirtualizingStackPanel.cs
- UserPersonalizationStateInfo.cs
- WinEventHandler.cs
- XmlAtomicValue.cs
- CodeArgumentReferenceExpression.cs
- GeometryHitTestResult.cs
- DataGridCaption.cs
- SHA384Managed.cs
- IDictionary.cs
- DataServiceRequest.cs
- EmbossBitmapEffect.cs
- StringUtil.cs
- UniqueIdentifierService.cs
- ResumeStoryboard.cs
- SmtpLoginAuthenticationModule.cs
- GeneralTransformGroup.cs
- ComboBoxAutomationPeer.cs
- PenLineCapValidation.cs
- WebZone.cs
- documentsequencetextcontainer.cs
- InputBinder.cs
- EventPropertyMap.cs
- HttpHandlerActionCollection.cs
- SrgsToken.cs
- Thread.cs
- HttpResponseWrapper.cs
- UnSafeCharBuffer.cs
- Base64Stream.cs
- XmlSchemaCompilationSettings.cs
- PersonalizablePropertyEntry.cs
- XomlCompilerResults.cs
- CryptoKeySecurity.cs
- UncommonField.cs
- SmiXetterAccessMap.cs
- MetafileHeaderEmf.cs
- DecimalStorage.cs
- IISUnsafeMethods.cs
- IntegerFacetDescriptionElement.cs
- EntityRecordInfo.cs
- ControlParameter.cs
- LayoutSettings.cs
- ExecutedRoutedEventArgs.cs
- ThemeInfoAttribute.cs
- sortedlist.cs
- XmlTextEncoder.cs
- CommonObjectSecurity.cs
- ValidationSummaryDesigner.cs
- DecimalMinMaxAggregationOperator.cs
- BamlRecordHelper.cs
- COM2ExtendedTypeConverter.cs
- CodeParameterDeclarationExpression.cs
- ObjectQueryProvider.cs
- SpecularMaterial.cs
- ProviderConnectionPointCollection.cs
- FixedPageAutomationPeer.cs
- FileStream.cs
- XmlSerializerSection.cs
- ActivityBindForm.cs
- VideoDrawing.cs
- SeekStoryboard.cs
- RegisteredScript.cs
- TextElement.cs
- SystemIcmpV4Statistics.cs
- Vector.cs
- MemberAssignmentAnalysis.cs
- QilLoop.cs
- ISAPIRuntime.cs
- ProfileGroupSettingsCollection.cs
- NumberFunctions.cs
- CustomTrackingRecord.cs
- RootBrowserWindowAutomationPeer.cs
- EntityContainer.cs
- ObjectList.cs
- OleDbInfoMessageEvent.cs
- OutOfMemoryException.cs
- PathGeometry.cs