protected override BoundRelation RewriteJoinRelation(BoundJoinRelation node) { node = (BoundJoinRelation)base.RewriteJoinRelation(node); var needsRewriting = NeedsRewriting(node); if (!needsRewriting) { return(node); } var node1 = (BoundJoinRelation)Instatiator.Instantiate(node); var node2 = (BoundJoinRelation)Instatiator.Instantiate(node); var leftOuterJoin = node1.Update(BoundJoinType.LeftOuter, node1.Left, node1.Right, node1.Condition, null, null); var leftAntiSemiJoin = node1.Update(BoundJoinType.LeftAntiSemi, node2.Right, node2.Left, node2.Condition, null, null); var computedValueSlots = node.Left.GetOutputValues().Select(v => v.Duplicate()).ToImmutableArray(); var computedValues = computedValueSlots.Select(v => new BoundComputedValue(Expression.Null(), v)); var compute = new BoundComputeRelation(leftAntiSemiJoin, computedValues); var project = new BoundProjectRelation(compute, computedValueSlots.Concat(leftAntiSemiJoin.GetOutputValues())); var concatValueSlots = node.GetOutputValues().ToImmutableArray(); var firstOutputs = leftOuterJoin.GetOutputValues().ToImmutableArray(); var secondOutputs = project.GetOutputValues().ToImmutableArray(); var unifiedValues = new BoundUnifiedValue[concatValueSlots.Length]; for (var i = 0; i < unifiedValues.Length; i++) { unifiedValues[i] = new BoundUnifiedValue(concatValueSlots[i], new[] { firstOutputs[i], secondOutputs[i] }); } return(new BoundConcatenationRelation(new BoundRelation[] { leftOuterJoin, project }, unifiedValues)); }
private BoundRelation PushOverCompute(BoundFilterRelation node, BoundComputeRelation input) { BoundExpression remainder = null; BoundExpression pushed = null; foreach (var conjunction in Expression.SplitConjunctions(node.Condition)) { if (conjunction.DependsOnAny(input.GetDefinedValues())) { remainder = Expression.And(remainder, conjunction); } else { pushed = Expression.And(pushed, conjunction); } } var newInputInput = pushed == null ? input.Input : new BoundFilterRelation(input.Input, pushed); var newInput = RewriteRelation(input.Update(newInputInput, input.DefinedValues)); var newNode = remainder == null ? newInput : new BoundFilterRelation(newInput, remainder); return(newNode); }
protected override BoundRelation RewriteComputeRelation(BoundComputeRelation node) { var input = RewriteRelation(node.Input); var computedValues = RewriteComputedValues(node.DefinedValues); var inputWithProbes = RewriteInputWithSubqueries(input); return(node.Update(inputWithProbes, computedValues)); }
private Iterator BuildCompute(BoundComputeRelation relation) { var input = BuildRelation(relation.Input); var allocation = BuildRowBufferAllocation(relation.Input, input.RowBuffer); var definedValue = relation.DefinedValues .Select(dv => BuildFunction(dv.Expression, allocation)) .ToImmutableArray(); return(new ComputeScalarIterator(input, definedValue)); }
private static BoundQuery CreateBoundQuery(BoundExpression expression) { var factory = new ValueSlotFactory(); var valueSlot = new ValueSlot(factory, @"result", 0, expression.Type); var computedValue = new BoundComputedValue(expression, valueSlot); var constantRelation = new BoundConstantRelation(); var computeRelation = new BoundComputeRelation(constantRelation, new[] { computedValue }); var projectRelation = new BoundProjectRelation(computeRelation, new [] { valueSlot }); var columnSymbol = new QueryColumnInstanceSymbol(valueSlot.Name, valueSlot); return(new BoundQuery(projectRelation, new[] { columnSymbol })); }
private static ShowPlanNode BuildCompute(BoundComputeRelation node) { var properties = Enumerable.Empty <KeyValuePair <string, string> >(); var input = new[] { Build(node.Input) }; var aggregates = from d in node.DefinedValues let dName = d.ValueSlot.Name let dProperties = Enumerable.Empty <KeyValuePair <string, string> >() let dChildren = new[] { Build(d.Expression) } select new ShowPlanNode(dName, dProperties, dChildren); var children = input.Concat(aggregates); return(new ShowPlanNode(@"Compute", properties, children)); }
protected override BoundRelation RewriteComputeRelation(BoundComputeRelation node) { var newInput = RewriteRelation(node.Input); if (newInput is BoundFilterRelation filter) { node = node.Update(filter.Input, node.DefinedValues); return(filter.WithInput(node)); } else { return(node.WithInput(newInput)); } }
protected override BoundRelation RewriteComputeRelation(BoundComputeRelation node) { var definedValues = RemoveUnusedSlots(node.DefinedValues, d => d.ValueSlot); node = node.Update(node.Input, definedValues); _recorder.Record(definedValues); if (!definedValues.Any()) { return(RewriteRelation(node.Input)); } return(base.RewriteComputeRelation(node)); }
private static Func <object> CreateTrivialExpression(BoundComputeRelation computeRelation) { var computedValue = computeRelation.DefinedValues.First(); return(ExpressionBuilder.BuildFunction(computedValue.Expression)); }
private static CardinalityEstimate EstimateComputeRelation(BoundComputeRelation relation) { return(Estimate(relation.Input)); }
private BoundRelation InstantiateRecursiveCommonTableExpression(ImmutableArray <ValueSlot> outputValues, CommonTableExpressionSymbol symbol) { // TableSpoolPusher // Concat // Compute (Recursion := 0) // <Anchor> // Assert (Recursion <= 100) // Inner Join // Compute (Recursion := Recursion + 1) // TableSpoolPopper // Concat // Filter <RecursiveJoinPredicate1> // <RecursiveMember1> // Filter <RecursiveJoinPredicate2> // <RecursiveMember2> var valueSlotFactory = outputValues.First().Factory; // Create output values var unionRecusionSlot = valueSlotFactory.CreateTemporary(typeof(int)); var concatValueSlots = outputValues.Add(unionRecusionSlot); // Create anchor var anchor = RewriteRelation(Instatiator.Instantiate(symbol.Anchor.Relation)); var anchorValues = anchor.GetOutputValues().ToImmutableArray(); var initRecursionSlot = valueSlotFactory.CreateTemporary(typeof(int)); var initRecursionDefinition = new BoundComputedValue(Expression.Literal(0), initRecursionSlot); var initRecursion = new BoundComputeRelation(anchor, ImmutableArray.Create(initRecursionDefinition)); var initRecursionOutputs = anchorValues.Add(initRecursionSlot); // Create TableSpoolPopper var tableSpoolPopperSlots = initRecursionOutputs.Select(v => v.Duplicate()).ToImmutableArray(); var tableSpoolPopper = new BoundTableSpoolPopper(tableSpoolPopperSlots); var anchorRecursionCounter = tableSpoolPopperSlots.Last(); var inc = Expression.Plus(Expression.Value(anchorRecursionCounter), Expression.Literal(1)); var incRecursionSlot = valueSlotFactory.CreateTemporary(typeof(int)); var incRecursionDefinition = new BoundComputedValue(inc, incRecursionSlot); var incRecursion = new BoundComputeRelation(tableSpoolPopper, ImmutableArray.Create(incRecursionDefinition)); // Create recursive members var recursiveRewriter = new CommonTableExpressionInstantiator(symbol); var recursiveMembers = new List <BoundRelation>(symbol.RecursiveMembers.Length); var recursiveMemberOutputs = new List <ImmutableArray <ValueSlot> >(symbol.RecursiveMembers.Length); var anchorReferences = tableSpoolPopperSlots.RemoveAt(tableSpoolPopperSlots.Length - 1); foreach (var recursiveMember in symbol.RecursiveMembers) { var recursivePrototype = recursiveMember.Relation; var mapping = CreateRecursiveMemberInstanceValueSlotMapping(symbol, anchorReferences, recursivePrototype); var recursiveInstance = Instatiator.Instantiate(recursivePrototype, mapping); var recursiveRelation = recursiveRewriter.RewriteRelation(recursiveInstance); var recursiveRelationOutputs = recursiveRelation.GetOutputValues().ToImmutableArray(); recursiveMembers.Add(recursiveRelation); recursiveMemberOutputs.Add(recursiveRelationOutputs); } // Concatenate recursive members var recursiveConcatValues = Enumerable .Range(0, concatValueSlots.Length - 1) .Select(i => { var slot = valueSlotFactory.CreateTemporary(concatValueSlots[i].Type); return(new BoundUnifiedValue(slot, recursiveMemberOutputs.Select(o => o[i]))); }) .ToImmutableArray(); var hasSingleRecursiveMember = recursiveMembers.Count == 1; var recursiveConcat = hasSingleRecursiveMember ? recursiveMembers.Single() : new BoundConcatenationRelation(recursiveMembers, recursiveConcatValues); var recursionOutputs = hasSingleRecursiveMember ? recursiveMemberOutputs.Single() : recursiveConcatValues.Select(u => u.ValueSlot).ToImmutableArray(); // Create inner join var join = new BoundJoinRelation(BoundJoinType.Inner, incRecursion, recursiveConcat, null, null, null); var joinOutputs = recursionOutputs.Add(incRecursionSlot); var recursiveProjection = new BoundProjectRelation(join, joinOutputs); // Create assert var assertCondition = Expression.LessThan(Expression.Value(incRecursionSlot), Expression.Literal(100)); var assert = new BoundAssertRelation(recursiveProjection, assertCondition, Resources.MaximumRecursionLevelExceeded); // Create top level concat var concatValues = concatValueSlots.Select((v, i) => { var slots = new[] { initRecursionOutputs[i], joinOutputs[i] }; return(new BoundUnifiedValue(v, slots)); }); var concatInputs = new BoundRelation[] { initRecursion, assert }; var concat = new BoundConcatenationRelation(concatInputs, concatValues); var tableSpoolPusher = new BoundTableSpoolPusher(concat); return(new BoundProjectRelation(tableSpoolPusher, concatValueSlots.Take(concatValueSlots.Length - 1))); }