Пример #1
0
        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);
            }
        }
Пример #2
0
        public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            if (node.Op == JoinAlgebraNode.JoinOperator.RightOuterJoin ||
                node.Op == JoinAlgebraNode.JoinOperator.RightAntiSemiJoin ||
                node.Op == JoinAlgebraNode.JoinOperator.RightSemiJoin)
            {
                if (node.OuterReferences != null && node.OuterReferences.Length > 0)
                {
                    throw ExceptionBuilder.InternalError("Outer references should not be possible for {0} and are not supported.", node.Op);
                }

                node.SwapSides();
            }

            NestedLoopsIterator nestedLoopsIterator;

            switch (node.Op)
            {
            case JoinAlgebraNode.JoinOperator.InnerJoin:
                nestedLoopsIterator = new InnerNestedLoopsIterator();
                break;

            case JoinAlgebraNode.JoinOperator.LeftOuterJoin:
                nestedLoopsIterator = new LeftOuterNestedLoopsIterator();
                break;

            case JoinAlgebraNode.JoinOperator.LeftSemiJoin:
                if (node.ProbeBufferEntry == null)
                {
                    nestedLoopsIterator = new LeftSemiNestedLoopsIterator();
                }
                else
                {
                    ProbedSemiJoinNestedLoopsIterator probedSemiJoinNestedLoopsIterator = new ProbedSemiJoinNestedLoopsIterator();
                    probedSemiJoinNestedLoopsIterator.ProbeOutput = GetDefinedValue(node.OutputList, node.ProbeBufferEntry);
                    nestedLoopsIterator = probedSemiJoinNestedLoopsIterator;
                }
                break;

            case JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin:
                if (node.ProbeBufferEntry == null)
                {
                    nestedLoopsIterator = new LeftAntiSemiNestedLoopsIterator();
                }
                else
                {
                    ProbedAntiSemiJoinNestedLoopsIterator probedSemiJoinNestedLoopsIterator = new ProbedAntiSemiJoinNestedLoopsIterator();
                    probedSemiJoinNestedLoopsIterator.ProbeOutput = GetDefinedValue(node.OutputList, node.ProbeBufferEntry);
                    nestedLoopsIterator = probedSemiJoinNestedLoopsIterator;
                }
                break;

            default:
                throw ExceptionBuilder.UnhandledCaseLabel(node.Op);
            }

            nestedLoopsIterator.RowBuffer  = new object[node.OutputList.Length];
            nestedLoopsIterator.Left       = ConvertAlgebraNode(node.Left);
            nestedLoopsIterator.LeftOutput = GetIteratorOutput(0, node.Left.OutputList, node.OutputList);

            PushOuterReferences(nestedLoopsIterator.Left.RowBuffer, node);

            nestedLoopsIterator.Right       = ConvertAlgebraNode(node.Right);
            nestedLoopsIterator.RightOutput = GetIteratorOutput(nestedLoopsIterator.LeftOutput.Length, node.Right.OutputList, node.OutputList);

            UpdatePredicateRowBufferReferences(nestedLoopsIterator, node);

            if (node.OuterReferences != null && node.OuterReferences.Length > 0)
            {
                _outerReferenceStack.Pop();
            }

            SetLastIterator(node, nestedLoopsIterator);

            return(node);
        }
Пример #3
0
        private void UpdatePredicateRowBufferReferences(NestedLoopsIterator nestedLoopsIterator, JoinAlgebraNode node)
        {
            BoundRowBufferEntrySet leftBoundRowBufferEntrySet  = new BoundRowBufferEntrySet(nestedLoopsIterator.Left.RowBuffer, node.Left.OutputList);
            BoundRowBufferEntrySet rightBoundRowBufferEntrySet = new BoundRowBufferEntrySet(nestedLoopsIterator.Right.RowBuffer, node.Right.OutputList);

            if (node.Predicate != null)
            {
                nestedLoopsIterator.Predicate = CreateRuntimeExpression(node.Predicate, leftBoundRowBufferEntrySet, rightBoundRowBufferEntrySet);
            }

            if (node.PassthruPredicate != null)
            {
                nestedLoopsIterator.PassthruPredicate = CreateRuntimeExpression(node.PassthruPredicate, leftBoundRowBufferEntrySet, rightBoundRowBufferEntrySet);
            }
        }