diff --git a/backend/Origam.DA.Service/Generators/AbstractSqlCommandGenerator.cs b/backend/Origam.DA.Service/Generators/AbstractSqlCommandGenerator.cs index c437d3e499..7a31d035f9 100644 --- a/backend/Origam.DA.Service/Generators/AbstractSqlCommandGenerator.cs +++ b/backend/Origam.DA.Service/Generators/AbstractSqlCommandGenerator.cs @@ -999,12 +999,6 @@ internal void SelectParameterDeclarationsSetSql(StringBuilder result, Hashtable var rowLimit = selectParameters.RowLimit; var rowOffset = selectParameters.RowOffset; bool rowOffsetSpecified = rowOffset.HasValue && rowOffset != 0; - bool hasLookupField = selectParameters.Entity.EntityDefinition - .EntityColumns - .Cast() - .OfType() - .Any(field => - selectParameters.ColumnsInfo.ColumnNames.Contains(field.Name)); if (!(entity.EntityDefinition is TableMappingItem)) { @@ -1259,7 +1253,7 @@ internal void SelectParameterDeclarationsSetSql(StringBuilder result, Hashtable finalString += $" OFFSET {rowOffset} ROWS FETCH NEXT {rowLimit} ROWS ONLY;"; } - if (hasLookupField && customGrouping != null) + if (customGrouping != null && GroupingUsesLookup(customGrouping, entity)) { var columnNames = selectParameters.ColumnsInfo.ColumnNames; if (selectParameters.AggregatedColumns.Count > 0) @@ -1279,6 +1273,27 @@ internal void SelectParameterDeclarationsSetSql(StringBuilder result, Hashtable return finalString; } + private static bool GroupingUsesLookup(Grouping customGrouping, DataStructureEntity entity) + { + var allLookupColumnNames = entity + .ChildrenRecursive.OfType() + .Concat(new[] { entity }) + .SelectMany(entity => + { + var dataStructureColumnNames = entity.ChildItems.ToGeneric() + .OfType() + .Where(x => x.UseLookupValue) + .Select(x => x.Name); + var entityColumnNames = entity.EntityDefinition.EntityColumns + .OfType() + .Select(lookupField => lookupField.Name); + return dataStructureColumnNames.Concat(entityColumnNames); + }); + + return customGrouping != null && + allLookupColumnNames.Contains(customGrouping.GroupBy); + } + private void PostProcessCustomCommandParserWhereClause( Hashtable replaceParameterTexts, Hashtable selectParameterReferences, @@ -1814,6 +1829,8 @@ internal bool ShouldUpdateColumn(DataStructureColumn column, DataStructureEntity forceDatabaseCalculation: forceDatabaseCalculation); } + private record GroupByData(DataStructureColumn Column, string Expression); + internal bool RenderSelectColumns(SelectParameters selectParameters, StringBuilder sqlExpression, StringBuilder orderByBuilder, StringBuilder groupByBuilder, @@ -1833,7 +1850,7 @@ internal bool ShouldUpdateColumn(DataStructureColumn column, DataStructureEntity var dynamicParameters = selectParameters.Parameters; var customFilters = selectParameters.CustomFilters; - DataStructureColumn groupByColumn = null; + GroupByData groupByData = null; int i = 0; List group = new List(); SortedList order = new SortedList(); @@ -1863,10 +1880,6 @@ internal bool ShouldUpdateColumn(DataStructureColumn column, DataStructureEntity GetSortedColumns(entity, columnsInfo?.ColumnNames, aggregatedColumns); foreach (DataStructureColumn column in dataStructureColumns) { - if (customGrouping != null && column.Name == customGrouping.GroupBy) - { - groupByColumn = column; - } LookupOrderingInfo customOrderingInfo = LookupOrderingInfo.TryCreate(customOrderings.Orderings, column.Name ); string groupByExpression = ""; @@ -1877,6 +1890,10 @@ internal bool ShouldUpdateColumn(DataStructureColumn column, DataStructureEntity columnsInfo ?? ColumnsInfo.Empty, column, customOrderingInfo, filterCommandParser, orderByCommandParser, selectParameters.RowOffset); + if (customGrouping != null && column.Name == customGrouping.GroupBy) + { + groupByData = new GroupByData(column, groupByExpression); + } string expression; if (columnRenderData != null) { @@ -1978,20 +1995,26 @@ internal bool ShouldUpdateColumn(DataStructureColumn column, DataStructureEntity new Key(customGrouping.LookupId)) as DataServiceDataLookup; var resultExpression = - RenderLookupColumnExpression(ds, entity, groupByColumn, + RenderLookupColumnExpression(ds, entity, groupByData.Column, replaceParameterTexts, dynamicParameters, selectParameterReferences, lookup); sqlExpression.Append(" , "); sqlExpression.Append(resultExpression); sqlExpression.Append($" AS {ColumnData.GroupByCaptionColumn} "); } - - groupByNeeded = true; - if (!group.Any(groupByExpression => - groupByExpression.Contains(customGrouping.GroupBy) || - groupByExpression == orderByExpression)) + else { - group.Add(customGrouping.GroupBy); + if (!group.Any(groupByExpression => + groupByExpression.Contains(customGrouping.GroupBy) || + groupByExpression == orderByExpression)) + { + if (groupByData.Column.Name == customGrouping.GroupBy && + !group.Contains(groupByData.Expression)) + { + group.Add(groupByData.Expression); + } + } } + groupByNeeded = true; } if (order.Count > 0) { @@ -2326,9 +2349,11 @@ private string ColumnDataToSql(ColumnRenderData columnRenderData) resultExpression = RenderLookupColumnExpression(ds, entity, column, replaceParameterTexts, dynamicParameters, selectParameterReferences); - // if we would group by lookuped column, we use original column in group-by clause - groupExpression = RenderExpression(column.Field as AbstractSchemaItem, - column.Entity == null ? entity : column.Entity, + var field = column.Field is LookupField lookupField + ? lookupField.Field + : column.Field; + groupExpression = RenderExpression(field, + column.Entity ?? entity, replaceParameterTexts, dynamicParameters, selectParameterReferences); } @@ -4190,4 +4215,4 @@ internal enum geoLatLonSql { Lat, Lon -} \ No newline at end of file +} diff --git a/model-tests/model/Widgets/DataStructure/Widgets/AllDataTypes.origam b/model-tests/model/Widgets/DataStructure/Widgets/AllDataTypes.origam index e6aac5f39f..ca2b9f4995 100644 --- a/model-tests/model/Widgets/DataStructure/Widgets/AllDataTypes.origam +++ b/model-tests/model/Widgets/DataStructure/Widgets/AllDataTypes.origam @@ -4,6 +4,7 @@ xmlns:ads="http://schemas.origam.com/Origam.Schema.EntityModel.AbstractDataStructure/6.0.0" xmlns:asi="http://schemas.origam.com/Origam.Schema.AbstractSchemaItem/6.0.0" xmlns:ds="http://schemas.origam.com/Origam.Schema.EntityModel.DataStructure/6.0.0" + xmlns:dsc="http://schemas.origam.com/Origam.Schema.EntityModel.DataStructureColumn/6.0.1" xmlns:dse="http://schemas.origam.com/Origam.Schema.EntityModel.DataStructureEntity/6.0.0" xmlns:dsfs="http://schemas.origam.com/Origam.Schema.EntityModel.DataStructureFilterSet/6.0.0" xmlns:dsfsf="http://schemas.origam.com/Origam.Schema.EntityModel.DataStructureFilterSetFilter/6.0.0" @@ -29,6 +30,19 @@ asi:name="AllDataTypes" dse:relationType="Normal" dse:useUpsert="false"> + + + + + + + + + + + + + + + + + + + + + + + + + pvi1:value="354" />