Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataEntity / System / Data / Common / CommandTrees / Internal / Validator.cs / 4 / 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
- FlowDocument.cs
- SymbolMethod.cs
- BitmapData.cs
- HashHelper.cs
- TimeZone.cs
- FixedSOMTableRow.cs
- PngBitmapEncoder.cs
- UdpDiscoveryEndpointProvider.cs
- DeferredElementTreeState.cs
- FileUtil.cs
- SyncMethodInvoker.cs
- C14NUtil.cs
- HttpVersion.cs
- PreservationFileWriter.cs
- SqlNodeAnnotation.cs
- Content.cs
- FamilyTypeface.cs
- RequestNavigateEventArgs.cs
- SizeAnimationBase.cs
- CellTreeNode.cs
- BaseTemplateBuildProvider.cs
- SqlBuffer.cs
- filewebresponse.cs
- CodeGenerator.cs
- ProjectionPathBuilder.cs
- PackageDigitalSignature.cs
- ActivityBindForm.cs
- ControlDesigner.cs
- TemplateColumn.cs
- ProcessThread.cs
- DesignConnectionCollection.cs
- SyndicationDeserializer.cs
- _CookieModule.cs
- CfgArc.cs
- TimeStampChecker.cs
- CopyCodeAction.cs
- OpCodes.cs
- BitmapEffectGroup.cs
- WorkflowFormatterBehavior.cs
- Boolean.cs
- RowToFieldTransformer.cs
- Property.cs
- WindowsRichEdit.cs
- TextTabProperties.cs
- CopyEncoder.cs
- SqlInternalConnectionTds.cs
- StateWorkerRequest.cs
- COM2PropertyDescriptor.cs
- OleDbInfoMessageEvent.cs
- XmlWrappingWriter.cs
- TTSVoice.cs
- MdiWindowListStrip.cs
- _DynamicWinsockMethods.cs
- DataKey.cs
- StructuredType.cs
- DataViewSettingCollection.cs
- FontSource.cs
- MulticastDelegate.cs
- View.cs
- ByteAnimation.cs
- IsolationInterop.cs
- RemotingService.cs
- CollectionChange.cs
- BrowserCapabilitiesFactoryBase.cs
- TextTreeTextNode.cs
- ScriptingRoleServiceSection.cs
- SqlClientMetaDataCollectionNames.cs
- PlatformCulture.cs
- FontStretch.cs
- NullEntityWrapper.cs
- RuleSetBrowserDialog.cs
- JsonWriterDelegator.cs
- ZipIOLocalFileDataDescriptor.cs
- Merger.cs
- SimpleType.cs
- UnsafeNativeMethods.cs
- OledbConnectionStringbuilder.cs
- MarkupWriter.cs
- ClientFormsIdentity.cs
- ScriptDescriptor.cs
- CloseSequenceResponse.cs
- NullableFloatMinMaxAggregationOperator.cs
- HttpHandlersSection.cs
- BindingListCollectionView.cs
- FileDialog_Vista_Interop.cs
- Directory.cs
- TextProperties.cs
- HotCommands.cs
- FormViewModeEventArgs.cs
- ToolboxItemWrapper.cs
- TdsParser.cs
- ValidatedControlConverter.cs
- WebControlAdapter.cs
- ArrayElementGridEntry.cs
- RemotingServices.cs
- PersonalizableAttribute.cs
- XhtmlBasicTextViewAdapter.cs
- CodeAssignStatement.cs
- CheckPair.cs
- QilGenerator.cs