コード例 #1
0
        private static FilterExpression PrepareJoins(QueryTableSetPlanner tablePlanner, TableSelectExpression expression, TableExpressionFromSet fromSet, FilterExpression whereClause)
        {
            // Look at the join set and resolve the ON Expression to this statement
            JoiningSet joinSet = expression.From.JoinSet;
            var        result  = whereClause;

            // Perform a quick scan and see if there are any outer joins in the
            // expression.
            bool allInnerJoins = true;

            for (int i = 0; i < joinSet.TableCount - 1; ++i)
            {
                JoinType type = joinSet.GetJoinType(i);
                if (type != JoinType.Inner)
                {
                    allInnerJoins = false;
                }
            }

            // Prepare the joins
            for (int i = 0; i < joinSet.TableCount - 1; ++i)
            {
                JoinType   type         = joinSet.GetJoinType(i);
                Expression onExpression = joinSet.GetOnExpression(i);

                if (allInnerJoins)
                {
                    // If the whole join set is inner joins then simply move the on
                    // expression (if there is one) to the WHERE clause.
                    if (onExpression != null)
                    {
                        result = result.Append(onExpression);
                    }
                }
                else
                {
                    // Not all inner joins,
                    if (type == 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 Exception("No ON expression in join.");
                        }

                        // Resolve the on_expression
                        onExpression = onExpression.Prepare(fromSet.ExpressionQualifier);
                        // And set it in the planner
                        tablePlanner.SetJoinInfoBetweenSources(i, type, onExpression);
                    }
                }
            }

            return(result);
        }
コード例 #2
0
        private static QueryTableSetPlanner SetupPlanners(IDatabaseConnection db, TableExpressionFromSet fromSet)
        {
            // Set up plans for each table in the from clause of the command.  For
            // sub-queries, we recurse.

            var tablePlanner = new QueryTableSetPlanner();

            for (int i = 0; i < fromSet.SetCount; ++i)
            {
                IFromTableSource table = fromSet.GetTable(i);
                if (table is FromTableSubQuerySource)
                {
                    // This represents a sub-command in the FROM clause

                    var sqlTable = (FromTableSubQuerySource)table;
                    TableSelectExpression  sqlExpr    = sqlTable.TableExpression;
                    TableExpressionFromSet sqlFromSet = sqlTable.FromSet;

                    // Form a plan for evaluating the sub-command FROM
                    IQueryPlanNode sqlPlan = FormQueryPlan(db, sqlExpr, sqlFromSet, null);

                    // The top should always be a SubsetNode,
                    if (sqlPlan is SubsetNode)
                    {
                        var subsetNode = (SubsetNode)sqlPlan;
                        subsetNode.SetGivenName(sqlTable.AliasedName);
                    }
                    else
                    {
                        throw new Exception("Top plan is not a SubsetNode!");
                    }

                    tablePlanner.AddTableSource(sqlPlan, sqlTable);
                }
                else if (table is FromTableDirectSource)
                {
                    // This represents a direct referencable table in the FROM clause
                    var            dsTable = (FromTableDirectSource)table;
                    IQueryPlanNode dsPlan  = dsTable.CreateFetchQueryPlanNode();
                    tablePlanner.AddTableSource(dsPlan, dsTable);
                }
                else
                {
                    throw new Exception("Unknown table source instance: " + table.GetType());
                }
            }

            return(tablePlanner);
        }