private void AddNullRejectedTable(RowBufferEntry rowBufferEntries) { if (!_nullRejectedRowBufferEntries.Contains(rowBufferEntries)) { _nullRejectedRowBufferEntries.Add(rowBufferEntries); } }
public void Add(AggregateExpression aggregateExpression) { AggregateExpression matchingAggregateExpression = null; foreach (AggregateExpression existingAggregateExpression in _aggregateExpressions) { if (existingAggregateExpression.IsStructuralEqualTo(aggregateExpression)) { matchingAggregateExpression = existingAggregateExpression; break; } } if (matchingAggregateExpression != null) { aggregateExpression.ValueDefinition = matchingAggregateExpression.ValueDefinition; } else { RowBufferEntry rowBufferEntry = new RowBufferEntry(aggregateExpression.Aggregator.ReturnType); AggregatedValueDefinition aggregatedValueDefinition = new AggregatedValueDefinition(); aggregatedValueDefinition.Target = rowBufferEntry; aggregatedValueDefinition.Aggregate = aggregateExpression.Aggregate; aggregatedValueDefinition.Aggregator = aggregateExpression.Aggregator; aggregatedValueDefinition.Argument = aggregateExpression.Argument; aggregateExpression.ValueDefinition = aggregatedValueDefinition; _aggregateExpressions.Add(aggregateExpression); } }
private static void CreateBufferedValue(ExpressionNode expression, ICollection <ComputedValueDefinition> computedColumnList, ICollection <RowBufferEntry> columnList, IEnumerable <ComputedValueDefinition> alreadyComputedBufferedValues) { if (alreadyComputedBufferedValues != null) { expression = ReplaceAlreadyComputedSubsequences(expression, alreadyComputedBufferedValues); } foreach (ComputedValueDefinition computedBufferedValue in computedColumnList) { if (expression.IsStructuralEqualTo(computedBufferedValue.Expression)) { columnList.Add(computedBufferedValue.Target); return; } } RowBufferEntryExpression rowBufferExpression = expression as RowBufferEntryExpression; if (rowBufferExpression != null) { columnList.Add(rowBufferExpression.RowBufferEntry); } else { RowBufferEntry rowBufferEntry = new RowBufferEntry(expression.ExpressionType); columnList.Add(rowBufferEntry); ComputedValueDefinition computedValue = new ComputedValueDefinition(); computedValue.Target = rowBufferEntry; computedValue.Expression = expression; computedColumnList.Add(computedValue); } }
private void CreateColumnRefs() { List<ColumnRefBinding> tableColumnRefs = new List<ColumnRefBinding>(); if (!(_definition is DerivedTableBinding) && !(_definition is CommonTableBinding)) { // Create special row column ref ColumnRefBinding rowColumnRefBinding = CreateRowColumnRefBinding(this); tableColumnRefs.Add(rowColumnRefBinding); } // Create all column refs. foreach (ColumnBinding columnDefinition in _definition.Columns) { ColumnRefBinding columnRefBinding = new ColumnRefBinding(this, columnDefinition); RowBufferEntry rowBufferEntry = new RowBufferEntry(columnRefBinding.ColumnBinding.DataType); rowBufferEntry.Name = columnRefBinding.GetFullName(); ColumnValueDefinition columnValueDefinition = new ColumnValueDefinition(); columnValueDefinition.Target = rowBufferEntry; columnValueDefinition.ColumnRefBinding = columnRefBinding; columnRefBinding.ValueDefinition = columnValueDefinition; tableColumnRefs.Add(columnRefBinding); } // Assign column refs to table ref. _columnRefs = tableColumnRefs.ToArray(); }
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 QueryNode VisitSortedQuery(SortedQuery query) { ResultAlgebraNode input = (ResultAlgebraNode)ConvertAstNode(query.Input); List <RowBufferEntry> sortColumns = new List <RowBufferEntry>(); List <SortOrder> sortOrders = new List <SortOrder>(); foreach (OrderByColumn orderByColumn in query.OrderByColumns) { RowBufferEntry sortColumn = input.OutputList[orderByColumn.ColumnIndex]; sortColumns.Add(sortColumn); sortOrders.Add(orderByColumn.SortOrder); } SortAlgebraNode sortAlgebraNode = new SortAlgebraNode(); sortAlgebraNode.Input = input.Input; sortAlgebraNode.SortEntries = sortColumns.ToArray(); sortAlgebraNode.SortOrders = sortOrders.ToArray(); input.Input = sortAlgebraNode; SetLastAlgebraNode(input); return(query); }
public override TableReference VisitDerivedTableReference(DerivedTableReference node) { AlgebraNode algebrizedQuery = Convert(node.Query); List <ComputedValueDefinition> definedValues = new List <ComputedValueDefinition>(); for (int i = 0; i < node.DerivedTableBinding.ColumnRefs.Length; i++) { RowBufferEntry targetRowBufferEntry = node.DerivedTableBinding.ColumnRefs[i].ValueDefinition.Target; RowBufferEntry sourceRowBufferEntry = algebrizedQuery.OutputList[i]; ComputedValueDefinition definedValue = new ComputedValueDefinition(); definedValue.Target = targetRowBufferEntry; definedValue.Expression = new RowBufferEntryExpression(sourceRowBufferEntry); definedValues.Add(definedValue); } ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode(); computeScalarAlgebraNode.Input = algebrizedQuery; computeScalarAlgebraNode.DefinedValues = definedValues.ToArray(); SetLastAlgebraNode(computeScalarAlgebraNode); 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); }
private void AddNeededRowBufferEntry(RowBufferEntry rowBufferEntry) { if (!IsNeeded(rowBufferEntry)) { _neededRowBufferColumns.Add(rowBufferEntry); } }
private RowBufferEntry ReplaceRowBuffer(RowBufferEntry oldRowBufferEntry) { RowBufferEntry newRowBufferEntry; if (_rowBufferMappings.TryGetValue(oldRowBufferEntry, out newRowBufferEntry)) { return(newRowBufferEntry); } return(oldRowBufferEntry); }
private static bool AndPartHasOuterReference(ExpressionNode andPart, RowBufferEntry[] definedValues) { RowBufferEntry[] rowBufferEntries = AstUtil.GetRowBufferEntryReferences(andPart); foreach (RowBufferEntry rowBufferEntry in rowBufferEntries) { if (!ArrayHelpers.Contains(definedValues, rowBufferEntry)) return true; } return false; }
private RowBufferEntry CreateProbeColumn() { if (!ProbingEnabled) { return(null); } RowBufferEntry probeColumn = new RowBufferEntry(typeof(bool)); return(probeColumn); }
private RowBufferEntry ReplaceRowBufferEntry(RowBufferEntry rowBufferEntry) { RowBufferEntry replacementEntry; if (_inliningDictionary.TryGetValue(rowBufferEntry, out replacementEntry)) { return(replacementEntry); } return(rowBufferEntry); }
private ExpressionNode CreateProbeColumnRef(RowBufferEntry probeColumn) { if (!ProbingEnabled) { return(LiteralExpression.FromBoolean(true)); } RowBufferEntryExpression probeColumnRef = new RowBufferEntryExpression(probeColumn); return(probeColumnRef); }
private void NameEntry(RowBufferEntry target, string formatString) { if (!_rowBufferEntries.Contains(target)) { if (target.Name == null) { target.Name = String.Format(CultureInfo.InvariantCulture, formatString, 1000 + _rowBufferEntries.Count); } _rowBufferEntries.Add(target); } }
private bool IsOuterReference(RowBufferEntry entry) { foreach (RowBufferEntry[] outerReferences in _outerReferences) { if (ArrayHelpers.Contains(outerReferences, entry)) { return(true); } } return(false); }
private static ColumnRefBinding CreateRowColumnRefBinding(TableRefBinding tableRefBinding) { RowColumnBinding rowColumnBinding = new RowColumnBinding(tableRefBinding.TableBinding); ColumnRefBinding rowColumnRefBinding = new ColumnRefBinding(tableRefBinding, rowColumnBinding); RowBufferEntry rowColumnBufferEntry = new RowBufferEntry(rowColumnRefBinding.ColumnBinding.DataType); rowColumnBufferEntry.Name = rowColumnRefBinding.TableRefBinding.Name; ColumnValueDefinition rowColumnValueDefinition = new ColumnValueDefinition(); rowColumnValueDefinition.Target = rowColumnBufferEntry; rowColumnValueDefinition.ColumnRefBinding = rowColumnRefBinding; rowColumnRefBinding.ValueDefinition = rowColumnValueDefinition; return rowColumnRefBinding; }
private static void WriteRowBufferEntry(PropertyListBuilder builder, RowBufferEntry rowBufferColumn) { string[] parts = rowBufferColumn.Name.Split('.'); if (parts.Length != 2) { builder.Write(Resources.ShowPlanKeyColumn, rowBufferColumn.Name); } else { builder.Write(Resources.ShowPlanKeyTable, parts[0]); builder.Write(Resources.ShowPlanKeyColumn, parts[1]); } builder.Write(Resources.ShowPlanKeyDataType, rowBufferColumn.DataType.Name); }
private static bool SemiJoinDoesNotDependOn(JoinAlgebraNode.JoinOperator op, ExpressionNode part, RowBufferEntry[] leftDefinedValues, RowBufferEntry[] rightDefinedValues) { if (op == JoinAlgebraNode.JoinOperator.LeftSemiJoin || op == JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin) { return AstUtil.ExpressionDoesNotReference(part, rightDefinedValues); } if (op == JoinAlgebraNode.JoinOperator.RightSemiJoin || op == JoinAlgebraNode.JoinOperator.RightAntiSemiJoin) { return AstUtil.ExpressionDoesNotReference(part, leftDefinedValues); } return true; }
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]; if (leftRowBufferEntry != rightRowBufferEntry) { // Both expressions depend on extactly one row buffer entry but // they are not refering to the same row buffer entry. bool leftDependsOnLeft = ArrayHelpers.Contains(_leftDefinedEntries, leftRowBufferEntry); bool rightDependsOnRight = ArrayHelpers.Contains(_rightDefinedEntries, rightRowBufferEntry); bool leftDependsOnRight = ArrayHelpers.Contains(_rightDefinedEntries, leftRowBufferEntry); bool rightDependsOnLeft = ArrayHelpers.Contains(_leftDefinedEntries, rightRowBufferEntry); if (leftDependsOnRight && rightDependsOnLeft) { ExpressionNode oldLeft = expression.Left; expression.Left = expression.Right; expression.Right = oldLeft; leftDependsOnLeft = true; rightDependsOnRight = true; } if (leftDependsOnLeft && rightDependsOnRight) { _equalPredicates.Add(expression); return(LiteralExpression.FromBoolean(true)); } } } } return(expression); }
private static AlgebraNode InstantiateCte(AlgebraNode algebrizedCte, CommonTableBinding commonTableBinding, TableRefBinding commonTableRefBinding) { // Replace row buffers to base tables by new ones. This must be done because a CTE could be referenced multiple times. // Since same row buffer entries means that the underlying data will be stored in the same physical data slot this // will lead to problems if, for example, two instances of the same CTE are joined together. Any join condition that // operates on the same column will always compare data coming from the same join side (and therefor will always // evaluate to true). // // Some notes on the implementation: // // 1. Note that just replacing references to row buffers of base tables in RowBufferExpression is not enough; // instead they must also be replaced in output lists, defined value references (esp. ConcatAlgebraNode) etc. // 2. Also note that although the QueryNodes are re-algebrized every time a CTE is references the expressions // are still copied from the QueryNodes (instead of cloned). Therefore two algrebrized CTEs will share the same // expression AST instances. That means that replacing the row buffers leads to failure. // HACK: This is a workaround for issue 2. However, // I am not quite sure how one should implement row buffer entry replacement without cloning the algebrized query. algebrizedCte = (AlgebraNode)algebrizedCte.Clone(); CteTableDefinedValuesReinitializer cteTableDefinedValuesReinitializer = new CteTableDefinedValuesReinitializer(); cteTableDefinedValuesReinitializer.Visit(algebrizedCte); RowBufferEntry[] outputList = algebrizedCte.OutputList; int skipRecursionLevel = commonTableBinding.IsRecursive ? 1 : 0; // Rename the query columns to the CTE columns List <ComputedValueDefinition> definedValues = new List <ComputedValueDefinition>(); for (int i = 0; i < commonTableRefBinding.ColumnRefs.Length; i++) { RowBufferEntry targetRowBufferEntry = commonTableRefBinding.ColumnRefs[i].ValueDefinition.Target; RowBufferEntry sourceRowBufferEntry = outputList[i + skipRecursionLevel]; ComputedValueDefinition definedValue = new ComputedValueDefinition(); definedValue.Target = targetRowBufferEntry; definedValue.Expression = new RowBufferEntryExpression(sourceRowBufferEntry); definedValues.Add(definedValue); } ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode(); computeScalarAlgebraNode.Input = algebrizedCte; computeScalarAlgebraNode.DefinedValues = definedValues.ToArray(); return(computeScalarAlgebraNode); }
public override ExpressionNode VisitExistsSubselect(ExistsSubselect expression) { AlgebraNode input = GetAndResetLastNode(); ResultAlgebraNode algebrizedQuery = Algebrizer.Convert(expression.Query); if (!expression.Negated && AstUtil.WillProduceAtLeastOneRow(algebrizedQuery)) { if (input == null) { SetLastAlgebraNode(CreateConstantScan()); } else { SetLastAlgebraNode(input); } return(LiteralExpression.FromBoolean(true)); } if (!expression.Negated && !ProbingEnabled && input == null) { SetLastAlgebraNode(algebrizedQuery); 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 = algebrizedQuery; joinAlgebraNode.Op = expression.Negated ? JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin : JoinAlgebraNode.JoinOperator.LeftSemiJoin; SetLastAlgebraNode(joinAlgebraNode); return(CreateProbeColumnRef(probeColumn)); } }
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 VisitTableAlgebraNode(TableAlgebraNode node) { TableRefBinding oldTableRefBinding = node.TableRefBinding; TableRefBinding newTableRefBinding = new TableRefBinding(oldTableRefBinding.Scope, oldTableRefBinding.TableBinding, oldTableRefBinding.Name); List <ColumnValueDefinition> definedValues = new List <ColumnValueDefinition>(); for (int i = 0; i < newTableRefBinding.ColumnRefs.Length; i++) { definedValues.Add(newTableRefBinding.ColumnRefs[i].ValueDefinition); RowBufferEntry oldRowBufferEntry = oldTableRefBinding.ColumnRefs[i].ValueDefinition.Target; RowBufferEntry newRowBufferEntry = newTableRefBinding.ColumnRefs[i].ValueDefinition.Target; _rowBufferMappings.Add(oldRowBufferEntry, newRowBufferEntry); } node.TableRefBinding = newTableRefBinding; node.DefinedValues = definedValues.ToArray(); return(node); }
private IComparer[] GetComparersFromExpressionTypes(RowBufferEntry[] rowBufferEntries) { IComparer[] result = new IComparer[rowBufferEntries.Length]; for (int i = 0; i < result.Length; i++) { IComparer customComparer = _metadataContext.Comparers[rowBufferEntries[i].DataType]; if (customComparer != null) result[i] = customComparer; else result[i] = Comparer.Default; } return result; }
private static RuntimeValueOutput GetDefinedValue(RowBufferEntry[] outputList, RowBufferEntry rowBufferEntry) { RuntimeValueOutput result = new RuntimeValueOutput(); result.TargetIndex = Array.IndexOf(outputList, rowBufferEntry); return result; }
private static IteratorInput[] GetIteratorInput(RowBufferEntry[] allEntries, RowBufferEntry[] neededEntries) { IteratorInput[] result = new IteratorInput[neededEntries.Length]; for (int i = 0; i < neededEntries.Length; i++) { result[i] = new IteratorInput(); result[i].SourceIndex = Array.IndexOf(allEntries, neededEntries[i]); } return result; }
public EqualPredicatesExtractor(RowBufferEntry[] leftDefinedEntries, RowBufferEntry[] rightDefinedEntries) { _leftDefinedEntries = leftDefinedEntries; _rightDefinedEntries = rightDefinedEntries; }
private static NullScanAlgebraNode CreateNullScan(RowBufferEntry[] outputList) { NullScanAlgebraNode result = new NullScanAlgebraNode(); result.OutputList = outputList; return result; }
private RowBufferEntry CreateProbeColumn() { if (!ProbingEnabled) return null; RowBufferEntry probeColumn = new RowBufferEntry(typeof(bool)); return probeColumn; }
private void AddNullRejectedTable(RowBufferEntry rowBufferEntries) { if (!_nullRejectedRowBufferEntries.Contains(rowBufferEntries)) _nullRejectedRowBufferEntries.Add(rowBufferEntries); }
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 BoundRowBufferEntrySet(object[] rowBuffer, RowBufferEntry[] entries) { RowBuffer = rowBuffer; Entries = entries; }
public CteColumnMappingFinder(CommonTableBinding commonTableBinding, RowBufferEntry[] spoolBufferEntries) { _commonTableBinding = commonTableBinding; _spoolBufferEntries = spoolBufferEntries; }
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 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 static bool DoesNotReference(RowBufferEntry[] rowBufferEntryReferences, RowBufferEntry[] rowBufferEntries) { foreach (RowBufferEntry rowBufferColumnDependency in rowBufferEntryReferences) { if (ArrayHelpers.Contains(rowBufferEntries, rowBufferColumnDependency)) return false; } return true; }
public static bool ExpressionDoesNotReference(ExpressionNode expression, RowBufferEntry[] rowBufferEntries) { RowBufferEntry[] rowBufferEntryReferences = GetRowBufferEntryReferences(expression); return DoesNotReference(rowBufferEntryReferences, rowBufferEntries); }
public static bool ExpressionYieldsNullOrFalseIfRowBufferEntryNull(ExpressionNode expressionNode, RowBufferEntry rowBufferEntry) { NullRejectionChecker checker = new NullRejectionChecker(rowBufferEntry); checker.Visit(expressionNode); if (checker.ExpressionRejectsNull) return true; return false; }
public NullRejectionChecker(RowBufferEntry rowBufferEntry) { _rowBufferEntry = rowBufferEntry; }
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 ResultAlgebraNode CreateAssertedSubquery(ResultAlgebraNode inputNode) { if (AstUtil.WillProduceAtMostOneRow(inputNode)) { return(inputNode); } RowBufferEntry inputEntry = inputNode.OutputList[0]; AggregatedValueDefinition countDefinedValue = new AggregatedValueDefinition(); countDefinedValue.Aggregate = new CountAggregateBinding("COUNT"); countDefinedValue.Aggregator = countDefinedValue.Aggregate.CreateAggregator(typeof(int)); countDefinedValue.Argument = LiteralExpression.FromInt32(0); RowBufferEntry countDefinedValueEntry = new RowBufferEntry(countDefinedValue.Aggregator.ReturnType); countDefinedValue.Target = countDefinedValueEntry; RowBufferEntryExpression anyAggregateArgument = new RowBufferEntryExpression(); anyAggregateArgument.RowBufferEntry = inputEntry; AggregatedValueDefinition anyDefinedValue = new AggregatedValueDefinition(); anyDefinedValue.Aggregate = new FirstAggregateBinding("ANY"); anyDefinedValue.Aggregator = anyDefinedValue.Aggregate.CreateAggregator(inputEntry.DataType); anyDefinedValue.Argument = anyAggregateArgument; RowBufferEntry anyDefinedValueEntry = new RowBufferEntry(inputEntry.DataType); anyDefinedValue.Target = anyDefinedValueEntry; AggregateAlgebraNode aggregateAlgebraNode = new AggregateAlgebraNode(); aggregateAlgebraNode.Input = inputNode.Input; aggregateAlgebraNode.DefinedValues = new AggregatedValueDefinition[] { countDefinedValue, anyDefinedValue }; // CASE WHEN SubqueryCount > 1 THEN 0 ELSE NULL END ExpressionBuilder expressionBuilder = new ExpressionBuilder(); expressionBuilder.Push(new RowBufferEntryExpression(countDefinedValueEntry)); expressionBuilder.Push(LiteralExpression.FromInt32(1)); expressionBuilder.PushBinary(BinaryOperator.Greater); ExpressionNode whenExpression = expressionBuilder.Pop(); ExpressionNode thenExpression = LiteralExpression.FromInt32(0); CaseExpression caseExpression = new CaseExpression(); caseExpression.WhenExpressions = new ExpressionNode[] { whenExpression }; caseExpression.ThenExpressions = new ExpressionNode[] { thenExpression }; expressionBuilder.Push(caseExpression); ExpressionNode predicate = expressionBuilder.Pop(); AssertAlgebraNode assertAlgebraNode = new AssertAlgebraNode(); assertAlgebraNode.Input = aggregateAlgebraNode; assertAlgebraNode.Predicate = predicate; assertAlgebraNode.AssertionType = AssertionType.MaxOneRow; ResultAlgebraNode resultAlgebraNode = new ResultAlgebraNode(); resultAlgebraNode.Input = assertAlgebraNode; resultAlgebraNode.OutputList = new RowBufferEntry[] { anyDefinedValueEntry }; resultAlgebraNode.ColumnNames = inputNode.ColumnNames; return(resultAlgebraNode); }
public RowBufferEntryExpression(RowBufferEntry rowBufferEntry) { _rowBufferEntry = rowBufferEntry; }
private static ResultAlgebraNode CreateAssertedSubquery(ResultAlgebraNode inputNode) { if (AstUtil.WillProduceAtMostOneRow(inputNode)) return inputNode; RowBufferEntry inputEntry = inputNode.OutputList[0]; AggregatedValueDefinition countDefinedValue = new AggregatedValueDefinition(); countDefinedValue.Aggregate = new CountAggregateBinding("COUNT"); countDefinedValue.Aggregator = countDefinedValue.Aggregate.CreateAggregator(typeof(int)); countDefinedValue.Argument = LiteralExpression.FromInt32(0); RowBufferEntry countDefinedValueEntry = new RowBufferEntry(countDefinedValue.Aggregator.ReturnType); countDefinedValue.Target = countDefinedValueEntry; RowBufferEntryExpression anyAggregateArgument = new RowBufferEntryExpression(); anyAggregateArgument.RowBufferEntry = inputEntry; AggregatedValueDefinition anyDefinedValue = new AggregatedValueDefinition(); anyDefinedValue.Aggregate = new FirstAggregateBinding("ANY"); anyDefinedValue.Aggregator = anyDefinedValue.Aggregate.CreateAggregator(inputEntry.DataType); anyDefinedValue.Argument = anyAggregateArgument; RowBufferEntry anyDefinedValueEntry = new RowBufferEntry(inputEntry.DataType); anyDefinedValue.Target = anyDefinedValueEntry; AggregateAlgebraNode aggregateAlgebraNode = new AggregateAlgebraNode(); aggregateAlgebraNode.Input = inputNode.Input; aggregateAlgebraNode.DefinedValues = new AggregatedValueDefinition[] { countDefinedValue, anyDefinedValue }; // CASE WHEN SubqueryCount > 1 THEN 0 ELSE NULL END ExpressionBuilder expressionBuilder = new ExpressionBuilder(); expressionBuilder.Push(new RowBufferEntryExpression(countDefinedValueEntry)); expressionBuilder.Push(LiteralExpression.FromInt32(1)); expressionBuilder.PushBinary(BinaryOperator.Greater); ExpressionNode whenExpression = expressionBuilder.Pop(); ExpressionNode thenExpression = LiteralExpression.FromInt32(0); CaseExpression caseExpression = new CaseExpression(); caseExpression.WhenExpressions = new ExpressionNode[] { whenExpression }; caseExpression.ThenExpressions = new ExpressionNode[] { thenExpression }; expressionBuilder.Push(caseExpression); ExpressionNode predicate = expressionBuilder.Pop(); AssertAlgebraNode assertAlgebraNode = new AssertAlgebraNode(); assertAlgebraNode.Input = aggregateAlgebraNode; assertAlgebraNode.Predicate = predicate; assertAlgebraNode.AssertionType = AssertionType.MaxOneRow; ResultAlgebraNode resultAlgebraNode = new ResultAlgebraNode(); resultAlgebraNode.Input = assertAlgebraNode; resultAlgebraNode.OutputList = new RowBufferEntry[] { anyDefinedValueEntry }; resultAlgebraNode.ColumnNames = inputNode.ColumnNames; return resultAlgebraNode; }
private bool IsNeeded(RowBufferEntry rowBufferColumn) { return(_neededRowBufferColumns.Contains(rowBufferColumn)); }
private ExpressionNode CreateProbeColumnRef(RowBufferEntry probeColumn) { if (!ProbingEnabled) return LiteralExpression.FromBoolean(true); RowBufferEntryExpression probeColumnRef = new RowBufferEntryExpression(probeColumn); return probeColumnRef; }
private void ReplaceRowBufferEntries(RowBufferEntry[] rowBufferEntries) { for (int i = 0; i < rowBufferEntries.Length; i++) rowBufferEntries[i] = ReplaceRowBufferEntry(rowBufferEntries[i]); }
private static void WriteRowBufferEntry(PropertyListBuilder builder, string groupName, RowBufferEntry rowBufferColumn) { builder.Begin(groupName); builder.SetGroupValue(rowBufferColumn.Name); WriteRowBufferEntry(builder, rowBufferColumn); builder.End(); }
private RowBufferEntry ReplaceRowBufferEntry(RowBufferEntry rowBufferEntry) { RowBufferEntry replacementEntry; if (_inliningDictionary.TryGetValue(rowBufferEntry, out replacementEntry)) return replacementEntry; return rowBufferEntry; }
private static IteratorOutput[] GetIteratorOutput(int offset, RowBufferEntry[] allEntries, RowBufferEntry[] neededEntries) { List<IteratorOutput> result = new List<IteratorOutput>(neededEntries.Length); for (int i = 0; i < allEntries.Length; i++) { if (ArrayHelpers.Contains(neededEntries, allEntries[i])) { IteratorOutput iteratorOutput = new IteratorOutput(); iteratorOutput.SourceIndex = i; iteratorOutput.TargetIndex = offset + result.Count; result.Add(iteratorOutput); } } return result.ToArray(); }
public static bool ExpressionYieldsNullOrFalseIfRowBufferEntryNull(ExpressionNode expressionNode, RowBufferEntry rowBufferEntry) { NullRejectionChecker checker = new NullRejectionChecker(rowBufferEntry); checker.Visit(expressionNode); if (checker.ExpressionRejectsNull) { return(true); } return(false); }
private RuntimeAggregateValueOutput[] GetDefinedValues(RowBufferEntry[] outputList, AggregatedValueDefinition[] definedValues, params BoundRowBufferEntrySet[] boundRowBufferEntrySets) { RuntimeAggregateValueOutput[] result = new RuntimeAggregateValueOutput[definedValues.Length]; for (int i = 0; i < definedValues.Length; i++) { RuntimeAggregateValueOutput definedValue = new RuntimeAggregateValueOutput(); definedValue.Aggregator = definedValues[i].Aggregator; definedValue.Argument = CreateRuntimeExpression(definedValues[i].Argument, boundRowBufferEntrySets); definedValue.TargetIndex = Array.IndexOf(outputList, definedValues[i].Target); result[i] = definedValue; } return result; }
private bool IsOuterReference(RowBufferEntry entry) { foreach (RowBufferEntry[] outerReferences in _outerReferences) { if (ArrayHelpers.Contains(outerReferences, entry)) return true; } return false; }
private void PushOuterReferences(object[] rowBuffer, JoinAlgebraNode node) { if (node.OuterReferences != null && node.OuterReferences.Length > 0) { // Important: We cannot use node.OuterReferences as argument for BoundRowBufferEntrySet(). // The replacment strategy below will replace occurences to the entries by their index // within the array. Therefore we need an array with the same layout as the row buffer. RowBufferEntry[] outerReferences = new RowBufferEntry[node.Left.OutputList.Length]; for (int i = 0; i < outerReferences.Length; i++) { if (ArrayHelpers.Contains(node.OuterReferences, node.Left.OutputList[i])) outerReferences[i] = node.Left.OutputList[i]; } BoundRowBufferEntrySet bufferEntrySet = new BoundRowBufferEntrySet(rowBuffer, outerReferences); _outerReferenceStack.Push(bufferEntrySet); } }
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); }
private static void CreateBufferedValue(ExpressionNode expression, ICollection<ComputedValueDefinition> computedColumnList, ICollection<RowBufferEntry> columnList, IEnumerable<ComputedValueDefinition> alreadyComputedBufferedValues) { if (alreadyComputedBufferedValues != null) expression = ReplaceAlreadyComputedSubsequences(expression, alreadyComputedBufferedValues); foreach (ComputedValueDefinition computedBufferedValue in computedColumnList) { if (expression.IsStructuralEqualTo(computedBufferedValue.Expression)) { columnList.Add(computedBufferedValue.Target); return; } } RowBufferEntryExpression rowBufferExpression = expression as RowBufferEntryExpression; if (rowBufferExpression != null) { columnList.Add(rowBufferExpression.RowBufferEntry); } else { RowBufferEntry rowBufferEntry = new RowBufferEntry(expression.ExpressionType); columnList.Add(rowBufferEntry); ComputedValueDefinition computedValue = new ComputedValueDefinition(); computedValue.Target = rowBufferEntry; computedValue.Expression = expression; computedColumnList.Add(computedValue); } }
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)); } }