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);
        }
Exemple #3
0
        //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));
        }
Exemple #4
0
        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);
        }