コード例 #1
0
        private QueryTablePlanner Clone()
        {
            var copy = new QueryTablePlanner();

            int sz = tablePlans.Count;

            for (int i = 0; i < sz; ++i)
            {
                copy.tablePlans.Add(tablePlans[i].Clone());
            }

            // Copy the left and right links in the PlanTableSource
            for (int i = 0; i < sz; ++i)
            {
                var src = tablePlans[i];
                var mod = copy.tablePlans[i];

                // See how the left plan links to which index,
                if (src.LeftPlan != null)
                {
                    int n = IndexOfPlan(src.LeftPlan);
                    mod.LeftJoin(copy.tablePlans[n], src.LeftJoinType, src.LeftOnExpression);
                }

                // See how the right plan links to which index,
                if (src.RightPlan != null)
                {
                    int n = IndexOfPlan(src.RightPlan);
                    mod.RightJoin(copy.tablePlans[n], src.RightJoinType, src.RightOnExpression);
                }
            }

            return(copy);
        }
コード例 #2
0
 public SimplePatternPlan(QueryTablePlanner planner, ObjectName columnName, SqlExpression expression)
     : base(0.25f)
 {
     this.planner    = planner;
     this.columnName = columnName;
     this.expression = expression;
 }
コード例 #3
0
 public ComplexSinglePlan(QueryTablePlanner planner, ObjectName columnName, SqlExpression expression)
     : base(0.8f)
 {
     this.planner    = planner;
     this.columnName = columnName;
     this.expression = expression;
 }
コード例 #4
0
 public ExhaustiveSubQueryPlan(QueryTablePlanner planner, ObjectName[] columnNames, SqlExpression expression)
     : base(0.85f)
 {
     this.planner     = planner;
     this.columnNames = columnNames;
     this.expression  = expression;
 }
コード例 #5
0
        private void PrepareJoins(QueryTablePlanner tablePlanner, SqlQueryExpression queryExpression, QueryExpressionFrom queryFrom, ref SqlExpression searchExpression)
        {
            var fromClause = queryExpression.FromClause;

            bool allInner = true;

            for (int i = 0; i < fromClause.JoinPartCount; i++)
            {
                var joinPart = fromClause.GetJoinPart(i);
                if (joinPart.JoinType != JoinType.Inner)
                {
                    allInner = false;
                }
            }

            for (int i = 0; i < fromClause.JoinPartCount; i++)
            {
                var joinPart = fromClause.GetJoinPart(i);

                var joinType     = joinPart.JoinType;
                var onExpression = joinPart.OnExpression;

                if (allInner)
                {
                    // If the whole join set is inner joins then simply move the on
                    // expression (if there is one) to the WHERE clause.
                    if (searchExpression != null && onExpression != null)
                    {
                        searchExpression = SqlExpression.And(searchExpression, onExpression);
                    }
                    else if (searchExpression == null)
                    {
                        searchExpression = onExpression;
                    }
                }
                else
                {
                    // Not all inner joins,
                    if (joinType == JoinType.Inner && onExpression == null)
                    {
                        // Regular join with no ON expression, so no preparation necessary
                    }
                    else
                    {
                        // Either an inner join with an ON expression, or an outer join with
                        // ON expression
                        if (onExpression == null)
                        {
                            throw new InvalidOperationException(String.Format("Join of type {0} requires ON expression.", joinType));
                        }

                        // Resolve the on_expression
                        onExpression = onExpression.Prepare(queryFrom.ExpressionPreparer);
                        // And set it in the planner
                        tablePlanner.JoinAt(i, joinType, onExpression);
                    }
                }
            }
        }
コード例 #6
0
 public SimpleSelectPlan(QueryTablePlanner planner, ObjectName columnName, SqlExpressionType op, SqlExpression expression)
     : base(0.2f)
 {
     this.planner    = planner;
     this.columnName = columnName;
     this.op         = op;
     this.expression = expression;
 }
コード例 #7
0
ファイル: QueryPlanner.cs プロジェクト: meikeric/deveeldb
        private QueryTablePlanner CreateTablePlanner(IRequest context, QueryExpressionFrom queryFrom)
        {
            // Set up plans for each table in the from clause of the command.  For
            // sub-queries, we recurse.

            var tablePlanner = new QueryTablePlanner();

            for (int i = 0; i < queryFrom.SourceCount; i++)
            {
                var            tableSource = queryFrom.GetTableSource(i);
                IQueryPlanNode plan;

                if (tableSource is FromTableSubQuerySource)
                {
                    var subQuerySource = (FromTableSubQuerySource)tableSource;

                    var subQueryExpr = subQuerySource.QueryExpression;
                    var subQueryFrom = subQuerySource.QueryFrom;

                    plan = PlanQuery(context, subQueryExpr, subQueryFrom, null, null);

                    if (!(plan is SubsetNode))
                    {
                        throw new InvalidOperationException("The root node of a sub-query plan must be a subset.");
                    }

                    var subsetNode = (SubsetNode)plan;
                    subsetNode.SetAliasParentName(subQuerySource.AliasName);
                }
                else if (tableSource is FromTableDirectSource)
                {
                    var directSource = (FromTableDirectSource)tableSource;
                    plan = directSource.QueryPlan;
                }
                else
                {
                    throw new InvalidOperationException(String.Format("The type of FROM source '{0}' is not supported.", tableSource.GetType()));
                }

                tablePlanner.AddPlan(plan, tableSource);
            }

            return(tablePlanner);
        }
コード例 #8
0
ファイル: QueryTablePlanner.cs プロジェクト: prepare/deveeldb
        private TablePlan NaturallyJoinPlans(TablePlan plan1, TablePlan plan2)
        {
            JoinType joinType;
            SqlExpression onExpr;
            TablePlan leftPlan, rightPlan;

            // Are the plans linked by common join information?
            if (plan1.RightPlan == plan2) {
                joinType = plan1.RightJoinType;
                onExpr = plan1.RightOnExpression;
                leftPlan = plan1;
                rightPlan = plan2;
            } else if (plan1.LeftPlan == plan2) {
                joinType = plan1.LeftJoinType;
                onExpr = plan1.LeftOnExpression;
                leftPlan = plan2;
                rightPlan = plan1;
            } else {
                // Assertion - make sure no join clashes!
                if ((plan1.LeftPlan != null && plan2.LeftPlan != null) ||
                    (plan1.RightPlan != null && plan2.RightPlan != null)) {
                    throw new InvalidOperationException("Plans can not be naturally join because " +
                                                        "the left/right join plans clash.");
                }

                // Else we must assume a non-dependent join (not an outer join).
                // Perform a natural join
                IQueryPlanNode node1 = new NaturalJoinNode(plan1.Plan, plan2.Plan);
                return MergePlans(plan1, plan2, node1);
            }

            // This means plan1 and plan2 are linked by a common join and ON
            // expression which we evaluate now.
            bool outerJoin;
            if (joinType == JoinType.Left) {
                // Mark the left plan
                leftPlan.UpdatePlan(new MarkerNode(leftPlan.Plan, "OUTER_JOIN"));
                outerJoin = true;
            } else if (joinType == JoinType.Right) {
                // Mark the right plan
                rightPlan.UpdatePlan(new MarkerNode(rightPlan.Plan, "OUTER_JOIN"));
                outerJoin = true;
            } else if (joinType == JoinType.Inner) {
                // Inner join with ON expression
                outerJoin = false;
            } else {
                throw new InvalidOperationException(String.Format("Join type ({0}) is not supported.", joinType));
            }

            // Make a Planner object for joining these plans.
            var planner = new QueryTablePlanner();
            planner.AddPlan(leftPlan.Clone());
            planner.AddPlan(rightPlan.Clone());

            // Evaluate the on expression
            var node = planner.LogicalEvaluate(onExpr);

            // If outer join add the left outer join node
            if (outerJoin)
                node = new LeftOuterJoinNode(node, "OUTER_JOIN");

            // And merge the plans in this set with the new node.
            return MergePlans(plan1, plan2, node);
        }
コード例 #9
0
ファイル: QueryTablePlanner.cs プロジェクト: prepare/deveeldb
 public ComplexSinglePlan(QueryTablePlanner planner, ObjectName columnName, SqlExpression expression)
     : base(0.8f)
 {
     this.planner = planner;
     this.columnName = columnName;
     this.expression = expression;
 }
コード例 #10
0
ファイル: QueryTablePlanner.cs プロジェクト: prepare/deveeldb
 public SubLogicPlan(QueryTablePlanner planner, SqlExpression expression, float optimizeFactor)
     : base(optimizeFactor)
 {
     this.planner = planner;
     this.expression = expression;
 }
コード例 #11
0
ファイル: QueryTablePlanner.cs プロジェクト: prepare/deveeldb
        private QueryTablePlanner Clone()
        {
            var copy = new QueryTablePlanner();

            int sz = tablePlans.Count;
            for (int i = 0; i < sz; ++i) {
                copy.tablePlans.Add(tablePlans[i].Clone());
            }

            // Copy the left and right links in the PlanTableSource
            for (int i = 0; i < sz; ++i) {
                var src = tablePlans[i];
                var mod = copy.tablePlans[i];

                // See how the left plan links to which index,
                if (src.LeftPlan != null) {
                    int n = IndexOfPlan(src.LeftPlan);
                    mod.LeftJoin(copy.tablePlans[n], src.LeftJoinType, src.LeftOnExpression);
                }

                // See how the right plan links to which index,
                if (src.RightPlan != null) {
                    int n = IndexOfPlan(src.RightPlan);
                    mod.RightJoin(copy.tablePlans[n], src.RightJoinType, src.RightOnExpression);
                }
            }

            return copy;
        }
コード例 #12
0
 public ExhaustiveJoinPlan(QueryTablePlanner planner, SqlExpression expression)
     : base(0.68f)
 {
     this.planner    = planner;
     this.expression = expression;
 }
コード例 #13
0
ファイル: QueryTablePlanner.cs プロジェクト: prepare/deveeldb
 public StandardJoinPlan(QueryTablePlanner planner, SqlBinaryExpression expression, float optimizeFactor)
     : base(optimizeFactor)
 {
     this.planner = planner;
     this.expression = expression;
 }
コード例 #14
0
 public ConstantPlan(QueryTablePlanner planner, SqlExpression expression)
     : base(0f)
 {
     this.planner    = planner;
     this.expression = expression;
 }
コード例 #15
0
ファイル: QueryTablePlanner.cs プロジェクト: prepare/deveeldb
 public ExhaustiveSelectPlan(QueryTablePlanner planner, SqlExpression expression)
     : base(0.82f)
 {
     this.planner = planner;
     this.expression = expression;
 }
コード例 #16
0
 public ExhaustiveSelectPlan(QueryTablePlanner planner, SqlExpression expression)
     : base(0.82f)
 {
     this.planner    = planner;
     this.expression = expression;
 }
コード例 #17
0
ファイル: QueryPlanner.cs プロジェクト: prepare/deveeldb
        private QueryTablePlanner CreateTablePlanner(IQueryContext context, QueryExpressionFrom queryFrom)
        {
            // Set up plans for each table in the from clause of the command.  For
            // sub-queries, we recurse.

            var tablePlanner = new QueryTablePlanner();

            for (int i = 0; i < queryFrom.SourceCount; i++) {
                var tableSource = queryFrom.GetTableSource(i);
                IQueryPlanNode plan;

                if (tableSource is FromTableSubQuerySource) {
                    var subQuerySource = (FromTableSubQuerySource) tableSource;

                    var subQueryExpr = subQuerySource.QueryExpression;
                    var subQueryFrom = subQuerySource.QueryFrom;

                    plan = PlanQuery(context, subQueryExpr, subQueryFrom, null);

                    if (!(plan is SubsetNode))
                        throw new InvalidOperationException("The root node of a sub-query plan must be a subset.");

                    var subsetNode = (SubsetNode) plan;
                    subsetNode.SetAliasParentName(subQuerySource.AliasName);
                } else if (tableSource is FromTableDirectSource) {
                    var directSource = (FromTableDirectSource) tableSource;
                    plan = directSource.QueryPlan;
                } else {
                    throw new InvalidOperationException(String.Format("The type of FROM source '{0}' is not supported.", tableSource.GetType()));
                }

                tablePlanner.AddPlan(plan, tableSource);
            }

            return tablePlanner;
        }
コード例 #18
0
        private TablePlan NaturallyJoinPlans(TablePlan plan1, TablePlan plan2)
        {
            JoinType      joinType;
            SqlExpression onExpr;
            TablePlan     leftPlan, rightPlan;

            // Are the plans linked by common join information?
            if (plan1.RightPlan == plan2)
            {
                joinType  = plan1.RightJoinType;
                onExpr    = plan1.RightOnExpression;
                leftPlan  = plan1;
                rightPlan = plan2;
            }
            else if (plan1.LeftPlan == plan2)
            {
                joinType  = plan1.LeftJoinType;
                onExpr    = plan1.LeftOnExpression;
                leftPlan  = plan2;
                rightPlan = plan1;
            }
            else
            {
                // Assertion - make sure no join clashes!
                if ((plan1.LeftPlan != null && plan2.LeftPlan != null) ||
                    (plan1.RightPlan != null && plan2.RightPlan != null))
                {
                    throw new InvalidOperationException("Plans can not be naturally join because " +
                                                        "the left/right join plans clash.");
                }

                // Else we must assume a non-dependent join (not an outer join).
                // Perform a natural join
                var node1 = new NaturalJoinNode(plan1.Plan, plan2.Plan);
                return(MergePlans(plan1, plan2, node1));
            }

            // This means plan1 and plan2 are linked by a common join and ON
            // expression which we evaluate now.
            bool outerJoin;

            if (joinType == JoinType.Left)
            {
                // Mark the left plan
                leftPlan.UpdatePlan(new MarkerNode(leftPlan.Plan, "OUTER_JOIN"));
                outerJoin = true;
            }
            else if (joinType == JoinType.Right)
            {
                // Mark the right plan
                rightPlan.UpdatePlan(new MarkerNode(rightPlan.Plan, "OUTER_JOIN"));
                outerJoin = true;
            }
            else if (joinType == JoinType.Inner)
            {
                // Inner join with ON expression
                outerJoin = false;
            }
            else
            {
                throw new InvalidOperationException(String.Format("Join type ({0}) is not supported.", joinType));
            }

            // Make a Planner object for joining these plans.
            var planner = new QueryTablePlanner();

            planner.AddPlan(leftPlan.Clone());
            planner.AddPlan(rightPlan.Clone());

            // Evaluate the on expression
            var node = planner.LogicalEvaluate(onExpr);

            // If outer join add the left outer join node
            if (outerJoin)
            {
                node = new LeftOuterJoinNode(node, "OUTER_JOIN");
            }

            // And merge the plans in this set with the new node.
            return(MergePlans(plan1, plan2, node));
        }
コード例 #19
0
 public SubLogicPlan(QueryTablePlanner planner, SqlExpression expression, float optimizeFactor)
     : base(optimizeFactor)
 {
     this.planner    = planner;
     this.expression = expression;
 }
コード例 #20
0
 public StandardJoinPlan(QueryTablePlanner planner, SqlBinaryExpression expression, float optimizeFactor)
     : base(optimizeFactor)
 {
     this.planner    = planner;
     this.expression = expression;
 }
コード例 #21
0
ファイル: QueryTablePlanner.cs プロジェクト: prepare/deveeldb
 public ConstantPlan(QueryTablePlanner planner, SqlExpression expression)
     : base(0f)
 {
     this.planner = planner;
     this.expression = expression;
 }
コード例 #22
0
ファイル: QueryTablePlanner.cs プロジェクト: prepare/deveeldb
 public SimpleSelectPlan(QueryTablePlanner planner, ObjectName columnName, SqlExpressionType op, SqlExpression expression)
     : base(0.2f)
 {
     this.planner = planner;
     this.columnName = columnName;
     this.op = op;
     this.expression = expression;
 }
コード例 #23
0
ファイル: QueryTablePlanner.cs プロジェクト: prepare/deveeldb
 public ExhaustiveJoinPlan(QueryTablePlanner planner, SqlExpression expression)
     : base(0.68f)
 {
     this.planner = planner;
     this.expression = expression;
 }
コード例 #24
0
ファイル: QueryTablePlanner.cs プロジェクト: prepare/deveeldb
 public SimpleSubQueryPlan(QueryTablePlanner planner, SqlBinaryExpression expression)
     : base(0.3f)
 {
     this.planner = planner;
     this.expression = expression;
 }
コード例 #25
0
ファイル: QueryTablePlanner.cs プロジェクト: prepare/deveeldb
 public ExhaustiveSubQueryPlan(QueryTablePlanner planner, ObjectName[] columnNames, SqlExpression expression)
     : base(0.85f)
 {
     this.planner = planner;
     this.columnNames = columnNames;
     this.expression = expression;
 }
コード例 #26
0
 public SimpleSubQueryPlan(QueryTablePlanner planner, SqlBinaryExpression expression)
     : base(0.3f)
 {
     this.planner    = planner;
     this.expression = expression;
 }
コード例 #27
0
ファイル: QueryPlanner.cs プロジェクト: prepare/deveeldb
        private void PrepareJoins(QueryTablePlanner tablePlanner, SqlQueryExpression queryExpression, QueryExpressionFrom queryFrom, ref SqlExpression searchExpression)
        {
            var fromClause = queryExpression.FromClause;

            bool allInner = true;
            for (int i = 0; i < fromClause.JoinPartCount; i++) {
                var joinPart = fromClause.GetJoinPart(i);
                if (joinPart.JoinType != JoinType.Inner)
                    allInner = false;
            }

            for (int i = 0; i < fromClause.JoinPartCount; i++) {
                var joinPart = fromClause.GetJoinPart(i);

                var joinType = joinPart.JoinType;
                var onExpression = joinPart.OnExpression;

                if (allInner) {
                    // If the whole join set is inner joins then simply move the on
                    // expression (if there is one) to the WHERE clause.
                    if (searchExpression != null && onExpression != null)
                        searchExpression = SqlExpression.And(searchExpression, onExpression);
                } else {
                    // Not all inner joins,
                    if (joinType == JoinType.Inner && onExpression == null) {
                        // Regular join with no ON expression, so no preparation necessary
                    } else {
                        // Either an inner join with an ON expression, or an outer join with
                        // ON expression
                        if (onExpression == null)
                            throw new InvalidOperationException(String.Format("Join of type {0} requires ON expression.", joinType));

                        // Resolve the on_expression
                        onExpression = onExpression.Prepare(queryFrom.ExpressionPreparer);
                        // And set it in the planner
                        tablePlanner.JoinAt(i, joinType, onExpression);
                    }
                }
            }
        }
コード例 #28
0
ファイル: QueryTablePlanner.cs プロジェクト: prepare/deveeldb
 public SimplePatternPlan(QueryTablePlanner planner, ObjectName columnName, SqlExpression expression)
     : base(0.25f)
 {
     this.planner = planner;
     this.columnName = columnName;
     this.expression = expression;
 }