public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node) { base.VisitJoinAlgebraNode(node); if (node.Op == JoinAlgebraNode.JoinOperator.FullOuterJoin) { // TODO: Check if we could represent this join condition by an hash match operator JoinAlgebraNode leftOuterJoinNode = new JoinAlgebraNode(); leftOuterJoinNode.Op = JoinAlgebraNode.JoinOperator.LeftOuterJoin; leftOuterJoinNode.Predicate = (ExpressionNode)node.Predicate.Clone(); leftOuterJoinNode.Left = (AlgebraNode)node.Left.Clone(); leftOuterJoinNode.Right = (AlgebraNode)node.Right.Clone(); leftOuterJoinNode.OutputList = ArrayHelpers.Clone(node.OutputList); List <RowBufferEntry> swappedOutputList = new List <RowBufferEntry>(); swappedOutputList.AddRange(node.Right.OutputList); swappedOutputList.AddRange(node.Left.OutputList); JoinAlgebraNode leftAntiSemiJoinNode = new JoinAlgebraNode(); leftAntiSemiJoinNode.Op = JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin; leftAntiSemiJoinNode.Predicate = (ExpressionNode)node.Predicate.Clone(); leftAntiSemiJoinNode.Left = (AlgebraNode)node.Right.Clone(); leftAntiSemiJoinNode.Right = (AlgebraNode)node.Left.Clone(); leftAntiSemiJoinNode.OutputList = swappedOutputList.ToArray(); List <ComputedValueDefinition> computeScalareDefinedValues = new List <ComputedValueDefinition>(); foreach (RowBufferEntry rowBufferEntry in node.Left.OutputList) { ComputedValueDefinition definedValue = new ComputedValueDefinition(); definedValue.Target = rowBufferEntry; definedValue.Expression = LiteralExpression.FromTypedNull(rowBufferEntry.DataType); computeScalareDefinedValues.Add(definedValue); } ComputeScalarAlgebraNode computeScalarNode = new ComputeScalarAlgebraNode(); computeScalarNode.Input = leftAntiSemiJoinNode; computeScalarNode.DefinedValues = computeScalareDefinedValues.ToArray(); computeScalarNode.OutputList = swappedOutputList.ToArray(); List <UnitedValueDefinition> concatDefinedValues = new List <UnitedValueDefinition>(); for (int i = 0; i < node.OutputList.Length; i++) { RowBufferEntry rowBufferEntry = node.OutputList[i]; UnitedValueDefinition concatDefinedValue = new UnitedValueDefinition(); concatDefinedValue.Target = rowBufferEntry; concatDefinedValue.DependendEntries = new RowBufferEntry[] { node.OutputList[i], node.OutputList[i] }; concatDefinedValues.Add(concatDefinedValue); } ConcatAlgebraNode concatenationNode = new ConcatAlgebraNode(); concatenationNode.Inputs = new AlgebraNode[] { leftOuterJoinNode, computeScalarNode }; concatenationNode.DefinedValues = concatDefinedValues.ToArray(); concatenationNode.OutputList = swappedOutputList.ToArray(); return(concatenationNode); } return(node); }
public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node) { base.VisitJoinAlgebraNode(node); if (node.Op == JoinAlgebraNode.JoinOperator.FullOuterJoin) { // TODO: Check if we could represent this join condition by an hash match operator JoinAlgebraNode leftOuterJoinNode = new JoinAlgebraNode(); leftOuterJoinNode.Op = JoinAlgebraNode.JoinOperator.LeftOuterJoin; leftOuterJoinNode.Predicate = (ExpressionNode)node.Predicate.Clone(); leftOuterJoinNode.Left = (AlgebraNode) node.Left.Clone(); leftOuterJoinNode.Right = (AlgebraNode) node.Right.Clone(); leftOuterJoinNode.OutputList = ArrayHelpers.Clone(node.OutputList); List<RowBufferEntry> swappedOutputList = new List<RowBufferEntry>(); swappedOutputList.AddRange(node.Right.OutputList); swappedOutputList.AddRange(node.Left.OutputList); JoinAlgebraNode leftAntiSemiJoinNode = new JoinAlgebraNode(); leftAntiSemiJoinNode.Op = JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin; leftAntiSemiJoinNode.Predicate = (ExpressionNode) node.Predicate.Clone(); leftAntiSemiJoinNode.Left = (AlgebraNode) node.Right.Clone(); leftAntiSemiJoinNode.Right = (AlgebraNode) node.Left.Clone(); leftAntiSemiJoinNode.OutputList = swappedOutputList.ToArray(); List<ComputedValueDefinition> computeScalareDefinedValues = new List<ComputedValueDefinition>(); foreach (RowBufferEntry rowBufferEntry in node.Left.OutputList) { ComputedValueDefinition definedValue = new ComputedValueDefinition(); definedValue.Target = rowBufferEntry; definedValue.Expression = LiteralExpression.FromTypedNull(rowBufferEntry.DataType); computeScalareDefinedValues.Add(definedValue); } ComputeScalarAlgebraNode computeScalarNode = new ComputeScalarAlgebraNode(); computeScalarNode.Input = leftAntiSemiJoinNode; computeScalarNode.DefinedValues = computeScalareDefinedValues.ToArray(); computeScalarNode.OutputList = swappedOutputList.ToArray(); List<UnitedValueDefinition> concatDefinedValues = new List<UnitedValueDefinition>(); for (int i = 0; i < node.OutputList.Length; i++) { RowBufferEntry rowBufferEntry = node.OutputList[i]; UnitedValueDefinition concatDefinedValue = new UnitedValueDefinition(); concatDefinedValue.Target = rowBufferEntry; concatDefinedValue.DependendEntries = new RowBufferEntry[] { node.OutputList[i], node.OutputList[i] }; concatDefinedValues.Add(concatDefinedValue); } ConcatAlgebraNode concatenationNode = new ConcatAlgebraNode(); concatenationNode.Inputs = new AlgebraNode[] {leftOuterJoinNode, computeScalarNode}; concatenationNode.DefinedValues = concatDefinedValues.ToArray(); concatenationNode.OutputList = swappedOutputList.ToArray(); return concatenationNode; } return node; }
public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node) { for (int i = 0; i < node.Inputs.Length; i++) node.Inputs[i] = VisitAlgebraNode(node.Inputs[i]); node.OutputList = GetRowBufferEntries(node.DefinedValues); return node; }
public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node) { base.VisitConcatAlgebraNode(node); foreach (UnitedValueDefinition definedValue in node.DefinedValues) ReplaceRowBufferEntries(definedValue.DependendEntries); return node; }
public virtual AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node) { for (int i = 0; i < node.Inputs.Length; i++) { node.Inputs[i] = VisitAlgebraNode(node.Inputs[i]); } return(node); }
public override AstElement Clone(Dictionary<AstElement, AstElement> alreadyClonedElements) { ConcatAlgebraNode result = new ConcatAlgebraNode(); result.StatisticsIterator = StatisticsIterator; result.OutputList = ArrayHelpers.Clone(OutputList); result.Inputs = ArrayHelpers.CreateDeepCopyOfAstElementArray(_inputs, alreadyClonedElements); result.DefinedValues = ArrayHelpers.CreateDeepCopyOfAstElementArray(_definedValues, alreadyClonedElements); return result; }
public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node) { base.VisitConcatAlgebraNode(node); foreach (UnitedValueDefinition definedValue in node.DefinedValues) NameEntry(definedValue.Target, UNION_NAME_FMT_STR); return node; }
public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node) { foreach (AlgebraNode input in node.Inputs) Visit(input); if (node.DefinedValues != null) AddDefinedValues(node.DefinedValues); return node; }
public override AstElement Clone(Dictionary <AstElement, AstElement> alreadyClonedElements) { ConcatAlgebraNode result = new ConcatAlgebraNode(); result.StatisticsIterator = StatisticsIterator; result.OutputList = ArrayHelpers.Clone(OutputList); result.Inputs = ArrayHelpers.CreateDeepCopyOfAstElementArray(_inputs, alreadyClonedElements); result.DefinedValues = ArrayHelpers.CreateDeepCopyOfAstElementArray(_definedValues, alreadyClonedElements); return(result); }
public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node) { for (int i = 0; i < node.Inputs.Length; i++) { node.Inputs[i] = VisitAlgebraNode(node.Inputs[i]); } node.OutputList = GetRowBufferEntries(node.DefinedValues); return(node); }
public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node) { base.VisitConcatAlgebraNode(node); foreach (UnitedValueDefinition definedValue in node.DefinedValues) { NameEntry(definedValue.Target, UNION_NAME_FMT_STR); } return(node); }
public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node) { base.VisitConcatAlgebraNode(node); foreach (UnitedValueDefinition definedValue in node.DefinedValues) { ReplaceRowBufferEntries(definedValue.DependendEntries); } return(node); }
public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node) { _xmlWriter.WriteStartElement("concatAlgebraNode"); for (int i = 0; i < node.Inputs.Length; i++) { Visit(node.Inputs[i]); } _xmlWriter.WriteEndElement(); return(node); }
public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node) { base.VisitConcatAlgebraNode(node); foreach (UnitedValueDefinition definedValue in node.DefinedValues) { for (int i = 0; i < definedValue.DependendEntries.Length; i++) { definedValue.DependendEntries[i] = ReplaceRowBuffer(definedValue.DependendEntries[i]); } } return(node); }
public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node) { foreach (AlgebraNode input in node.Inputs) { Visit(input); } if (node.DefinedValues != null) { AddDefinedValues(node.DefinedValues); } return(node); }
private AlgebraNode PushOverConcat(FilterAlgebraNode node) { ConcatAlgebraNode inputNode = (ConcatAlgebraNode)node.Input; for (int i = 0; i < inputNode.Inputs.Length; i++) { ExpressionNode predicate = (ExpressionNode)node.Predicate.Clone(); ConcatRowBufferEntryReplacer concatRowBufferEntryReplacer = new ConcatRowBufferEntryReplacer(inputNode.DefinedValues, i); predicate = concatRowBufferEntryReplacer.VisitExpression(predicate); FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode(); filterAlgebraNode.Input = inputNode.Inputs[i]; filterAlgebraNode.Predicate = predicate; inputNode.Inputs[i] = VisitAlgebraNode(filterAlgebraNode); } return(inputNode); }
public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node) { node.OutputList = RemovedUnneededRowBufferColumns(node.OutputList); List <UnitedValueDefinition> definedValues = new List <UnitedValueDefinition>(); foreach (UnitedValueDefinition definedValue in node.DefinedValues) { if (IsNeeded(definedValue.Target)) { definedValues.Add(definedValue); foreach (RowBufferEntry dependendValue in definedValue.DependendEntries) { AddNeededRowBufferEntry(dependendValue); } } } node.DefinedValues = definedValues.ToArray(); node.OutputList = GetRowBufferEntries(node.DefinedValues); return(base.VisitConcatAlgebraNode(node)); }
public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node) { List <ShowPlanElement> inputList = new List <ShowPlanElement>(); foreach (AlgebraNode inputNode in node.Inputs) { inputList.Add(ConvertNode(inputNode)); } PropertyListBuilder propertyListBuilder = new PropertyListBuilder(); AddRowBufferEntries(propertyListBuilder, Resources.ShowPlanGroupOutputList, node.OutputList); AddStatistics(propertyListBuilder, node.StatisticsIterator); AddDefinedValues(propertyListBuilder, node.DefinedValues); IList <ShowPlanProperty> properties = propertyListBuilder.ToList(); ShowPlanElement element = new ShowPlanElement(ShowPlanOperator.Concatenation, properties, inputList.ToArray()); _currentElement = element; return(node); }
public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node) { base.VisitConcatAlgebraNode(node); foreach (UnitedValueDefinition definedValue in node.DefinedValues) { for (int i = 0; i < definedValue.DependendEntries.Length; i++) definedValue.DependendEntries[i] = ReplaceRowBuffer(definedValue.DependendEntries[i]); } return node; }
public virtual AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node) { for (int i = 0; i < node.Inputs.Length; i++) node.Inputs[i] = VisitAlgebraNode(node.Inputs[i]); return node; }
public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node) { node.Left = VisitAlgebraNode(node.Left); node.Right = VisitAlgebraNode(node.Right); bool leftIsNull = node.Left is NullScanAlgebraNode; bool rightIsNull = node.Right is NullScanAlgebraNode; bool joinConditionAlwaysFalse = false; if (node.Predicate != null) { ExpressionNode predicate = node.Predicate; ConstantExpression predicateAsConstant = predicate as ConstantExpression; if (predicateAsConstant != null) { if (predicateAsConstant.AsBoolean) node.Predicate = null; else joinConditionAlwaysFalse = true; } } if (node.Op == JoinAlgebraNode.JoinOperator.RightOuterJoin || node.Op == JoinAlgebraNode.JoinOperator.RightSemiJoin || node.Op == JoinAlgebraNode.JoinOperator.RightAntiSemiJoin) { node.SwapSides(); } switch (node.Op) { case JoinAlgebraNode.JoinOperator.InnerJoin: if (joinConditionAlwaysFalse || leftIsNull || rightIsNull) return CreateNullScan(node.OutputList); break; case JoinAlgebraNode.JoinOperator.FullOuterJoin: if (leftIsNull && rightIsNull) return CreateNullScan(node.OutputList); if (leftIsNull) return PadRightWithNullsOnLeftSide(node, RowBufferCreationMode.KeepExisting); if (rightIsNull) return PadLeftWithNullsOnRightSide(node, RowBufferCreationMode.KeepExisting); if (joinConditionAlwaysFalse) { AlgebraNode left = PadLeftWithNullsOnRightSide(node, RowBufferCreationMode.CreateNew); AlgebraNode right = PadRightWithNullsOnLeftSide(node, RowBufferCreationMode.CreateNew); ConcatAlgebraNode concatAlgebraNode = new ConcatAlgebraNode(); concatAlgebraNode.Inputs = new AlgebraNode[] { left, right }; List<RowBufferEntry> outputList = new List<RowBufferEntry>(); List<UnitedValueDefinition> definedValues = new List<UnitedValueDefinition>(); for (int i = 0; i < node.Left.OutputList.Length; i++) { int leftIndex = i; int rightIndex = node.Right.OutputList.Length + i; UnitedValueDefinition definedValue = new UnitedValueDefinition(); definedValue.Target = node.Left.OutputList[leftIndex]; definedValue.DependendEntries = new RowBufferEntry[] { left.OutputList[leftIndex], right.OutputList[rightIndex] }; definedValues.Add(definedValue); outputList.Add(definedValue.Target); } for (int i = 0; i < node.Right.OutputList.Length; i++) { int leftIndex = node.Left.OutputList.Length + i; int rightIndex = i; UnitedValueDefinition definedValue = new UnitedValueDefinition(); definedValue.Target = node.Right.OutputList[rightIndex]; definedValue.DependendEntries = new RowBufferEntry[] { left.OutputList[leftIndex], right.OutputList[rightIndex] }; definedValues.Add(definedValue); outputList.Add(definedValue.Target); } concatAlgebraNode.DefinedValues = definedValues.ToArray(); concatAlgebraNode.OutputList = outputList.ToArray(); return concatAlgebraNode; } break; case JoinAlgebraNode.JoinOperator.LeftOuterJoin: if (leftIsNull) return CreateNullScan(node.OutputList); if (rightIsNull || joinConditionAlwaysFalse) return PadLeftWithNullsOnRightSide(node, RowBufferCreationMode.KeepExisting); break; case JoinAlgebraNode.JoinOperator.LeftSemiJoin: if (leftIsNull || rightIsNull || joinConditionAlwaysFalse) return CreateNullScan(node.OutputList); if (node.Predicate == null && AstUtil.WillProduceAtLeastOneRow(node.Right)) return node.Left; break; case JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin: if (leftIsNull) return CreateNullScan(node.OutputList); if (rightIsNull || joinConditionAlwaysFalse) return node.Left; if (node.Predicate == null && AstUtil.WillProduceAtLeastOneRow(node.Right)) return CreateNullScan(node.OutputList); break; } 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 ExpressionNode VisitBinaryExpression(BinaryExpression expression) { if (expression.Op != BinaryOperator.LogicalAnd && expression.Op != BinaryOperator.LogicalOr) return base.VisitBinaryExpression(expression); if (expression.Op == BinaryOperator.LogicalAnd) { // AND expression.Left = VisitExpression(expression.Left); expression.Right = VisitExpression(expression.Right); return expression; } else { // OR AlgebraNode input = GetAndResetLastNode(); _probingEnabledStack.Push(false); List<ExpressionNode> scalarOrParts = new List<ExpressionNode>(); List<AlgebraNode> algebrizedOrParts = new List<AlgebraNode>(); foreach (ExpressionNode orPart in AstUtil.SplitCondition(LogicalOperator.Or, expression)) { if (!AstUtil.ContainsSubselect(orPart)) { scalarOrParts.Add(orPart); } else { ExpressionNode replacedOrPart = VisitExpression(orPart); FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode(); filterAlgebraNode.Input = GetAndResetLastNode(); filterAlgebraNode.Predicate = replacedOrPart; algebrizedOrParts.Add(filterAlgebraNode); } } if (scalarOrParts.Count > 0) { FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode(); filterAlgebraNode.Predicate = AstUtil.CombineConditions(LogicalOperator.Or, scalarOrParts); filterAlgebraNode.Input = CreateConstantScan(); algebrizedOrParts.Insert(0, filterAlgebraNode); } _probingEnabledStack.Pop(); ConcatAlgebraNode concat = new ConcatAlgebraNode(); concat.DefinedValues = new UnitedValueDefinition[0]; concat.Inputs = algebrizedOrParts.ToArray(); RowBufferEntry probeColumn = CreateProbeColumn(); JoinAlgebraNode leftSemiJoinBetweenInputAndConcat = new JoinAlgebraNode(); leftSemiJoinBetweenInputAndConcat.Op = JoinAlgebraNode.JoinOperator.LeftSemiJoin; leftSemiJoinBetweenInputAndConcat.PassthruPredicate = CurrentPassthruPredicate; leftSemiJoinBetweenInputAndConcat.ProbeBufferEntry = probeColumn; leftSemiJoinBetweenInputAndConcat.Left = input; leftSemiJoinBetweenInputAndConcat.Right = concat; SetLastAlgebraNode(leftSemiJoinBetweenInputAndConcat); return CreateProbeColumnRef(probeColumn); } }
public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node) { base.VisitConcatAlgebraNode(node); List<AlgebraNode> nonEmptyInputs = new List<AlgebraNode>(); foreach (AlgebraNode input in node.Inputs) { if (input is NullScanAlgebraNode) { // removed by not adding to list. } else { nonEmptyInputs.Add(input); } } if (nonEmptyInputs.Count == 0) return CreateNullScan(node.OutputList); if (nonEmptyInputs.Count == 1) { int inputIndex = Array.IndexOf(node.Inputs, nonEmptyInputs[0]); List<ComputedValueDefinition> definedValues = new List<ComputedValueDefinition>(); ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode(); computeScalarAlgebraNode.Input = nonEmptyInputs[0]; foreach (UnitedValueDefinition unitedValueDefinition in node.DefinedValues) { ComputedValueDefinition computedValueDefinition = new ComputedValueDefinition(); computedValueDefinition.Target = unitedValueDefinition.Target; computedValueDefinition.Expression = new RowBufferEntryExpression(unitedValueDefinition.DependendEntries[inputIndex]); definedValues.Add(computedValueDefinition); } computeScalarAlgebraNode.DefinedValues = definedValues.ToArray(); computeScalarAlgebraNode.OutputList = node.OutputList; return computeScalarAlgebraNode; } node.Inputs = nonEmptyInputs.ToArray(); // Update dependend entries for (int i = 0; i < node.DefinedValues.Length; i++) { UnitedValueDefinition definition = node.DefinedValues[i]; List<RowBufferEntry> dependendEntries = new List<RowBufferEntry>(); foreach (RowBufferEntry dependendEntry in definition.DependendEntries) { bool entryInAnyInput = false; foreach (AlgebraNode input in node.Inputs) { if (ArrayHelpers.Contains(input.OutputList, dependendEntry)) { entryInAnyInput = true; break; } } if (entryInAnyInput) dependendEntries.Add(dependendEntry); } definition.DependendEntries = dependendEntries.ToArray(); } return node; }
public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node) { node.Left = VisitAlgebraNode(node.Left); node.Right = VisitAlgebraNode(node.Right); bool leftIsNull = node.Left is NullScanAlgebraNode; bool rightIsNull = node.Right is NullScanAlgebraNode; bool joinConditionAlwaysFalse = false; if (node.Predicate != null) { ExpressionNode predicate = node.Predicate; ConstantExpression predicateAsConstant = predicate as ConstantExpression; if (predicateAsConstant != null) { if (predicateAsConstant.AsBoolean) { node.Predicate = null; } else { joinConditionAlwaysFalse = true; } } } if (node.Op == JoinAlgebraNode.JoinOperator.RightOuterJoin || node.Op == JoinAlgebraNode.JoinOperator.RightSemiJoin || node.Op == JoinAlgebraNode.JoinOperator.RightAntiSemiJoin) { node.SwapSides(); } switch (node.Op) { case JoinAlgebraNode.JoinOperator.InnerJoin: if (joinConditionAlwaysFalse || leftIsNull || rightIsNull) { return(CreateNullScan(node.OutputList)); } break; case JoinAlgebraNode.JoinOperator.FullOuterJoin: if (leftIsNull && rightIsNull) { return(CreateNullScan(node.OutputList)); } if (leftIsNull) { return(PadRightWithNullsOnLeftSide(node, RowBufferCreationMode.KeepExisting)); } if (rightIsNull) { return(PadLeftWithNullsOnRightSide(node, RowBufferCreationMode.KeepExisting)); } if (joinConditionAlwaysFalse) { AlgebraNode left = PadLeftWithNullsOnRightSide(node, RowBufferCreationMode.CreateNew); AlgebraNode right = PadRightWithNullsOnLeftSide(node, RowBufferCreationMode.CreateNew); ConcatAlgebraNode concatAlgebraNode = new ConcatAlgebraNode(); concatAlgebraNode.Inputs = new AlgebraNode[] { left, right }; List <RowBufferEntry> outputList = new List <RowBufferEntry>(); List <UnitedValueDefinition> definedValues = new List <UnitedValueDefinition>(); for (int i = 0; i < node.Left.OutputList.Length; i++) { int leftIndex = i; int rightIndex = node.Right.OutputList.Length + i; UnitedValueDefinition definedValue = new UnitedValueDefinition(); definedValue.Target = node.Left.OutputList[leftIndex]; definedValue.DependendEntries = new RowBufferEntry[] { left.OutputList[leftIndex], right.OutputList[rightIndex] }; definedValues.Add(definedValue); outputList.Add(definedValue.Target); } for (int i = 0; i < node.Right.OutputList.Length; i++) { int leftIndex = node.Left.OutputList.Length + i; int rightIndex = i; UnitedValueDefinition definedValue = new UnitedValueDefinition(); definedValue.Target = node.Right.OutputList[rightIndex]; definedValue.DependendEntries = new RowBufferEntry[] { left.OutputList[leftIndex], right.OutputList[rightIndex] }; definedValues.Add(definedValue); outputList.Add(definedValue.Target); } concatAlgebraNode.DefinedValues = definedValues.ToArray(); concatAlgebraNode.OutputList = outputList.ToArray(); return(concatAlgebraNode); } break; case JoinAlgebraNode.JoinOperator.LeftOuterJoin: if (leftIsNull) { return(CreateNullScan(node.OutputList)); } if (rightIsNull || joinConditionAlwaysFalse) { return(PadLeftWithNullsOnRightSide(node, RowBufferCreationMode.KeepExisting)); } break; case JoinAlgebraNode.JoinOperator.LeftSemiJoin: if (leftIsNull || rightIsNull || joinConditionAlwaysFalse) { return(CreateNullScan(node.OutputList)); } if (node.Predicate == null && AstUtil.WillProduceAtLeastOneRow(node.Right)) { return(node.Left); } break; case JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin: if (leftIsNull) { return(CreateNullScan(node.OutputList)); } if (rightIsNull || joinConditionAlwaysFalse) { return(node.Left); } if (node.Predicate == null && AstUtil.WillProduceAtLeastOneRow(node.Right)) { return(CreateNullScan(node.OutputList)); } break; } return(node); }
public override QueryNode VisitBinaryQuery(BinaryQuery query) { switch (query.Op) { case BinaryQueryOperator.Intersect: case BinaryQueryOperator.Except: { ResultAlgebraNode left = ((ResultAlgebraNode)ConvertAstNode(query.Left)); ResultAlgebraNode right = ((ResultAlgebraNode)ConvertAstNode(query.Right)); // Create distinct sort SortAlgebraNode sortAlgebraNode = new SortAlgebraNode(); sortAlgebraNode.Distinct = true; sortAlgebraNode.Input = left; sortAlgebraNode.SortEntries = left.OutputList; sortAlgebraNode.SortOrders = CreateAscendingSortOrders(sortAlgebraNode.SortEntries.Length); // Insert left (anti) semi join to (except) intersect left and right. ExpressionBuilder expressionBuilder = new ExpressionBuilder(); for (int i = 0; i < left.OutputList.Length; i++) { RowBufferEntryExpression leftExpr = new RowBufferEntryExpression(); leftExpr.RowBufferEntry = left.OutputList[i]; RowBufferEntryExpression rightExpr = new RowBufferEntryExpression(); rightExpr.RowBufferEntry = right.OutputList[i]; expressionBuilder.Push(leftExpr); expressionBuilder.Push(rightExpr); expressionBuilder.PushBinary(BinaryOperator.Equal); expressionBuilder.Push(leftExpr); expressionBuilder.PushIsNull(); expressionBuilder.Push(rightExpr); expressionBuilder.PushIsNull(); expressionBuilder.PushBinary(BinaryOperator.LogicalAnd); expressionBuilder.PushBinary(BinaryOperator.LogicalOr); } expressionBuilder.PushNAry(LogicalOperator.And); ExpressionNode joinCondition = expressionBuilder.Pop(); JoinAlgebraNode joinAlgebraNode = new JoinAlgebraNode(); if (query.Op == BinaryQueryOperator.Intersect) joinAlgebraNode.Op = JoinAlgebraNode.JoinOperator.LeftSemiJoin; else joinAlgebraNode.Op = JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin; joinAlgebraNode.Left = sortAlgebraNode; joinAlgebraNode.Right = right; joinAlgebraNode.Predicate = joinCondition; SetLastAlgebraNode(joinAlgebraNode); ResultAlgebraNode resultAlgebraNode = new ResultAlgebraNode(); resultAlgebraNode.Input = GetLastAlgebraNode(); resultAlgebraNode.OutputList = left.OutputList; resultAlgebraNode.ColumnNames = left.ColumnNames; SetLastAlgebraNode(resultAlgebraNode); break; } case BinaryQueryOperator.Union: case BinaryQueryOperator.UnionAll: { // Build a flat list with all inputs. List<QueryNode> inputList = AstUtil.FlattenBinaryQuery(query); AlgebraNode[] inputs = new AlgebraNode[inputList.Count]; for (int i = 0; i < inputs.Length; i++) inputs[i] = ConvertAstNode(inputList[i]); int outputColumnCount = inputs[0].OutputList.Length; UnitedValueDefinition[] definedValues = new UnitedValueDefinition[outputColumnCount]; List<RowBufferEntry> definedValueEntries = new List<RowBufferEntry>(); for (int i = 0; i < outputColumnCount; i++) { RowBufferEntry rowBufferEntry = new RowBufferEntry(inputs[0].OutputList[i].DataType); definedValueEntries.Add(rowBufferEntry); UnitedValueDefinition definedValue = new UnitedValueDefinition(); definedValue.Target = rowBufferEntry; List<RowBufferEntry> dependencies = new List<RowBufferEntry>(); foreach (ResultAlgebraNode node in inputs) dependencies.Add(node.OutputList[i]); definedValue.DependendEntries = dependencies.ToArray(); definedValues[i] = definedValue; } ConcatAlgebraNode concatAlgebraNode = new ConcatAlgebraNode(); concatAlgebraNode.Inputs = inputs; concatAlgebraNode.DefinedValues = definedValues; SetLastAlgebraNode(concatAlgebraNode); if (query.Op == BinaryQueryOperator.Union) { SortAlgebraNode sortAlgebraNode = new SortAlgebraNode(); sortAlgebraNode.Distinct = true; sortAlgebraNode.Input = GetLastAlgebraNode(); sortAlgebraNode.SortEntries = definedValueEntries.ToArray(); sortAlgebraNode.SortOrders = CreateAscendingSortOrders(sortAlgebraNode.SortEntries.Length); SetLastAlgebraNode(sortAlgebraNode); } ResultAlgebraNode unionResultAlgebraNode = new ResultAlgebraNode(); unionResultAlgebraNode.Input = GetLastAlgebraNode(); unionResultAlgebraNode.ColumnNames = ((ResultAlgebraNode)inputs[0]).ColumnNames; unionResultAlgebraNode.OutputList = definedValueEntries.ToArray(); SetLastAlgebraNode(unionResultAlgebraNode); break; } } return query; }
public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node) { base.VisitConcatAlgebraNode(node); List <AlgebraNode> nonEmptyInputs = new List <AlgebraNode>(); foreach (AlgebraNode input in node.Inputs) { if (input is NullScanAlgebraNode) { // removed by not adding to list. } else { nonEmptyInputs.Add(input); } } if (nonEmptyInputs.Count == 0) { return(CreateNullScan(node.OutputList)); } if (nonEmptyInputs.Count == 1) { int inputIndex = Array.IndexOf(node.Inputs, nonEmptyInputs[0]); List <ComputedValueDefinition> definedValues = new List <ComputedValueDefinition>(); ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode(); computeScalarAlgebraNode.Input = nonEmptyInputs[0]; foreach (UnitedValueDefinition unitedValueDefinition in node.DefinedValues) { ComputedValueDefinition computedValueDefinition = new ComputedValueDefinition(); computedValueDefinition.Target = unitedValueDefinition.Target; computedValueDefinition.Expression = new RowBufferEntryExpression(unitedValueDefinition.DependendEntries[inputIndex]); definedValues.Add(computedValueDefinition); } computeScalarAlgebraNode.DefinedValues = definedValues.ToArray(); computeScalarAlgebraNode.OutputList = node.OutputList; return(computeScalarAlgebraNode); } node.Inputs = nonEmptyInputs.ToArray(); // Update dependend entries for (int i = 0; i < node.DefinedValues.Length; i++) { UnitedValueDefinition definition = node.DefinedValues[i]; List <RowBufferEntry> dependendEntries = new List <RowBufferEntry>(); foreach (RowBufferEntry dependendEntry in definition.DependendEntries) { bool entryInAnyInput = false; foreach (AlgebraNode input in node.Inputs) { if (ArrayHelpers.Contains(input.OutputList, dependendEntry)) { entryInAnyInput = true; break; } } if (entryInAnyInput) { dependendEntries.Add(dependendEntry); } } definition.DependendEntries = dependendEntries.ToArray(); } return(node); }
public override ExpressionNode VisitBinaryExpression(BinaryExpression expression) { if (expression.Op != BinaryOperator.LogicalAnd && expression.Op != BinaryOperator.LogicalOr) { return(base.VisitBinaryExpression(expression)); } if (expression.Op == BinaryOperator.LogicalAnd) { // AND expression.Left = VisitExpression(expression.Left); expression.Right = VisitExpression(expression.Right); return(expression); } else { // OR AlgebraNode input = GetAndResetLastNode(); _probingEnabledStack.Push(false); List <ExpressionNode> scalarOrParts = new List <ExpressionNode>(); List <AlgebraNode> algebrizedOrParts = new List <AlgebraNode>(); foreach (ExpressionNode orPart in AstUtil.SplitCondition(LogicalOperator.Or, expression)) { if (!AstUtil.ContainsSubselect(orPart)) { scalarOrParts.Add(orPart); } else { ExpressionNode replacedOrPart = VisitExpression(orPart); FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode(); filterAlgebraNode.Input = GetAndResetLastNode(); filterAlgebraNode.Predicate = replacedOrPart; algebrizedOrParts.Add(filterAlgebraNode); } } if (scalarOrParts.Count > 0) { FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode(); filterAlgebraNode.Predicate = AstUtil.CombineConditions(LogicalOperator.Or, scalarOrParts); filterAlgebraNode.Input = CreateConstantScan(); algebrizedOrParts.Insert(0, filterAlgebraNode); } _probingEnabledStack.Pop(); ConcatAlgebraNode concat = new ConcatAlgebraNode(); concat.DefinedValues = new UnitedValueDefinition[0]; concat.Inputs = algebrizedOrParts.ToArray(); RowBufferEntry probeColumn = CreateProbeColumn(); JoinAlgebraNode leftSemiJoinBetweenInputAndConcat = new JoinAlgebraNode(); leftSemiJoinBetweenInputAndConcat.Op = JoinAlgebraNode.JoinOperator.LeftSemiJoin; leftSemiJoinBetweenInputAndConcat.PassthruPredicate = CurrentPassthruPredicate; leftSemiJoinBetweenInputAndConcat.ProbeBufferEntry = probeColumn; leftSemiJoinBetweenInputAndConcat.Left = input; leftSemiJoinBetweenInputAndConcat.Right = concat; SetLastAlgebraNode(leftSemiJoinBetweenInputAndConcat); return(CreateProbeColumnRef(probeColumn)); } }
public override QueryNode VisitBinaryQuery(BinaryQuery query) { switch (query.Op) { case BinaryQueryOperator.Intersect: case BinaryQueryOperator.Except: { ResultAlgebraNode left = ((ResultAlgebraNode)ConvertAstNode(query.Left)); ResultAlgebraNode right = ((ResultAlgebraNode)ConvertAstNode(query.Right)); // Create distinct sort SortAlgebraNode sortAlgebraNode = new SortAlgebraNode(); sortAlgebraNode.Distinct = true; sortAlgebraNode.Input = left; sortAlgebraNode.SortEntries = left.OutputList; sortAlgebraNode.SortOrders = CreateAscendingSortOrders(sortAlgebraNode.SortEntries.Length); // Insert left (anti) semi join to (except) intersect left and right. ExpressionBuilder expressionBuilder = new ExpressionBuilder(); for (int i = 0; i < left.OutputList.Length; i++) { RowBufferEntryExpression leftExpr = new RowBufferEntryExpression(); leftExpr.RowBufferEntry = left.OutputList[i]; RowBufferEntryExpression rightExpr = new RowBufferEntryExpression(); rightExpr.RowBufferEntry = right.OutputList[i]; expressionBuilder.Push(leftExpr); expressionBuilder.Push(rightExpr); expressionBuilder.PushBinary(BinaryOperator.Equal); expressionBuilder.Push(leftExpr); expressionBuilder.PushIsNull(); expressionBuilder.Push(rightExpr); expressionBuilder.PushIsNull(); expressionBuilder.PushBinary(BinaryOperator.LogicalAnd); expressionBuilder.PushBinary(BinaryOperator.LogicalOr); } expressionBuilder.PushNAry(LogicalOperator.And); ExpressionNode joinCondition = expressionBuilder.Pop(); JoinAlgebraNode joinAlgebraNode = new JoinAlgebraNode(); if (query.Op == BinaryQueryOperator.Intersect) { joinAlgebraNode.Op = JoinAlgebraNode.JoinOperator.LeftSemiJoin; } else { joinAlgebraNode.Op = JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin; } joinAlgebraNode.Left = sortAlgebraNode; joinAlgebraNode.Right = right; joinAlgebraNode.Predicate = joinCondition; SetLastAlgebraNode(joinAlgebraNode); ResultAlgebraNode resultAlgebraNode = new ResultAlgebraNode(); resultAlgebraNode.Input = GetLastAlgebraNode(); resultAlgebraNode.OutputList = left.OutputList; resultAlgebraNode.ColumnNames = left.ColumnNames; SetLastAlgebraNode(resultAlgebraNode); break; } case BinaryQueryOperator.Union: case BinaryQueryOperator.UnionAll: { // Build a flat list with all inputs. List <QueryNode> inputList = AstUtil.FlattenBinaryQuery(query); AlgebraNode[] inputs = new AlgebraNode[inputList.Count]; for (int i = 0; i < inputs.Length; i++) { inputs[i] = ConvertAstNode(inputList[i]); } int outputColumnCount = inputs[0].OutputList.Length; UnitedValueDefinition[] definedValues = new UnitedValueDefinition[outputColumnCount]; List <RowBufferEntry> definedValueEntries = new List <RowBufferEntry>(); for (int i = 0; i < outputColumnCount; i++) { RowBufferEntry rowBufferEntry = new RowBufferEntry(inputs[0].OutputList[i].DataType); definedValueEntries.Add(rowBufferEntry); UnitedValueDefinition definedValue = new UnitedValueDefinition(); definedValue.Target = rowBufferEntry; List <RowBufferEntry> dependencies = new List <RowBufferEntry>(); foreach (ResultAlgebraNode node in inputs) { dependencies.Add(node.OutputList[i]); } definedValue.DependendEntries = dependencies.ToArray(); definedValues[i] = definedValue; } ConcatAlgebraNode concatAlgebraNode = new ConcatAlgebraNode(); concatAlgebraNode.Inputs = inputs; concatAlgebraNode.DefinedValues = definedValues; SetLastAlgebraNode(concatAlgebraNode); if (query.Op == BinaryQueryOperator.Union) { SortAlgebraNode sortAlgebraNode = new SortAlgebraNode(); sortAlgebraNode.Distinct = true; sortAlgebraNode.Input = GetLastAlgebraNode(); sortAlgebraNode.SortEntries = definedValueEntries.ToArray(); sortAlgebraNode.SortOrders = CreateAscendingSortOrders(sortAlgebraNode.SortEntries.Length); SetLastAlgebraNode(sortAlgebraNode); } ResultAlgebraNode unionResultAlgebraNode = new ResultAlgebraNode(); unionResultAlgebraNode.Input = GetLastAlgebraNode(); unionResultAlgebraNode.ColumnNames = ((ResultAlgebraNode)inputs[0]).ColumnNames; unionResultAlgebraNode.OutputList = definedValueEntries.ToArray(); SetLastAlgebraNode(unionResultAlgebraNode); break; } } return(query); }
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 AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node) { _xmlWriter.WriteStartElement("concatAlgebraNode"); for (int i = 0; i < node.Inputs.Length; i++) Visit(node.Inputs[i]); _xmlWriter.WriteEndElement(); return node; }
public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node) { ConcatenationIterator concatenationIterator = new ConcatenationIterator(); concatenationIterator.RowBuffer = new object[node.OutputList.Length]; concatenationIterator.Inputs = new Iterator[node.Inputs.Length]; concatenationIterator.InputOutput = new IteratorOutput[node.Inputs.Length][]; for (int i = 0; i < concatenationIterator.Inputs.Length; i++) { concatenationIterator.Inputs[i] = ConvertAlgebraNode(node.Inputs[i]); List<IteratorOutput> inputOutputList = new List<IteratorOutput>(); foreach (UnitedValueDefinition unitedValueDefinition in node.DefinedValues) { IteratorOutput iteratorOutput = new IteratorOutput(); iteratorOutput.SourceIndex = Array.IndexOf(node.Inputs[i].OutputList, unitedValueDefinition.DependendEntries[i]); iteratorOutput.TargetIndex = Array.IndexOf(node.OutputList, unitedValueDefinition.Target); inputOutputList.Add(iteratorOutput); } concatenationIterator.InputOutput[i] = inputOutputList.ToArray(); } SetLastIterator(node, concatenationIterator); return node; }
public override AlgebraNode VisitConcatAlgebraNode(ConcatAlgebraNode node) { List<ShowPlanElement> inputList = new List<ShowPlanElement>(); foreach (AlgebraNode inputNode in node.Inputs) inputList.Add(ConvertNode(inputNode)); PropertyListBuilder propertyListBuilder = new PropertyListBuilder(); AddRowBufferEntries(propertyListBuilder, Resources.ShowPlanGroupOutputList, node.OutputList); AddStatistics(propertyListBuilder, node.StatisticsIterator); AddDefinedValues(propertyListBuilder, node.DefinedValues); IList<ShowPlanProperty> properties = propertyListBuilder.ToList(); ShowPlanElement element = new ShowPlanElement(ShowPlanOperator.Concatenation, properties, inputList.ToArray()); _currentElement = element; return node; }