public static ExpressionNode CombineConditions(LogicalOperator logicalOperator, IList <ExpressionNode> conditions) { if (conditions == null || conditions.Count == 0) { return(null); } ExpressionBuilder expressionBuilder = new ExpressionBuilder(); foreach (ExpressionNode condition in conditions) { if (condition != null) { expressionBuilder.Push(condition); } } if (expressionBuilder.Count == 0) { return(null); } expressionBuilder.PushNAry(logicalOperator); return(expressionBuilder.Pop()); }
private void SetWhenPassthru(ICollection <ExpressionNode> processedWhenExpressions) { if (processedWhenExpressions.Count == 0) { _currentPassthruPredicate = null; } else { foreach (ExpressionNode processedWhenExpression in processedWhenExpressions) { ExpressionNode clonedExpr = (ExpressionNode)processedWhenExpression.Clone(); _expressionBuilder.Push(clonedExpr); } _expressionBuilder.PushNAry(LogicalOperator.Or); _currentPassthruPredicate = _expressionBuilder.Pop(); } }
public static ExpressionNode CombineConditions(LogicalOperator logicalOperator, IList<ExpressionNode> conditions) { if (conditions == null || conditions.Count == 0) return null; ExpressionBuilder expressionBuilder = new ExpressionBuilder(); foreach (ExpressionNode condition in conditions) { if (condition != null) expressionBuilder.Push(condition); } if (expressionBuilder.Count == 0) return null; expressionBuilder.PushNAry(logicalOperator); return expressionBuilder.Pop(); }
public override ExpressionNode VisitAllAnySubselect(AllAnySubselect expression) { expression.Left = VisitExpression(expression.Left); ResultAlgebraNode algebrizedQuery = Algebrizer.Convert(expression.Query); ExpressionNode leftExpression = expression.Left; RowBufferEntryExpression rightExpression = new RowBufferEntryExpression(); rightExpression.RowBufferEntry = algebrizedQuery.OutputList[0]; ExpressionBuilder expressionBuilder = new ExpressionBuilder(); expressionBuilder.Push(leftExpression); expressionBuilder.Push(rightExpression); expressionBuilder.PushBinary(expression.Op); bool negated = (expression.Type == AllAnySubselect.AllAnyType.All); if (negated) { expressionBuilder.PushUnary(UnaryOperator.LogicalNot); expressionBuilder.Push(leftExpression); expressionBuilder.PushIsNull(); expressionBuilder.Push(rightExpression); expressionBuilder.PushIsNull(); expressionBuilder.PushNAry(LogicalOperator.Or); } ExpressionNode filterPredicate = expressionBuilder.Pop(); FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode(); filterAlgebraNode.Input = algebrizedQuery; filterAlgebraNode.Predicate = filterPredicate; AlgebraNode input = GetAndResetLastNode(); if (!negated && !ProbingEnabled && input == null) { SetLastAlgebraNode(filterAlgebraNode); return LiteralExpression.FromBoolean(true); } else { if (input == null) input = CreateConstantScan(); RowBufferEntry probeColumn = CreateProbeColumn(); JoinAlgebraNode joinAlgebraNode = new JoinAlgebraNode(); joinAlgebraNode.PassthruPredicate = CurrentPassthruPredicate; joinAlgebraNode.ProbeBufferEntry = probeColumn; joinAlgebraNode.Left = input; joinAlgebraNode.Right = filterAlgebraNode; joinAlgebraNode.Op = negated ? JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin : JoinAlgebraNode.JoinOperator.LeftSemiJoin; SetLastAlgebraNode(joinAlgebraNode); 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); }
public override ExpressionNode VisitAllAnySubselect(AllAnySubselect expression) { expression.Left = VisitExpression(expression.Left); ResultAlgebraNode algebrizedQuery = Algebrizer.Convert(expression.Query); ExpressionNode leftExpression = expression.Left; RowBufferEntryExpression rightExpression = new RowBufferEntryExpression(); rightExpression.RowBufferEntry = algebrizedQuery.OutputList[0]; ExpressionBuilder expressionBuilder = new ExpressionBuilder(); expressionBuilder.Push(leftExpression); expressionBuilder.Push(rightExpression); expressionBuilder.PushBinary(expression.Op); bool negated = (expression.Type == AllAnySubselect.AllAnyType.All); if (negated) { expressionBuilder.PushUnary(UnaryOperator.LogicalNot); expressionBuilder.Push(leftExpression); expressionBuilder.PushIsNull(); expressionBuilder.Push(rightExpression); expressionBuilder.PushIsNull(); expressionBuilder.PushNAry(LogicalOperator.Or); } ExpressionNode filterPredicate = expressionBuilder.Pop(); FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode(); filterAlgebraNode.Input = algebrizedQuery; filterAlgebraNode.Predicate = filterPredicate; AlgebraNode input = GetAndResetLastNode(); if (!negated && !ProbingEnabled && input == null) { SetLastAlgebraNode(filterAlgebraNode); return(LiteralExpression.FromBoolean(true)); } else { if (input == null) { input = CreateConstantScan(); } RowBufferEntry probeColumn = CreateProbeColumn(); JoinAlgebraNode joinAlgebraNode = new JoinAlgebraNode(); joinAlgebraNode.PassthruPredicate = CurrentPassthruPredicate; joinAlgebraNode.ProbeBufferEntry = probeColumn; joinAlgebraNode.Left = input; joinAlgebraNode.Right = filterAlgebraNode; joinAlgebraNode.Op = negated ? JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin : JoinAlgebraNode.JoinOperator.LeftSemiJoin; SetLastAlgebraNode(joinAlgebraNode); return(CreateProbeColumnRef(probeColumn)); } }
public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node) { node.Left = VisitAlgebraNode(node.Left); node.Right = VisitAlgebraNode(node.Right); if (node.Predicate != null && (node.OuterReferences == null || node.OuterReferences.Length == 0) && ( node.Op == JoinAlgebraNode.JoinOperator.InnerJoin || node.Op == JoinAlgebraNode.JoinOperator.LeftOuterJoin || node.Op == JoinAlgebraNode.JoinOperator.RightOuterJoin || node.Op == JoinAlgebraNode.JoinOperator.FullOuterJoin) ) { RowBufferEntry[] leftDefinedEntries = AstUtil.GetDefinedValueEntries(node.Left); RowBufferEntry[] rightDefinedEntries = AstUtil.GetDefinedValueEntries(node.Right); EqualPredicatesExtractor equalPredicatesExtractor = new EqualPredicatesExtractor(leftDefinedEntries, rightDefinedEntries); ExpressionNode probeResidual = equalPredicatesExtractor.VisitExpression(node.Predicate); BinaryExpression[] equalPredicates = equalPredicatesExtractor.GetEqualPredicates(); if (equalPredicates.Length > 0) { BinaryExpression equalPredicate = equalPredicates[0]; ExpressionBuilder expressionBuilder = new ExpressionBuilder(); expressionBuilder.Push(probeResidual); if (equalPredicates.Length > 1) { for (int i = 1; i < equalPredicates.Length; i++) expressionBuilder.Push(equalPredicates[i]); expressionBuilder.PushNAry(LogicalOperator.And); } probeResidual = expressionBuilder.Pop(); if (probeResidual is ConstantExpression) probeResidual = null; AlgebraNode leftInput = node.Left; AlgebraNode rightInput = node.Right; if (node.Op == JoinAlgebraNode.JoinOperator.LeftOuterJoin) { node.Op = JoinAlgebraNode.JoinOperator.RightOuterJoin; leftInput = node.Right; rightInput = node.Left; ExpressionNode oldLeft = equalPredicate.Left; equalPredicate.Left = equalPredicate.Right; equalPredicate.Right = oldLeft; } RowBufferEntry leftEntry; RowBufferEntryExpression leftAsRowBufferEntryExpression = equalPredicate.Left as RowBufferEntryExpression; if (leftAsRowBufferEntryExpression != null) { leftEntry = leftAsRowBufferEntryExpression.RowBufferEntry; } else { leftEntry = new RowBufferEntry(equalPredicate.Left.ExpressionType); ComputedValueDefinition definedValue = new ComputedValueDefinition(); definedValue.Target = leftEntry; definedValue.Expression = equalPredicate.Left; ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode(); computeScalarAlgebraNode.Input = leftInput; computeScalarAlgebraNode.DefinedValues = new ComputedValueDefinition[] {definedValue}; leftInput = computeScalarAlgebraNode; } RowBufferEntry rightEntry; RowBufferEntryExpression rightAsRowBufferEntryExpression = equalPredicate.Right as RowBufferEntryExpression; if (rightAsRowBufferEntryExpression != null) { rightEntry = rightAsRowBufferEntryExpression.RowBufferEntry; } else { rightEntry = new RowBufferEntry(equalPredicate.Right.ExpressionType); ComputedValueDefinition definedValue = new ComputedValueDefinition(); definedValue.Target = rightEntry; definedValue.Expression = equalPredicate.Right; ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode(); computeScalarAlgebraNode.Input = rightInput; computeScalarAlgebraNode.DefinedValues = new ComputedValueDefinition[] {definedValue}; rightInput = computeScalarAlgebraNode; } HashMatchAlgebraNode hashMatchAlgebraNode = new HashMatchAlgebraNode(); hashMatchAlgebraNode.Op = node.Op; hashMatchAlgebraNode.Left = leftInput; hashMatchAlgebraNode.Right = rightInput; hashMatchAlgebraNode.BuildKeyEntry = leftEntry; hashMatchAlgebraNode.ProbeEntry = rightEntry; hashMatchAlgebraNode.ProbeResidual = probeResidual; return hashMatchAlgebraNode; } } return node; }
public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node) { node.Left = VisitAlgebraNode(node.Left); node.Right = VisitAlgebraNode(node.Right); if (node.Predicate != null && (node.OuterReferences == null || node.OuterReferences.Length == 0) && ( node.Op == JoinAlgebraNode.JoinOperator.InnerJoin || node.Op == JoinAlgebraNode.JoinOperator.LeftOuterJoin || node.Op == JoinAlgebraNode.JoinOperator.RightOuterJoin || node.Op == JoinAlgebraNode.JoinOperator.FullOuterJoin) ) { RowBufferEntry[] leftDefinedEntries = AstUtil.GetDefinedValueEntries(node.Left); RowBufferEntry[] rightDefinedEntries = AstUtil.GetDefinedValueEntries(node.Right); EqualPredicatesExtractor equalPredicatesExtractor = new EqualPredicatesExtractor(leftDefinedEntries, rightDefinedEntries); ExpressionNode probeResidual = equalPredicatesExtractor.VisitExpression(node.Predicate); BinaryExpression[] equalPredicates = equalPredicatesExtractor.GetEqualPredicates(); if (equalPredicates.Length > 0) { BinaryExpression equalPredicate = equalPredicates[0]; ExpressionBuilder expressionBuilder = new ExpressionBuilder(); expressionBuilder.Push(probeResidual); if (equalPredicates.Length > 1) { for (int i = 1; i < equalPredicates.Length; i++) { expressionBuilder.Push(equalPredicates[i]); } expressionBuilder.PushNAry(LogicalOperator.And); } probeResidual = expressionBuilder.Pop(); if (probeResidual is ConstantExpression) { probeResidual = null; } AlgebraNode leftInput = node.Left; AlgebraNode rightInput = node.Right; if (node.Op == JoinAlgebraNode.JoinOperator.LeftOuterJoin) { node.Op = JoinAlgebraNode.JoinOperator.RightOuterJoin; leftInput = node.Right; rightInput = node.Left; ExpressionNode oldLeft = equalPredicate.Left; equalPredicate.Left = equalPredicate.Right; equalPredicate.Right = oldLeft; } RowBufferEntry leftEntry; RowBufferEntryExpression leftAsRowBufferEntryExpression = equalPredicate.Left as RowBufferEntryExpression; if (leftAsRowBufferEntryExpression != null) { leftEntry = leftAsRowBufferEntryExpression.RowBufferEntry; } else { leftEntry = new RowBufferEntry(equalPredicate.Left.ExpressionType); ComputedValueDefinition definedValue = new ComputedValueDefinition(); definedValue.Target = leftEntry; definedValue.Expression = equalPredicate.Left; ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode(); computeScalarAlgebraNode.Input = leftInput; computeScalarAlgebraNode.DefinedValues = new ComputedValueDefinition[] { definedValue }; leftInput = computeScalarAlgebraNode; } RowBufferEntry rightEntry; RowBufferEntryExpression rightAsRowBufferEntryExpression = equalPredicate.Right as RowBufferEntryExpression; if (rightAsRowBufferEntryExpression != null) { rightEntry = rightAsRowBufferEntryExpression.RowBufferEntry; } else { rightEntry = new RowBufferEntry(equalPredicate.Right.ExpressionType); ComputedValueDefinition definedValue = new ComputedValueDefinition(); definedValue.Target = rightEntry; definedValue.Expression = equalPredicate.Right; ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode(); computeScalarAlgebraNode.Input = rightInput; computeScalarAlgebraNode.DefinedValues = new ComputedValueDefinition[] { definedValue }; rightInput = computeScalarAlgebraNode; } HashMatchAlgebraNode hashMatchAlgebraNode = new HashMatchAlgebraNode(); hashMatchAlgebraNode.Op = node.Op; hashMatchAlgebraNode.Left = leftInput; hashMatchAlgebraNode.Right = rightInput; hashMatchAlgebraNode.BuildKeyEntry = leftEntry; hashMatchAlgebraNode.ProbeEntry = rightEntry; hashMatchAlgebraNode.ProbeResidual = probeResidual; return(hashMatchAlgebraNode); } } 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; }