From cdadfa6db61c9248b6e3169cc813be3df59c095f Mon Sep 17 00:00:00 2001 From: Marc Gravell Date: Thu, 19 Oct 2023 12:25:11 +0100 Subject: [PATCH] whitespace for auto-SP detection: use unicode spec via regex (#1987) * add fix and test for #1975 * wrong ticket number; is #1986 --- Dapper/CommandDefinition.cs | 7 ++++--- tests/Dapper.Tests/ProcedureTests.cs | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/Dapper/CommandDefinition.cs b/Dapper/CommandDefinition.cs index 1820d86f4..f7132ed52 100644 --- a/Dapper/CommandDefinition.cs +++ b/Dapper/CommandDefinition.cs @@ -2,6 +2,7 @@ using System.Data; using System.Reflection; using System.Reflection.Emit; +using System.Text.RegularExpressions; using System.Threading; namespace Dapper @@ -103,14 +104,14 @@ public CommandDefinition(string commandText, object? parameters = null, IDbTrans static CommandType InferCommandType(string sql) { - if (sql is null || sql.IndexOfAny(WhitespaceChars) >= 0) return System.Data.CommandType.Text; + if (sql is null || WhitespaceChars.IsMatch(sql)) return System.Data.CommandType.Text; return System.Data.CommandType.StoredProcedure; } } - // if the sql contains any whitespace character (space/tab/cr/lf): interpret as ad-hoc; but "SomeName" should be treated as a stored-proc + // if the sql contains any whitespace character (space/tab/cr/lf/etc - via unicode): interpret as ad-hoc; but "SomeName" should be treated as a stored-proc // (note TableDirect would need to be specified explicitly, but in reality providers don't usually support TableDirect anyway) - private static readonly char[] WhitespaceChars = new char[] { ' ', '\t', '\r', '\n' }; + private static readonly Regex WhitespaceChars = new(@"\s", RegexOptions.Compiled); private CommandDefinition(object? parameters) : this() { diff --git a/tests/Dapper.Tests/ProcedureTests.cs b/tests/Dapper.Tests/ProcedureTests.cs index 9d76f44b9..9cc71f474 100644 --- a/tests/Dapper.Tests/ProcedureTests.cs +++ b/tests/Dapper.Tests/ProcedureTests.cs @@ -302,5 +302,20 @@ select 1 as Num Assert.Empty(result); } + + [Theory] + [InlineData(" ")] + [InlineData("\u00A0")] // nbsp + [InlineData("\u202F")] // narrow nbsp + [InlineData("\u2000")] // n quad + [InlineData("\t")] + [InlineData("\r")] + [InlineData("\n")] + public async Task Issue1986_AutoProc_Whitespace(string space) + { + var sql = "select!42".Replace("!", space); + var result = await connection.QuerySingleAsync(sql); + Assert.Equal(42, result); + } } }