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 AstElement Clone(Dictionary<AstElement, AstElement> alreadyClonedElements) { UnitedValueDefinition result = new UnitedValueDefinition(); result.Target = Target; result.DependendEntries = ArrayHelpers.Clone(_dependendEntries); return result; }
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 AstElement Clone(Dictionary <AstElement, AstElement> alreadyClonedElements) { UnitedValueDefinition result = new UnitedValueDefinition(); result.Target = Target; result.DependendEntries = ArrayHelpers.Clone(_dependendEntries); return(result); }
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 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 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 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 ConcatRowBufferEntryReplacer(UnitedValueDefinition[] unitedValues, int inputIndex) { _unitedValues = unitedValues; _inputIndex = inputIndex; }
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; }