internal override SqlExpression VisitMultiset(SqlSubSelect sms) { // allow one big-join per query? if ((this.options & SqlMultiplexerOptionType.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); } return(QueryExtractor.Extract(sms, this.parentParameters)); }
protected override SqlSelect GenerateSkipTake(SqlSelect sequence, SqlExpression skipExp, SqlExpression takeExp) { //return base.GenerateSkipTake(sequence, skipExp, takeExp); SqlSelect node = LockSelect(sequence); var value2 = skipExp as SqlValue; if ((skipExp == null) || ((value2 != null) && (((int)value2.Value) <= 0))) { skipExp = sql.ValueFromObject(0, dominatingExpression); } var alias = new SqlAlias(node); var selection = new SqlAliasRef(alias); if (UseConverterStrategy(ConverterStrategy.SkipWithRowNumber)) { var col = new SqlColumn("ROW_NUMBER", this.sql.RowNumber(new List <SqlOrderExpression>(), this.dominatingExpression)); var expr = new SqlColumnRef(col); node.Row.Columns.Add(col); var select2 = new SqlSelect(selection, alias, this.dominatingExpression); if (takeExp != null) { select2.Where = this.sql.Between(expr, this.sql.Add(skipExp, 1), this.sql.Binary(SqlNodeType.Add, (SqlExpression)SqlDuplicator.Copy(skipExp), takeExp), this.dominatingExpression); return(select2); } select2.Where = this.sql.Binary(SqlNodeType.GT, expr, skipExp); return(select2); } if (!this.CanSkipOnSelection(node.Selection)) { throw SqlClient.Error.SkipNotSupportedForSequenceTypes(); } var visitor = new SingleTableQueryVisitor(); visitor.Visit(node); if (!visitor.IsValid) { throw ALinq.SqlClient.Error.SkipRequiresSingleTableQueryWithPKs(); } var select3 = (SqlSelect)SqlDuplicator.Copy(node); select3.Top = skipExp; var alias2 = new SqlAlias(select3); var ref4 = new SqlAliasRef(alias2); var select = new SqlSelect(ref4, alias2, this.dominatingExpression); select.Where = this.sql.Binary(SqlNodeType.EQ2V, selection, ref4); SqlSubSelect expression = this.sql.SubSelect(SqlNodeType.Exists, select); var select6 = new SqlSelect(selection, alias, this.dominatingExpression); select6.Where = this.sql.Unary(SqlNodeType.Not, expression, this.dominatingExpression); select6.Top = takeExp; return(select6); }
//private new void Initialize(IDataServices dataServices, IDbConnection connection) //{ // services = dataServices; // conManager = new SqlConnectionManager(this, (DbConnection)connection, 100); // var type = typeof(ALinq.Oracle.DataReader); // readerCompiler = new ObjectReaderCompiler(type, services); // InitializeProviderMode(); //} internal override ICompiledSubQuery CompileSubQuery(SqlNode query, Type elementType, ReadOnlyCollection <SqlParameter> parameters) { query = SqlDuplicator.Copy(query); var annotations = new SqlNodeAnnotations(); var queries = BuildQuery(ResultShape.Sequence, TypeSystem.GetSequenceType(elementType), query, parameters, annotations); var queryInfo = queries[0]; //Set CommandText queryInfo.CommandText = new OracleFormatter(this).Format(queryInfo.Query); ICompiledSubQuery[] subQueries = CompileSubQueries(queryInfo.Query); IObjectReaderFactory readerFactory = GetReaderFactory(queryInfo.Query, elementType); CheckSqlCompatibility(queries, annotations); return(new CompiledSubQuery(queryInfo, readerFactory, parameters, subQueries)); }
internal override ICompiledSubQuery CompileSubQuery(SqlNode query, Type elementType, ReadOnlyCollection <SqlParameter> parameters) { query = SqlDuplicator.Copy(query); var annotations = new SqlNodeAnnotations(); QueryInfo[] queries = BuildQuery(ResultShape.Sequence, TypeSystem.GetSequenceType(elementType), query, parameters, annotations); QueryInfo queryInfo = queries[0]; ICompiledSubQuery[] subQueries = this.CompileSubQueries(queryInfo.Query); var formatter = new MySqlFormatter(this); for (int i = 0; i < subQueries.Length; i++) { var subQuery = (CompiledSubQuery)subQueries[i]; subQuery.QueryInfo.CommandText = formatter.Format(subQuery.QueryInfo.Query); } IObjectReaderFactory readerFactory = this.GetReaderFactory(queryInfo.Query, elementType); CheckSqlCompatibility(queries, annotations); return(new CompiledSubQuery(queryInfo, readerFactory, parameters, subQueries, connectionString, this)); }
internal override SqlRowNumber VisitRowNumber(SqlRowNumber rowNumber) { if (rowNumber.OrderBy.Count > 0) { return(rowNumber); } SqlDuplicator dup = new SqlDuplicator(true); List <SqlOrderExpression> orderBy = new List <SqlOrderExpression>(); List <SqlOrderExpression> existingOrders = new List <SqlOrderExpression>(); if (this.rowNumberOrders != null && this.rowNumberOrders.Count != 0) { existingOrders = new List <SqlOrderExpression>(this.rowNumberOrders); } else if (this.orders != null) { existingOrders = new List <SqlOrderExpression>(this.orders); } foreach (SqlOrderExpression expr in existingOrders) { if (!expr.Expression.IsConstantColumn) { orderBy.Add(expr); if (this.rowNumberOrders != null) { this.rowNumberOrders.Remove(expr); } if (this.orders != null) { this.orders.Remove(expr); } } } rowNumber.OrderBy.Clear(); if (orderBy.Count == 0) { List <SqlColumn> columns = SqlGatherColumnsProduced.GatherColumns(this.currentSelect.From); foreach (SqlColumn col in columns) { if (col.Expression.SqlType.IsOrderable) { orderBy.Add(new SqlOrderExpression(SqlOrderType.Ascending, new SqlColumnRef(col))); } } if (orderBy.Count == 0) { // insert simple column SqlColumn col = new SqlColumn( "rowNumberOrder", sql.Value(typeof(int), this.typeProvider.From(typeof(int)), 1, false, rowNumber.SourceExpression) ); this.PushDown(col); orderBy.Add(new SqlOrderExpression(SqlOrderType.Ascending, new SqlColumnRef(col))); } } foreach (SqlOrderExpression sox in orderBy) { rowNumber.OrderBy.Add(new SqlOrderExpression(sox.OrderType, (SqlExpression)dup.Duplicate(sox.Expression))); } return(rowNumber); }
internal override SqlSelect VisitSelect(SqlSelect select) { bool saveTop = this.topSelect; bool savePK = this.addPrimaryKeys; SqlSelect saveSelect = this.currentSelect; this.currentSelect = select; if (select.OrderingType == SqlOrderingType.Always) { this.addPrimaryKeys = true; } this.topSelect = false; // can't forward ordering information through a group-by if (select.GroupBy.Count > 0) { this.Visit(select.From); this.orders = null; } else { this.Visit(select.From); } if (select.OrderBy.Count > 0) { this.PrependOrderExpressions(select.OrderBy); } List <SqlOrderExpression> save = this.orders; this.orders = null; this.rowNumberOrders = save; // lest orders be null when we need info /* do all the lower level stuff */ select.Where = this.VisitExpression(select.Where); for (int i = 0, n = select.GroupBy.Count; i < n; i++) { select.GroupBy[i] = this.VisitExpression(select.GroupBy[i]); } select.Having = this.VisitExpression(select.Having); for (int i = 0, n = select.OrderBy.Count; i < n; i++) { select.OrderBy[i].Expression = this.VisitExpression(select.OrderBy[i].Expression); } select.Top = this.VisitExpression(select.Top); select.Selection = this.VisitExpression(select.Selection); select.Row = (SqlRow)this.Visit(select.Row); this.topSelect = saveTop; this.addPrimaryKeys = savePK; this.orders = save; // all ordering is blocked for this layer and above if (select.OrderingType == SqlOrderingType.Blocked) { this.orders = null; } // rebuild orderby expressions, provided this select doesn't contain a SqlRowNumber // otherwise, replace the orderby with a reference to that column select.OrderBy.Clear(); var rowNumberChecker = new SqlRowNumberChecker(); if (rowNumberChecker.HasRowNumber(select) && rowNumberChecker.RowNumberColumn != null) { select.Row.Columns.Remove(rowNumberChecker.RowNumberColumn); this.PushDown(rowNumberChecker.RowNumberColumn); this.Orders.Add(new SqlOrderExpression(SqlOrderType.Ascending, new SqlColumnRef(rowNumberChecker.RowNumberColumn))); } if ((this.topSelect || select.Top != null) && select.OrderingType != SqlOrderingType.Never && this.orders != null) { this.orders = new HashSet <SqlOrderExpression>(this.orders).ToList(); SqlDuplicator dup = new SqlDuplicator(true); foreach (SqlOrderExpression sox in this.orders) { select.OrderBy.Add(new SqlOrderExpression(sox.OrderType, (SqlExpression)dup.Duplicate(sox.Expression))); } } this.currentSelect = saveSelect; return(select); }