Skip to content

Commit b5f684e

Browse files
Merge pull request #111 from bruce-dunwiddie/develop
v2.5.0 Release
2 parents 9cee89b + 60b7cfd commit b5f684e

7 files changed

Lines changed: 83 additions & 26 deletions

File tree

TSQL_Parser/TSQL_Parser/Clauses/Parsers/TSQLForClauseParser.cs

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using TSQL.Statements;
77
using TSQL.Statements.Parsers;
88
using TSQL.Tokens;
9+
using TSQL.Tokens.Parsers;
910

1011
namespace TSQL.Clauses.Parsers
1112
{
@@ -23,24 +24,43 @@ public TSQLForClause Parse(ITSQLTokenizer tokenizer)
2324

2425
forClause.Tokens.Add(tokenizer.Current);
2526

26-
while (
27-
tokenizer.MoveNext() &&
28-
!tokenizer.Current.IsCharacter(TSQLCharacters.Semicolon) &&
29-
(
30-
tokenizer.Current.Type != TSQLTokenType.Keyword ||
31-
(
32-
tokenizer.Current.Type == TSQLTokenType.Keyword &&
33-
!tokenizer.Current.AsKeyword.Keyword.In
34-
(
35-
TSQLKeywords.OPTION
36-
) &&
37-
!tokenizer.Current.AsKeyword.Keyword.IsStatementStart()
38-
)
39-
))
27+
TSQLTokenParserHelper.ReadThroughAnyCommentsOrWhitespace(
28+
tokenizer,
29+
forClause.Tokens);
30+
31+
if (tokenizer.Current.AsIdentifier?.Text?.ToUpper() != "XML")
4032
{
41-
forClause.Tokens.Add(tokenizer.Current);
33+
throw new InvalidOperationException("XML expected.");
4234
}
4335

36+
forClause.Tokens.Add(tokenizer.Current);
37+
38+
TSQLTokenParserHelper.ReadThroughAnyCommentsOrWhitespace(
39+
tokenizer,
40+
forClause.Tokens);
41+
42+
// https://docs.microsoft.com/en-us/sql/relational-databases/xml/for-xml-sql-server?view=sql-server-ver16
43+
44+
if (!new List<string>
45+
{
46+
"RAW",
47+
"AUTO",
48+
"EXPLICIT",
49+
"PATH"
50+
}.Contains(tokenizer.Current.AsIdentifier?.Text?.ToUpper()))
51+
{
52+
throw new InvalidOperationException("RAW, AUTO, EXPLICIT, or PATH expected.");
53+
}
54+
55+
forClause.Tokens.Add(tokenizer.Current);
56+
57+
TSQLTokenParserHelper.ReadUntilStop(
58+
tokenizer,
59+
forClause,
60+
new List<TSQLFutureKeywords> { },
61+
new List<TSQLKeywords> { },
62+
lookForStatementStarts: true);
63+
4464
return forClause;
4565
}
4666
}

TSQL_Parser/TSQL_Parser/Expressions/Parsers/TSQLSelectExpressionParser.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Threading.Tasks;
66

77
using TSQL.Tokens;
8-
using TSQL.Tokens.Parsers;
98

109
namespace TSQL.Expressions.Parsers
1110
{
@@ -17,7 +16,6 @@ public TSQLExpression Parse(ITSQLTokenizer tokenizer)
1716

1817
if (
1918
tokenizer.Current != null &&
20-
tokenizer.Current.Text != "*" &&
2119
tokenizer.Current.Type.In(
2220
TSQLTokenType.Operator) &&
2321

TSQL_Parser/TSQL_Parser/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
// You can specify all the values or you can default the Build and Revision Numbers
3333
// by using the '*' as shown below:
3434
// [assembly: AssemblyVersion("1.0.*")]
35-
[assembly: AssemblyVersion("2.4.0.0")]
36-
[assembly: AssemblyFileVersion("2.4.0.0")]
35+
[assembly: AssemblyVersion("2.5.0.0")]
36+
[assembly: AssemblyFileVersion("2.5.0.0")]
3737

3838
[assembly: InternalsVisibleTo("Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100793625650b945744f8a2c57bc75da89cd4d2c551636aa180c3020b7a15b815c10e983e83c312eb02f131c6fcf18aaffd6c8d9af6c4353c91ca0e9206b0fb8fb7805fc07b510a47ff40705ae56977ae8893e2d247d166aa400926582840e8a5602df055762bc3479dd14c9621a77946b6e6b0a00a77204c78fb52c65121bd75ba")]

TSQL_Parser/TSQL_Parser/Push.bat

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
nuget SetApiKey %NUGET_KEY%
2-
nuget push TSQL.Parser.2.4.0.snupkg -Source https://api.nuget.org/v3/index.json
3-
nuget push TSQL.Parser.2.4.0.nupkg -Source https://api.nuget.org/v3/index.json
2+
nuget push TSQL.Parser.2.5.0.snupkg -Source https://api.nuget.org/v3/index.json
3+
nuget push TSQL.Parser.2.5.0.nupkg -Source https://api.nuget.org/v3/index.json
44
pause

TSQL_Parser/TSQL_Parser/TSQL_Parser.nuspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
<package>
33
<metadata>
44
<id>TSQL.Parser</id>
5-
<version>2.4.0</version>
5+
<version>2.5.0</version>
66
<title>TSQL.Parser</title>
77
<authors>Bruce Dunwiddie</authors>
88
<owners>shriop</owners>
99
<license type="expression">Apache-2.0</license>
1010
<projectUrl>https://github.com/bruce-dunwiddie/tsql-parser</projectUrl>
1111
<requireLicenseAcceptance>false</requireLicenseAcceptance>
1212
<description>Library for Parsing SQL Server T-SQL Scripts</description>
13-
<releaseNotes>Fixed handling of NULL in SELECT, and DISTINCT in COUNT().</releaseNotes>
13+
<releaseNotes>Fixed handling of FOR XML in SELECT.</releaseNotes>
1414
<copyright>Copyright © 2022</copyright>
1515
<tags>sql parser sql-server tsql</tags>
1616
</metadata>

TSQL_Parser/TSQL_Parser/TSQL_Parser_NetStandard.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
<TargetFramework>netstandard2.0</TargetFramework>
55
<AssemblyName>TSQL_Parser</AssemblyName>
66
<RootNamespace>TSQL_Parser</RootNamespace>
7-
<Version>2.4.0.0</Version>
8-
<AssemblyVersion>2.4.0.0</AssemblyVersion>
9-
<FileVersion>2.4.0.0</FileVersion>
7+
<Version>2.5.0.0</Version>
8+
<AssemblyVersion>2.5.0.0</AssemblyVersion>
9+
<FileVersion>2.5.0.0</FileVersion>
1010
<Description>Library for Parsing SQL Server TSQL Scripts</Description>
1111
<Copyright>Copyright © 2022</Copyright>
1212
<Company />

TSQL_Parser/Tests/Statements/SelectStatementTests.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,8 @@ FROM SomeTable a JOIN SomeTable b
309309
Assert.AreEqual(21, select.From.Tokens.Count);
310310
Assert.IsNull(select.Where);
311311
Assert.AreEqual(1, select.Select.Columns.Count);
312+
Assert.AreEqual(3, select.Select.Columns[0].Tokens.Count);
313+
Assert.AreEqual("a", select.Select.Columns[0].Expression.AsMulticolumn.TableReference.Single().Text);
312314
}
313315

314316
[Test]
@@ -889,5 +891,42 @@ public void SelectStatement_SELECT_NULL()
889891
Assert.AreEqual(TSQLExpressionType.Null, select.Select.Columns[3].Expression.Type);
890892
Assert.AreEqual(5, select.Select.Columns[4].Expression.AsConstant.Literal.AsNumericLiteral.Value);
891893
}
894+
895+
[Test]
896+
public void SelectStatement_ChainedOperators()
897+
{
898+
// regression test for https://github.com/bruce-dunwiddie/tsql-parser/issues/110
899+
List<TSQLStatement> statements = TSQLStatementReader.ParseStatements(
900+
@"select isnull(a, 0) * isnull(b, 0) / 100 as Result from myTable",
901+
includeWhitespace: false);
902+
903+
Assert.AreEqual(1, statements.Count);
904+
TSQLSelectStatement select = statements.Single().AsSelect;
905+
Assert.AreEqual(20, select.Tokens.Count);
906+
Assert.AreEqual(1, select.Select.Columns.Count);
907+
}
908+
909+
[Test]
910+
public void SelectStatement_Stuff()
911+
{
912+
// regression test for https://github.com/bruce-dunwiddie/tsql-parser/issues/108
913+
List<TSQLStatement> statements = TSQLStatementReader.ParseStatements(
914+
@"select stuff ( (select top 10 note from asset_note where note is not null order by note_id for XML path('')) , 1 , 1 , 'Note: ' );",
915+
includeWhitespace: false);
916+
917+
Assert.AreEqual(1, statements.Count);
918+
TSQLSelectStatement select = statements.Single().AsSelect;
919+
920+
TSQLSelectStatement innerSelect = select
921+
.Select
922+
.Columns[0]
923+
.Expression
924+
.AsFunction
925+
.Arguments[0]
926+
.AsSubquery
927+
.Select;
928+
929+
Assert.AreEqual(6, innerSelect.For.Tokens.Count);
930+
}
892931
}
893932
}

0 commit comments

Comments
 (0)