Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
26 changes: 25 additions & 1 deletion SqlScriptDom/Parser/TSql/TSql160.g
Original file line number Diff line number Diff line change
Expand Up @@ -31967,6 +31967,11 @@ overClause returns [OverClause vResult]
)?
tRParen:RightParenthesis
{
// Window name inside parentheses requires at least one clause (PARTITION BY, ORDER BY, or window frame)
if (vResult.WindowName != null && vResult.Partitions.Count == 0 && vResult.OrderByClause == null && vResult.WindowFrameClause == null)
{
ThrowParseErrorException("SQL46010", tRParen, TSqlParserResource.SQL46010Message, vResult.WindowName.Value);
}
UpdateTokenInfo(vResult,tRParen);
}
| vResult = overClauseWithWindow
Expand All @@ -31989,7 +31994,7 @@ overClauseWithWindow returns [OverClause vResult = FragmentFactory.CreateFragmen

overClauseNoOrderBy returns [OverClause vResult]
:
vResult = overClauseBeginning
vResult = overClauseBeginningNoWindowName
tRParen:RightParenthesis
{
UpdateTokenInfo(vResult,tRParen);
Expand Down Expand Up @@ -32021,6 +32026,25 @@ overClauseBeginning returns [OverClause vResult = FragmentFactory.CreateFragment
)?
;

overClauseBeginningNoWindowName returns [OverClause vResult = FragmentFactory.CreateFragment<OverClause>()]
:
tOver:Over
{
UpdateTokenInfo(vResult,tOver);
}
LeftParenthesis
(
(Identifier By) =>
tPartition:Identifier
{
Match(tPartition, CodeGenerationSupporter.Partition);
}
By expressionList[vResult, vResult.Partitions]
|
/* empty - allow OVER() with no PARTITION BY */
)
;

windowFrameClause returns [WindowFrameClause vResult = FragmentFactory.CreateFragment<WindowFrameClause>()]
:
tRowsRange:Identifier
Expand Down
26 changes: 25 additions & 1 deletion SqlScriptDom/Parser/TSql/TSql170.g
Original file line number Diff line number Diff line change
Expand Up @@ -32956,6 +32956,11 @@ overClause returns [OverClause vResult]
)?
tRParen:RightParenthesis
{
// Window name inside parentheses requires at least one clause (PARTITION BY, ORDER BY, or window frame)
if (vResult.WindowName != null && vResult.Partitions.Count == 0 && vResult.OrderByClause == null && vResult.WindowFrameClause == null)
{
ThrowParseErrorException("SQL46010", tRParen, TSqlParserResource.SQL46010Message, vResult.WindowName.Value);
}
UpdateTokenInfo(vResult,tRParen);
}
| vResult = overClauseWithWindow
Expand All @@ -32978,7 +32983,7 @@ overClauseWithWindow returns [OverClause vResult = FragmentFactory.CreateFragmen

overClauseNoOrderBy returns [OverClause vResult]
:
vResult = overClauseBeginning
vResult = overClauseBeginningNoWindowName
tRParen:RightParenthesis
{
UpdateTokenInfo(vResult,tRParen);
Expand Down Expand Up @@ -33010,6 +33015,25 @@ overClauseBeginning returns [OverClause vResult = FragmentFactory.CreateFragment
)?
;

overClauseBeginningNoWindowName returns [OverClause vResult = FragmentFactory.CreateFragment<OverClause>()]
:
tOver:Over
{
UpdateTokenInfo(vResult,tOver);
}
LeftParenthesis
(
(Identifier By) =>
tPartition:Identifier
{
Match(tPartition, CodeGenerationSupporter.Partition);
}
By expressionList[vResult, vResult.Partitions]
|
/* empty - allow OVER() with no PARTITION BY */
)
;

windowFrameClause returns [WindowFrameClause vResult = FragmentFactory.CreateFragment<WindowFrameClause>()]
:
tRowsRange:Identifier
Expand Down
26 changes: 25 additions & 1 deletion SqlScriptDom/Parser/TSql/TSql180.g
Original file line number Diff line number Diff line change
Expand Up @@ -32956,6 +32956,11 @@ overClause returns [OverClause vResult]
)?
tRParen:RightParenthesis
{
// Window name inside parentheses requires at least one clause (PARTITION BY, ORDER BY, or window frame)
if (vResult.WindowName != null && vResult.Partitions.Count == 0 && vResult.OrderByClause == null && vResult.WindowFrameClause == null)
{
ThrowParseErrorException("SQL46010", tRParen, TSqlParserResource.SQL46010Message, vResult.WindowName.Value);
}
UpdateTokenInfo(vResult,tRParen);
}
| vResult = overClauseWithWindow
Expand All @@ -32978,7 +32983,7 @@ overClauseWithWindow returns [OverClause vResult = FragmentFactory.CreateFragmen

overClauseNoOrderBy returns [OverClause vResult]
:
vResult = overClauseBeginning
vResult = overClauseBeginningNoWindowName
tRParen:RightParenthesis
{
UpdateTokenInfo(vResult,tRParen);
Expand Down Expand Up @@ -33010,6 +33015,25 @@ overClauseBeginning returns [OverClause vResult = FragmentFactory.CreateFragment
)?
;

overClauseBeginningNoWindowName returns [OverClause vResult = FragmentFactory.CreateFragment<OverClause>()]
:
tOver:Over
{
UpdateTokenInfo(vResult,tOver);
}
LeftParenthesis
(
(Identifier By) =>
tPartition:Identifier
{
Match(tPartition, CodeGenerationSupporter.Partition);
}
By expressionList[vResult, vResult.Partitions]
|
/* empty - allow OVER() with no PARTITION BY */
)
;

windowFrameClause returns [WindowFrameClause vResult = FragmentFactory.CreateFragment<WindowFrameClause>()]
:
tRowsRange:Identifier
Expand Down
14 changes: 13 additions & 1 deletion Test/SqlDom/Baselines160/WindowClauseTests160.sql
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,16 @@ SELECT Sum(t.c1) OVER Win1
FROM t1 AS t
GROUP BY t.c1
WINDOW Win1 AS (PARTITION BY t.c1)
ORDER BY t.c1;
ORDER BY t.c1;


GO
SELECT COUNT(*) OVER Win1
FROM tb1
WINDOW Win1 AS (PARTITION BY c1);


GO
SELECT COUNT(*) OVER (Win1 ORDER BY c1)
FROM tb1
WINDOW Win1 AS (PARTITION BY c1);
2 changes: 1 addition & 1 deletion Test/SqlDom/Only160SyntaxTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public partial class SqlDomTests
new ParserTest160("ExpressionTests160.sql", nErrors80: 1, nErrors90: 0, nErrors100: 0, nErrors110: 0, nErrors120: 0, nErrors130: 0, nErrors140: 0, nErrors150: 0),
new ParserTest160("CreateUserFromExternalProvider160.sql", nErrors80: 2, nErrors90: 1, nErrors100: 1, nErrors110: 1, nErrors120: 1, nErrors130: 1, nErrors140: 1, nErrors150: 1),
new ParserTest160("CreateExternalTableStatementTests160.sql", nErrors80: 2, nErrors90: 2, nErrors100: 2, nErrors110: 2, nErrors120: 2, nErrors130: 2, nErrors140: 2, nErrors150: 2),
new ParserTest160("WindowClauseTests160.sql", nErrors80: 14, nErrors90: 13, nErrors100: 13, nErrors110: 13, nErrors120: 13, nErrors130: 13, nErrors140: 13, nErrors150: 13),
new ParserTest160("WindowClauseTests160.sql", nErrors80: 16, nErrors90: 15, nErrors100: 15, nErrors110: 15, nErrors120: 15, nErrors130: 15, nErrors140: 15, nErrors150: 15),
new ParserTest160("CreateExternalDataSourceStatementTests160.sql", nErrors80: 2, nErrors90: 2, nErrors100: 2, nErrors110: 2, nErrors120: 2, nErrors130: 0, nErrors140: 0, nErrors150: 0),
new ParserTest160("CreateDatabaseTests160.sql", nErrors80: 4, nErrors90: 4, nErrors100: 4, nErrors110: 4, nErrors120: 4, nErrors130: 4, nErrors140: 4, nErrors150: 4),
new ParserTest160("CreateLedgerTableTests160.sql", nErrors80: 14, nErrors90: 14, nErrors100: 14, nErrors110: 14, nErrors120: 14, nErrors130: 14, nErrors140: 14, nErrors150: 14),
Expand Down
35 changes: 35 additions & 0 deletions Test/SqlDom/ParserErrorsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2156,6 +2156,41 @@ public void IgnoreOrRecpectNullsSyntaxNegativeTest()
new ParserErrorInfo(41, "SQL46010", "NULLS"));
}

/// <summary>
/// Negative tests for invalid OVER clause syntax.
/// Tests for issue: Invalid OVER clause parses successfully
/// OVER clause with just a column reference in parentheses should fail.
/// </summary>
[TestMethod]
[Priority(0)]
[SqlStudioTestCategory(Category.UnitTest)]
public void InvalidOverClauseNegativeTest()
{
// OVER clause with just an identifier in parentheses is invalid
// Valid syntax is either OVER identifier (window name reference without parens)
// or OVER (PARTITION BY ...) or OVER (ORDER BY ...) or OVER ()
// The error occurs at the closing paren when no clauses follow the window name
// Note: Error message shows the identifier value without quotes
//
ParserTestUtils.ErrorTest160("SELECT COUNT(*) OVER([col]) FROM t1",
new ParserErrorInfo(26, "SQL46010", "col"));
ParserTestUtils.ErrorTest170("SELECT COUNT(*) OVER([col]) FROM t1",
new ParserErrorInfo(26, "SQL46010", "col"));
ParserTestUtils.ErrorTest180("SELECT COUNT(*) OVER([col]) FROM t1",
new ParserErrorInfo(26, "SQL46010", "col"));

// Another variant with a regular identifier
ParserTestUtils.ErrorTest160("SELECT SUM(Amount) OVER(MyColumn) FROM t1",
new ParserErrorInfo(32, "SQL46010", "MyColumn"));
ParserTestUtils.ErrorTest170("SELECT SUM(Amount) OVER(MyColumn) FROM t1",
new ParserErrorInfo(32, "SQL46010", "MyColumn"));

// This should also fail for aggregate functions
ParserTestUtils.ErrorTest160("SELECT AVG(Value) OVER(col1) FROM t1",
new ParserErrorInfo(27, "SQL46010", "col1"));
}


/// <summary>
/// Negative tests for IS [NOT] DISTINCT FROM syntax.
/// </summary>
Expand Down
10 changes: 10 additions & 0 deletions Test/SqlDom/TestScripts/WindowClauseTests160.sql
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,14 @@ SELECT Sum(t.c1) OVER Win1 FROM t1 t
GROUP BY t.c1
WINDOW Win1 AS (PARTITION BY t.c1)
ORDER BY t.c1
GO

-- checking COUNT(*) with WINDOW clause and window name reference (without parentheses)
SELECT COUNT(*) OVER Win1 FROM tb1
WINDOW Win1 AS (PARTITION BY c1)
GO

-- checking COUNT(*) with partial window specification (window name inside parentheses)
SELECT COUNT(*) OVER (Win1 ORDER BY c1) FROM tb1
WINDOW Win1 AS (PARTITION BY c1)
GO
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "8.0.419",
"version": "8.0.420",
"rollForward": "latestMajor"
},
"msbuild-sdks": {
Expand Down
31 changes: 31 additions & 0 deletions release-notes/180/180.18.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Release Notes

## Microsoft.SqlServer.TransactSql.ScriptDom 180.18.1
This update brings the following changes over the previous release:

### Target Platform Support

* .NET Framework 4.7.2 (Windows x86, Windows x64)
* .NET 8 (Windows x86, Windows x64, Linux, macOS)
* .NET Standard 2.0+ (Windows x86, Windows x64, Linux, macOS)

### Dependencies
* Updates .NET SDK to latest patch version 8.0.420

#### .NET Framework
#### .NET Core

### New Features

### Fixed
* TRIM with FROM clause in RETURN statement fails to parse [#188](https://github.com/microsoft/SqlScriptDOM/issues/188)
* DATEADD/DATEDIFF/DATEPART/DATENAME first argument parsed as ColumnReferenceExpression instead of datepart keyword [#196](https://github.com/microsoft/SqlScriptDOM/issues/196)
* DAY used as argument for DATEADD() is interpreted as ColumnReferenceExpression [#124](https://github.com/microsoft/SqlScriptDOM/issues/124)
* TSql160Parser misidentifies interval parameter in DATEDIFF function as ColumnReferenceExpression [#98](https://github.com/microsoft/SqlScriptDOM/issues/98)
* Invalid OVER clause parses successfully [#195](https://github.com/microsoft/SqlScriptDOM/issues/195)

### Changes
* Updates the Transact-SQL script generator to ensure that semicolons are correctly placed before any trailing comments

### Known Issues
* None
Loading