public override AstNode VisitTableSpoolRefAlgebraNode(StackedTableSpoolRefAlgebraNode node) { foreach (RowBufferEntry definedValue in node.DefinedValues) { NameEntry(definedValue, EXPRESSION_NAME_FMT_STR); } return(node); }
public override AstElement Clone(Dictionary<AstElement, AstElement> alreadyClonedElements) { StackedTableSpoolRefAlgebraNode result = new StackedTableSpoolRefAlgebraNode(); result.StatisticsIterator = StatisticsIterator; result.OutputList = ArrayHelpers.Clone(OutputList); result.DefinedValues = ArrayHelpers.Clone(_definedValues); result.PrimarySpool = (StackedTableSpoolAlgebraNode) alreadyClonedElements[_primarySpool]; return result; }
public override AstElement Clone(Dictionary <AstElement, AstElement> alreadyClonedElements) { StackedTableSpoolRefAlgebraNode result = new StackedTableSpoolRefAlgebraNode(); result.StatisticsIterator = StatisticsIterator; result.OutputList = ArrayHelpers.Clone(OutputList); result.DefinedValues = ArrayHelpers.Clone(_definedValues); result.PrimarySpool = (StackedTableSpoolAlgebraNode)alreadyClonedElements[_primarySpool]; return(result); }
public override AstNode VisitTableSpoolRefAlgebraNode(StackedTableSpoolRefAlgebraNode node) { PropertyListBuilder propertyListBuilder = new PropertyListBuilder(); AddRowBufferEntries(propertyListBuilder, Resources.ShowPlanGroupOutputList, node.OutputList); AddStatistics(propertyListBuilder, node.StatisticsIterator); propertyListBuilder.Write(Resources.ShowPlanKeyLogicalOperator, Resources.ShowPlanLogicalOperatorLazySpool); propertyListBuilder.Write(Resources.ShowPlanKeyWithStack, Boolean.TrueString); IList <ShowPlanProperty> properties = propertyListBuilder.ToList(); ShowPlanElement element = new ShowPlanElement(ShowPlanOperator.TableSpool, properties); _currentElement = element; return(node); }
public override AstNode VisitTableSpoolRefAlgebraNode(StackedTableSpoolRefAlgebraNode node) { TableSpoolRefIterator tableSpoolRefIterator = new TableSpoolRefIterator(); tableSpoolRefIterator.RowBuffer = new object[node.OutputList.Length]; tableSpoolRefIterator.PrimarySpool = tableSpoolIterators[node.PrimarySpool]; SetLastIterator(node, tableSpoolRefIterator); return node; }
private static AlgebraNode AlgebrizeRecursiveCte(CommonTableBinding commonTableBinding) { // It is a recursive query. // // Create row buffer entry that is used to guard the recursion and the primary table spool // that spools the results needed by nested recursion calls. ExpressionBuilder expressionBuilder = new ExpressionBuilder(); StackedTableSpoolAlgebraNode primaryTableSpool = new StackedTableSpoolAlgebraNode(); RowBufferEntry anchorRecursionLevel; RowBufferEntry[] anchorOutput; AlgebraNode anchorNode; #region Anchor member { // Emit anchor member. AlgebraNode algebrizedAnchor = Convert(commonTableBinding.AnchorMember); // Emit compute scalar that initializes the recursion level to 0. anchorRecursionLevel = new RowBufferEntry(typeof(int)); ComputedValueDefinition computedValueDefinition1 = new ComputedValueDefinition(); computedValueDefinition1.Target = anchorRecursionLevel; computedValueDefinition1.Expression = LiteralExpression.FromInt32(0); ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode(); computeScalarAlgebraNode.Input = algebrizedAnchor; computeScalarAlgebraNode.DefinedValues = new ComputedValueDefinition[] { computedValueDefinition1 }; anchorOutput = algebrizedAnchor.OutputList; anchorNode = computeScalarAlgebraNode; } #endregion RowBufferEntry incrementedRecursionLevel; RowBufferEntry[] tableSpoolOutput; AlgebraNode tableSpoolNode; #region Table spool { // Emit table spool reference. RowBufferEntry recursionLevelRefEntry = new RowBufferEntry(typeof(int)); tableSpoolOutput = new RowBufferEntry[anchorOutput.Length]; for (int i = 0; i < tableSpoolOutput.Length; i++) { tableSpoolOutput[i] = new RowBufferEntry(anchorOutput[i].DataType); } StackedTableSpoolRefAlgebraNode tableSpoolReference = new StackedTableSpoolRefAlgebraNode(); tableSpoolReference.PrimarySpool = primaryTableSpool; tableSpoolReference.DefinedValues = ArrayHelpers.JoinArrays(new RowBufferEntry[] { recursionLevelRefEntry }, tableSpoolOutput); // Emit compute scalar that increases the recursion level by one and renames // columns from the spool to the CTE column buffer entries. expressionBuilder.Push(new RowBufferEntryExpression(recursionLevelRefEntry)); expressionBuilder.Push(LiteralExpression.FromInt32(1)); expressionBuilder.PushBinary(BinaryOperator.Add); incrementedRecursionLevel = new RowBufferEntry(typeof(int)); ComputedValueDefinition incremenedRecLevelValueDefinition = new ComputedValueDefinition(); incremenedRecLevelValueDefinition.Target = incrementedRecursionLevel; incremenedRecLevelValueDefinition.Expression = expressionBuilder.Pop(); CteColumnMappingFinder cteColumnMappingFinder = new CteColumnMappingFinder(commonTableBinding, tableSpoolOutput); foreach (QueryNode recursiveMember in commonTableBinding.RecursiveMembers) { cteColumnMappingFinder.Visit(recursiveMember); } CteColumnMapping[] cteColumnMappings = cteColumnMappingFinder.GetMappings(); List <ComputedValueDefinition> definedValues = new List <ComputedValueDefinition>(); definedValues.Add(incremenedRecLevelValueDefinition); foreach (CteColumnMapping cteColumnMapping in cteColumnMappings) { ComputedValueDefinition definedValue = new ComputedValueDefinition(); definedValue.Target = cteColumnMapping.VirtualBufferEntry; definedValue.Expression = new RowBufferEntryExpression(cteColumnMapping.SpoolBufferEntry); definedValues.Add(definedValue); } ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode(); computeScalarAlgebraNode.Input = tableSpoolReference; computeScalarAlgebraNode.DefinedValues = definedValues.ToArray(); tableSpoolNode = computeScalarAlgebraNode; } #endregion RowBufferEntry[] recursiveOutput; AlgebraNode recursiveNode; #region Recursive member(s) { // Emit all recursive parts. The join conditions to the recursive part are replaced by simple filters // in the nested Convert() call. ConcatAlgebraNode concatAlgebraNode = new ConcatAlgebraNode(); concatAlgebraNode.Inputs = new AlgebraNode[commonTableBinding.RecursiveMembers.Length]; for (int i = 0; i < commonTableBinding.RecursiveMembers.Length; i++) { concatAlgebraNode.Inputs[i] = Convert(commonTableBinding, commonTableBinding.RecursiveMembers[i]); } concatAlgebraNode.DefinedValues = new UnitedValueDefinition[anchorOutput.Length]; for (int i = 0; i < anchorOutput.Length; i++) { List <RowBufferEntry> dependencies = new List <RowBufferEntry>(); foreach (ResultAlgebraNode algebrizedRecursivePart in concatAlgebraNode.Inputs) { dependencies.Add(algebrizedRecursivePart.OutputList[i]); } concatAlgebraNode.DefinedValues[i] = new UnitedValueDefinition(); concatAlgebraNode.DefinedValues[i].Target = new RowBufferEntry(anchorOutput[i].DataType); concatAlgebraNode.DefinedValues[i].DependendEntries = dependencies.ToArray(); } // Calculate the recursive output. recursiveOutput = new RowBufferEntry[concatAlgebraNode.DefinedValues.Length]; for (int i = 0; i < concatAlgebraNode.DefinedValues.Length; i++) { recursiveOutput[i] = concatAlgebraNode.DefinedValues[i].Target; } // Emit cross join JoinAlgebraNode crossJoinNode = new JoinAlgebraNode(); crossJoinNode.Left = tableSpoolNode; crossJoinNode.Right = concatAlgebraNode; // Emit assert that ensures that the recursion level is <= 100. expressionBuilder.Push(new RowBufferEntryExpression(incrementedRecursionLevel)); expressionBuilder.Push(LiteralExpression.FromInt32(100)); expressionBuilder.PushBinary(BinaryOperator.Greater); CaseExpression caseExpression = new CaseExpression(); caseExpression.WhenExpressions = new ExpressionNode[1]; caseExpression.WhenExpressions[0] = expressionBuilder.Pop(); caseExpression.ThenExpressions = new ExpressionNode[1]; caseExpression.ThenExpressions[0] = LiteralExpression.FromInt32(0); AssertAlgebraNode assertAlgebraNode = new AssertAlgebraNode(); assertAlgebraNode.Input = crossJoinNode; assertAlgebraNode.AssertionType = AssertionType.BelowRecursionLimit; assertAlgebraNode.Predicate = caseExpression; recursiveNode = assertAlgebraNode; } #endregion RowBufferEntry[] algebrizedOutput; AlgebraNode algebrizedCte; #region Combination { // Create concat node to combine anchor and recursive part. ConcatAlgebraNode concatAlgebraNode = new ConcatAlgebraNode(); concatAlgebraNode.Inputs = new AlgebraNode[2]; concatAlgebraNode.Inputs[0] = anchorNode; concatAlgebraNode.Inputs[1] = recursiveNode; concatAlgebraNode.DefinedValues = new UnitedValueDefinition[anchorOutput.Length + 1]; concatAlgebraNode.DefinedValues[0] = new UnitedValueDefinition(); concatAlgebraNode.DefinedValues[0].Target = new RowBufferEntry(anchorRecursionLevel.DataType); concatAlgebraNode.DefinedValues[0].DependendEntries = new RowBufferEntry[] { anchorRecursionLevel, incrementedRecursionLevel }; for (int i = 0; i < anchorOutput.Length; i++) { concatAlgebraNode.DefinedValues[i + 1] = new UnitedValueDefinition(); concatAlgebraNode.DefinedValues[i + 1].Target = new RowBufferEntry(anchorOutput[i].DataType); concatAlgebraNode.DefinedValues[i + 1].DependendEntries = new RowBufferEntry[] { anchorOutput[i], recursiveOutput[i] }; } algebrizedOutput = new RowBufferEntry[concatAlgebraNode.DefinedValues.Length]; for (int i = 0; i < concatAlgebraNode.DefinedValues.Length; i++) { algebrizedOutput[i] = concatAlgebraNode.DefinedValues[i].Target; } // Assign the combination as the input to the primray spool primaryTableSpool.Input = concatAlgebraNode; // The primary spool represents the result of the "inlined" CTE. algebrizedCte = primaryTableSpool; } #endregion algebrizedCte.OutputList = algebrizedOutput; return(algebrizedCte); }
public virtual AstNode VisitTableSpoolRefAlgebraNode(StackedTableSpoolRefAlgebraNode node) { return(node); }
public virtual AstNode VisitTableSpoolRefAlgebraNode(StackedTableSpoolRefAlgebraNode node) { return node; }
public override AstNode VisitTableSpoolRefAlgebraNode(StackedTableSpoolRefAlgebraNode node) { node.OutputList = node.DefinedValues; return(node); }
public override AstNode VisitTableSpoolRefAlgebraNode(StackedTableSpoolRefAlgebraNode node) { node.OutputList = node.DefinedValues; return node; }
public override AstNode VisitTableSpoolRefAlgebraNode(StackedTableSpoolRefAlgebraNode node) { _definedValueEntries.AddRange(node.DefinedValues); return node; }
public override AstNode VisitTableSpoolRefAlgebraNode(StackedTableSpoolRefAlgebraNode node) { _definedValueEntries.AddRange(node.DefinedValues); return(node); }
private static AlgebraNode AlgebrizeRecursiveCte(CommonTableBinding commonTableBinding) { // It is a recursive query. // // Create row buffer entry that is used to guard the recursion and the primary table spool // that spools the results needed by nested recursion calls. ExpressionBuilder expressionBuilder = new ExpressionBuilder(); StackedTableSpoolAlgebraNode primaryTableSpool = new StackedTableSpoolAlgebraNode(); RowBufferEntry anchorRecursionLevel; RowBufferEntry[] anchorOutput; AlgebraNode anchorNode; #region Anchor member { // Emit anchor member. AlgebraNode algebrizedAnchor = Convert(commonTableBinding.AnchorMember); // Emit compute scalar that initializes the recursion level to 0. anchorRecursionLevel = new RowBufferEntry(typeof(int)); ComputedValueDefinition computedValueDefinition1 = new ComputedValueDefinition(); computedValueDefinition1.Target = anchorRecursionLevel; computedValueDefinition1.Expression = LiteralExpression.FromInt32(0); ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode(); computeScalarAlgebraNode.Input = algebrizedAnchor; computeScalarAlgebraNode.DefinedValues = new ComputedValueDefinition[] { computedValueDefinition1 }; anchorOutput = algebrizedAnchor.OutputList; anchorNode = computeScalarAlgebraNode; } #endregion RowBufferEntry incrementedRecursionLevel; RowBufferEntry[] tableSpoolOutput; AlgebraNode tableSpoolNode; #region Table spool { // Emit table spool reference. RowBufferEntry recursionLevelRefEntry = new RowBufferEntry(typeof(int)); tableSpoolOutput = new RowBufferEntry[anchorOutput.Length]; for (int i = 0; i < tableSpoolOutput.Length; i++) tableSpoolOutput[i] = new RowBufferEntry(anchorOutput[i].DataType); StackedTableSpoolRefAlgebraNode tableSpoolReference = new StackedTableSpoolRefAlgebraNode(); tableSpoolReference.PrimarySpool = primaryTableSpool; tableSpoolReference.DefinedValues = ArrayHelpers.JoinArrays(new RowBufferEntry[] { recursionLevelRefEntry }, tableSpoolOutput); // Emit compute scalar that increases the recursion level by one and renames // columns from the spool to the CTE column buffer entries. expressionBuilder.Push(new RowBufferEntryExpression(recursionLevelRefEntry)); expressionBuilder.Push(LiteralExpression.FromInt32(1)); expressionBuilder.PushBinary(BinaryOperator.Add); incrementedRecursionLevel = new RowBufferEntry(typeof(int)); ComputedValueDefinition incremenedRecLevelValueDefinition = new ComputedValueDefinition(); incremenedRecLevelValueDefinition.Target = incrementedRecursionLevel; incremenedRecLevelValueDefinition.Expression = expressionBuilder.Pop(); CteColumnMappingFinder cteColumnMappingFinder = new CteColumnMappingFinder(commonTableBinding, tableSpoolOutput); foreach (QueryNode recursiveMember in commonTableBinding.RecursiveMembers) cteColumnMappingFinder.Visit(recursiveMember); CteColumnMapping[] cteColumnMappings = cteColumnMappingFinder.GetMappings(); List<ComputedValueDefinition> definedValues = new List<ComputedValueDefinition>(); definedValues.Add(incremenedRecLevelValueDefinition); foreach (CteColumnMapping cteColumnMapping in cteColumnMappings) { ComputedValueDefinition definedValue = new ComputedValueDefinition(); definedValue.Target = cteColumnMapping.VirtualBufferEntry; definedValue.Expression = new RowBufferEntryExpression(cteColumnMapping.SpoolBufferEntry); definedValues.Add(definedValue); } ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode(); computeScalarAlgebraNode.Input = tableSpoolReference; computeScalarAlgebraNode.DefinedValues = definedValues.ToArray(); tableSpoolNode = computeScalarAlgebraNode; } #endregion RowBufferEntry[] recursiveOutput; AlgebraNode recursiveNode; #region Recursive member(s) { // Emit all recursive parts. The join conditions to the recursive part are replaced by simple filters // in the nested Convert() call. ConcatAlgebraNode concatAlgebraNode = new ConcatAlgebraNode(); concatAlgebraNode.Inputs = new AlgebraNode[commonTableBinding.RecursiveMembers.Length]; for (int i = 0; i < commonTableBinding.RecursiveMembers.Length; i++) concatAlgebraNode.Inputs[i] = Convert(commonTableBinding, commonTableBinding.RecursiveMembers[i]); concatAlgebraNode.DefinedValues = new UnitedValueDefinition[anchorOutput.Length]; for (int i = 0; i < anchorOutput.Length; i++) { List<RowBufferEntry> dependencies = new List<RowBufferEntry>(); foreach (ResultAlgebraNode algebrizedRecursivePart in concatAlgebraNode.Inputs) dependencies.Add(algebrizedRecursivePart.OutputList[i]); concatAlgebraNode.DefinedValues[i] = new UnitedValueDefinition(); concatAlgebraNode.DefinedValues[i].Target = new RowBufferEntry(anchorOutput[i].DataType); concatAlgebraNode.DefinedValues[i].DependendEntries = dependencies.ToArray(); } // Calculate the recursive output. recursiveOutput = new RowBufferEntry[concatAlgebraNode.DefinedValues.Length]; for (int i = 0; i < concatAlgebraNode.DefinedValues.Length; i++) recursiveOutput[i] = concatAlgebraNode.DefinedValues[i].Target; // Emit cross join JoinAlgebraNode crossJoinNode = new JoinAlgebraNode(); crossJoinNode.Left = tableSpoolNode; crossJoinNode.Right = concatAlgebraNode; // Emit assert that ensures that the recursion level is <= 100. expressionBuilder.Push(new RowBufferEntryExpression(incrementedRecursionLevel)); expressionBuilder.Push(LiteralExpression.FromInt32(100)); expressionBuilder.PushBinary(BinaryOperator.Greater); CaseExpression caseExpression = new CaseExpression(); caseExpression.WhenExpressions = new ExpressionNode[1]; caseExpression.WhenExpressions[0] = expressionBuilder.Pop(); caseExpression.ThenExpressions = new ExpressionNode[1]; caseExpression.ThenExpressions[0] = LiteralExpression.FromInt32(0); AssertAlgebraNode assertAlgebraNode = new AssertAlgebraNode(); assertAlgebraNode.Input = crossJoinNode; assertAlgebraNode.AssertionType = AssertionType.BelowRecursionLimit; assertAlgebraNode.Predicate = caseExpression; recursiveNode = assertAlgebraNode; } #endregion RowBufferEntry[] algebrizedOutput; AlgebraNode algebrizedCte; #region Combination { // Create concat node to combine anchor and recursive part. ConcatAlgebraNode concatAlgebraNode = new ConcatAlgebraNode(); concatAlgebraNode.Inputs = new AlgebraNode[2]; concatAlgebraNode.Inputs[0] = anchorNode; concatAlgebraNode.Inputs[1] = recursiveNode; concatAlgebraNode.DefinedValues = new UnitedValueDefinition[anchorOutput.Length + 1]; concatAlgebraNode.DefinedValues[0] = new UnitedValueDefinition(); concatAlgebraNode.DefinedValues[0].Target = new RowBufferEntry(anchorRecursionLevel.DataType); concatAlgebraNode.DefinedValues[0].DependendEntries = new RowBufferEntry[] { anchorRecursionLevel, incrementedRecursionLevel }; for (int i = 0; i < anchorOutput.Length; i++) { concatAlgebraNode.DefinedValues[i + 1] = new UnitedValueDefinition(); concatAlgebraNode.DefinedValues[i + 1].Target = new RowBufferEntry(anchorOutput[i].DataType); concatAlgebraNode.DefinedValues[i + 1].DependendEntries = new RowBufferEntry[] { anchorOutput[i], recursiveOutput[i] }; } algebrizedOutput = new RowBufferEntry[concatAlgebraNode.DefinedValues.Length]; for (int i = 0; i < concatAlgebraNode.DefinedValues.Length; i++) algebrizedOutput[i] = concatAlgebraNode.DefinedValues[i].Target; // Assign the combination as the input to the primray spool primaryTableSpool.Input = concatAlgebraNode; // The primary spool represents the result of the "inlined" CTE. algebrizedCte = primaryTableSpool; } #endregion algebrizedCte.OutputList = algebrizedOutput; return algebrizedCte; }
public override AstNode VisitTableSpoolRefAlgebraNode(StackedTableSpoolRefAlgebraNode node) { foreach (RowBufferEntry definedValue in node.DefinedValues) NameEntry(definedValue, EXPRESSION_NAME_FMT_STR); return node; }
public override AstNode VisitTableSpoolRefAlgebraNode(StackedTableSpoolRefAlgebraNode node) { PropertyListBuilder propertyListBuilder = new PropertyListBuilder(); AddRowBufferEntries(propertyListBuilder, Resources.ShowPlanGroupOutputList, node.OutputList); AddStatistics(propertyListBuilder, node.StatisticsIterator); propertyListBuilder.Write(Resources.ShowPlanKeyLogicalOperator, Resources.ShowPlanLogicalOperatorLazySpool); propertyListBuilder.Write(Resources.ShowPlanKeyWithStack, Boolean.TrueString); IList<ShowPlanProperty> properties = propertyListBuilder.ToList(); ShowPlanElement element = new ShowPlanElement(ShowPlanOperator.TableSpool, properties); _currentElement = element; return node; }