public override ExpressionNode VisitBinaryExpression(BinaryExpression expression) { if (expression.Op == BinaryOperator.LogicalAnd) { return(base.VisitBinaryExpression(expression)); } else if (expression.Op == BinaryOperator.Equal) { RowBufferEntry[] leftRowBufferEntries = AstUtil.GetRowBufferEntryReferences(expression.Left); RowBufferEntry[] rightRowBufferEntries = AstUtil.GetRowBufferEntryReferences(expression.Right); if (leftRowBufferEntries.Length == 1 && rightRowBufferEntries.Length == 1) { RowBufferEntry leftRowBufferEntry = leftRowBufferEntries[0]; RowBufferEntry rightRowBufferEntry = rightRowBufferEntries[0]; bool leftIsOuter = IsOuterReference(leftRowBufferEntry); bool rightIsOuter = IsOuterReference(rightRowBufferEntry); if (leftRowBufferEntry != rightRowBufferEntry && leftIsOuter ^ rightIsOuter) { // Both expressions depend on extactly one row buffer entry but // they are not refering to the same row buffer entry and // only one is an outer reference. SpoolExpression spoolExpression = new SpoolExpression(); if (leftIsOuter) { spoolExpression.IndexExpression = expression.Right; spoolExpression.ProbeExpression = expression.Left; } else { spoolExpression.IndexExpression = expression.Left; spoolExpression.ProbeExpression = expression.Right; } _spoolExpressions.Add(spoolExpression); return(LiteralExpression.FromBoolean(true)); } } } return(expression); }
public override AlgebraNode VisitFilterAlgebraNode(FilterAlgebraNode node) { node.Input = VisitAlgebraNode(node.Input); ExpressionNode originalPredicate = (ExpressionNode)node.Predicate.Clone(); SpoolExpressionExtractor spoolExpressionExtractor = new SpoolExpressionExtractor(_outerReferences); // HACK: This hack ensures that TRUE literals introduced by SpoolExpressionExtractor are removed. node.Predicate = AstUtil.CombineConditions(LogicalOperator.And, spoolExpressionExtractor.VisitExpression(node.Predicate)); SpoolExpression[] spoolExpressions = spoolExpressionExtractor.GetSpoolExpressions(); // Now we must check that the remaining filter incl. input to the filter don't reference any other // outer reference. bool remainingFilterHasDependenciesToOuterReferences = CheckIfNodeHasDependenciesToOuterReferences(node); if (remainingFilterHasDependenciesToOuterReferences) { // OK; we cannot insert a spool operation here. Undo the expression replacement. node.Predicate = originalPredicate; } else if (spoolExpressions.Length > 0) { SpoolExpression spoolExpression = spoolExpressions[0]; AlgebraNode currentInput; if (node.Predicate is ConstantExpression) { currentInput = node.Input; } else { currentInput = node; } RowBufferEntry indexEntry; RowBufferEntryExpression indexExpressionAsRowBufferEntryExpression = spoolExpression.IndexExpression as RowBufferEntryExpression; if (indexExpressionAsRowBufferEntryExpression != null) { indexEntry = indexExpressionAsRowBufferEntryExpression.RowBufferEntry; } else { indexEntry = new RowBufferEntry(spoolExpression.IndexExpression.ExpressionType); ComputedValueDefinition definedValue = new ComputedValueDefinition(); definedValue.Target = indexEntry; definedValue.Expression = spoolExpression.IndexExpression; ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode(); computeScalarAlgebraNode.Input = currentInput; computeScalarAlgebraNode.DefinedValues = new ComputedValueDefinition[] { definedValue }; currentInput = computeScalarAlgebraNode; } IndexSpoolAlgebraNode indexSpoolAlgebraNode = new IndexSpoolAlgebraNode(); indexSpoolAlgebraNode.Input = currentInput; indexSpoolAlgebraNode.IndexEntry = indexEntry; indexSpoolAlgebraNode.ProbeExpression = spoolExpression.ProbeExpression; return(indexSpoolAlgebraNode); } return(node); }
public override ExpressionNode VisitBinaryExpression(BinaryExpression expression) { if (expression.Op == BinaryOperator.LogicalAnd) { return base.VisitBinaryExpression(expression); } else if (expression.Op == BinaryOperator.Equal) { RowBufferEntry[] leftRowBufferEntries = AstUtil.GetRowBufferEntryReferences(expression.Left); RowBufferEntry[] rightRowBufferEntries = AstUtil.GetRowBufferEntryReferences(expression.Right); if (leftRowBufferEntries.Length == 1 && rightRowBufferEntries.Length == 1) { RowBufferEntry leftRowBufferEntry = leftRowBufferEntries[0]; RowBufferEntry rightRowBufferEntry = rightRowBufferEntries[0]; bool leftIsOuter = IsOuterReference(leftRowBufferEntry); bool rightIsOuter = IsOuterReference(rightRowBufferEntry); if (leftRowBufferEntry != rightRowBufferEntry && leftIsOuter ^ rightIsOuter) { // Both expressions depend on extactly one row buffer entry but // they are not refering to the same row buffer entry and // only one is an outer reference. SpoolExpression spoolExpression = new SpoolExpression(); if (leftIsOuter) { spoolExpression.IndexExpression = expression.Right; spoolExpression.ProbeExpression = expression.Left; } else { spoolExpression.IndexExpression = expression.Left; spoolExpression.ProbeExpression = expression.Right; } _spoolExpressions.Add(spoolExpression); return LiteralExpression.FromBoolean(true); } } } return expression; }