From ab2051d96ff96df5e5f544360f68246e1288b4a5 Mon Sep 17 00:00:00 2001 From: Bruce Dunwiddie Date: Sun, 5 Jun 2022 14:26:04 -0500 Subject: [PATCH 1/2] Fixed parsing of simple SELECT's #93 --- .../Parsers/TSQLValueExpressionParser.cs | 34 ++++++++++++- TSQL_Parser/TSQL_Parser/TSQLIdentifiers.cs | 1 - .../Tests/Statements/SelectStatementTests.cs | 48 +++++++++++++++++++ 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/TSQL_Parser/TSQL_Parser/Expressions/Parsers/TSQLValueExpressionParser.cs b/TSQL_Parser/TSQL_Parser/Expressions/Parsers/TSQLValueExpressionParser.cs index 390f531..1c6929a 100644 --- a/TSQL_Parser/TSQL_Parser/Expressions/Parsers/TSQLValueExpressionParser.cs +++ b/TSQL_Parser/TSQL_Parser/Expressions/Parsers/TSQLValueExpressionParser.cs @@ -393,7 +393,39 @@ public TSQLExpression ParseNext( } } - return null; + // this is the fall through if none of the "returns" hit above + + // will also hit if we parse a simple single column expression, e.g. "SELECT blah" + + TSQLColumnExpression simpleColumn = new TSQLColumnExpression(); + + simpleColumn.Tokens.AddRange(tokens); + + List simpleColumnReference = tokens + .Where(t => + !t.IsComment() && + !t.IsWhitespace() && + !t.IsCharacter(TSQLCharacters.Semicolon)) + .ToList(); + + if (simpleColumnReference.Count > 1) + { + // p.ProductID will have the single token p in the final list + + // AdventureWorks..ErrorLog.ErrorLogID will have 4 tokens in the final list + // e.g. {AdventureWorks, ., ., ErrorLog} + + simpleColumn.TableReference = simpleColumnReference + .GetRange(0, simpleColumnReference + .FindLastIndex(t => t.IsCharacter(TSQLCharacters.Period))) + .ToList(); + } + + simpleColumn.Column = simpleColumnReference + .Last() + .AsIdentifier; + + return simpleColumn; } else { diff --git a/TSQL_Parser/TSQL_Parser/TSQLIdentifiers.cs b/TSQL_Parser/TSQL_Parser/TSQLIdentifiers.cs index 353a3bc..5cf4a24 100644 --- a/TSQL_Parser/TSQL_Parser/TSQLIdentifiers.cs +++ b/TSQL_Parser/TSQL_Parser/TSQLIdentifiers.cs @@ -275,7 +275,6 @@ public struct TSQLIdentifiers public static readonly TSQLIdentifiers COLUMNS_UPDATED = new TSQLIdentifiers("COLUMNS_UPDATED"); public static readonly TSQLIdentifiers EVENTDATA = new TSQLIdentifiers("EVENTDATA"); public static readonly TSQLIdentifiers TRIGGER_NESTLEVEL = new TSQLIdentifiers("TRIGGER_NESTLEVEL"); - public static readonly TSQLIdentifiers UPDATE = new TSQLIdentifiers("UPDATE"); #pragma warning restore 1591 diff --git a/TSQL_Parser/Tests/Statements/SelectStatementTests.cs b/TSQL_Parser/Tests/Statements/SelectStatementTests.cs index 1d3fe9b..c4182cd 100644 --- a/TSQL_Parser/Tests/Statements/SelectStatementTests.cs +++ b/TSQL_Parser/Tests/Statements/SelectStatementTests.cs @@ -744,5 +744,53 @@ public void SelectStatement_CASTMissingASRegression() TSQLSelectStatement select = statements.Single().AsSelect; Assert.AreEqual(14, select.Tokens.Count); } + + [Test] + public void SelectStatement_system_user_Regression() + { + // regression test for https://github.com/bruce-dunwiddie/tsql-parser/issues/93 + List statements = TSQLStatementReader.ParseStatements( + //@"SELECT system_user;", + @"SELECT system_user;", + includeWhitespace: false); + + // System.NullReferenceException + // this shouldn't happen even if only because it encountered the end of the string + + // system_user is a system property, not a function + // is it trying to parse arguments? + + // should system properties be split out from system functions? + // what should each be named? + + Assert.AreEqual(1, statements.Count); + TSQLSelectStatement select = statements.Single().AsSelect; + Assert.AreEqual(3, select.Tokens.Count); + Assert.AreEqual("system_user", select.Select.Columns[0].Expression.AsColumn.Column.Name); + } + + [Test] + public void SelectStatement_system_user_Regression_without_semicolon() + { + // regression test for https://github.com/bruce-dunwiddie/tsql-parser/issues/93 + List statements = TSQLStatementReader.ParseStatements( + //@"SELECT system_user;", + @"SELECT system_user", + includeWhitespace: false); + + // System.NullReferenceException + // this shouldn't happen even if only because it encountered the end of the string + + // system_user is a system property, not a function + // is it trying to parse arguments? + + // should system properties be split out from system functions? + // what should each be named? + + Assert.AreEqual(1, statements.Count); + TSQLSelectStatement select = statements.Single().AsSelect; + Assert.AreEqual(2, select.Tokens.Count); + Assert.AreEqual("system_user", select.Select.Columns[0].Expression.AsColumn.Column.Name); + } } } From c99d643967bd3ec589c885049c802b8244054469 Mon Sep 17 00:00:00 2001 From: Bruce Dunwiddie Date: Sun, 5 Jun 2022 14:39:48 -0500 Subject: [PATCH 2/2] Updating version numbers for publish. --- TSQL_Parser/TSQL_Parser/Properties/AssemblyInfo.cs | 4 ++-- TSQL_Parser/TSQL_Parser/Push.bat | 4 ++-- TSQL_Parser/TSQL_Parser/TSQL_Parser.nuspec | 4 ++-- TSQL_Parser/TSQL_Parser/TSQL_Parser_NetStandard.csproj | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/TSQL_Parser/TSQL_Parser/Properties/AssemblyInfo.cs b/TSQL_Parser/TSQL_Parser/Properties/AssemblyInfo.cs index 27718c3..a94ce39 100644 --- a/TSQL_Parser/TSQL_Parser/Properties/AssemblyInfo.cs +++ b/TSQL_Parser/TSQL_Parser/Properties/AssemblyInfo.cs @@ -32,7 +32,7 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.1.0.0")] -[assembly: AssemblyFileVersion("2.1.0.0")] +[assembly: AssemblyVersion("2.2.0.0")] +[assembly: AssemblyFileVersion("2.2.0.0")] [assembly: InternalsVisibleTo("Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100793625650b945744f8a2c57bc75da89cd4d2c551636aa180c3020b7a15b815c10e983e83c312eb02f131c6fcf18aaffd6c8d9af6c4353c91ca0e9206b0fb8fb7805fc07b510a47ff40705ae56977ae8893e2d247d166aa400926582840e8a5602df055762bc3479dd14c9621a77946b6e6b0a00a77204c78fb52c65121bd75ba")] \ No newline at end of file diff --git a/TSQL_Parser/TSQL_Parser/Push.bat b/TSQL_Parser/TSQL_Parser/Push.bat index 5185675..ec35d9d 100644 --- a/TSQL_Parser/TSQL_Parser/Push.bat +++ b/TSQL_Parser/TSQL_Parser/Push.bat @@ -1,4 +1,4 @@ nuget SetApiKey %NUGET_KEY% -nuget push TSQL.Parser.2.1.0.snupkg -Source https://api.nuget.org/v3/index.json -nuget push TSQL.Parser.2.1.0.nupkg -Source https://api.nuget.org/v3/index.json +nuget push TSQL.Parser.2.2.0.snupkg -Source https://api.nuget.org/v3/index.json +nuget push TSQL.Parser.2.2.0.nupkg -Source https://api.nuget.org/v3/index.json pause \ No newline at end of file diff --git a/TSQL_Parser/TSQL_Parser/TSQL_Parser.nuspec b/TSQL_Parser/TSQL_Parser/TSQL_Parser.nuspec index b0a57a9..6b361ab 100644 --- a/TSQL_Parser/TSQL_Parser/TSQL_Parser.nuspec +++ b/TSQL_Parser/TSQL_Parser/TSQL_Parser.nuspec @@ -2,7 +2,7 @@ TSQL.Parser - 2.1.0 + 2.2.0 TSQL.Parser Bruce Dunwiddie shriop @@ -10,7 +10,7 @@ https://github.com/bruce-dunwiddie/tsql-parser false Library for Parsing SQL Server T-SQL Scripts - Fixed argument parsing for CAST function. + Fixed simple single column SELECT parsing. Copyright © 2022 sql parser sql-server tsql diff --git a/TSQL_Parser/TSQL_Parser/TSQL_Parser_NetStandard.csproj b/TSQL_Parser/TSQL_Parser/TSQL_Parser_NetStandard.csproj index 6e6be08..0405d3a 100644 --- a/TSQL_Parser/TSQL_Parser/TSQL_Parser_NetStandard.csproj +++ b/TSQL_Parser/TSQL_Parser/TSQL_Parser_NetStandard.csproj @@ -4,9 +4,9 @@ netstandard2.0 TSQL_Parser TSQL_Parser - 2.1.0.0 - 2.1.0.0 - 2.1.0.0 + 2.2.0.0 + 2.2.0.0 + 2.2.0.0 Library for Parsing SQL Server TSQL Scripts Copyright © 2022