private SqlOrderbyClause Substitute(SqlSelectSpec spec, SqlIdentifier inputParam, SqlOrderbyClause orderByClause) { if (orderByClause == null) { return(null); } if (spec is SqlSelectStarSpec) { return(orderByClause); } SqlSelectValueSpec selValue = spec as SqlSelectValueSpec; if (selValue != null) { SqlScalarExpression replaced = selValue.Expression; SqlOrderByItem[] substitutedItems = new SqlOrderByItem[orderByClause.OrderbyItems.Count]; for (int i = 0; i < substitutedItems.Length; ++i) { SqlScalarExpression substituted = SqlExpressionManipulation.Substitute(replaced, inputParam, orderByClause.OrderbyItems[i].Expression); substitutedItems[i] = SqlOrderByItem.Create(substituted, orderByClause.OrderbyItems[i].IsDescending); } SqlOrderbyClause result = SqlOrderbyClause.Create(substitutedItems); return(result); } throw new DocumentQueryException("Unexpected SQL select clause type: " + spec.Kind); }
public override SqlObject VisitOrder_by_clause([NotNull] sqlParser.Order_by_clauseContext context) { Contract.Requires(context != null); List <SqlOrderByItem> orderByItems = new List <SqlOrderByItem>(); foreach (sqlParser.Order_by_itemContext orderByItemContext in context.order_by_items().order_by_item()) { SqlScalarExpression expression = (SqlScalarExpression)this.Visit(orderByItemContext.scalar_expression()); bool isDescending = false; if (orderByItemContext.sort_order() != null) { if (orderByItemContext.sort_order().K_ASC() != null) { isDescending = false; } else if (orderByItemContext.sort_order().K_DESC() != null) { isDescending = true; } else { throw new ArgumentOutOfRangeException($"Unknown sort order : {orderByItemContext.sort_order()}."); } } SqlOrderByItem orderByItem = SqlOrderByItem.Create(expression, isDescending); orderByItems.Add(orderByItem); } return(SqlOrderbyClause.Create(orderByItems)); }
public override SqlObject Visit(SqlOrderbyClause sqlOrderByClause) { SqlOrderByItem[] items = new SqlOrderByItem[sqlOrderByClause.OrderbyItems.Length]; for (int i = 0; i < sqlOrderByClause.OrderbyItems.Length; i++) { items[i] = sqlOrderByClause.OrderbyItems[i].Accept(this) as SqlOrderByItem; } return(SqlOrderbyClause.Create(items)); }
public override void Visit(SqlOrderbyClause sqlOrderByClause) { this.writer.Write("ORDER BY "); sqlOrderByClause.OrderbyItems[0].Accept(this); for (int i = 1; i < sqlOrderByClause.OrderbyItems.Length; i++) { this.writer.Write(", "); sqlOrderByClause.OrderbyItems[i].Accept(this); } }
public override int Visit(SqlOrderbyClause sqlOrderByClause) { int hashCode = SqlOrderbyClauseHashCode; for (int i = 0; i < sqlOrderByClause.OrderbyItems.Length; i++) { hashCode = CombineHashes(hashCode, sqlOrderByClause.OrderbyItems[i].Accept(this)); } return(hashCode); }
public SqlQuery( SqlSelectClause selectClause, SqlFromClause fromClause, SqlWhereClause whereClause, SqlOrderbyClause orderbyClause) : base(SqlObjectKind.Query) { this.SelectClause = selectClause; this.FromClause = fromClause; this.WhereClause = whereClause; this.OrderbyClause = orderbyClause; }
public QueryUnderConstruction AddOrderByClause(SqlOrderbyClause orderBy, TranslationContext context) { QueryUnderConstruction result = context.PackageCurrentQueryIfNeccessary(); result.orderByClause = orderBy; foreach (Binding binding in context.CurrentSubqueryBinding.TakeBindings()) { result.AddBinding(binding); } return(result); }
public override SqlObject VisitOrder_by_clause([NotNull] sqlParser.Order_by_clauseContext context) { Contract.Requires(context != null); List <SqlOrderByItem> orderByItems = new List <SqlOrderByItem>(); foreach (sqlParser.Order_by_itemContext orderByItemContext in context.order_by_items().order_by_item()) { SqlOrderByItem orderByItem = (SqlOrderByItem)this.VisitOrder_by_item(orderByItemContext); orderByItems.Add(orderByItem); } return(SqlOrderbyClause.Create(orderByItems)); }
public override bool Visit(SqlOrderbyClause first, SqlObject secondAsObject) { if (!(secondAsObject is SqlOrderbyClause second)) { return(false); } if (!SequenceEquals(first.OrderbyItems, second.OrderbyItems)) { return(false); } return(true); }
public QueryUnderConstruction UpdateOrderByClause(SqlOrderbyClause thenBy, TranslationContext context) { List <SqlOrderByItem> items = new List <SqlOrderByItem>(context.currentQuery.orderByClause.OrderbyItems); items.AddRange(thenBy.OrderbyItems); context.currentQuery.orderByClause = SqlOrderbyClause.Create(items); foreach (Binding binding in context.CurrentSubqueryBinding.TakeBindings()) { context.currentQuery.AddBinding(binding); } return(context.currentQuery); }
public QueryUnderConstruction AddOrderByClause(SqlOrderbyClause orderBy, TranslationContext context) { QueryUnderConstruction result = this; if (context.CurrentSubqueryBinding.ShouldBeOnNewQuery) { result = this.PackageQuery(context.InScope, context.PeekCollection()); context.CurrentSubqueryBinding.ShouldBeOnNewQuery = false; } result.orderByClause = orderBy; foreach (Binding binding in context.CurrentSubqueryBinding.TakeBindings()) { result.AddBinding(binding); } return(result); }
public QueryUnderConstruction AddOrderByClause(SqlOrderbyClause orderBy, HashSet <ParameterExpression> inScope) { QueryUnderConstruction.ValidateNonSubquerySupport(this); QueryUnderConstruction result = this; if (this.selectClause != null) { result = this.PackageQuery(inScope); } if (result.orderByClause != null) { throw new DocumentQueryException("Multiple OrderBy is not supported."); } result.orderByClause = orderBy; return(result); }
public abstract void Visit(SqlOrderbyClause sqlObject);
public abstract TResult Visit(SqlOrderbyClause sqlObject);
public abstract TOutput Visit(SqlOrderbyClause sqlObject, TArg input);
private static IEnumerable <CosmosElement> ExecuteOrderByClause( IEnumerable <CosmosElement> dataSource, SqlOrderbyClause sqlOrderByClause, IReadOnlyDictionary <string, PartitionKeyRange> ridToPartitionKeyRange) { // Sort by the columns left to right SqlOrderByItem firstItem = sqlOrderByClause.OrderbyItems[0]; // Since we don't supply an explicit index on the policy undefined items don't show up in the sort order if (sqlOrderByClause.OrderbyItems.Count == 1) { dataSource = dataSource.Where(element => firstItem.Expression.Accept( ScalarExpressionEvaluator.Singleton, element) != Undefined); } IOrderedEnumerable <CosmosElement> orderedDataSource; if (firstItem.IsDescending) { orderedDataSource = dataSource.OrderByDescending( element => firstItem.Expression.Accept( ScalarExpressionEvaluator.Singleton, element)); } else { orderedDataSource = dataSource.OrderBy( element => firstItem.Expression.Accept( ScalarExpressionEvaluator.Singleton, element)); } foreach (SqlOrderByItem sqlOrderByItem in sqlOrderByClause.OrderbyItems.Skip(1)) { if (sqlOrderByItem.IsDescending) { orderedDataSource = orderedDataSource.ThenByDescending( element => sqlOrderByItem.Expression.Accept( ScalarExpressionEvaluator.Singleton, element)); } else { orderedDataSource = orderedDataSource.ThenBy( element => sqlOrderByItem.Expression.Accept( ScalarExpressionEvaluator.Singleton, element)); } } // Grab from the left most partition first orderedDataSource = orderedDataSource .ThenBy((element) => { string rid = ((CosmosString)((CosmosObject)element)["_rid"]).Value; PartitionKeyRange partitionKeyRange = ridToPartitionKeyRange[rid]; return(partitionKeyRange.MinInclusive); }, StringComparer.Ordinal); // Break all final ties within partition by document id if (firstItem.IsDescending) { orderedDataSource = orderedDataSource .ThenByDescending(element => ResourceId.Parse(((CosmosString)((CosmosObject)element)["_rid"]).Value).Document); } else { orderedDataSource = orderedDataSource .ThenBy(element => ResourceId.Parse(((CosmosString)((CosmosObject)element)["_rid"]).Value).Document); } return(orderedDataSource); }
/// <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); }