Beispiel #1
0
 internal SqlClientQuery(SqlSubSelect subquery)
     : base(SqlNodeType.ClientQuery, subquery.ClrType, subquery.SqlType, subquery.SourceExpression)
 {
     query      = subquery;
     arguments  = new List <SqlExpression>();
     parameters = new List <SqlParameter>();
 }
Beispiel #2
0
            internal override SqlExpression VisitMultiset(SqlSubSelect sms)
            {
                // allow one big-join per query?
                if ((this.options & Options.EnableBigJoin) != 0 &&
                    !this.hasBigJoin && this.canJoin && this.isTopLevel && this.outerSelect != null &&
                    !MultisetChecker.HasMultiset(sms.Select.Selection) &&
                    BigJoinChecker.CanBigJoin(sms.Select))
                {
                    sms.Select = this.VisitSelect(sms.Select);

                    SqlAlias alias = new SqlAlias(sms.Select);
                    SqlJoin  join  = new SqlJoin(SqlJoinType.OuterApply, this.outerSelect.From, alias, null, sms.SourceExpression);
                    this.outerSelect.From         = join;
                    this.outerSelect.OrderingType = SqlOrderingType.Always;

                    // make joined expression
                    SqlExpression expr = (SqlExpression)SqlDuplicator.Copy(sms.Select.Selection);

                    // make count expression
                    SqlSelect copySelect  = (SqlSelect)SqlDuplicator.Copy(sms.Select);
                    SqlAlias  copyAlias   = new SqlAlias(copySelect);
                    SqlSelect countSelect = new SqlSelect(sql.Unary(SqlNodeType.Count, null, sms.SourceExpression), copyAlias, sms.SourceExpression);
                    countSelect.OrderingType = SqlOrderingType.Never;
                    SqlExpression count = sql.SubSelect(SqlNodeType.ScalarSubSelect, countSelect);

                    // make joined collection
                    SqlJoinedCollection jc = new SqlJoinedCollection(sms.ClrType, sms.SqlType, expr, count, sms.SourceExpression);
                    this.hasBigJoin = true;
                    return(jc);
                }
                else
                {
                    return(QueryExtractor.Extract(sms, this.parentParameters));
                }
            }
Beispiel #3
0
            internal override SqlExpression VisitSubSelect(SqlSubSelect ss)
            {
                List <SqlOrderExpression> save = this.orders;

                this.orders = new List <SqlOrderExpression>();
                base.VisitSubSelect(ss);
                this.orders = save;
                return(ss);
            }
Beispiel #4
0
            internal override SqlExpression VisitSubSelect(SqlSubSelect ss)
            {
                Scope save = this.CurrentScope;

                this.CurrentScope = new Scope(null, this.CurrentScope);
                base.VisitSubSelect(ss);
                this.CurrentScope = save;
                return(ss);
            }
            internal override SqlExpression VisitSubSelect(SqlSubSelect ss)
            {
                // block where clauses from being lifted out of a sub-query
                Scope save = this.current;

                this.current = null;
                SqlExpression result = base.VisitSubSelect(ss);

                this.current = save;
                return(result);
            }
 internal override SqlExpression VisitScalarSubSelect(SqlSubSelect ss)
 {
     base.VisitScalarSubSelect(ss);
     if (ss.Select.Row.Columns.Count > 0)
     {
         System.Diagnostics.Debug.Assert(ss != null && ss.Select != null && ss.Select.Row != null && ss.Select.Row.Columns.Count == 1);
         // make sure these scalar subselects don't get redundantly named
         ss.Select.Row.Columns[0].Name = "";
     }
     return(ss);
 }
Beispiel #7
0
            internal override SqlExpression VisitSubSelect(SqlSubSelect ss)
            {
                bool saveIsTopLevel = this.isTopLevel;

                try {
                    return(base.VisitSubSelect(ss));
                }
                finally {
                    this.isTopLevel = saveIsTopLevel;
                }
            }
Beispiel #8
0
        internal static SqlClientQuery Extract(SqlSubSelect subquery, IEnumerable <System.Data.Linq.SqlClient.SqlParameter> parentParameters)
        {
            SqlClientQuery cq = new SqlClientQuery(subquery);

            if (parentParameters != null)
            {
                cq.Parameters.AddRange(parentParameters);
            }
            Visitor v = new Visitor(cq.Arguments, cq.Parameters);

            cq.Query = (SqlSubSelect)v.Visit(subquery);
            return(cq);
        }
Beispiel #9
0
        internal virtual SqlExpression VisitSubSelect(SqlSubSelect ss)
        {
            switch (ss.NodeType)
            {
            case SqlNodeType.ScalarSubSelect: return(this.VisitScalarSubSelect(ss));

            case SqlNodeType.Multiset: return(this.VisitMultiset(ss));

            case SqlNodeType.Element: return(this.VisitElement(ss));

            case SqlNodeType.Exists: return(this.VisitExists(ss));
            }
            throw Error.UnexpectedNode(ss.NodeType);
        }
            internal override SqlExpression VisitScalarSubSelect(SqlSubSelect ss)
            {
                SqlSelect innerSelect = this.VisitSelect(ss.Select);

                if (!this.aggregateChecker.HasAggregates(innerSelect))
                {
                    innerSelect.Top = this.sql.ValueFromObject(1, ss.SourceExpression);
                }
                innerSelect.OrderingType = SqlOrderingType.Blocked;
                SqlAlias alias = new SqlAlias(innerSelect);

                this.currentSelect.From = new SqlJoin(SqlJoinType.OuterApply, this.currentSelect.From, alias, null, ss.SourceExpression);
                return(new SqlColumnRef(innerSelect.Row.Columns[0]));
            }
Beispiel #11
0
        internal SqlNode TranslateLink(SqlLink link, List <SqlExpression> keyExpressions, bool asExpression)
        {
            MetaDataMember mm = link.Member;

            if (mm.IsAssociation)
            {
                // Create the row source.
                MetaType   otherType = mm.Association.OtherType;
                Type       tableType = otherType.InheritanceRoot.Type;
                ITable     table     = this.services.Context.GetTable(tableType);
                Expression source    = new LinkedTableExpression(link, table, typeof(IQueryable <>).MakeGenericType(otherType.Type));
                // Build key expression nodes.
                Expression[] keyExprs = new Expression[keyExpressions.Count];
                for (int i = 0; i < keyExpressions.Count; ++i)
                {
                    MetaDataMember metaMember = mm.Association.OtherKey[i];
                    Type           memberType = TypeSystem.GetMemberType(metaMember.Member);
                    keyExprs[i] = InternalExpression.Known(keyExpressions[i], memberType);
                }
                Expression lex = link.Expression != null
                    ? (Expression)InternalExpression.Known(link.Expression)
                    : (Expression)Expression.Constant(null, link.Member.Member.DeclaringType);
                Expression expr = TranslateAssociation(this.services.Context, mm.Association, source, keyExprs, lex);
                // Convert
                QueryConverter qc  = new QueryConverter(this.services, this.typeProvider, this, this.sql);
                SqlSelect      sel = (SqlSelect)qc.ConvertInner(expr, link.SourceExpression);
                // Turn it into an expression is necessary
                SqlNode result = sel;
                if (asExpression)
                {
                    if (mm.Association.IsMany)
                    {
                        result = new SqlSubSelect(SqlNodeType.Multiset, link.ClrType, link.SqlType, sel);
                    }
                    else
                    {
                        result = new SqlSubSelect(SqlNodeType.Element, link.ClrType, link.SqlType, sel);
                    }
                }
                return(result);
            }
            else
            {
                System.Diagnostics.Debug.Assert(link.Expansion != null);
                System.Diagnostics.Debug.Assert(link.KeyExpressions == keyExpressions);
                // deferred expression already defined...
                return(link.Expansion);
            }
        }
            internal override SqlExpression VisitClientQuery(SqlClientQuery cq)
            {
                SqlSubSelect   query = (SqlSubSelect)this.VisitExpression(cq.Query);
                SqlClientQuery nq    = new SqlClientQuery(query);

                for (int i = 0, n = cq.Arguments.Count; i < n; i++)
                {
                    nq.Arguments.Add(this.VisitExpression(cq.Arguments[i]));
                }
                for (int i = 0, n = cq.Parameters.Count; i < n; i++)
                {
                    nq.Parameters.Add((SqlParameter)this.VisitExpression(cq.Parameters[i]));
                }
                return(nq);
            }
Beispiel #13
0
            internal override SqlExpression VisitScalarSubSelect(SqlSubSelect ss)
            {
                bool saveIsTopLevel = this.isTopLevel;

                this.isTopLevel = false;
                bool saveCanJoin = this.canJoin;

                this.canJoin = false;
                try {
                    return(base.VisitScalarSubSelect(ss));
                }
                finally {
                    this.isTopLevel = saveIsTopLevel;
                    this.canJoin    = saveCanJoin;
                }
            }
Beispiel #14
0
            internal override SqlExpression VisitScalarSubSelect(SqlSubSelect ss)
            {
                bool saveIsTopLevel = this.isTopLevel;

                this.isTopLevel = false;
                bool saveForceReferenceAll = this.forceReferenceAll;

                this.forceReferenceAll = true;
                try {
                    return(base.VisitScalarSubSelect(ss));
                }
                finally {
                    this.isTopLevel        = saveIsTopLevel;
                    this.forceReferenceAll = saveForceReferenceAll;
                }
            }
Beispiel #15
0
 internal virtual SqlExpression VisitExists(SqlSubSelect sqlExpr)
 {
     sqlExpr.Select = this.VisitSequence(sqlExpr.Select);
     return(sqlExpr);
 }
Beispiel #16
0
 internal virtual SqlExpression VisitElement(SqlSubSelect elem)
 {
     elem.Select = this.VisitSequence(elem.Select);
     return(elem);
 }
Beispiel #17
0
 internal virtual SqlExpression VisitMultiset(SqlSubSelect sms)
 {
     sms.Select = this.VisitSequence(sms.Select);
     return(sms);
 }
 internal override SqlExpression VisitElement(SqlSubSelect elem)
 {
     return(this.VisitMultiset(elem));
 }
Beispiel #19
0
 internal override SqlExpression VisitSubSelect(SqlSubSelect ss)
 {
     return((SqlExpression) new SqlDuplicator().Duplicate(ss));
 }
Beispiel #20
0
 internal override SqlExpression VisitMultiset(SqlSubSelect sms)
 {
     this.foundMultiset = true;
     return(sms);
 }
Beispiel #21
0
 internal override SqlExpression VisitMultiset(SqlSubSelect sms)
 {
     return(sms);
 }
 internal override SqlExpression VisitScalarSubSelect(SqlSubSelect ss)
 {
     return(new SqlSubSelect(SqlNodeType.ScalarSubSelect, ss.ClrType, ss.SqlType, this.VisitSequence(ss.Select)));
 }
 internal override SqlExpression VisitMultiset(SqlSubSelect sms)
 {
     return(new SqlSubSelect(sms.NodeType, sms.ClrType, sms.SqlType, (SqlSelect)this.Visit(sms.Select)));
 }
 internal override SqlExpression VisitExists(SqlSubSelect sqlExpr)
 {
     return(new SqlSubSelect(sqlExpr.NodeType, sqlExpr.ClrType, sqlExpr.SqlType, (SqlSelect)this.Visit(sqlExpr.Select)));
 }
Beispiel #25
0
        internal SqlExpression TranslateEquals(SqlBinary expr)
        {
            System.Diagnostics.Debug.Assert(
                expr.NodeType == SqlNodeType.EQ || expr.NodeType == SqlNodeType.NE ||
                expr.NodeType == SqlNodeType.EQ2V || expr.NodeType == SqlNodeType.NE2V);
            SqlExpression eLeft  = expr.Left;
            SqlExpression eRight = expr.Right;

            if (eRight.NodeType == SqlNodeType.Element)
            {
                SqlSubSelect sub    = (SqlSubSelect)eRight;
                SqlAlias     alias  = new SqlAlias(sub.Select);
                SqlAliasRef  aref   = new SqlAliasRef(alias);
                SqlSelect    select = new SqlSelect(aref, alias, expr.SourceExpression);
                select.Where = sql.Binary(expr.NodeType, sql.DoNotVisitExpression(eLeft), aref);
                return(sql.SubSelect(SqlNodeType.Exists, select));
            }
            else if (eLeft.NodeType == SqlNodeType.Element)
            {
                SqlSubSelect sub    = (SqlSubSelect)eLeft;
                SqlAlias     alias  = new SqlAlias(sub.Select);
                SqlAliasRef  aref   = new SqlAliasRef(alias);
                SqlSelect    select = new SqlSelect(aref, alias, expr.SourceExpression);
                select.Where = sql.Binary(expr.NodeType, sql.DoNotVisitExpression(eRight), aref);
                return(sql.SubSelect(SqlNodeType.Exists, select));
            }

            MetaType mtLeft  = TypeSource.GetSourceMetaType(eLeft, this.services.Model);
            MetaType mtRight = TypeSource.GetSourceMetaType(eRight, this.services.Model);

            if (eLeft.NodeType == SqlNodeType.TypeCase)
            {
                eLeft = BestIdentityNode((SqlTypeCase)eLeft);
            }
            if (eRight.NodeType == SqlNodeType.TypeCase)
            {
                eRight = BestIdentityNode((SqlTypeCase)eRight);
            }

            if (mtLeft.IsEntity && mtRight.IsEntity && mtLeft.Table != mtRight.Table)
            {
                throw Error.CannotCompareItemsAssociatedWithDifferentTable();
            }

            // do simple or no translation for non-structural types
            if (!mtLeft.IsEntity && !mtRight.IsEntity &&
                (eLeft.NodeType != SqlNodeType.New || eLeft.SqlType.CanBeColumn) &&
                (eRight.NodeType != SqlNodeType.New || eRight.SqlType.CanBeColumn))
            {
                if (expr.NodeType == SqlNodeType.EQ2V || expr.NodeType == SqlNodeType.NE2V)
                {
                    return(this.TranslateEqualsOp(expr.NodeType, sql.DoNotVisitExpression(expr.Left), sql.DoNotVisitExpression(expr.Right), false));
                }
                return(expr);
            }

            // If the two types are not comparable, we return the predicate "1=0".
            if ((mtLeft != mtRight) && (mtLeft.InheritanceRoot != mtRight.InheritanceRoot))
            {
                return(sql.Binary(SqlNodeType.EQ, sql.ValueFromObject(0, expr.SourceExpression), sql.ValueFromObject(1, expr.SourceExpression)));
            }

            List <SqlExpression> exprs1;
            List <SqlExpression> exprs2;

            SqlLink link1 = eLeft as SqlLink;

            if (link1 != null && link1.Member.IsAssociation && link1.Member.Association.IsForeignKey)
            {
                exprs1 = link1.KeyExpressions;
            }
            else
            {
                exprs1 = this.GetIdentityExpressions(mtLeft, sql.DoNotVisitExpression(eLeft));
            }

            SqlLink link2 = eRight as SqlLink;

            if (link2 != null && link2.Member.IsAssociation && link2.Member.Association.IsForeignKey)
            {
                exprs2 = link2.KeyExpressions;
            }
            else
            {
                exprs2 = this.GetIdentityExpressions(mtRight, sql.DoNotVisitExpression(eRight));
            }

            System.Diagnostics.Debug.Assert(exprs1.Count > 0);
            System.Diagnostics.Debug.Assert(exprs2.Count > 0);
            System.Diagnostics.Debug.Assert(exprs1.Count == exprs2.Count);

            SqlExpression exp    = null;
            SqlNodeType   eqKind = (expr.NodeType == SqlNodeType.EQ2V || expr.NodeType == SqlNodeType.NE2V) ? SqlNodeType.EQ2V : SqlNodeType.EQ;

            for (int i = 0, n = exprs1.Count; i < n; i++)
            {
                SqlExpression eq = this.TranslateEqualsOp(eqKind, exprs1[i], exprs2[i], !mtLeft.IsEntity);
                if (exp == null)
                {
                    exp = eq;
                }
                else
                {
                    exp = sql.Binary(SqlNodeType.And, exp, eq);
                }
            }
            if (expr.NodeType == SqlNodeType.NE || expr.NodeType == SqlNodeType.NE2V)
            {
                exp = sql.Unary(SqlNodeType.Not, exp, exp.SourceExpression);
            }
            return(exp);
        }
Beispiel #26
0
 // ignore subquery in selection
 internal override SqlExpression VisitSubSelect(SqlSubSelect ss)
 {
     return(ss);
 }
Beispiel #27
0
 internal virtual SqlExpression VisitScalarSubSelect(SqlSubSelect ss)
 {
     ss.Select = this.VisitSequence(ss.Select);
     return(ss);
 }
Beispiel #28
0
 internal override SqlExpression VisitElement(SqlSubSelect elem)
 {
     return(QueryExtractor.Extract(elem, this.parentParameters));
 }
Beispiel #29
0
 internal override SqlExpression VisitScalarSubSelect(SqlSubSelect ss)
 {
     base.VisitScalarSubSelect(ss);
     ss.SetSqlType(ss.Select.Selection.SqlType);
     return(ss);
 }
Beispiel #30
0
 internal override SqlExpression VisitElement(SqlSubSelect elem)
 {
     return(elem);
 }