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 PushOverProject(BoundFilterRelation node, BoundProjectRelation input) { var newFilter = RewriteRelation(node.Update(input.Input, node.Condition)); var newInput = input.Update(newFilter, input.Outputs); return(newInput); }
protected override BoundRelation RewriteProjectRelation(BoundProjectRelation node) { var outputs = RemoveUnusedSlots(node.Outputs, v => v); node = node.Update(node.Input, outputs); return(base.RewriteProjectRelation(node)); }
private Iterator BuildProject(BoundProjectRelation relation) { var input = BuildRelation(relation.Input); var inputRowBufferAllocation = BuildRowBufferAllocation(relation.Input, input.RowBuffer); var projectedIndices = relation.Outputs.Select(vs => inputRowBufferAllocation[vs]).ToImmutableArray(); return(new ProjectionIterator(input, projectedIndices)); }
protected override BoundRelation RewriteProjectRelation(BoundProjectRelation node) { if (IsSemiJoinContext) { return(RewriteRelation(node.Input)); } return(base.RewriteProjectRelation(node)); }
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 CardinalityEstimate EstimateProjectRelation(BoundProjectRelation 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))); }