Skip to content

Commit ce34113

Browse files
authored
Merge pull request #1035 from FirelyTeam/copilot/fix-1007-2
1007 Fix multi-source query sorting and update skip list categorization
2 parents a1ff017 + dbeadbd commit ce34113

File tree

4 files changed

+1782
-57
lines changed

4 files changed

+1782
-57
lines changed

Cql/Cql.Compiler/ExpressionBuilderContext.cs

Lines changed: 1 addition & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1702,60 +1702,7 @@ void PushScopes(
17021702

17031703
if (query.sort is { by.Length: > 0 })
17041704
{
1705-
if (sources.Length == 1)
1706-
@return = SortClause(query, @return);
1707-
else
1708-
{
1709-
throw new NotImplementedException("Sort is broken in ELM XSD?").WithContext(this);
1710-
//foreach (var by in query.sort.by)
1711-
//{
1712-
// var order = ListSortDirection.Ascending;
1713-
// if (by.direction == "desc" || by.direction == "descending")
1714-
// order = ListSortDirection.Descending;
1715-
// else if (by.direction == "asc" || by.direction == "ascending")
1716-
// order = ListSortDirection.Ascending;
1717-
// else throw ctx.NewExpressionBuildingException($"Invalid sort order {by.direction}");
1718-
1719-
// if (by.expression != null)
1720-
// {
1721-
// var parameterName = "@this";
1722-
// var returnElementType = TypeResolver.GetListElementType(@return.Type);
1723-
// var sortMemberParameter = Expression.Parameter(returnElementType, parameterName);
1724-
// var subContext = ctx.WithImpliedAlias(parameterName!, sortMemberParameter, by.expression);
1725-
// var sortMemberExpression = TranslateExpression(by.expression, subContext);
1726-
// var lambdaBody = Expression.Convert(sortMemberExpression, typeof(object));
1727-
// var sortLambda = System.Linq.Expressions.Expression.Lambda(lambdaBody, sortMemberParameter);
1728-
// var sort = Operators.Bind(CqlOperator.SortBy, ctx.RuntimeContextParameter,
1729-
// @return, sortLambda, Expression.Constant(order, typeof(SortOrder)));
1730-
// @return = sort;
1731-
// }
1732-
// else if (by.path != null && by.resultTypeName != null)
1733-
// {
1734-
// var parameterName = "@this";
1735-
// var returnElementType = TypeResolver.GetListElementType(@return.Type);
1736-
// var sortMemberParameter = Expression.Parameter(returnElementType, parameterName);
1737-
// var pathMemberType = TypeResolver.ResolveType(by.resultTypeName);
1738-
// if (pathMemberType == null)
1739-
// {
1740-
// var msg = $"Type specifier {by.resultTypeName} at {by.locator ?? "unknown"} could not be resolved.";
1741-
// ctx.LogError(msg);
1742-
// throw ctx.NewExpressionBuildingException(msg);
1743-
// }
1744-
// var pathExpression = PropertyHelper(sortMemberParameter, by.path, pathMemberType!, ctx);
1745-
// var lambdaBody = Expression.Convert(pathExpression, typeof(object));
1746-
// var sortLambda = System.Linq.Expressions.Expression.Lambda(lambdaBody, sortMemberParameter);
1747-
// var sort = Operators.Bind(CqlOperator.SortBy, ctx.RuntimeContextParameter,
1748-
// @return, sortLambda, Expression.Constant(order, typeof(SortOrder)));
1749-
// @return = sort;
1750-
// }
1751-
// else
1752-
// {
1753-
// var sort = Operators.Bind(CqlOperator.Sort, ctx.RuntimeContextParameter,
1754-
// @return, Expression.Constant(order, typeof(SortOrder)));
1755-
// @return = sort;
1756-
// }
1757-
//}
1758-
}
1705+
@return = SortClause(query, @return);
17591706
}
17601707

17611708
// Because we promoted the source to a list, we now have to demote the result again.

Cql/CqlToElmTests/(tests)/QueryTest.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,5 +420,29 @@ then flatten({ (result) r where r !~ Last(result),
420420
var query = lib.Should().BeACorrectlyInitializedLibraryWithStatementOfType<Query>();
421421
query.Should().HaveType(SystemTypes.DateType.ToIntervalType().ToListType());
422422
}
423+
424+
[TestMethod]
425+
public void Multisource_sort_by_expression()
426+
{
427+
var lib = CreateCqlToolkit().MakeLibrary("""
428+
library MultisourceSort version '1.0.0'
429+
430+
define "Multisource sort by expression":
431+
from
432+
({3, 1}) Num1,
433+
({4, 2}) Num2
434+
return Tuple { sum: Num1 + Num2, n1: Num1, n2: Num2 }
435+
sort by sum desc
436+
""");
437+
438+
lib.GetErrors().Should().BeEmpty();
439+
lib.statements.Should().HaveCount(1);
440+
var expression = lib.statements[0].expression.Should().BeOfType<Query>().Subject;
441+
expression.source.Should().HaveCount(2);
442+
expression.sort.Should().NotBeNull();
443+
expression.sort.by.Should().HaveCount(1);
444+
var byExpression = expression.sort.by[0].Should().BeOfType<ByExpression>().Subject;
445+
byExpression.direction.Should().Be(SortDirection.desc);
446+
}
423447
}
424448
}

Cql/PackagerCLI/Hl7.Cql.Packager.ecqm-content-qicore-2025.appsettings.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
// Tuple element value does not have a resultTypeSpecifier
55
"CMS2FHIRPCSDepressionScreenAndFollowUp.json",
66
"CMS145FHIRCADBetaBlockerTherapyPriorMIorLVSD.json",
7-
8-
// Sort is broken in ELM XSD
9-
"CMS986FHIRMalnutritionScore.json",
107
"CMS832HHAKIFHIR.json",
118

129
// Cannot resolve type {http://hl7.org/fhir}DoNotPerformReason} for expression

0 commit comments

Comments
 (0)