Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Common / EntitySql / StaticContext.cs / 1305376 / StaticContext.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- namespace System.Data.Common.EntitySql { using System; using System.Collections.Generic; using System.Diagnostics; using System.Data.Common.CommandTrees; using System.Data.Common.CommandTrees.ExpressionBuilder; using System.Data.Entity; using System.Data.Metadata.Edm; ////// Represents a scope of key-value pairs. /// internal sealed class Scope : IEnumerable> { private readonly Dictionary _scopeEntries; /// /// Initialize using a given key comparer. /// /// internal Scope(IEqualityComparerkeyComparer) { _scopeEntries = new Dictionary (keyComparer); } /// /// Add new key to the scope. If key already exists - throw. /// internal Scope Add(string key, ScopeEntry value) { _scopeEntries.Add(key, value); return this; } ////// Remove an entry from the scope. /// internal void Remove(string key) { Debug.Assert(Contains(key)); _scopeEntries.Remove(key); } internal void Replace(string key, ScopeEntry value) { Debug.Assert(Contains(key)); _scopeEntries[key] = value; } ////// Returns true if the key belongs to the scope. /// internal bool Contains(string key) { return _scopeEntries.ContainsKey(key); } ////// Search item by key. Returns true in case of success and false otherwise. /// internal bool TryLookup(string key, out ScopeEntry value) { return (_scopeEntries.TryGetValue(key, out value)); } #region GetEnumerator public Dictionary.Enumerator GetEnumerator() { return _scopeEntries.GetEnumerator(); } System.Collections.Generic.IEnumerator > System.Collections.Generic.IEnumerable >.GetEnumerator() { return _scopeEntries.GetEnumerator(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return _scopeEntries.GetEnumerator(); } #endregion } internal enum ScopeEntryKind { SourceVar, GroupKeyDefinition, ProjectionItemDefinition, FreeVar, /// /// Represents a group input scope entry that should no longer be referenced. /// InvalidGroupInputRef } ////// Represents an entry in the scope. /// internal abstract class ScopeEntry { private readonly ScopeEntryKind _scopeEntryKind; internal ScopeEntry(ScopeEntryKind scopeEntryKind) { _scopeEntryKind = scopeEntryKind; } internal ScopeEntryKind EntryKind { get { return _scopeEntryKind; } } ////// Returns CQT expression corresponding to the scope entry. /// internal abstract DbExpression GetExpression(string refName, ErrorContext errCtx); } internal interface IGroupExpressionExtendedInfo { ////// Returns DbExpression GroupVarBasedExpression { get; } ///based expression during the construction process, otherwise null. /// /// Returns DbExpression GroupAggBasedExpression { get; } } internal interface IGetAlternativeName { ///based expression during the construction process, otherwise null. /// /// If current scope entry reperesents an alternative group key name (see SemanticAnalyzer.ProcessGroupByClause(...) for more info) /// then this property returns the alternative name, otherwise null. /// string[] AlternativeName { get; } } ////// Represents simple source var scope entry. /// internal sealed class SourceScopeEntry : ScopeEntry, IGroupExpressionExtendedInfo, IGetAlternativeName { private readonly string[] _alternativeName; private List_propRefs; private DbExpression _varBasedExpression; private DbExpression _groupVarBasedExpression; private DbExpression _groupAggBasedExpression; private bool _joinClauseLeftExpr = false; internal SourceScopeEntry(DbVariableReferenceExpression varRef) : this(varRef, null) { } internal SourceScopeEntry(DbVariableReferenceExpression varRef, string[] alternativeName) : base(ScopeEntryKind.SourceVar) { _varBasedExpression = varRef; _alternativeName = alternativeName; } internal override DbExpression GetExpression(string refName, ErrorContext errCtx) { return _varBasedExpression; } DbExpression IGroupExpressionExtendedInfo.GroupVarBasedExpression { get { return _groupVarBasedExpression; } } DbExpression IGroupExpressionExtendedInfo.GroupAggBasedExpression { get { return _groupAggBasedExpression; } } internal bool IsJoinClauseLeftExpr { get { return _joinClauseLeftExpr; } set { _joinClauseLeftExpr = value; } } string[] IGetAlternativeName.AlternativeName { get { return _alternativeName; } } /// /// Prepend internal SourceScopeEntry AddParentVar(DbVariableReferenceExpression parentVarRef) { // // No parent var adjustment is allowed while adjusted to group var (see AdjustToGroupVar(...) for more info). // Debug.Assert(_groupVarBasedExpression == null, "_groupVarBasedExpression == null"); Debug.Assert(_groupAggBasedExpression == null, "_groupAggBasedExpression == null"); if (_propRefs == null) { Debug.Assert(_varBasedExpression is DbVariableReferenceExpression, "_varBasedExpression is DbVariableReferenceExpression"); _propRefs = new Listto the property chain. /// (2); _propRefs.Add(((DbVariableReferenceExpression)_varBasedExpression).VariableName); } _varBasedExpression = parentVarRef; for (int i = _propRefs.Count - 1; i >= 0; --i) { _varBasedExpression = _varBasedExpression.Property(_propRefs[i]); } _propRefs.Add(parentVarRef.VariableName); return this; } /// /// Replace existing var at the head of the property chain with the new internal void ReplaceParentVar(DbVariableReferenceExpression parentVarRef) { // // No parent var adjustment is allowed while adjusted to group var (see AdjustToGroupVar(...) for more info). // Debug.Assert(_groupVarBasedExpression == null, "_groupVarBasedExpression == null"); Debug.Assert(_groupAggBasedExpression == null, "_groupAggBasedExpression == null"); if (_propRefs == null) { Debug.Assert(_varBasedExpression is DbVariableReferenceExpression, "_varBasedExpression is DbVariableReferenceExpression"); _varBasedExpression = parentVarRef; } else { Debug.Assert(_propRefs.Count > 0, "_propRefs.Count > 0"); _propRefs.RemoveAt(_propRefs.Count - 1); AddParentVar(parentVarRef); } } ///. /// /// Rebuild the current scope entry expression as the property chain off the internal void AdjustToGroupVar(DbVariableReferenceExpression parentVarRef, DbVariableReferenceExpression parentGroupVarRef, DbVariableReferenceExpression groupAggRef) { // Adjustment is not reentrant. Debug.Assert(_groupVarBasedExpression == null, "_groupVarBasedExpression == null"); Debug.Assert(_groupAggBasedExpression == null, "_groupAggBasedExpression == null"); // // Let's assume this entry represents variable "x" in the following query: // select x, y, z from {1, 2} as x join {2, 3} as y on x = y join {3, 4} as z on y = z // In this case _propRefs contains x._##join0._##join1 and the corresponding input expression looks like this: // |_Input : '_##join1' // | |_InnerJoin // | |_Left : '_##join0' // | | |_InnerJoin // | | |_Left : 'x' // | | |_Right : 'y' // | |_Right : 'z' // When we start processing a group by, like in this query: // select k1, k2, k3 from {1, 2} as x join {2, 3} as y on x = y join {3, 4} as z on y = z group by x as k1, y as k2, z as k3 // we are switching to the following input expression: // |_Input : '_##geb2', '_##group3' // | |_InnerJoin // | |_Left : '_##join0' // | | |_InnerJoin // | | |_Left : 'x' // | | |_Right : 'y' // | |_Right : 'z' // where _##join1 is replaced by _##geb2 for the regular expression and by _##group3 for the group var based expression. // So the switch, or the adjustment, is done by // a. replacing _##join1 with _##geb2 in _propRefs and rebuilding the regular expression accordingly to get // the following property chain: _##geb2._##join1.x // b. building a group var based expression using _##group3 instead of _##geb2 to get // the following property chain: _##group3._##join1.x // // // Rebuild ScopeEntry.Expression using the new parent var. // ReplaceParentVar(parentVarRef); // // Build the GroupVarBasedExpression and GroupAggBasedExpression, // take into account that parentVarRef has already been added to the _propRefs in the AdjustToParentVar(...) call, so ignore it. // _groupVarBasedExpression = parentGroupVarRef; _groupAggBasedExpression = groupAggRef; if (_propRefs != null) { for (int i = _propRefs.Count - 2/*ignore the parentVarRef*/; i >= 0; --i) { _groupVarBasedExpression = _groupVarBasedExpression.Property(_propRefs[i]); _groupAggBasedExpression = _groupAggBasedExpression.Property(_propRefs[i]); } } } ///expression. /// Also build /// - off the expression; /// - off the expression. /// This adjustment is reversable by (...). /// /// Rolls back the internal void RollbackAdjustmentToGroupVar(DbVariableReferenceExpression pregroupParentVarRef) { Debug.Assert(_groupVarBasedExpression != null, "_groupVarBasedExpression != null"); _groupVarBasedExpression = null; _groupAggBasedExpression = null; ReplaceParentVar(pregroupParentVarRef); } } ///(...) adjustment, clears the . /// /// Represents a group input scope entry that should no longer be referenced. /// internal sealed class InvalidGroupInputRefScopeEntry : ScopeEntry { internal InvalidGroupInputRefScopeEntry() : base(ScopeEntryKind.InvalidGroupInputRef) { } internal override DbExpression GetExpression(string refName, ErrorContext errCtx) { throw EntityUtil.EntitySqlError(errCtx, Strings.InvalidGroupIdentifierReference(refName)); } } ////// Represents group key during GROUP BY clause processing phase, used during group aggregate search mode. /// This entry will be replaced by the internal sealed class GroupKeyDefinitionScopeEntry : ScopeEntry, IGroupExpressionExtendedInfo, IGetAlternativeName { private readonly DbExpression _varBasedExpression; private readonly DbExpression _groupVarBasedExpression; private readonly DbExpression _groupAggBasedExpression; private readonly string[] _alternativeName; internal GroupKeyDefinitionScopeEntry( DbExpression varBasedExpression, DbExpression groupVarBasedExpression, DbExpression groupAggBasedExpression, string[] alternativeName) : base(ScopeEntryKind.GroupKeyDefinition) { _varBasedExpression = varBasedExpression; _groupVarBasedExpression = groupVarBasedExpression; _groupAggBasedExpression = groupAggBasedExpression; _alternativeName = alternativeName; } internal override DbExpression GetExpression(string refName, ErrorContext errCtx) { return _varBasedExpression; } DbExpression IGroupExpressionExtendedInfo.GroupVarBasedExpression { get { return _groupVarBasedExpression; } } DbExpression IGroupExpressionExtendedInfo.GroupAggBasedExpression { get { return _groupAggBasedExpression; } } string[] IGetAlternativeName.AlternativeName { get { return _alternativeName; } } } ///when GROUP BY processing is complete. /// /// Represents a projection item definition scope entry. /// internal sealed class ProjectionItemDefinitionScopeEntry : ScopeEntry { private readonly DbExpression _expression; internal ProjectionItemDefinitionScopeEntry(DbExpression expression) : base(ScopeEntryKind.ProjectionItemDefinition) { _expression = expression; } internal override DbExpression GetExpression(string refName, ErrorContext errCtx) { return _expression; } } ////// Represents a free variable scope entry. /// Example: parameters of an inline function definition are free variables in the scope of the function definition. /// internal sealed class FreeVariableScopeEntry : ScopeEntry { private readonly DbVariableReferenceExpression _varRef; internal FreeVariableScopeEntry(DbVariableReferenceExpression varRef) : base(ScopeEntryKind.FreeVar) { _varRef = varRef; } internal override DbExpression GetExpression(string refName, ErrorContext errCtx) { return _varRef; } } ////// Represents a generic list of scopes. /// internal sealed class ScopeManager { private readonly IEqualityComparer_keyComparer; private readonly List _scopes = new List (); /// /// Initialize scope manager using given key-string comparer. /// internal ScopeManager(IEqualityComparerkeyComparer) { _keyComparer = keyComparer; } /// /// Enter a new scope. /// internal void EnterScope() { _scopes.Add(new Scope(_keyComparer)); } ////// Leave the current scope. /// internal void LeaveScope() { Debug.Assert(CurrentScopeIndex >= 0); _scopes.RemoveAt(CurrentScopeIndex); } ////// Return current scope index. /// Outer scopes have smaller index values than inner scopes. /// internal int CurrentScopeIndex { get { return _scopes.Count - 1; } } ////// Return current scope. /// internal Scope CurrentScope { get { return _scopes[CurrentScopeIndex]; } } ////// Get a scope by the index. /// internal Scope GetScopeByIndex(int scopeIndex) { Debug.Assert(scopeIndex >= 0, "scopeIndex >= 0"); Debug.Assert(scopeIndex <= CurrentScopeIndex, "scopeIndex <= CurrentScopeIndex"); if (0 > scopeIndex || scopeIndex > CurrentScopeIndex) { throw EntityUtil.EntitySqlError(Strings.InvalidScopeIndex); } return _scopes[scopeIndex]; } ////// Rollback all scopes to the scope at the index. /// internal void RollbackToScope(int scopeIndex) { // // assert preconditions // Debug.Assert(scopeIndex >= 0, "[PRE] savePoint.ScopeIndex >= 0"); Debug.Assert(scopeIndex <= CurrentScopeIndex, "[PRE] savePoint.ScopeIndex <= CurrentScopeIndex"); Debug.Assert(CurrentScopeIndex >= 0, "[PRE] CurrentScopeIndex >= 0"); if (scopeIndex > CurrentScopeIndex || scopeIndex < 0 || CurrentScopeIndex < 0) { throw EntityUtil.EntitySqlError(Strings.InvalidSavePoint); } int delta = CurrentScopeIndex - scopeIndex; if (delta > 0) { _scopes.RemoveRange(scopeIndex + 1, CurrentScopeIndex - scopeIndex); } // // make sure invariants are preserved // Debug.Assert(scopeIndex == CurrentScopeIndex, "[POST] savePoint.ScopeIndex == CurrentScopeIndex"); Debug.Assert(CurrentScopeIndex >= 0, "[POST] CurrentScopeIndex >= 0"); } ////// True if key exists in current scope. /// internal bool IsInCurrentScope(string key) { return CurrentScope.Contains(key); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Trace.cs
- UseManagedPresentationBindingElementImporter.cs
- DesignerCategoryAttribute.cs
- CustomDictionarySources.cs
- Point3DConverter.cs
- NameScopePropertyAttribute.cs
- CharEntityEncoderFallback.cs
- MetricEntry.cs
- EntityCollectionChangedParams.cs
- CryptoHandle.cs
- MultipleViewPattern.cs
- ToolboxItemCollection.cs
- DbDeleteCommandTree.cs
- CodeParameterDeclarationExpressionCollection.cs
- JsonWriterDelegator.cs
- AppDomainManager.cs
- AppDomainFactory.cs
- OptimizerPatterns.cs
- UdpContractFilterBehavior.cs
- Configuration.cs
- ToolStripSplitButton.cs
- WrappedIUnknown.cs
- MaterialGroup.cs
- KeyValueConfigurationElement.cs
- ResourceDisplayNameAttribute.cs
- WebPartUserCapability.cs
- ImportContext.cs
- TwoPhaseCommit.cs
- GlyphRunDrawing.cs
- ConcurrentBag.cs
- SettingsSection.cs
- AsymmetricKeyExchangeFormatter.cs
- LogRestartAreaEnumerator.cs
- AssertFilter.cs
- TextElementEditingBehaviorAttribute.cs
- ByteKeyFrameCollection.cs
- RelatedCurrencyManager.cs
- AuthenticationSection.cs
- EventLogPermissionEntryCollection.cs
- DataView.cs
- ComponentConverter.cs
- MSHTMLHostUtil.cs
- HtmlElement.cs
- TcpTransportSecurity.cs
- SByteStorage.cs
- Buffer.cs
- ControlCollection.cs
- CancellationScope.cs
- StringDictionaryCodeDomSerializer.cs
- TrackBarRenderer.cs
- TextModifierScope.cs
- AddingNewEventArgs.cs
- ValueConversionAttribute.cs
- ApplicationServiceHelper.cs
- Utils.cs
- GCHandleCookieTable.cs
- ConfigPathUtility.cs
- OutputCacheSettingsSection.cs
- Walker.cs
- Visual3D.cs
- RootBrowserWindowAutomationPeer.cs
- ExecutionContext.cs
- JoinCqlBlock.cs
- DragEvent.cs
- ContractCodeDomInfo.cs
- Freezable.cs
- XXXInfos.cs
- PersonalizationProviderHelper.cs
- Propagator.cs
- ZipPackage.cs
- DeclarationUpdate.cs
- NativeMethods.cs
- ClickablePoint.cs
- ToolStripOverflow.cs
- DomainConstraint.cs
- WebPartConnectionsEventArgs.cs
- XmlWellformedWriter.cs
- EdmSchemaAttribute.cs
- AxHost.cs
- SQLDecimal.cs
- securitymgrsite.cs
- DecoderReplacementFallback.cs
- Stream.cs
- WindowsListViewSubItem.cs
- SHA1.cs
- SchemaMerger.cs
- ConfigXmlAttribute.cs
- TextEditorParagraphs.cs
- SoapExtensionImporter.cs
- TagPrefixInfo.cs
- TextElementCollectionHelper.cs
- BitmapImage.cs
- MemoryFailPoint.cs
- CaseStatementSlot.cs
- CultureMapper.cs
- GetUserPreferenceRequest.cs
- ExpressionBindingsDialog.cs
- DecimalKeyFrameCollection.cs
- RoleManagerSection.cs
- MailAddressCollection.cs