internal SqlClientQuery(SqlSubSelect subquery) : base(SqlNodeType.ClientQuery, subquery.ClrType, subquery.SqlType, subquery.SourceExpression) { query = subquery; arguments = new List <SqlExpression>(); parameters = new List <SqlParameter>(); }
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)); } }
internal override SqlExpression VisitSubSelect(SqlSubSelect ss) { List <SqlOrderExpression> save = this.orders; this.orders = new List <SqlOrderExpression>(); base.VisitSubSelect(ss); this.orders = save; return(ss); }
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); }
internal override SqlExpression VisitSubSelect(SqlSubSelect ss) { bool saveIsTopLevel = this.isTopLevel; try { return(base.VisitSubSelect(ss)); } finally { this.isTopLevel = saveIsTopLevel; } }
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); }
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])); }
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); }
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; } }
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; } }
internal virtual SqlExpression VisitExists(SqlSubSelect sqlExpr) { sqlExpr.Select = this.VisitSequence(sqlExpr.Select); return(sqlExpr); }
internal virtual SqlExpression VisitElement(SqlSubSelect elem) { elem.Select = this.VisitSequence(elem.Select); return(elem); }
internal virtual SqlExpression VisitMultiset(SqlSubSelect sms) { sms.Select = this.VisitSequence(sms.Select); return(sms); }
internal override SqlExpression VisitElement(SqlSubSelect elem) { return(this.VisitMultiset(elem)); }
internal override SqlExpression VisitSubSelect(SqlSubSelect ss) { return((SqlExpression) new SqlDuplicator().Duplicate(ss)); }
internal override SqlExpression VisitMultiset(SqlSubSelect sms) { this.foundMultiset = true; return(sms); }
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))); }
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); }
// ignore subquery in selection internal override SqlExpression VisitSubSelect(SqlSubSelect ss) { return(ss); }
internal virtual SqlExpression VisitScalarSubSelect(SqlSubSelect ss) { ss.Select = this.VisitSequence(ss.Select); return(ss); }
internal override SqlExpression VisitElement(SqlSubSelect elem) { return(QueryExtractor.Extract(elem, this.parentParameters)); }
internal override SqlExpression VisitScalarSubSelect(SqlSubSelect ss) { base.VisitScalarSubSelect(ss); ss.SetSqlType(ss.Select.Selection.SqlType); return(ss); }
internal override SqlExpression VisitElement(SqlSubSelect elem) { return(elem); }