Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DataEntity / System / Data / Common / CommandTrees / Internal / Validator.cs / 1 / Validator.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....], [....] //--------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Globalization; using System.Data.Common; using System.Data.Metadata.Edm; using System.Linq; using System.Diagnostics; namespace System.Data.Common.CommandTrees.Internal { internal class Validator : BasicExpressionVisitor { #region Private Member Variables private Stack> _scopes = new Stack >(); private Stack _cycleStack = new Stack (); #endregion #region Private Implementation private void Reset() { _scopes.Clear(); _cycleStack.Clear(); } private void PushScope() { _scopes.Push(new Dictionary ()); } private void PopScope() { _scopes.Pop(); } private void AddToScope(string strName, TypeUsage t) { _scopes.Peek().Add(strName, t); } private void AddToScope(IEnumerable > scopeElements) { Dictionary currentScope = _scopes.Peek(); foreach (KeyValuePair scopeElement in scopeElements) { currentScope.Add(scopeElement.Key, scopeElement.Value); } } private TypeUsage FindInScopes(string name) { TypeUsage foundType = null; foreach (Dictionary scope in _scopes) { if (scope.TryGetValue(name, out foundType)) { return foundType; } } return null; } private void Validate(DbExpression expression) { this.Reset(); VisitExpression(expression); } private static void Invalid(DbCommandTree tree, string message) { InvalidCommandTreeException ict = new InvalidCommandTreeException(message); EntityUtil.TraceExceptionAsReturnValue(ict); throw ict; } #endregion #region Constructors public Validator() { } #endregion #region 'Public' Validation API internal void Validate(DbQueryCommandTree cmd) { EntityUtil.CheckArgumentNull(cmd, "cmd"); using (new EntityBid.ScopeAuto(" cmd=%d#", cmd.ObjectId)) { if (null == cmd.Query) { Invalid(cmd, System.Data.Entity.Strings.Cqt_QueryTree_NullQueryInvalid); } this.Validate(cmd.Query); } } #endregion #region BasicExpressionVisitor IExpressionVisitor implementation overrides public override void Visit(DbVariableReferenceExpression e) { TypeUsage varType = this.FindInScopes(e.VariableName); if (null == varType) { Invalid(e.CommandTree, System.Data.Entity.Strings.Cqt_Validator_VarRefInvalid(e.VariableName)); } // SQLBUDT#545720: Equivalence is not a sufficient check (consider row types) - equality is required. if (!TypeSemantics.IsStructurallyEqualTo(e.ResultType, varType)) { Invalid(e.CommandTree, System.Data.Entity.Strings.Cqt_Validator_VarRefTypeMismatch(e.VariableName)); } } public override void Visit(DbParameterReferenceExpression e) { if (!e.CommandTree.HasParameter(e.ParameterName, e.ResultType)) { Invalid(e.CommandTree, System.Data.Entity.Strings.Cqt_CommandTree_NoParameterExists); } } public override void Visit(DbCrossJoinExpression e) { // // SQL BU Defect Tracking #422696: CQT DbJoinExpression allows left-correlation of Inputs // Visit(DbJoinExpression) must be overriden since VisitExpressionBindingPre has been overridden to bring the DbExpressionBinding's // variable into scope. This is not correct for DbJoinExpression since it brings each Input's variable into scope // as it is visited, meaning that a subsequent Input can reference the variable of a preceeding Input (left correlation). // Since left-correlation is explicitly not allowed in CQT DbJoinExpression, the correct approach is not visit the expression // of each Input binding - not by calling VisitExpressionBindingPre - and bring the variables of all Inputs into scope // only when the Join condition is visited. After visiting the condition, the current scope is popped from the stack // with a call to m_scopes.Pop() rather than by calling VisitExpressionBindingPost for each Input DbExpressionBinding. // // // Visit the expression of each Input binding, without updating the variables that are in scope // for(int idx = 0; idx < e.Inputs.Count; idx++) { VisitExpression(e.Inputs[idx].Expression); } } public override void Visit(DbJoinExpression e) { // // SQL BU Defect Tracking #422696: CQT DbJoinExpression allows left-correlation of Inputs // Visit(DbJoinExpression) must be overriden since VisitExpressionBindingPre has been overridden to bring the DbExpressionBinding's // variable into scope. This is not correct for DbJoinExpression since it brings each Input's variable into scope // as it is visited, meaning that a subsequent Input can reference the variable of a preceeding Input (left correlation). // Since left-correlation is explicitly not allowed in CQT DbJoinExpression, the correct approach is not visit the expression // of each Input binding - not by calling VisitExpressionBindingPre - and bring the variables of all Inputs into scope // only when the Join condition is visited. After visiting the condition, the current scope is popped from the stack // with a call to m_scopes.Pop() rather than by calling VisitExpressionBindingPost for each Input DbExpressionBinding. // // // First visit the expression of each Input binding, without updating the variables that are in scope // List > inputVarInfo = new List >(2); VisitExpression(e.Left.Expression); inputVarInfo.Add(new KeyValuePair (e.Left.VariableName, e.Left.VariableType)); VisitExpression(e.Right.Expression); inputVarInfo.Add(new KeyValuePair (e.Right.VariableName, e.Right.VariableType)); // // Create a new scope and introduce the variables of each Input binding // this.PushScope(); this.AddToScope(inputVarInfo); // // Visit the Join condition with the Input variables in scope // VisitExpression(e.JoinCondition); // // Remove the new scope from the scope stack // this.PopScope(); } #endregion #region BasicExpressionVisitor protected API overrides /// /// Convenience method to visit the specified /// The expression to visit. ///, if non-null. /// public override void VisitExpression(DbExpression expression) { foreach(int visitedId in _cycleStack) { if(visitedId == expression.ObjectId) { Invalid(expression.CommandTree, System.Data.Entity.Strings.Cqt_Validator_CycleDetected); } } _cycleStack.Push(expression.ObjectId); base.VisitExpression(expression); _cycleStack.Pop(); } protected override void VisitExpressionBindingPre(DbExpressionBinding b) { base.VisitExpressionBindingPre(b); this.PushScope(); this.AddToScope(b.VariableName, b.VariableType); } protected override void VisitExpressionBindingPost(DbExpressionBinding b) { base.VisitExpressionBindingPost(b); this.PopScope(); } protected override void VisitGroupExpressionBindingPre(DbGroupExpressionBinding gb) { base.VisitGroupExpressionBindingPre(gb); this.PushScope(); this.AddToScope(gb.VariableName, gb.VariableType); } protected override void VisitGroupExpressionBindingMid(DbGroupExpressionBinding gb) { base.VisitGroupExpressionBindingMid(gb); this.PopScope(); this.PushScope(); this.AddToScope(gb.GroupVariableName, gb.GroupVariableType); } protected override void VisitGroupExpressionBindingPost(DbGroupExpressionBinding gb) { base.VisitGroupExpressionBindingPost(gb); this.PopScope(); } protected override void VisitLambdaFunctionPre(EdmFunction function, DbExpression body) { base.VisitLambdaFunctionPre(function, body); this.PushScope(); foreach(FunctionParameter paramInfo in function.Parameters) { this.AddToScope(paramInfo.Name, paramInfo.TypeUsage); } } protected override void VisitLambdaFunctionPost(EdmFunction function, DbExpression body) { base.VisitLambdaFunctionPost(function, body); this.PopScope(); } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- // is null // Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....], [....] //--------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Globalization; using System.Data.Common; using System.Data.Metadata.Edm; using System.Linq; using System.Diagnostics; namespace System.Data.Common.CommandTrees.Internal { internal class Validator : BasicExpressionVisitor { #region Private Member Variables private Stack> _scopes = new Stack >(); private Stack _cycleStack = new Stack (); #endregion #region Private Implementation private void Reset() { _scopes.Clear(); _cycleStack.Clear(); } private void PushScope() { _scopes.Push(new Dictionary ()); } private void PopScope() { _scopes.Pop(); } private void AddToScope(string strName, TypeUsage t) { _scopes.Peek().Add(strName, t); } private void AddToScope(IEnumerable > scopeElements) { Dictionary currentScope = _scopes.Peek(); foreach (KeyValuePair scopeElement in scopeElements) { currentScope.Add(scopeElement.Key, scopeElement.Value); } } private TypeUsage FindInScopes(string name) { TypeUsage foundType = null; foreach (Dictionary scope in _scopes) { if (scope.TryGetValue(name, out foundType)) { return foundType; } } return null; } private void Validate(DbExpression expression) { this.Reset(); VisitExpression(expression); } private static void Invalid(DbCommandTree tree, string message) { InvalidCommandTreeException ict = new InvalidCommandTreeException(message); EntityUtil.TraceExceptionAsReturnValue(ict); throw ict; } #endregion #region Constructors public Validator() { } #endregion #region 'Public' Validation API internal void Validate(DbQueryCommandTree cmd) { EntityUtil.CheckArgumentNull(cmd, "cmd"); using (new EntityBid.ScopeAuto(" cmd=%d#", cmd.ObjectId)) { if (null == cmd.Query) { Invalid(cmd, System.Data.Entity.Strings.Cqt_QueryTree_NullQueryInvalid); } this.Validate(cmd.Query); } } #endregion #region BasicExpressionVisitor IExpressionVisitor implementation overrides public override void Visit(DbVariableReferenceExpression e) { TypeUsage varType = this.FindInScopes(e.VariableName); if (null == varType) { Invalid(e.CommandTree, System.Data.Entity.Strings.Cqt_Validator_VarRefInvalid(e.VariableName)); } // SQLBUDT#545720: Equivalence is not a sufficient check (consider row types) - equality is required. if (!TypeSemantics.IsStructurallyEqualTo(e.ResultType, varType)) { Invalid(e.CommandTree, System.Data.Entity.Strings.Cqt_Validator_VarRefTypeMismatch(e.VariableName)); } } public override void Visit(DbParameterReferenceExpression e) { if (!e.CommandTree.HasParameter(e.ParameterName, e.ResultType)) { Invalid(e.CommandTree, System.Data.Entity.Strings.Cqt_CommandTree_NoParameterExists); } } public override void Visit(DbCrossJoinExpression e) { // // SQL BU Defect Tracking #422696: CQT DbJoinExpression allows left-correlation of Inputs // Visit(DbJoinExpression) must be overriden since VisitExpressionBindingPre has been overridden to bring the DbExpressionBinding's // variable into scope. This is not correct for DbJoinExpression since it brings each Input's variable into scope // as it is visited, meaning that a subsequent Input can reference the variable of a preceeding Input (left correlation). // Since left-correlation is explicitly not allowed in CQT DbJoinExpression, the correct approach is not visit the expression // of each Input binding - not by calling VisitExpressionBindingPre - and bring the variables of all Inputs into scope // only when the Join condition is visited. After visiting the condition, the current scope is popped from the stack // with a call to m_scopes.Pop() rather than by calling VisitExpressionBindingPost for each Input DbExpressionBinding. // // // Visit the expression of each Input binding, without updating the variables that are in scope // for(int idx = 0; idx < e.Inputs.Count; idx++) { VisitExpression(e.Inputs[idx].Expression); } } public override void Visit(DbJoinExpression e) { // // SQL BU Defect Tracking #422696: CQT DbJoinExpression allows left-correlation of Inputs // Visit(DbJoinExpression) must be overriden since VisitExpressionBindingPre has been overridden to bring the DbExpressionBinding's // variable into scope. This is not correct for DbJoinExpression since it brings each Input's variable into scope // as it is visited, meaning that a subsequent Input can reference the variable of a preceeding Input (left correlation). // Since left-correlation is explicitly not allowed in CQT DbJoinExpression, the correct approach is not visit the expression // of each Input binding - not by calling VisitExpressionBindingPre - and bring the variables of all Inputs into scope // only when the Join condition is visited. After visiting the condition, the current scope is popped from the stack // with a call to m_scopes.Pop() rather than by calling VisitExpressionBindingPost for each Input DbExpressionBinding. // // // First visit the expression of each Input binding, without updating the variables that are in scope // List > inputVarInfo = new List >(2); VisitExpression(e.Left.Expression); inputVarInfo.Add(new KeyValuePair (e.Left.VariableName, e.Left.VariableType)); VisitExpression(e.Right.Expression); inputVarInfo.Add(new KeyValuePair (e.Right.VariableName, e.Right.VariableType)); // // Create a new scope and introduce the variables of each Input binding // this.PushScope(); this.AddToScope(inputVarInfo); // // Visit the Join condition with the Input variables in scope // VisitExpression(e.JoinCondition); // // Remove the new scope from the scope stack // this.PopScope(); } #endregion #region BasicExpressionVisitor protected API overrides /// /// Convenience method to visit the specified /// The expression to visit. ///, if non-null. /// public override void VisitExpression(DbExpression expression) { foreach(int visitedId in _cycleStack) { if(visitedId == expression.ObjectId) { Invalid(expression.CommandTree, System.Data.Entity.Strings.Cqt_Validator_CycleDetected); } } _cycleStack.Push(expression.ObjectId); base.VisitExpression(expression); _cycleStack.Pop(); } protected override void VisitExpressionBindingPre(DbExpressionBinding b) { base.VisitExpressionBindingPre(b); this.PushScope(); this.AddToScope(b.VariableName, b.VariableType); } protected override void VisitExpressionBindingPost(DbExpressionBinding b) { base.VisitExpressionBindingPost(b); this.PopScope(); } protected override void VisitGroupExpressionBindingPre(DbGroupExpressionBinding gb) { base.VisitGroupExpressionBindingPre(gb); this.PushScope(); this.AddToScope(gb.VariableName, gb.VariableType); } protected override void VisitGroupExpressionBindingMid(DbGroupExpressionBinding gb) { base.VisitGroupExpressionBindingMid(gb); this.PopScope(); this.PushScope(); this.AddToScope(gb.GroupVariableName, gb.GroupVariableType); } protected override void VisitGroupExpressionBindingPost(DbGroupExpressionBinding gb) { base.VisitGroupExpressionBindingPost(gb); this.PopScope(); } protected override void VisitLambdaFunctionPre(EdmFunction function, DbExpression body) { base.VisitLambdaFunctionPre(function, body); this.PushScope(); foreach(FunctionParameter paramInfo in function.Parameters) { this.AddToScope(paramInfo.Name, paramInfo.TypeUsage); } } protected override void VisitLambdaFunctionPost(EdmFunction function, DbExpression body) { base.VisitLambdaFunctionPost(function, body); this.PopScope(); } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. is null
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- BufferedGraphics.cs
- InheritanceContextChangedEventManager.cs
- Operand.cs
- SqlCacheDependencySection.cs
- GregorianCalendarHelper.cs
- NavigatorInput.cs
- CharacterMetricsDictionary.cs
- SqlXml.cs
- XmlAggregates.cs
- CallSiteBinder.cs
- TypeDescriptionProviderAttribute.cs
- XmlnsCache.cs
- XsdDuration.cs
- MenuItemBindingCollection.cs
- ToolStripButton.cs
- StateMachineDesignerPaint.cs
- HeaderedItemsControl.cs
- ResourceKey.cs
- DbMetaDataFactory.cs
- NetPipeSection.cs
- DataGridViewCellStyleContentChangedEventArgs.cs
- MenuItemCollectionEditorDialog.cs
- Vector3DAnimationUsingKeyFrames.cs
- TailPinnedEventArgs.cs
- SetUserLanguageRequest.cs
- ClientSponsor.cs
- DataSourceControl.cs
- DesignerActionUI.cs
- Baml2006Reader.cs
- ListDictionary.cs
- ContextDataSource.cs
- DataGridViewElement.cs
- ScaleTransform.cs
- MenuItemBindingCollection.cs
- PostBackOptions.cs
- XPathSelectionIterator.cs
- ScriptReferenceBase.cs
- WinHttpWebProxyFinder.cs
- InternalBufferManager.cs
- ProgressPage.cs
- MetabaseSettings.cs
- Block.cs
- UnsafeNetInfoNativeMethods.cs
- backend.cs
- VideoDrawing.cs
- TreeNodeCollection.cs
- ChannelBinding.cs
- ClientSection.cs
- LoginView.cs
- MSAANativeProvider.cs
- TableParagraph.cs
- ProfilePropertyMetadata.cs
- EntityCodeGenerator.cs
- WindowsEditBoxRange.cs
- DataGridViewComboBoxEditingControl.cs
- ADConnectionHelper.cs
- RenameRuleObjectDialog.Designer.cs
- AssemblySettingAttributes.cs
- XmlNodeList.cs
- MimeXmlImporter.cs
- serverconfig.cs
- LinqDataSource.cs
- HintTextConverter.cs
- ResourceBinder.cs
- DriveNotFoundException.cs
- XsltException.cs
- ListInitExpression.cs
- FragmentNavigationEventArgs.cs
- RenderTargetBitmap.cs
- BoundColumn.cs
- OleDbConnectionFactory.cs
- EasingKeyFrames.cs
- SqlCaseSimplifier.cs
- ControlParameter.cs
- RegexWriter.cs
- _FtpDataStream.cs
- EmissiveMaterial.cs
- Opcode.cs
- SizeChangedEventArgs.cs
- TripleDES.cs
- EditorZoneBase.cs
- QueryAccessibilityHelpEvent.cs
- X509CertificateStore.cs
- Rfc4050KeyFormatter.cs
- EndpointConfigContainer.cs
- AlignmentXValidation.cs
- TreeNodeCollection.cs
- TableParagraph.cs
- HttpApplication.cs
- ServiceContractListItem.cs
- Rijndael.cs
- SettingsBindableAttribute.cs
- SoapSchemaMember.cs
- XmlNamespaceMapping.cs
- ByteStreamMessageEncoder.cs
- OuterGlowBitmapEffect.cs
- CommonXSendMessage.cs
- QueryableDataSourceView.cs
- ChannelSinkStacks.cs
- HwndProxyElementProvider.cs