protected override BoundRelation RewriteConcatenationRelation(BoundConcatenationRelation node) { var definedValues = RemoveUnusedSlots(node.DefinedValues, d => d.ValueSlot); node = node.Update(node.Inputs, definedValues); _recorder.Record(node.DefinedValues); return(base.RewriteConcatenationRelation(node)); }
private Iterator BuildConcatenationRelation(BoundConcatenationRelation relation) { var inputs = relation.Inputs.Select(BuildRelation).ToImmutableArray(); var inputEntries = from i in Enumerable.Range(0, inputs.Length) let allocation = BuildRowBufferAllocation(relation.Inputs[i], inputs[i].RowBuffer) let slots = relation.DefinedValues.Select(d => d.InputValueSlots[i]) let entries = slots.Select(s => allocation[s]) select entries.ToImmutableArray(); return(new ConcatenationIterator(inputs, inputEntries)); }
protected override BoundRelation RewriteUnionRelation(BoundUnionRelation node) { var inputs = RewriteRelations(node.Inputs); var values = node.DefinedValues; var concatenation = new BoundConcatenationRelation(inputs, values); if (node.IsUnionAll) { return(concatenation); } var sortedValues = values.Zip(node.Comparers, (v, c) => new BoundComparedValue(v.ValueSlot, c)); return(new BoundSortRelation(true, concatenation, sortedValues)); }
private static CardinalityEstimate EstimateConcatenationRelation(BoundConcatenationRelation relation) { return(CardinalityEstimate.Unknown); }
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))); }