public ICriteria SetProjection(IProjection projection) { if (projection is ProjectionList) { throw new NotSupportedException("Projection lists are not (yet) supported in sharded criteria."); } if (projection is Distinct) { ApplyActionToShards(c => c.SetProjection(projection)); this.exitOperationBuilder.Distinct = true; return(this); } if (!projection.IsAggregate) { ApplyActionToShards(c => c.SetProjection(projection)); return(this); } string aggregationName = projection.ToString(); if (aggregationName.StartsWith("avg", StringComparison.OrdinalIgnoreCase)) { var projectionList = Projections.ProjectionList() .Add(projection) .Add(Projections.RowCount()); ApplyActionToShards(c => c.SetProjection(projectionList)); this.exitOperationBuilder.Aggregation = c => AggregationUtil.Average(c, GetFieldSelector(0), GetFieldSelector(1)); return(this); } if (aggregationName.StartsWith("sum", StringComparison.OrdinalIgnoreCase)) { ApplyActionToShards(c => c.SetProjection(projection)); this.exitOperationBuilder.Aggregation = c => AggregationUtil.Sum(c, GetFieldSelector(0)); return(this); } if (aggregationName.StartsWith("count", StringComparison.OrdinalIgnoreCase)) { ApplyActionToShards(c => c.SetProjection(projection)); this.exitOperationBuilder.Aggregation = c => AggregationUtil.SumInt64(c, GetFieldSelector(0)); return(this); } if (aggregationName.StartsWith("min", StringComparison.OrdinalIgnoreCase)) { ApplyActionToShards(c => c.SetProjection(projection)); this.exitOperationBuilder.Aggregation = c => AggregationUtil.Min(c, GetFieldSelector(0)); return(this); } if (aggregationName.StartsWith("max", StringComparison.OrdinalIgnoreCase)) { ApplyActionToShards(c => c.SetProjection(projection)); this.exitOperationBuilder.Aggregation = c => AggregationUtil.Max(c, GetFieldSelector(0)); return(this); } var message = string.Format( CultureInfo.InvariantCulture, "Aggregate projection '{0}' is currently not supported across shards.", aggregationName); Log.Error(message); throw new NotSupportedException(message); }
private bool CanCopy(IASTNode node, out Action <IASTNode> copyTransformer) { copyTransformer = null; IASTNode child; switch (node.Type) { case HqlSqlWalker.SKIP: child = node.GetFirstChild(); if (TryGetParameterName(child, out var skipParameterName)) { this.exitOperationBuilder.FirstResult = (int)namedParameters[skipParameterName].Item1; } else if (TryGetInt32(child, out var firstResult)) { this.exitOperationBuilder.FirstResult = firstResult; } return(false); case HqlSqlWalker.TAKE: child = node.GetFirstChild(); if (TryGetParameterName(child, out var takeParameterName)) { this.exitOperationBuilder.MaxResults = (int)namedParameters[takeParameterName].Item1; } else if (TryGetInt32(child, out var maxResults)) { this.exitOperationBuilder.MaxResults = maxResults; } return(false); case HqlSqlWalker.ORDER: ExtractOrders(node); return(true); case HqlSqlWalker.AGGREGATE: if ("avg".Equals(node.Text, StringComparison.OrdinalIgnoreCase)) { goto case HqlSqlWalker.AVG; } if ("min".Equals(node.Text, StringComparison.OrdinalIgnoreCase)) { goto case HqlSqlWalker.MIN; } else if ("max".Equals(node.Text, StringComparison.OrdinalIgnoreCase)) { goto case HqlSqlWalker.MAX; } throw new NotSupportedException(string.Format( CultureInfo.InvariantCulture, "HQL aggregate function '{0}' is currently not supported across shards.", node.Text)); case HqlSqlWalker.AVG: ThrowIfAggregationInComplexSelectList(node); this.exitOperationBuilder.Aggregation = c => AggregationUtil.Average(c, GetFieldSelector(0), GetFieldSelector(1)); copyTransformer = TransformUnshardedAverageNode; return(true); case HqlSqlWalker.COUNT: ThrowIfAggregationInComplexSelectList(node); this.exitOperationBuilder.Aggregation = c => AggregationUtil.SumInt64(c, o => o); return(true); case HqlSqlWalker.MIN: ThrowIfAggregationInComplexSelectList(node); this.exitOperationBuilder.Aggregation = c => AggregationUtil.Min(c, o => o); return(true); case HqlSqlWalker.MAX: ThrowIfAggregationInComplexSelectList(node); this.exitOperationBuilder.Aggregation = c => AggregationUtil.Max(c, o => o); return(true); case HqlSqlWalker.SUM: ThrowIfAggregationInComplexSelectList(node); this.exitOperationBuilder.Aggregation = c => AggregationUtil.Sum(c, o => o); return(true); } return(true); }