Exemple #1
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;
		}
Exemple #2
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);
        }
Exemple #3
0
        public ResultAlgebraNode CompileQuery(string queryText, Scope scope)
        {
            // Algebraization

            Parser    parser      = new Parser(_errorReporter);
            QueryNode parsedQuery = parser.ParseQuery(queryText);

            // When the parser detected errors or could not even construct an AST it
            // does not make any sense to go ahead.

            if (_errorReporter.ErrorsSeen || parsedQuery == null)
            {
                return(null);
            }

            PhaseRunner phaseRunner = new PhaseRunner(_errorReporter, parsedQuery);

            phaseRunner.Phases.Add(PHASE_NORMALIZATION, new Normalizer());
            phaseRunner.Phases.Add(PHASE_RESOLUTION, new Resolver(_errorReporter, scope));
            phaseRunner.Phases.Add(PHASE_AGGREGATE_BINDING, new AggregateBinder(_errorReporter));
            phaseRunner.Phases.Add(PHASE_VALIDATION, new Validator(_errorReporter, scope.DataContext.MetadataContext));
            phaseRunner.Phases.Add(PHASE_CONSTANT_FOLDING, new ConstantFolder(_errorReporter));
            phaseRunner.Phases.Add(PHASE_COLUMN_AND_AGGREGATE_EXPRESSION_REPLACEMENT, new ColumnAndAggregateExpressionReplacer());
            phaseRunner.Phases.Add(PHASE_ALGEBRAIZATION, delegate(AstNode input)
            {
                return(Algebrizer.Convert((QueryNode)input));
            });
            phaseRunner.Phases.Add(PHASE_ROW_BUFFER_ENTRY_INLINING, new RowBufferEntryInliner());
            phaseRunner.Phases.Add(PHASE_SEMI_JOIN_SIMPLIFICATION, new SemiJoinSimplifier());
            phaseRunner.Phases.Add(PHASE_DECORRELATION, new Decorrelator());
            phaseRunner.Phases.Add(PHASE_OUTER_JOIN_REMOVAL, new OuterJoinRemover());
            phaseRunner.Phases.Add(PHASE_SELECTION_PUSHING, new SelectionPusher());
            phaseRunner.Phases.Add(PHASE_JOIN_LINEARIZATION, new JoinLinearizer());
            phaseRunner.Phases.Add(PHASE_OUTER_JOIN_REORDERING, new OuterJoinReorderer());
            phaseRunner.Phases.Add(PHASE_JOIN_ORDER_OPTIMIZATION, new JoinOrderOptimizer());
            phaseRunner.Phases.Add(PHASE_AT_MOST_ONE_ROW_REORDERING, new AtMostOneRowReorderer());
            phaseRunner.Phases.Add(PHASE_OUTER_REFERENCE_LABELING, new OuterReferenceLabeler());
            phaseRunner.Phases.Add(PHASE_SPOOL_INSERTION, new SpoolInserter());
            phaseRunner.Phases.Add(PHASE_PUSH_COMPUTATIONS, new ComputationPusher());
            phaseRunner.Phases.Add(PHASE_PHYSICAL_JOIN_OP_CHOOSING, new PhysicalJoinOperationChooser());
            phaseRunner.Phases.Add(PHASE_OUTPUTLIST_GENERATION, new OutputListGenerator());
            phaseRunner.Phases.Add(PHASE_NULL_SCAN_OPTIMIZATION, new NullScanOptimizer());
            phaseRunner.Phases.Add(PHASE_FULL_OUTER_JOIN_EXPANSION, new FullOuterJoinExpander());
            phaseRunner.Phases.Add(PHASE_OUTPUTLIST_OPTIMIZATION, new OutputListOptimizer());
            phaseRunner.Phases.Add(PHASE_ROW_BUFFER_ENTRY_NAMING, new RowBufferEntryNamer());

            // TODO: Acutally, we should perform "PushComputations" after "NullScanOptimization" since
            //       we can merge some ComputeScalar nodes there. But currently the "PushComputations"
            //       visitor does not correctly update the OutputList so later phases will fail.

            // TODO: The phases "SpoolInsertion" and "PhysicalJoinOperationChoosing" should be the last
            //       entries but currently they must precede PHASE_OUTPUTLIST_GENERATION, PHASE_OUTPUTLIST_OPTIMIZATION,
            //       and PHASE_ROW_BUFFER_ENTRY_NAMING.

            return((ResultAlgebraNode)phaseRunner.Run());
        }
        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]));
        }
        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));
            }
        }
        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));
            }
        }