Example #1
0
        public static bool WillProduceAtMostOneRow(AlgebraNode algebraNode)
        {
            AtMostOneRowChecker atMostOneRowChecker = new AtMostOneRowChecker();

            atMostOneRowChecker.Visit(algebraNode);
            return(atMostOneRowChecker.WillProduceAtMostOneRow);
        }
Example #2
0
        private AlgebraNode GetLastAlgebraNode()
        {
            AlgebraNode result = _lastAlgebraNode;

            _lastAlgebraNode = null;
            return(result);
        }
Example #3
0
        public static RowBufferEntry[] GetDefinedValueEntries(AlgebraNode node)
        {
            DefinedValuesFinder definedValuesFinder = new DefinedValuesFinder();

            definedValuesFinder.Visit(node);
            return(definedValuesFinder.GetDefinedValueEntries());
        }
Example #4
0
        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);
        }
Example #5
0
        private ShowPlanElement ConvertNode(AlgebraNode node)
        {
            Visit(node);
            ShowPlanElement result = _currentElement;

            _currentElement = null;
            return(result);
        }
Example #6
0
        public static ShowPlanElement Convert(AlgebraNode algebraNode)
        {
            if (algebraNode == null)
                return new ShowPlanElement(ShowPlanOperator.Select, new ShowPlanProperty[0]);

            ShowPlanBuilder showPlanBuilder = new ShowPlanBuilder();
            return showPlanBuilder.ConvertNode(algebraNode);
        }
Example #7
0
        private static ResultAlgebraNode Convert(CommonTableBinding currentCommonTableBinding, QueryNode queryNode)
        {
            Algebrizer  algebrizer = new Algebrizer(currentCommonTableBinding);
            AlgebraNode result     = algebrizer.ConvertAstNode(queryNode);

            result = new SubqueryExpander().VisitAlgebraNode(result);
            return((ResultAlgebraNode)result);
        }
Example #8
0
		private static AlgebraNode WrapWithFilter(AlgebraNode input, ExpressionNode predicate)
		{
			if (predicate == null)
				return input;

			FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
			filterAlgebraNode.Input = input;
			filterAlgebraNode.Predicate = predicate;
			return filterAlgebraNode;
		}
Example #9
0
        private AlgebraNode GetOrCreateInput()
        {
            AlgebraNode lastNode = GetAndResetLastNode();

            if (lastNode != null)
            {
                return(lastNode);
            }

            return(CreateConstantScan());
        }
Example #10
0
        public static ShowPlanElement Convert(AlgebraNode algebraNode)
        {
            if (algebraNode == null)
            {
                return(new ShowPlanElement(ShowPlanOperator.Select, new ShowPlanProperty[0]));
            }

            ShowPlanBuilder showPlanBuilder = new ShowPlanBuilder();

            return(showPlanBuilder.ConvertNode(algebraNode));
        }
Example #11
0
		private void SetLastIterator(AlgebraNode owner, Iterator iterator)
		{
			if (_includeStatistics && owner.StatisticsIterator == null)
			{
				owner.StatisticsIterator = new StatisticsIterator();
				owner.StatisticsIterator.RowBuffer = iterator.RowBuffer;
				owner.StatisticsIterator.Input = iterator;
				iterator = owner.StatisticsIterator;
			}

			_lastIterator = iterator;
		}
Example #12
0
        private static AlgebraNode WrapWithFilter(AlgebraNode input, ExpressionNode predicate)
        {
            if (predicate == null)
            {
                return(input);
            }

            FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();

            filterAlgebraNode.Input     = input;
            filterAlgebraNode.Predicate = predicate;
            return(filterAlgebraNode);
        }
Example #13
0
 private bool CheckIfNodeHasDependenciesToOuterReferences(AlgebraNode node)
 {
     foreach (RowBufferEntry rowBufferEntryReference in AstUtil.GetRowBufferEntryReferences(node))
     {
         foreach (RowBufferEntry[] outerReferences in _outerReferences)
         {
             if (ArrayHelpers.Contains(outerReferences, rowBufferEntryReference))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
Example #14
0
        public override TableReference VisitNamedTableReference(NamedTableReference node)
        {
            CommonTableBinding tableBindingAsCommonTable = node.TableRefBinding.TableBinding as CommonTableBinding;

            if (tableBindingAsCommonTable == null)
            {
                // It is a regular table reference. Emit just a table node.

                List <ColumnValueDefinition> definedValues = new List <ColumnValueDefinition>();
                foreach (ColumnRefBinding columnRefBinding in node.TableRefBinding.ColumnRefs)
                {
                    definedValues.Add(columnRefBinding.ValueDefinition);
                }

                TableAlgebraNode algebraNode = new TableAlgebraNode();
                algebraNode.TableRefBinding = node.TableRefBinding;
                algebraNode.DefinedValues   = definedValues.ToArray();
                SetLastAlgebraNode(algebraNode);
            }
            else
            {
                // It is a reference to a CTE. Instead of emitting a table node we have to replace the
                // reference to the CTE by the algebrized representation of the CTE. One could speak
                // of "inlining" the CTE.

                if (tableBindingAsCommonTable == _currentCommonTableBinding)
                {
                    // This should never happen. The JoinAlgebraNode should ignore these table references.
                    Debug.Fail("The current common table binding should never be reached as a table reference.");
                }

                AlgebraNode algebrizedCte;
                if (tableBindingAsCommonTable.IsRecursive)
                {
                    algebrizedCte = AlgebrizeRecursiveCte(tableBindingAsCommonTable);
                }
                else
                {
                    algebrizedCte = Convert(tableBindingAsCommonTable.AnchorMember);
                }

                // In order to use the CTE we have to instantiate it. See commonets in InstantiateCte() for
                // details.

                AlgebraNode computeScalarAlgebraNode = InstantiateCte(algebrizedCte, tableBindingAsCommonTable, node.TableRefBinding);
                SetLastAlgebraNode(computeScalarAlgebraNode);
            }

            return(node);
        }
Example #15
0
        public override ExpressionNode VisitSingleRowSubselect(SingleRowSubselect expression)
        {
            AlgebraNode       inputNode          = GetOrCreateInput();
            ResultAlgebraNode algebrizedSubquery = Algebrizer.Convert(expression.Query);
            ResultAlgebraNode assertedSubquery   = CreateAssertedSubquery(algebrizedSubquery);

            JoinAlgebraNode joinAlgebraNode = new JoinAlgebraNode();

            joinAlgebraNode.PassthruPredicate = CurrentPassthruPredicate;
            joinAlgebraNode.Op    = JoinAlgebraNode.JoinOperator.LeftOuterJoin;
            joinAlgebraNode.Left  = inputNode;
            joinAlgebraNode.Right = assertedSubquery;
            SetLastAlgebraNode(joinAlgebraNode);

            return(new RowBufferEntryExpression(assertedSubquery.OutputList[0]));
        }
Example #16
0
            public override AstNode Visit(AstNode node)
            {
                node = base.Visit(node);

                AlgebraNode algebraNode = node as AlgebraNode;

                if (algebraNode != null && algebraNode.OutputList != null)
                {
                    for (int i = 0; i < algebraNode.OutputList.Length; i++)
                    {
                        algebraNode.OutputList[i] = ReplaceRowBuffer(algebraNode.OutputList[i]);
                    }
                }

                return(node);
            }
Example #17
0
        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);
        }
Example #18
0
        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));
            }
        }
Example #19
0
        public static bool JoinDoesNotDependOn(JoinAlgebraNode joinNode, AlgebraNode joinSide)
        {
            RowBufferEntry[] joinSideDefinedValues = GetDefinedValueEntries(joinSide);

            if (joinNode.Predicate != null)
            {
                RowBufferEntry[] referencedRowBufferEntries = GetRowBufferEntryReferences(joinNode.Predicate);

                foreach (RowBufferEntry joinSideDefinedValue in joinSideDefinedValues)
                {
                    if (ArrayHelpers.Contains(referencedRowBufferEntries, joinSideDefinedValue))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Example #20
0
        public void SwapSides()
        {
            AlgebraNode oldLeft = _left;

            _left  = _right;
            _right = oldLeft;

            switch (_op)
            {
            case JoinOperator.LeftOuterJoin:
                _op = JoinOperator.RightOuterJoin;
                break;

            case JoinOperator.LeftSemiJoin:
                _op = JoinOperator.RightSemiJoin;
                break;

            case JoinOperator.LeftAntiSemiJoin:
                _op = JoinOperator.RightAntiSemiJoin;
                break;

            case JoinOperator.RightOuterJoin:
                _op = JoinOperator.LeftOuterJoin;
                break;

            case JoinOperator.RightSemiJoin:
                _op = JoinOperator.LeftSemiJoin;
                break;

            case JoinOperator.RightAntiSemiJoin:
                _op = JoinOperator.LeftAntiSemiJoin;
                break;

            case JoinOperator.InnerJoin:
            case JoinOperator.FullOuterJoin:
                // Nothing to do.
                break;

            default:
                throw ExceptionBuilder.UnhandledCaseLabel(_op);
            }
        }
Example #21
0
		public void SwapSides()
		{
			AlgebraNode oldLeft = _left;
			_left = _right;
			_right = oldLeft;
			
			switch (_op)
			{
				case JoinOperator.LeftOuterJoin:
					_op = JoinOperator.RightOuterJoin;
					break;
				case JoinOperator.LeftSemiJoin:
					_op = JoinOperator.RightSemiJoin;
					break;
				case JoinOperator.LeftAntiSemiJoin:
					_op = JoinOperator.RightAntiSemiJoin;
					break;

				case JoinOperator.RightOuterJoin:
					_op = JoinOperator.LeftOuterJoin;
					break;
				case JoinOperator.RightSemiJoin:
					_op = JoinOperator.LeftSemiJoin;
					break;
				case JoinOperator.RightAntiSemiJoin:
					_op = JoinOperator.LeftAntiSemiJoin;
					break;
										
				case JoinOperator.InnerJoin:
				case JoinOperator.FullOuterJoin:
					// Nothing to do.
					break;

				default:
					throw ExceptionBuilder.UnhandledCaseLabel(_op);
			}
		}
Example #22
0
        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);
        }
Example #23
0
		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;
		}
Example #24
0
        public override TableReference VisitJoinedTableReference(JoinedTableReference node)
        {
            TableReference nonCteTableRef;

            if (IsTableReferenceToCurrentCommonTableBinding(node.Left))
            {
                nonCteTableRef = node.Right;
            }
            else if (IsTableReferenceToCurrentCommonTableBinding(node.Right))
            {
                nonCteTableRef = node.Left;
            }
            else
            {
                nonCteTableRef = null;
            }

            if (nonCteTableRef != null)
            {
                Debug.Assert(node.JoinType == JoinType.Inner);
                AlgebraNode algebrizedPath = ConvertAstNode(nonCteTableRef);
                SetLastAlgebraNode(algebrizedPath);

                if (node.Condition != null)
                {
                    FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
                    filterAlgebraNode.Input     = GetLastAlgebraNode();
                    filterAlgebraNode.Predicate = node.Condition;
                    SetLastAlgebraNode(filterAlgebraNode);
                }
                return(node);
            }

            JoinAlgebraNode algebraNode = new JoinAlgebraNode();

            algebraNode.Left      = ConvertAstNode(node.Left);
            algebraNode.Right     = ConvertAstNode(node.Right);
            algebraNode.Predicate = node.Condition;

            switch (node.JoinType)
            {
            case JoinType.Inner:
                algebraNode.Op = JoinAlgebraNode.JoinOperator.InnerJoin;
                break;

            case JoinType.LeftOuter:
                algebraNode.Op = JoinAlgebraNode.JoinOperator.LeftOuterJoin;
                break;

            case JoinType.RightOuter:
                algebraNode.Op = JoinAlgebraNode.JoinOperator.RightOuterJoin;
                break;

            case JoinType.FullOuter:
                algebraNode.Op = JoinAlgebraNode.JoinOperator.FullOuterJoin;
                break;
            }

            SetLastAlgebraNode(algebraNode);
            return(node);
        }
Example #25
0
        public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            if (node.Predicate == null || !AstUtil.ContainsSubselect(node.Predicate))
            {
                return(base.VisitJoinAlgebraNode(node));
            }

            node.Left  = VisitAlgebraNode(node.Left);
            node.Right = VisitAlgebraNode(node.Right);

            switch (node.Op)
            {
            case JoinAlgebraNode.JoinOperator.InnerJoin:
            {
                FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
                filterAlgebraNode.Predicate = node.Predicate;
                filterAlgebraNode.Input     = node;
                node.Predicate = null;

                SetLastAlgebraNode(node);
                _probingEnabledStack.Push(false);
                filterAlgebraNode.Predicate = VisitExpression(filterAlgebraNode.Predicate);
                _probingEnabledStack.Pop();
                filterAlgebraNode.Input = GetAndResetLastNode();

                return(filterAlgebraNode);
            }

            case JoinAlgebraNode.JoinOperator.LeftOuterJoin:
            {
                FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
                filterAlgebraNode.Predicate = node.Predicate;
                filterAlgebraNode.Input     = node.Right;

                node.Right     = filterAlgebraNode;
                node.Predicate = null;

                SetLastAlgebraNode(filterAlgebraNode.Input);
                _probingEnabledStack.Push(false);
                filterAlgebraNode.Predicate = VisitExpression(filterAlgebraNode.Predicate);
                _probingEnabledStack.Pop();
                filterAlgebraNode.Input = GetAndResetLastNode();

                return(node);
            }

            case JoinAlgebraNode.JoinOperator.RightOuterJoin:
            {
                node.Op = JoinAlgebraNode.JoinOperator.LeftOuterJoin;
                AlgebraNode oldLeft = node.Left;
                node.Left  = node.Right;
                node.Right = oldLeft;
                goto case JoinAlgebraNode.JoinOperator.LeftOuterJoin;
            }

            case JoinAlgebraNode.JoinOperator.FullOuterJoin:
                // TODO: Support subqueries in FULL OUTER JOIN.
                throw ExceptionBuilder.InternalError("FULL OUTER JOIN containing a subselect predicate in ON clause is not supported.");

            default:
                throw ExceptionBuilder.UnhandledCaseLabel(node.Op);
            }
        }
Example #26
0
		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;
		}
Example #27
0
 public virtual AlgebraNode VisitAlgebraNode(AlgebraNode node)
 {
     return((AlgebraNode)Visit(node));
 }
Example #28
0
 internal static ShowPlan Build(AlgebraNode root)
 {
     ShowPlanElement rootElement = ShowPlanBuilder.Convert(root);
     return new ShowPlan(rootElement);
 }
Example #29
0
        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));
            }
        }
Example #30
0
        public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            node.Left  = VisitAlgebraNode(node.Left);
            node.Right = VisitAlgebraNode(node.Right);

            bool leftIsNull  = node.Left is NullScanAlgebraNode;
            bool rightIsNull = node.Right is NullScanAlgebraNode;
            bool joinConditionAlwaysFalse = false;

            if (node.Predicate != null)
            {
                ExpressionNode     predicate           = node.Predicate;
                ConstantExpression predicateAsConstant = predicate as ConstantExpression;
                if (predicateAsConstant != null)
                {
                    if (predicateAsConstant.AsBoolean)
                    {
                        node.Predicate = null;
                    }
                    else
                    {
                        joinConditionAlwaysFalse = true;
                    }
                }
            }

            if (node.Op == JoinAlgebraNode.JoinOperator.RightOuterJoin ||
                node.Op == JoinAlgebraNode.JoinOperator.RightSemiJoin ||
                node.Op == JoinAlgebraNode.JoinOperator.RightAntiSemiJoin)
            {
                node.SwapSides();
            }

            switch (node.Op)
            {
            case JoinAlgebraNode.JoinOperator.InnerJoin:
                if (joinConditionAlwaysFalse || leftIsNull || rightIsNull)
                {
                    return(CreateNullScan(node.OutputList));
                }
                break;

            case JoinAlgebraNode.JoinOperator.FullOuterJoin:
                if (leftIsNull && rightIsNull)
                {
                    return(CreateNullScan(node.OutputList));
                }
                if (leftIsNull)
                {
                    return(PadRightWithNullsOnLeftSide(node, RowBufferCreationMode.KeepExisting));
                }
                if (rightIsNull)
                {
                    return(PadLeftWithNullsOnRightSide(node, RowBufferCreationMode.KeepExisting));
                }
                if (joinConditionAlwaysFalse)
                {
                    AlgebraNode left  = PadLeftWithNullsOnRightSide(node, RowBufferCreationMode.CreateNew);
                    AlgebraNode right = PadRightWithNullsOnLeftSide(node, RowBufferCreationMode.CreateNew);

                    ConcatAlgebraNode concatAlgebraNode = new ConcatAlgebraNode();
                    concatAlgebraNode.Inputs = new AlgebraNode[] { left, right };

                    List <RowBufferEntry>        outputList    = new List <RowBufferEntry>();
                    List <UnitedValueDefinition> definedValues = new List <UnitedValueDefinition>();
                    for (int i = 0; i < node.Left.OutputList.Length; i++)
                    {
                        int leftIndex  = i;
                        int rightIndex = node.Right.OutputList.Length + i;

                        UnitedValueDefinition definedValue = new UnitedValueDefinition();
                        definedValue.Target           = node.Left.OutputList[leftIndex];
                        definedValue.DependendEntries = new RowBufferEntry[] { left.OutputList[leftIndex], right.OutputList[rightIndex] };
                        definedValues.Add(definedValue);
                        outputList.Add(definedValue.Target);
                    }
                    for (int i = 0; i < node.Right.OutputList.Length; i++)
                    {
                        int leftIndex  = node.Left.OutputList.Length + i;
                        int rightIndex = i;

                        UnitedValueDefinition definedValue = new UnitedValueDefinition();
                        definedValue.Target           = node.Right.OutputList[rightIndex];
                        definedValue.DependendEntries = new RowBufferEntry[] { left.OutputList[leftIndex], right.OutputList[rightIndex] };
                        definedValues.Add(definedValue);
                        outputList.Add(definedValue.Target);
                    }

                    concatAlgebraNode.DefinedValues = definedValues.ToArray();
                    concatAlgebraNode.OutputList    = outputList.ToArray();
                    return(concatAlgebraNode);
                }
                break;

            case JoinAlgebraNode.JoinOperator.LeftOuterJoin:
                if (leftIsNull)
                {
                    return(CreateNullScan(node.OutputList));
                }
                if (rightIsNull || joinConditionAlwaysFalse)
                {
                    return(PadLeftWithNullsOnRightSide(node, RowBufferCreationMode.KeepExisting));
                }
                break;

            case JoinAlgebraNode.JoinOperator.LeftSemiJoin:
                if (leftIsNull || rightIsNull || joinConditionAlwaysFalse)
                {
                    return(CreateNullScan(node.OutputList));
                }
                if (node.Predicate == null && AstUtil.WillProduceAtLeastOneRow(node.Right))
                {
                    return(node.Left);
                }
                break;

            case JoinAlgebraNode.JoinOperator.LeftAntiSemiJoin:
                if (leftIsNull)
                {
                    return(CreateNullScan(node.OutputList));
                }
                if (rightIsNull || joinConditionAlwaysFalse)
                {
                    return(node.Left);
                }
                if (node.Predicate == null && AstUtil.WillProduceAtLeastOneRow(node.Right))
                {
                    return(CreateNullScan(node.OutputList));
                }
                break;
            }

            return(node);
        }
Example #31
0
 private void SetLastAlgebraNode(AlgebraNode algebraNode)
 {
     _lastAlgebraNode = algebraNode;
 }
Example #32
0
 private static FilterAlgebraNode GetFilterFromAndParts(IList<ExpressionNode> andParts, AlgebraNode input)
 {
     FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
     filterAlgebraNode.Input = input;
     filterAlgebraNode.Predicate = AstUtil.CombineConditions(LogicalOperator.And, andParts);
     return filterAlgebraNode;
 }
Example #33
0
        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);
        }
Example #34
0
 private void SetLastAlgebraNode(AlgebraNode algebraNode)
 {
     _lastAlgebraNode = algebraNode;
 }
Example #35
0
 private bool CheckIfNodeHasDependenciesToOuterReferences(AlgebraNode node)
 {
     foreach (RowBufferEntry rowBufferEntryReference in AstUtil.GetRowBufferEntryReferences(node))
     {
         foreach (RowBufferEntry[] outerReferences in _outerReferences)
         {
             if (ArrayHelpers.Contains(outerReferences, rowBufferEntryReference))
                 return true;
         }
     }
     return false;
 }
Example #36
0
		public virtual AlgebraNode VisitAlgebraNode(AlgebraNode node)
		{
			return (AlgebraNode)Visit(node);
		}
Example #37
0
        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);
        }
Example #38
0
        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));
            }
        }
Example #39
0
 private AlgebraNode GetAndResetLastNode()
 {
     AlgebraNode result = _lastAlgebraNode;
     _lastAlgebraNode = null;
     return result;
 }
Example #40
0
 private ShowPlanElement ConvertNode(AlgebraNode node)
 {
     Visit(node);
     ShowPlanElement result = _currentElement;
     _currentElement = null;
     return result;
 }
Example #41
0
		public static bool WillProduceAtMostOneRow(AlgebraNode algebraNode)
		{
			AtMostOneRowChecker atMostOneRowChecker = new AtMostOneRowChecker();
			atMostOneRowChecker.Visit(algebraNode);
			return atMostOneRowChecker.WillProduceAtMostOneRow;
		}
Example #42
0
        private static FilterAlgebraNode GetFilterFromAndParts(IList <ExpressionNode> andParts, AlgebraNode input)
        {
            FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();

            filterAlgebraNode.Input     = input;
            filterAlgebraNode.Predicate = AstUtil.CombineConditions(LogicalOperator.And, andParts);
            return(filterAlgebraNode);
        }
Example #43
0
		private Iterator ConvertAlgebraNode(AlgebraNode algebraNode)
		{
			Visit(algebraNode);
			Iterator iterator = GetLastIterator();
			return iterator;
		}
Example #44
0
		public static RowBufferEntry[] GetDefinedValueEntries(AlgebraNode node)
		{
			DefinedValuesFinder definedValuesFinder = new DefinedValuesFinder();
			definedValuesFinder.Visit(node);
			return definedValuesFinder.GetDefinedValueEntries();
		}
Example #45
0
        public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node)
        {
            // Check if node only consists of INNER join nodes and simple table reference nodes.
            // This algorithm assumes that the table references have been lineraized so that
            //
            // - JoinedTableReference appear on the LHS only (the last one must be NamedTableReference ovbiviously)
            // - NamedTableReference appear on the RHS only
            //
            // While scanning the node's children we create a list of all JoinedTableReferences and
            // NamedTableReferences.

            InnerJoinTableExtractor innerJoinTableExtractor = new InnerJoinTableExtractor();

            innerJoinTableExtractor.Visit(node);

            if (!innerJoinTableExtractor.ConsistsOnlyOfInnerJoinsFiltersAndTables)
            {
                node.Left  = VisitAlgebraNode(node.Left);
                node.Right = VisitAlgebraNode(node.Right);
                return(node);
            }
            else
            {
                TableAlgebraNode[] algebraNodes = innerJoinTableExtractor.GetTableNodes();
                Dictionary <TableRefBinding, TableAlgebraNode> tableRefToNodeDictionary = new Dictionary <TableRefBinding, TableAlgebraNode>();
                List <TableRefBinding> tableList = new List <TableRefBinding>();
                foreach (TableAlgebraNode algebraNode in algebraNodes)
                {
                    tableRefToNodeDictionary.Add(algebraNode.TableRefBinding, algebraNode);
                    tableList.Add(algebraNode.TableRefBinding);
                }

                // Create a mapping RowBufferEntry -> ColumnRefBinding

                Dictionary <RowBufferEntry, ColumnRefBinding> rowBufferColumnDictionary = new Dictionary <RowBufferEntry, ColumnRefBinding>();
                foreach (TableRefBinding tableRefBinding in tableList)
                {
                    foreach (ColumnRefBinding columnRefBinding in tableRefBinding.ColumnRefs)
                    {
                        rowBufferColumnDictionary.Add(columnRefBinding.ValueDefinition.Target, columnRefBinding);
                    }
                }

                // Create list of all possible join conditions and remaining AND-parts.

                List <JoinCondition>  joinConditionList = new List <JoinCondition>();
                List <ExpressionNode> andPartList       = new List <ExpressionNode>();

                ExpressionNode filter = AstUtil.CombineConditions(LogicalOperator.And, innerJoinTableExtractor.GetFilters());

                foreach (ExpressionNode andPart in AstUtil.SplitCondition(LogicalOperator.And, filter))
                {
                    JoinCondition joinCondition = ConvertToJoinCondition(rowBufferColumnDictionary, andPart);

                    if (joinCondition != null)
                    {
                        joinConditionList.Add(joinCondition);
                    }
                    else
                    {
                        andPartList.Add(andPart);
                    }
                }

                // After creating the list of all join conditions and AND-parts we have all we need to create
                // an optimimal join order between all tables of this part of the table tree.
                JoinOrder bestJoinOrder = GetBestJoinOrder(tableList.ToArray(), joinConditionList.ToArray(), andPartList.ToArray());

                // Get all tables that are introduced by this join order

                Dictionary <RowBufferEntry, ColumnValueDefinition> introducedColumns = GetIntroducedColumns(bestJoinOrder);

                // Combine AND-part list with all unused join conditions.

                andPartList.AddRange(bestJoinOrder.UnusedConditions);

                // Now we will re-create this part of the tree using the this join order.

                AlgebraNode lastAlgebraNode = null;
                for (int joinIndex = 0; joinIndex < bestJoinOrder.Joins.Length; joinIndex++)
                {
                    Join join = bestJoinOrder.Joins[joinIndex];

                    AlgebraNode      tableInput;
                    TableAlgebraNode tableNode = tableRefToNodeDictionary[join.TableRefBinding];

                    ExpressionNode tableFilter = ExtractConditionsApplicableToTable(introducedColumns, andPartList, join.TableRefBinding);
                    if (tableFilter == null)
                    {
                        tableInput = tableNode;
                    }
                    else
                    {
                        FilterAlgebraNode filterAlgebraNode = new FilterAlgebraNode();
                        filterAlgebraNode.Input     = tableNode;
                        filterAlgebraNode.Predicate = tableFilter;
                        tableInput = filterAlgebraNode;
                    }

                    if (lastAlgebraNode == null)
                    {
                        // This was the first one.
                        lastAlgebraNode = tableInput;
                    }
                    else
                    {
                        // Not the first one, we can create a join with the current table reference
                        // and last table reference.

                        // Get all AND-parts that can be applied to the tables already joined.
                        // This expression is merged to one condition.
                        ExpressionNode[] applicableAndParts = GetAndPartsApplicableToJoin(introducedColumns, bestJoinOrder, joinIndex, andPartList, true);
                        ExpressionNode   condition          = AstUtil.CombineConditions(LogicalOperator.And, applicableAndParts);

                        ExpressionNode joinCondition;
                        if (join.JoinCondition == null)
                        {
                            joinCondition = null;
                        }
                        else
                        {
                            joinCondition = join.JoinCondition.ToExpression();
                        }

                        ExpressionNode completeCondition = AstUtil.CombineConditions(LogicalOperator.And, condition, joinCondition);

                        JoinAlgebraNode joinAlgebraNode = new JoinAlgebraNode();
                        joinAlgebraNode.Op        = JoinAlgebraNode.JoinOperator.InnerJoin;
                        joinAlgebraNode.Left      = lastAlgebraNode;
                        joinAlgebraNode.Right     = tableInput;
                        joinAlgebraNode.Predicate = completeCondition;

                        // Next time this newly created join is the last table reference.
                        lastAlgebraNode = joinAlgebraNode;
                    }
                }

                return(lastAlgebraNode);
            }
        }
Example #46
0
		public static bool JoinDoesNotDependOn(JoinAlgebraNode joinNode, AlgebraNode joinSide)
		{
			RowBufferEntry[] joinSideDefinedValues = GetDefinedValueEntries(joinSide);

			if (joinNode.Predicate != null)
			{
				RowBufferEntry[] referencedRowBufferEntries = GetRowBufferEntryReferences(joinNode.Predicate);

				foreach (RowBufferEntry joinSideDefinedValue in joinSideDefinedValues)
				{
					if (ArrayHelpers.Contains(referencedRowBufferEntries, joinSideDefinedValue))
						return false;
				}
			}

			return true;
		}