Visitar URL original
Sync Repos: Release 180.102.0 by allancascante · Pull Request #230 · microsoft/SqlScriptDOM · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add Fabric DW GROUP BY ALL and ORDER BY ALL support
  • Loading branch information
Allan Cascante
Allan Cascante committed Aug 27, 2026
commit d4f1dd863ffbc4d549b6d82b1749293eef1fc6f9
2 changes: 2 additions & 0 deletions SqlScriptDom/Parser/TSql/Ast.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3550,6 +3550,8 @@
</Class>
<Class Name="OrderByClause" Summary="Represents the order by clause that can be used in statements like select.">
<Member Name="OrderByElements" Type="ExpressionWithSortOrder" Collection="true" Summary="The items."/>
<Member Name="All" Type="bool" Summary="True if the ORDER BY ALL shorthand is used, which orders by every column in the select list. When true, OrderByElements is empty."/>
<Member Name="AllSortOrder" Type="SortOrder" GenerateUpdatePositionInfoCall="false" Summary="The sort order (ASC/DESC) applied to ORDER BY ALL. Only meaningful when All is true."/>
</Class>
<Class Name="JoinTableReference" Base="TableReference" Abstract="true" Summary="Base class for JOIN table references">
<Member Name="FirstTableReference" Type="TableReference" Summary="The first table reference."/>
Expand Down
75 changes: 55 additions & 20 deletions SqlScriptDom/Parser/TSql/TSqlFabricDW.g
Original file line number Diff line number Diff line change
Expand Up @@ -17983,7 +17983,7 @@ select [SubDmlFlags subDmlFlags] returns [SelectStatement vResult = this.Fragmen
}
: vQueryExpression=queryExpression[subDmlFlags, vResult]
(
vOrderByClause=orderByClause
vOrderByClause=orderByClause[true]
{
vQueryExpression.OrderByClause = vOrderByClause;
}
Expand Down Expand Up @@ -18257,7 +18257,7 @@ subquerySpecification [SubDmlFlags subDmlFlags] returns [QuerySpecification vRes
}
)?
(
vOrderByClause=orderByClause
vOrderByClause=orderByClause[true]
{
vResult.OrderByClause = vOrderByClause;
}
Expand Down Expand Up @@ -20153,7 +20153,7 @@ selectInsertSource [SubDmlFlags subDmlFlags] returns [SelectInsertSource vResult
:
vQueryExpression = queryExpression[subDmlFlags, null]
(
vOrderByClause=orderByClause
vOrderByClause=orderByClause[true]
{
vQueryExpression.OrderByClause = vOrderByClause;
}
Expand Down Expand Up @@ -21417,16 +21417,32 @@ groupByClause returns [GroupByClause vResult = FragmentFactory.CreateFragment<Gr
{
vResult.All = true;
}
)?
vGroupingItem = groupByItem[vResult.All, ref encounteredCubeRollupGroupingSets, ref alreadyEncounteredDistributedAggHint]
{
AddAndUpdateTokenInfo(vResult, vResult.GroupingSpecifications, vGroupingItem);
}
(Comma vGroupingItem = groupByItem[vResult.All, ref encounteredCubeRollupGroupingSets, ref alreadyEncounteredDistributedAggHint]
(
// Greedy: a grouping-item start token always belongs to the optional
// list; non-item tokens (WITH, end of clause) exit. This is the intended
// resolution, so mark it greedy to avoid a spurious nondeterminism warning.
options {greedy = true; } :
vGroupingItem = groupByItem[vResult.All, ref encounteredCubeRollupGroupingSets, ref alreadyEncounteredDistributedAggHint]
{
AddAndUpdateTokenInfo(vResult, vResult.GroupingSpecifications, vGroupingItem);
}
(Comma vGroupingItem = groupByItem[vResult.All, ref encounteredCubeRollupGroupingSets, ref alreadyEncounteredDistributedAggHint]
{
AddAndUpdateTokenInfo(vResult, vResult.GroupingSpecifications, vGroupingItem);
}
)*
)?
|
vGroupingItem = groupByItem[vResult.All, ref encounteredCubeRollupGroupingSets, ref alreadyEncounteredDistributedAggHint]
{
AddAndUpdateTokenInfo(vResult, vResult.GroupingSpecifications, vGroupingItem);
}
)*
(Comma vGroupingItem = groupByItem[vResult.All, ref encounteredCubeRollupGroupingSets, ref alreadyEncounteredDistributedAggHint]
{
AddAndUpdateTokenInfo(vResult, vResult.GroupingSpecifications, vGroupingItem);
}
)*
)
(
// Greedy due to conflict with withCommonTableExpressionsAndXmlNamespaces
options {greedy = true; } :
Expand Down Expand Up @@ -21660,25 +21676,44 @@ havingClause returns [HavingClause vResult = this.FragmentFactory.CreateFragment
}
;

orderByClause returns [OrderByClause vResult = this.FragmentFactory.CreateFragment<OrderByClause>()]
orderByClause [bool allowAll] returns [OrderByClause vResult = this.FragmentFactory.CreateFragment<OrderByClause>()]
{
ExpressionWithSortOrder vExpressionWithSortOrder;
SortOrder vAllSortOrder;
}
:
tOrder:Order By
{
UpdateTokenInfo(vResult,tOrder);
}
vExpressionWithSortOrder=expressionWithSortOrder
{
AddAndUpdateTokenInfo(vResult, vResult.OrderByElements, vExpressionWithSortOrder);
}
(
Comma vExpressionWithSortOrder=expressionWithSortOrder
tAll:All
{
// ORDER BY ALL (Fabric DW) is only allowed at the query / subquery level.
// It is not permitted inside OVER(), WINDOW definitions or WITHIN GROUP.
if (!allowAll)
ThrowIncorrectSyntaxErrorException(tAll);

vResult.All = true;
UpdateTokenInfo(vResult, tAll);
}
(vAllSortOrder = orderByOption[vResult]
{
vResult.AllSortOrder = vAllSortOrder;
}
)?
|
vExpressionWithSortOrder=expressionWithSortOrder
{
AddAndUpdateTokenInfo(vResult, vResult.OrderByElements, vExpressionWithSortOrder);
}
)*
(
Comma vExpressionWithSortOrder=expressionWithSortOrder
{
AddAndUpdateTokenInfo(vResult, vResult.OrderByElements, vExpressionWithSortOrder);
}
)*
)
;

expressionWithSortOrder returns [ExpressionWithSortOrder vResult = this.FragmentFactory.CreateFragment<ExpressionWithSortOrder>()]
Expand Down Expand Up @@ -32008,7 +32043,7 @@ windowDefinition returns [WindowDefinition vResult = FragmentFactory.CreateFragm
By expressionList[vResult, vResult.Partitions]
)?
(
vOrderByClause=orderByClause
vOrderByClause=orderByClause[false]
{
vResult.OrderByClause = vOrderByClause;
}
Expand All @@ -32033,7 +32068,7 @@ overClause returns [OverClause vResult]
}
: vResult = overClauseBeginning
(
vOrderByClause=orderByClause
vOrderByClause=orderByClause[false]
{
vResult.OrderByClause = vOrderByClause;
}
Expand Down Expand Up @@ -32207,7 +32242,7 @@ withinGroupClause returns [WithinGroupClause vResult = FragmentFactory.CreateFra
graphPathClause[vResult]
)
|
vOrderByClause=orderByClause
vOrderByClause=orderByClause[false]
{
vResult.OrderByClause = vOrderByClause;
UpdateTokenInfo(vResult,tLParen);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,19 @@ public override void ExplicitVisit(GroupByClause node)
}

AlignmentPoint clauseBody = GetAlignmentPointForFragment(node, ClauseBody);
if (!GenerateClauseBodyStart(_options.NewLineBeforeGroupByClause, clauseBody))

// Modern GROUP BY ALL (no explicit column list) has no grouping specifications;
// the grouping columns are inferred from the SELECT list. Only emit the body
// (and its leading space/newline) when a column list is actually present.
if (!node.All || node.GroupingSpecifications.Count > 0)
{
GenerateSpace();
if (!GenerateClauseBodyStart(_options.NewLineBeforeGroupByClause, clauseBody))
{
GenerateSpace();
}

GenerateCommaSeparatedList(node.GroupingSpecifications);
}
GenerateCommaSeparatedList(node.GroupingSpecifications);

if (node.GroupByOption != GroupByOption.None)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,32 @@ public override void ExplicitVisit(OrderByClause node)
GenerateSpaceAndKeyword(TSqlTokenType.By);

AlignmentPoint clauseBody = GetAlignmentPointForFragment(node, ClauseBody);
if (!GenerateClauseBodyStart(_options.NewLineBeforeOrderByClause, clauseBody))

if (node.All)
{
// ORDER BY ALL shorthand: orders by every column in the select list.
// ALL is a keyword modifier of the clause (like GROUP BY ALL), so keep it on
// the same line as ORDER BY. The NewLineBeforeOrderByClause option only applies
// to an explicit column list, not to the ALL shorthand.
GenerateSpace();
GenerateKeyword(TSqlTokenType.All);

TokenGenerator sortOrderGenerator = GetValueForEnumKey(_sortOrderGenerators, node.AllSortOrder);
if (sortOrderGenerator != null && node.AllSortOrder != SortOrder.NotSpecified)
{
GenerateSpace();
GenerateToken(sortOrderGenerator);
}
}
else
{
if (!GenerateClauseBodyStart(_options.NewLineBeforeOrderByClause, clauseBody))
{
GenerateSpace();
}

GenerateCommaSeparatedList(node.OrderByElements);
}
GenerateCommaSeparatedList(node.OrderByElements);

PopAlignmentPoint();
}
Expand Down
4 changes: 4 additions & 0 deletions Test/SqlDom/BaselinesCommon/SelectStatementTests.sql
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ SELECT *
FROM t1
GROUP BY ALL c1;

SELECT *
FROM t1
GROUP BY ALL c1, c2, c3;

SELECT *
FROM t1
GROUP BY c1, c2, c3;
Expand Down
71 changes: 71 additions & 0 deletions Test/SqlDom/BaselinesFabricDW/ModernGroupByAllTestsFabricDW.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
SELECT City,
Region,
COUNT(*) AS NumEmps
FROM dbo.Employees
GROUP BY ALL;
GO

SELECT City,
COUNT(*) AS NumEmps
FROM dbo.Employees
WHERE HireDate >= '19930101'
GROUP BY ALL
HAVING COUNT(*) > 5
ORDER BY City;
GO

SELECT Region,
YEAR(OrderDate) AS OrderYear,
Category,
COUNT(*) AS NumOrders,
SUM(Amount) AS Total
FROM Sales
WHERE Amount > 0
GROUP BY ALL;
GO

SELECT c.CustomerName,
COUNT(*) AS Orders
FROM Orders AS o
INNER JOIN
Customers AS c
ON o.CustomerId = c.CustomerId
GROUP BY ALL;
GO

SELECT City,
COUNT(*) AS NumEmps
FROM dbo.Employees
GROUP BY ALL
ORDER BY City DESC;
GO

SELECT *
FROM (SELECT City,
COUNT(*) AS Cnt
FROM dbo.Employees
GROUP BY ALL) AS t;
GO

SELECT Region,
SUM(Amount) / COUNT(DISTINCT CustomerId) AS AvgSpend
FROM Sales
GROUP BY ALL;
GO

CREATE VIEW v_GroupByAllView
AS
SELECT City,
COUNT(*) AS NumEmps
FROM dbo.Employees
GROUP BY ALL;
GO

CREATE PROCEDURE usp_GroupByAll
AS
BEGIN
SELECT City,
COUNT(*) AS NumEmps
FROM dbo.Employees
GROUP BY ALL;
END
95 changes: 95 additions & 0 deletions Test/SqlDom/BaselinesFabricDW/OrderByAllTestsFabricDW.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
SELECT c1,
c2
FROM t1
ORDER BY ALL;
GO

SELECT c1,
c2
FROM t1
ORDER BY ALL ASC;
GO

SELECT c1,
c2
FROM t1
ORDER BY ALL DESC;
GO

SELECT *
FROM t1
ORDER BY ALL;
GO

SELECT c1,
c2
FROM t1
ORDER BY ALL
OFFSET 2 ROWS FETCH NEXT 5 ROWS ONLY;
GO

SELECT c1
FROM t1
UNION ALL
SELECT c1
FROM t2
ORDER BY ALL;
GO

SELECT *
FROM (SELECT TOP 5 c1,
c2
FROM t1
ORDER BY ALL) AS sub;
GO

SELECT c1,
COUNT(*) AS Cnt
FROM t1
GROUP BY c1
ORDER BY ALL;
GO

SELECT c1,
COUNT(*) AS Cnt
FROM t1
GROUP BY c1
HAVING COUNT(*) > 1
ORDER BY ALL DESC;
GO

SELECT a.c1,
b.c2
FROM t1 AS a
INNER JOIN
t2 AS b
ON a.c1 = b.c1
WHERE b.c2 > 0
ORDER BY ALL;
GO

SELECT c1,
COUNT(*) AS Cnt,
SUM(COUNT(*)) OVER (ORDER BY c1 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS RunningCnt
FROM t1
GROUP BY c1
ORDER BY ALL;
GO

CREATE VIEW v_OrderByAllView
AS
SELECT c1,
c2
FROM t1
ORDER BY ALL
OFFSET 0 ROWS;
GO

CREATE PROCEDURE usp_OrderByAll
AS
BEGIN
SELECT c1,
c2
FROM t1
ORDER BY ALL;
END
Loading