コード例 #1
0
        public override SqlObject VisitLimit_count([NotNull] sqlParser.Limit_countContext context)
        {
            Contract.Requires(context != null);

            SqlLimitSpec sqlLimitSpec;

            if (context.NUMERIC_LITERAL() != null)
            {
                sqlLimitSpec = SqlLimitSpec.Create(
                    SqlNumberLiteral.Create(
                        CstToAstVisitor.GetNumber64ValueFromNode(
                            context.NUMERIC_LITERAL())));
            }
            else if (context.PARAMETER() != null)
            {
                sqlLimitSpec = SqlLimitSpec.Create(
                    SqlParameter.Create(
                        context.PARAMETER().GetText()));
            }
            else
            {
                throw new NotImplementedException();
            }

            return(sqlLimitSpec);
        }
コード例 #2
0
        public override int Visit(SqlLimitSpec sqlObject)
        {
            int hashCode = SqlLimitSpecHashCode;

            hashCode = CombineHashes(hashCode, sqlObject.LimitExpression.Accept(this));
            return(hashCode);
        }
コード例 #3
0
        private static IEnumerable <CosmosElement> ExecuteOffsetLimitClause(
            IEnumerable <CosmosElement> dataSource,
            SqlOffsetLimitClause sqlOffsetLimitClause)
        {
            SqlOffsetSpec sqlOffsetSpec = sqlOffsetLimitClause.OffsetSpec;

            if (sqlOffsetSpec != null)
            {
                CosmosNumber cosmosOffsetValue = (CosmosNumber)sqlOffsetSpec.OffsetExpression.Accept(
                    ScalarExpressionEvaluator.Singleton,
                    input: null);
                long offsetCount = Number64.ToLong(cosmosOffsetValue.Value);
                dataSource = dataSource.Skip((int)offsetCount);
            }

            SqlLimitSpec sqlLimitSpec = sqlOffsetLimitClause.LimitSpec;

            if (sqlLimitSpec != null)
            {
                CosmosNumber cosmosLimitValue = (CosmosNumber)sqlLimitSpec.LimitExpression.Accept(
                    ScalarExpressionEvaluator.Singleton,
                    input: null);
                long limitCount = Number64.ToLong(cosmosLimitValue.Value);
                dataSource = dataSource.Take((int)limitCount);
            }

            return(dataSource);
        }
コード例 #4
0
        private static long GetLimitCount(SqlLimitSpec limitSpec)
        {
            if (limitSpec == null)
            {
                throw new ArgumentNullException(nameof(limitSpec));
            }

            SqlScalarExpression limitExpression = limitSpec.LimitExpression;

            if (!(limitExpression is SqlLiteralScalarExpression limitLiteralExpression))
            {
                throw new ArgumentException($"Expected number literal scalar expression.");
            }

            SqlLiteral sqlLiteral = limitLiteralExpression.Literal;

            if (!(sqlLiteral is SqlNumberLiteral sqlNumberLiteral))
            {
                throw new ArgumentException($"Expected number literal.");
            }

            if (!sqlNumberLiteral.Value.IsInteger)
            {
                throw new ArgumentException($"Expected integer literal.");
            }

            long value = Number64.ToLong(sqlNumberLiteral.Value);

            return(value);
        }
コード例 #5
0
        public override bool Visit(SqlLimitSpec first, SqlObject secondAsObject)
        {
            if (!(secondAsObject is SqlLimitSpec second))
            {
                return(false);
            }

            return(Equals(first.LimitExpression, second.LimitExpression));
        }
コード例 #6
0
        public override SqlObject VisitOffset_limit_clause([NotNull] sqlParser.Offset_limit_clauseContext context)
        {
            Contract.Requires(context != null);
            Contract.Requires(context.offset_count() != null);
            Contract.Requires(context.limit_count() != null);

            SqlOffsetSpec sqlOffsetSpec = (SqlOffsetSpec)this.Visit(context.offset_count());
            SqlLimitSpec  sqlLimitSpec  = (SqlLimitSpec)this.Visit(context.limit_count());

            return(SqlOffsetLimitClause.Create(sqlOffsetSpec, sqlLimitSpec));
        }
コード例 #7
0
        public QueryUnderConstruction AddLimitSpec(SqlLimitSpec limitSpec, TranslationContext context)
        {
            QueryUnderConstruction result = this;

            if (result.limitSpec != null)
            {
                result.limitSpec = (result.limitSpec.Limit < limitSpec.Limit) ? result.limitSpec : limitSpec;
            }
            else
            {
                result.limitSpec = limitSpec;
            }

            return(result);
        }
コード例 #8
0
        public override SqlObject VisitOffset_limit_clause([NotNull] sqlParser.Offset_limit_clauseContext context)
        {
            Contract.Requires(context != null);

            SqlOffsetSpec sqlOffsetSpec = SqlOffsetSpec.Create(
                SqlNumberLiteral.Create(
                    CstToAstVisitor.GetNumber64ValueFromNode(
                        context.offset_count().NUMERIC_LITERAL())));

            SqlLimitSpec sqlLimitSpec = SqlLimitSpec.Create(
                SqlNumberLiteral.Create(
                    CstToAstVisitor.GetNumber64ValueFromNode(
                        context.limit_count().NUMERIC_LITERAL())));

            return(SqlOffsetLimitClause.Create(sqlOffsetSpec, sqlLimitSpec));
        }
コード例 #9
0
        public QueryUnderConstruction AddLimitSpec(SqlLimitSpec limitSpec, TranslationContext context)
        {
            QueryUnderConstruction result = this;

            if (result.limitSpec != null)
            {
                long accumulatedLimitCount = QueryUnderConstruction.GetLimitCount(result.limitSpec);
                long currentLimitCount     = QueryUnderConstruction.GetLimitCount(limitSpec);
                if (currentLimitCount < accumulatedLimitCount)
                {
                    result.limitSpec = limitSpec;
                }
            }
            else
            {
                result.limitSpec = limitSpec;
            }

            return(result);
        }
コード例 #10
0
 public abstract void Visit(SqlLimitSpec sqlObject);
コード例 #11
0
        /// <summary>
        /// Flatten subqueries into a single query by substituting their expressions in the current query.
        /// </summary>
        /// <returns>A flattened query.</returns>
        private QueryUnderConstruction Flatten()
        {
            // SELECT fo(y) FROM y IN (SELECT fi(x) FROM x WHERE gi(x)) WHERE go(y)
            // is translated by substituting fi(x) for y in the outer query
            // producing
            // SELECT fo(fi(x)) FROM x WHERE gi(x) AND (go(fi(x))
            if (this.inputQuery == null)
            {
                // we are flat already
                if (this.selectClause == null)
                {
                    // If selectClause doesn't exists, use SELECT v0 where v0 is the input parameter, instead of SELECT *.
                    string parameterName = this.fromParameters.GetInputParameter().Name;
                    SqlScalarExpression parameterExpression = SqlPropertyRefScalarExpression.Create(null, SqlIdentifier.Create(parameterName));
                    this.selectClause = SqlSelectClause.Create(SqlSelectValueSpec.Create(parameterExpression));
                }
                else
                {
                    this.selectClause = SqlSelectClause.Create(this.selectClause.SelectSpec, this.topSpec, this.selectClause.HasDistinct);
                }

                return(this);
            }

            QueryUnderConstruction flatInput   = this.inputQuery.Flatten();
            SqlSelectClause        inputSelect = flatInput.selectClause;
            SqlWhereClause         inputwhere  = flatInput.whereClause;

            // Determine the paramName to be replaced in the current query
            // It should be the top input parameter name which is not binded in this collection.
            // That is because if it has been binded before, it has global scope and should not be replaced.
            string           paramName        = null;
            HashSet <string> inputQueryParams = new HashSet <string>();

            foreach (Binding binding in this.inputQuery.fromParameters.GetBindings())
            {
                inputQueryParams.Add(binding.Parameter.Name);
            }

            foreach (Binding binding in this.fromParameters.GetBindings())
            {
                if (binding.ParameterDefinition == null || inputQueryParams.Contains(binding.Parameter.Name))
                {
                    paramName = binding.Parameter.Name;
                }
            }

            SqlIdentifier         replacement     = SqlIdentifier.Create(paramName);
            SqlSelectClause       composedSelect  = Substitute(inputSelect, inputSelect.TopSpec ?? this.topSpec, replacement, this.selectClause);
            SqlWhereClause        composedWhere   = Substitute(inputSelect.SelectSpec, replacement, this.whereClause);
            SqlOrderbyClause      composedOrderBy = Substitute(inputSelect.SelectSpec, replacement, this.orderByClause);
            SqlWhereClause        and             = QueryUnderConstruction.CombineWithConjunction(inputwhere, composedWhere);
            FromParameterBindings fromParams      = QueryUnderConstruction.CombineInputParameters(flatInput.fromParameters, this.fromParameters);
            SqlOffsetSpec         offsetSpec;
            SqlLimitSpec          limitSpec;

            if (flatInput.offsetSpec != null)
            {
                offsetSpec = flatInput.offsetSpec;
                limitSpec  = flatInput.limitSpec;
            }
            else
            {
                offsetSpec = this.offsetSpec;
                limitSpec  = this.limitSpec;
            }
            QueryUnderConstruction result = new QueryUnderConstruction(this.aliasCreatorFunc)
            {
                selectClause   = composedSelect,
                whereClause    = and,
                inputQuery     = null,
                fromParameters = flatInput.fromParameters,
                orderByClause  = composedOrderBy ?? this.inputQuery.orderByClause,
                offsetSpec     = offsetSpec,
                limitSpec      = limitSpec,
                alias          = new Lazy <ParameterExpression>(() => this.Alias)
            };

            return(result);
        }
コード例 #12
0
        /// <summary>
        /// Convert the entire query to a SQL Query.
        /// </summary>
        /// <returns>The corresponding SQL Query.</returns>
        public SqlQuery GetSqlQuery()
        {
            SqlFromClause fromClause;

            if (this.inputQuery != null)
            {
#if SUPPORT_SUBQUERIES
                fromClause = this.CreateSubqueryFromClause();
#else
                throw new DocumentQueryException("SQL subqueries currently not supported");
#endif
            }
            else
            {
                fromClause = this.CreateFrom(inputCollectionExpression: null);
            }

            // Create a SqlSelectClause with the topSpec.
            // If the query is flatten then selectClause may have a topSpec. It should be taken in that case.
            // If the query doesn't have a selectClause, use SELECT v0 where v0 is the input param.
            SqlSelectClause selectClause = this.selectClause;
            if (selectClause == null)
            {
                string parameterName = this.fromParameters.GetInputParameter().Name;
                SqlScalarExpression parameterExpression = SqlPropertyRefScalarExpression.Create(null, SqlIdentifier.Create(parameterName));
                selectClause = this.selectClause = SqlSelectClause.Create(SqlSelectValueSpec.Create(parameterExpression));
            }
            selectClause = SqlSelectClause.Create(selectClause.SelectSpec, selectClause.TopSpec ?? this.topSpec, selectClause.HasDistinct);
            SqlOffsetLimitClause offsetLimitClause = (this.offsetSpec != null) ?
                                                     SqlOffsetLimitClause.Create(this.offsetSpec, this.limitSpec ?? SqlLimitSpec.Create(int.MaxValue)) :
                                                     offsetLimitClause = default(SqlOffsetLimitClause);
            SqlQuery result = SqlQuery.Create(selectClause, fromClause, this.whereClause, this.orderByClause, offsetLimitClause);
            return(result);
        }
コード例 #13
0
 public override void Visit(SqlLimitSpec sqlObject)
 {
     this.writer.Write("LIMIT ");
     sqlObject.LimitExpression.Accept(this);
 }
コード例 #14
0
 public override SqlObject Visit(SqlLimitSpec sqlObject)
 {
     return(SqlLimitSpec.Create(SqlNumberLiteral.Create(0)));
 }
コード例 #15
0
 public abstract TResult Visit(SqlLimitSpec sqlObject);
コード例 #16
0
 public abstract TOutput Visit(SqlLimitSpec sqlObject, TArg input);