Exemplo n.º 1
0
            internal static bool CanLift(SqlSource source, HashSet <SqlAlias> aliasesForLifting, HashSet <SqlExpression> liftedExpressions)
            {
                Visitor v = new Visitor(false, aliasesForLifting, liftedExpressions);

                v.VisitSource(source);
                return(v.canLiftAll);
            }
Exemplo n.º 2
0
            private SqlSource PushSourceDown(SqlSource sqlSource, List <SqlColumn> cols)
            {
                SqlSelect ns = new SqlSelect(new SqlNop(cols[0].ClrType, cols[0].SqlType, sqlSource.SourceExpression), sqlSource, sqlSource.SourceExpression);

                ns.Row.Columns.AddRange(cols);
                return(new SqlAlias(ns));
            }
Exemplo n.º 3
0
            private SqlJoin GetLeftOuterWithUnreferencedSingletonOnLeft(SqlSource source)
            {
                SqlAlias alias = source as SqlAlias;

                if (alias != null)
                {
                    SqlSelect select = alias.Node as SqlSelect;
                    if (select != null &&
                        select.Where == null &&
                        select.Top == null &&
                        select.GroupBy.Count == 0 &&
                        select.OrderBy.Count == 0)
                    {
                        return(this.GetLeftOuterWithUnreferencedSingletonOnLeft(select.From));
                    }
                }
                SqlJoin join = source as SqlJoin;

                if (join == null || join.JoinType != SqlJoinType.LeftOuter)
                {
                    return(null);
                }
                if (!this.IsSingletonSelect(join.Left))
                {
                    return(null);
                }
                HashSet <SqlAlias> p = SqlGatherProducedAliases.Gather(join.Left);
                HashSet <SqlAlias> c = SqlGatherConsumedAliases.Gather(join.Right);

                if (p.Overlaps(c))
                {
                    return(null);
                }
                return(join);
            }
Exemplo n.º 4
0
            internal static List <List <SqlColumn> > Lift(SqlSource source, HashSet <SqlAlias> aliasesForLifting, HashSet <SqlExpression> liftedExpressions)
            {
                Visitor v = new Visitor(true, aliasesForLifting, liftedExpressions);

                v.VisitSource(source);
                return(v.lifted);
            }
            internal override SqlSource VisitJoin(SqlJoin join)
            {
                if (join.JoinType == SqlJoinType.CrossApply)
                {
                    // Visit the left side as usual.
                    join.Left = this.VisitSource(join.Left);

                    // Visit the condition as usual.
                    join.Condition = this.VisitExpression(join.Condition);

                    // Visit the right, with the expressionSink set.
                    SelectScope s = expressionSink;

                    expressionSink = new SelectScope();
                    expressionSink.LeftProduction = SqlGatherProducedAliases.Gather(join.Left);
                    join.Right = this.VisitSource(join.Right);

                    // Were liftable expressions found?
                    SqlSource newSource = join;
                    foreach (List <SqlColumn> cols in expressionSink.Lifted)
                    {
                        newSource = PushSourceDown(newSource, cols);
                    }
                    expressionSink = s;
                    return(newSource);
                }
                return(base.VisitJoin(join));
            }
Exemplo n.º 6
0
            static internal List <SqlColumn> GatherColumns(SqlSource source)
            {
                List <SqlColumn> columns = new List <SqlColumn>();

                new Visitor(columns).Visit(source);
                return(columns);
            }
            internal override SqlSource VisitJoin(SqlJoin join)
            {
                SqlSource     left  = this.VisitSource(join.Left);
                SqlSource     right = this.VisitSource(join.Right);
                SqlExpression cond  = (SqlExpression)this.Visit(join.Condition);

                return(new SqlJoin(join.JoinType, left, right, cond, join.SourceExpression));
            }
Exemplo n.º 8
0
 internal SqlJoin(SqlJoinType type, SqlSource left, SqlSource right, SqlExpression cond, Expression sourceExpression)
     : base(SqlNodeType.Join, sourceExpression)
 {
     JoinType  = type;
     Left      = left;
     Right     = right;
     Condition = cond;
 }
Exemplo n.º 9
0
            internal static SqlExpression Lift(SqlSource source, HashSet <SqlAlias> aliasesForLifting)
            {
                System.Diagnostics.Debug.Assert(source != null);
                System.Diagnostics.Debug.Assert(aliasesForLifting != null);
                Visitor v = new Visitor(true, aliasesForLifting, null);

                v.VisitSource(source);
                return(v.lifted);
            }
Exemplo n.º 10
0
            internal static bool CanLift(SqlSource source, HashSet <SqlAlias> aliasesForLifting, HashSet <SqlExpression> liftedExpressions)
            {
                System.Diagnostics.Debug.Assert(source != null);
                System.Diagnostics.Debug.Assert(aliasesForLifting != null);
                Visitor v = new Visitor(false, aliasesForLifting, liftedExpressions);

                v.VisitSource(source);
                return(v.canLiftAll);
            }
Exemplo n.º 11
0
            private bool HasTrivialSource(SqlSource node)
            {
                SqlAlias alias = node as SqlAlias;

                if (alias == null)
                {
                    return(false);
                }
                return(alias.Node is SqlSelect);
            }
Exemplo n.º 12
0
            private bool HasTrivialSource(SqlSource node)
            {
                SqlJoin join = node as SqlJoin;

                if (join != null)
                {
                    return(this.HasTrivialSource(join.Left) &&
                           this.HasTrivialSource(join.Right));
                }
                return(node is SqlAlias);
            }
Exemplo n.º 13
0
 internal SqlJoin MakeJoin(SqlJoinType joinType, SqlSource location, SqlAlias alias, SqlExpression condition, Expression source)
 {
     if (joinType == SqlJoinType.LeftOuter)
     {
         var sqlSelect = alias.Node as SqlSelect;
         if (sqlSelect != null && sqlSelect.Selection != null && sqlSelect.Selection.NodeType != SqlNodeType.OptionalValue)
         {
             sqlSelect.Selection = new SqlOptionalValue(new SqlColumn("test", Unary(SqlNodeType.OuterJoinedValue, Value(typeof(int?), TypeProvider.From(typeof(int)), 1, false, source))), sqlSelect.Selection);
         }
     }
     return(new SqlJoin(joinType, location, alias, condition, source));
 }
            internal override SqlSelect VisitSelect(SqlSelect select)
            {
                SqlSource            from = this.VisitSource(select.From);
                List <SqlExpression> gex  = null;

                if (select.GroupBy.Count > 0)
                {
                    gex = new List <SqlExpression>(select.GroupBy.Count);
                    foreach (SqlExpression sqlExpr in select.GroupBy)
                    {
                        gex.Add((SqlExpression)this.Visit(sqlExpr));
                    }
                }
                SqlExpression             having = (SqlExpression)this.Visit(select.Having);
                List <SqlOrderExpression> lex    = null;

                if (select.OrderBy.Count > 0)
                {
                    lex = new List <SqlOrderExpression>(select.OrderBy.Count);
                    foreach (SqlOrderExpression sox in select.OrderBy)
                    {
                        SqlOrderExpression nsox = new SqlOrderExpression(sox.OrderType, (SqlExpression)this.Visit(sox.Expression));
                        lex.Add(nsox);
                    }
                }
                SqlExpression top = (SqlExpression)this.Visit(select.Top);

                SqlExpression where = (SqlExpression)this.Visit(select.Where);
                SqlRow        row       = (SqlRow)this.Visit(select.Row);
                SqlExpression selection = this.VisitExpression(select.Selection);

                SqlSelect n = new SqlSelect(selection, from, select.SourceExpression);

                if (gex != null)
                {
                    n.GroupBy.AddRange(gex);
                }
                n.Having = having;
                if (lex != null)
                {
                    n.OrderBy.AddRange(lex);
                }
                n.OrderingType = select.OrderingType;
                n.Row          = row;
                n.Top          = top;
                n.IsDistinct   = select.IsDistinct;
                n.IsPercent    = select.IsPercent;
                n.Where        = where;
                n.DoNotOutput  = select.DoNotOutput;
                return(n);
            }
Exemplo n.º 15
0
            private SqlUnion GetUnion(SqlSource source)
            {
                SqlAlias alias = source as SqlAlias;

                if (alias != null)
                {
                    SqlUnion union = alias.Node as SqlUnion;
                    if (union != null)
                    {
                        return(union);
                    }
                }
                return(null);
            }
Exemplo n.º 16
0
            internal override SqlSelect VisitSelect(SqlSelect select)
            {
                SqlSource            from = VisitSource(select.From);
                List <SqlExpression> list = null;

                if (select.GroupBy.Count > 0)
                {
                    list = new List <SqlExpression>(select.GroupBy.Count);
                    foreach (var item2 in select.GroupBy)
                    {
                        list.Add((SqlExpression)Visit(item2));
                    }
                }
                var having = (SqlExpression)Visit(select.Having);
                List <SqlOrderExpression> list2 = null;

                if (select.OrderBy.Count > 0)
                {
                    list2 = new List <SqlOrderExpression>(select.OrderBy.Count);
                    foreach (var item3 in select.OrderBy)
                    {
                        var item = new SqlOrderExpression(item3.OrderType, (SqlExpression)Visit(item3.Expression));
                        list2.Add(item);
                    }
                }
                var top = (SqlExpression)Visit(select.Top);

                var where = (SqlExpression)Visit(select.Where);
                var           row       = (SqlRow)Visit(select.Row);
                SqlExpression selection = VisitExpression(select.Selection);
                var           sqlSelect = new SqlSelect(selection, from, select.SourceExpression);

                if (list != null)
                {
                    sqlSelect.GroupBy.AddRange(list);
                }
                sqlSelect.Having = having;
                if (list2 != null)
                {
                    sqlSelect.OrderBy.AddRange(list2);
                }
                sqlSelect.OrderingType = select.OrderingType;
                sqlSelect.Row          = row;
                sqlSelect.Top          = top;
                sqlSelect.IsDistinct   = select.IsDistinct;
                sqlSelect.IsPercent    = select.IsPercent;
                sqlSelect.Where        = where;
                sqlSelect.DoNotOutput  = select.DoNotOutput;
                return(sqlSelect);
            }
Exemplo n.º 17
0
            internal override SqlSource VisitSource(SqlSource node)
            {
                node = (SqlSource)this.Visit(node);
                SqlAlias alias = node as SqlAlias;

                if (alias != null)
                {
                    SqlSelect sel = alias.Node as SqlSelect;
                    if (sel != null && this.IsTrivialSelect(sel))
                    {
                        this.removedMap[alias] = alias;
                        node = sel.From;
                    }
                }
                return(node);
            }
Exemplo n.º 18
0
            private void GetSelectionsBeforeJoin(SqlSource source, List <List <SqlColumn> > selections)
            {
                SqlJoin join = source as SqlJoin;

                if (join != null)
                {
                    return;
                }
                SqlAlias alias = source as SqlAlias;

                if (alias != null)
                {
                    SqlSelect select = alias.Node as SqlSelect;
                    if (select != null)
                    {
                        this.GetSelectionsBeforeJoin(select.From, selections);
                        selections.Add(select.Row.Columns);
                    }
                }
            }
Exemplo n.º 19
0
            private bool IsSingletonSelect(SqlSource source)
            {
                SqlAlias alias = source as SqlAlias;

                if (alias == null)
                {
                    return(false);
                }
                SqlSelect select = alias.Node as SqlSelect;

                if (select == null)
                {
                    return(false);
                }
                if (select.From != null)
                {
                    return(false);
                }
                return(true);
            }
Exemplo n.º 20
0
            private bool HasEmptySource(SqlSource node)
            {
                SqlAlias alias = node as SqlAlias;

                if (alias == null)
                {
                    return(false);
                }
                SqlSelect sel = alias.Node as SqlSelect;

                if (sel == null)
                {
                    return(false);
                }
                return(sel.Row.Columns.Count == 0 &&
                       sel.From == null &&
                       sel.Where == null &&
                       sel.GroupBy.Count == 0 &&
                       sel.Having == null &&
                       sel.OrderBy.Count == 0);
            }
 internal SqlJoin MakeJoin(SqlJoinType joinType, SqlSource location, SqlAlias alias, SqlExpression condition, Expression source)
 {
     // if the new item is on the right side of some outer join then fixup the projection to reflect that it can possibly be null
     if (joinType == SqlJoinType.LeftOuter)
     {
         SqlSelect sel = alias.Node as SqlSelect;
         if (sel != null && sel.Selection != null && sel.Selection.NodeType != SqlNodeType.OptionalValue)
         {
             // replace selection w/ optional + outer-joined-value
             sel.Selection = new SqlOptionalValue(
                 new SqlColumn(
                     "test",
                     this.Unary(SqlNodeType.OuterJoinedValue,
                                this.Value(typeof(int?), this.typeProvider.From(typeof(int)), 1, false, source))
                     ),
                 sel.Selection
                 );
         }
     }
     return(new SqlJoin(joinType, location, alias, condition, source));
 }
Exemplo n.º 22
0
 internal void BuildEqivalenceMap(SqlSource scope)
 {
     this.map = new Dictionary <SqlColumn, SqlColumn>();
     this.Visit(scope);
 }
Exemplo n.º 23
0
 internal virtual SqlSource VisitSource(SqlSource source)
 {
     return((SqlSource)this.Visit(source));
 }
Exemplo n.º 24
0
 internal override SqlSource VisitSource(SqlSource source)
 {
     return(source);
 }
Exemplo n.º 25
0
            internal override SqlSource VisitSource(SqlSource source)
            {
                source = base.VisitSource(source);

                SqlJoin join = source as SqlJoin;

                if (join != null)
                {
                    if (join.JoinType == SqlJoinType.OuterApply)
                    {
                        // Reduce outer-apply into left-outer-join
                        HashSet <SqlAlias>      leftProducedAliases = SqlGatherProducedAliases.Gather(join.Left);
                        HashSet <SqlExpression> liftedExpressions   = new HashSet <SqlExpression>();

                        if (SqlPredicateLifter.CanLift(join.Right, leftProducedAliases, liftedExpressions) &&
                            SqlSelectionLifter.CanLift(join.Right, leftProducedAliases, liftedExpressions) &&
                            !SqlAliasDependencyChecker.IsDependent(join.Right, leftProducedAliases, liftedExpressions))
                        {
                            SqlExpression            liftedPredicate  = SqlPredicateLifter.Lift(join.Right, leftProducedAliases);
                            List <List <SqlColumn> > liftedSelections = SqlSelectionLifter.Lift(join.Right, leftProducedAliases, liftedExpressions);

                            join.JoinType  = SqlJoinType.LeftOuter;
                            join.Condition = liftedPredicate;

                            if (liftedSelections != null)
                            {
                                foreach (List <SqlColumn> selection in liftedSelections)
                                {
                                    source = this.PushSourceDown(source, selection);
                                }
                            }
                        }
                        else
                        {
                            this.AnnotateSqlIncompatibility(join, SqlProvider.ProviderMode.Sql2000);
                        }
                    }
                    else if (join.JoinType == SqlJoinType.CrossApply)
                    {
                        // reduce cross apply with special nested left-outer-join's into a single left-outer-join
                        //
                        // SELECT x.*, y.*
                        // FROM X
                        // CROSS APPLY (
                        //      SELECT y.*
                        //       FROM (
                        //          SELECT ?
                        //       )
                        //       LEFT OUTER JOIN (
                        //          SELECT y.* FROM Y
                        //       ) AS y
                        //
                        // ==>
                        //
                        // SELECT x.*, y.*
                        // FROM X
                        // LEFT OUTER JOIN (
                        //     SELECT y.* FROM Y
                        // )

                        SqlJoin leftOuter = this.GetLeftOuterWithUnreferencedSingletonOnLeft(join.Right);
                        if (leftOuter != null)
                        {
                            HashSet <SqlAlias>      leftProducedAliases = SqlGatherProducedAliases.Gather(join.Left);
                            HashSet <SqlExpression> liftedExpressions   = new HashSet <SqlExpression>();

                            if (SqlPredicateLifter.CanLift(leftOuter.Right, leftProducedAliases, liftedExpressions) &&
                                SqlSelectionLifter.CanLift(leftOuter.Right, leftProducedAliases, liftedExpressions) &&
                                !SqlAliasDependencyChecker.IsDependent(leftOuter.Right, leftProducedAliases, liftedExpressions)
                                )
                            {
                                SqlExpression            liftedPredicate  = SqlPredicateLifter.Lift(leftOuter.Right, leftProducedAliases);
                                List <List <SqlColumn> > liftedSelections = SqlSelectionLifter.Lift(leftOuter.Right, leftProducedAliases, liftedExpressions);

                                // add intermediate selections
                                this.GetSelectionsBeforeJoin(join.Right, liftedSelections);

                                // push down all selections
                                foreach (List <SqlColumn> selection in liftedSelections.Where(s => s.Count > 0))
                                {
                                    source = this.PushSourceDown(source, selection);
                                }

                                join.JoinType  = SqlJoinType.LeftOuter;
                                join.Condition = this.factory.AndAccumulate(leftOuter.Condition, liftedPredicate);
                                join.Right     = leftOuter.Right;
                            }
                            else
                            {
                                this.AnnotateSqlIncompatibility(join, SqlProvider.ProviderMode.Sql2000);
                            }
                        }
                    }

                    // re-balance join tree of left-outer-joins to expose LOJ w/ leftside unreferenced
                    while (join.JoinType == SqlJoinType.LeftOuter)
                    {
                        // look for buried left-outer-joined-with-unreferenced singleton
                        SqlJoin leftLeftOuter = this.GetLeftOuterWithUnreferencedSingletonOnLeft(join.Left);
                        if (leftLeftOuter == null)
                        {
                            break;
                        }

                        List <List <SqlColumn> > liftedSelections = new List <List <SqlColumn> >();

                        // add intermediate selections
                        this.GetSelectionsBeforeJoin(join.Left, liftedSelections);

                        // push down all selections
                        foreach (List <SqlColumn> selection in liftedSelections)
                        {
                            source = this.PushSourceDown(source, selection);
                        }

                        // bubble this one up on-top of this 'join'.
                        SqlSource     jRight     = join.Right;
                        SqlExpression jCondition = join.Condition;

                        join.Left      = leftLeftOuter.Left;
                        join.Right     = leftLeftOuter;
                        join.Condition = leftLeftOuter.Condition;

                        leftLeftOuter.Left      = leftLeftOuter.Right;
                        leftLeftOuter.Right     = jRight;
                        leftLeftOuter.Condition = jCondition;
                    }
                }

                return(source);
            }