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
- DispatcherObject.cs
- UnsafeNativeMethods.cs
- GeneralTransform3D.cs
- GenericTypeParameterBuilder.cs
- CodeObjectCreateExpression.cs
- TextFormatterImp.cs
- EntityDataSourceUtil.cs
- FrameworkPropertyMetadata.cs
- DoneReceivingAsyncResult.cs
- ToolStripComboBox.cs
- SqlCacheDependencySection.cs
- URLIdentityPermission.cs
- UnauthorizedAccessException.cs
- SqlBuilder.cs
- Identifier.cs
- VarRefManager.cs
- ColorInterpolationModeValidation.cs
- ImageList.cs
- CharEnumerator.cs
- DocumentApplicationJournalEntry.cs
- Rect3D.cs
- ComplexObject.cs
- Variable.cs
- PagesChangedEventArgs.cs
- StateDesigner.LayoutSelectionGlyph.cs
- RSAProtectedConfigurationProvider.cs
- FileDialog.cs
- MessageQueueKey.cs
- HttpCacheVaryByContentEncodings.cs
- PreservationFileReader.cs
- TextBoxLine.cs
- PopupRootAutomationPeer.cs
- sqlser.cs
- AssemblyGen.cs
- RuntimeEnvironment.cs
- Point.cs
- ProxyBuilder.cs
- PrivilegeNotHeldException.cs
- TextServicesContext.cs
- __Filters.cs
- DataKey.cs
- FormatConvertedBitmap.cs
- InputBinding.cs
- sqlser.cs
- BamlResourceContent.cs
- PreservationFileReader.cs
- EntityTypeEmitter.cs
- MediaSystem.cs
- ModelFactory.cs
- MetadataArtifactLoaderCompositeResource.cs
- EventData.cs
- BitmapFrameDecode.cs
- ServerType.cs
- Internal.cs
- EntityStoreSchemaFilterEntry.cs
- Pipe.cs
- ServiceBusyException.cs
- QilUnary.cs
- ContractInstanceProvider.cs
- DetailsViewRowCollection.cs
- AudioBase.cs
- ColorConverter.cs
- RawTextInputReport.cs
- TextLineResult.cs
- HtmlHistory.cs
- TracedNativeMethods.cs
- ProgressBar.cs
- CallTemplateAction.cs
- QilXmlReader.cs
- TogglePattern.cs
- QuerySettings.cs
- _AutoWebProxyScriptEngine.cs
- MultiView.cs
- DivideByZeroException.cs
- DataViewManager.cs
- ContentIterators.cs
- ReversePositionQuery.cs
- CodeAttributeDeclarationCollection.cs
- ProfileBuildProvider.cs
- ToolStripItem.cs
- ProcessThread.cs
- EntitySqlException.cs
- CloseSequence.cs
- PlainXmlDeserializer.cs
- StylusPointPropertyInfo.cs
- RemoteCryptoDecryptRequest.cs
- ImageCodecInfo.cs
- ErrorEventArgs.cs
- Baml2006ReaderSettings.cs
- OleStrCAMarshaler.cs
- SplineKeyFrames.cs
- ReadOnlyMetadataCollection.cs
- WebPartEditorCancelVerb.cs
- ImageSourceValueSerializer.cs
- SystemBrushes.cs
- Underline.cs
- PackageRelationshipSelector.cs
- FontStyle.cs
- GeneralTransform3DTo2DTo3D.cs
- Int32Storage.cs