Skip to content

Commit 3298279

Browse files
committed
Add NoBackslashEscapes option. Fixes #701
1 parent 3d6713c commit 3298279

File tree

7 files changed

+48
-0
lines changed

7 files changed

+48
-0
lines changed

docs/content/connection-options.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,11 @@ These are the other options that MySqlConnector supports. They are set to sensib
344344
<dd>Servers are tried in ascending order of number of currently-open connections in this connection pool. Requires <code>Pooling=True</code>.
345345
</dl>
346346
</tr>
347+
<tr>
348+
<td>No Backslash Escapes, NoBackslashEscapes</td>
349+
<td>false</td>
350+
<td>If <code>true</code>, backslashes are not escaped in string parameters. Set this to <code>true</code> if the server’s SQL mode includes <a href="https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#sqlmode_no_backslash_escapes"><code>NO_BACKSLASH_ESCAPES</code></a>.</td>
351+
</tr>
347352
<tr>
348353
<td>Old Guids, OldGuids</td>
349354
<td>false</td>

src/MySqlConnector/Core/ConnectionSettings.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ public ConnectionSettings(MySqlConnectionStringBuilder csb)
8484
InteractiveSession = csb.InteractiveSession;
8585
GuidFormat = GetEffectiveGuidFormat(csb.GuidFormat, csb.OldGuids);
8686
Keepalive = csb.Keepalive;
87+
NoBackslashEscapes = csb.NoBackslashEscapes;
8788
PersistSecurityInfo = csb.PersistSecurityInfo;
8889
ServerRsaPublicKeyFile = csb.ServerRsaPublicKeyFile;
8990
ServerSPN = csb.ServerSPN;
@@ -167,6 +168,7 @@ private static MySqlGuidFormat GetEffectiveGuidFormat(MySqlGuidFormat guidFormat
167168
public bool IgnorePrepare { get; }
168169
public bool InteractiveSession { get; }
169170
public uint Keepalive { get; }
171+
public bool NoBackslashEscapes { get; }
170172
public bool PersistSecurityInfo { get; }
171173
public string ServerRsaPublicKeyFile { get; }
172174
public string ServerSPN { get; }

src/MySqlConnector/Core/IMySqlCommand.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ public static StatementPreparerOptions CreateStatementPreparerOptions(this IMySq
3636
statementPreparerOptions |= StatementPreparerOptions.DateTimeLocal;
3737
if (command.CommandType == CommandType.StoredProcedure)
3838
statementPreparerOptions |= StatementPreparerOptions.AllowOutputParameters;
39+
if (connection.NoBackslashEscapes)
40+
statementPreparerOptions |= StatementPreparerOptions.NoBackslashEscapes;
3941

4042
statementPreparerOptions |= connection.GuidFormat switch
4143
{

src/MySqlConnector/MySql.Data.MySqlClient/MySqlConnection.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,7 @@ internal async Task<CachedProcedure> GetCachedProcedure(IOBehavior ioBehavior, s
548548
internal bool IgnoreCommandTransaction => m_connectionSettings.IgnoreCommandTransaction || m_enlistedTransaction is StandardEnlistedTransaction;
549549
#endif
550550
internal bool IgnorePrepare => m_connectionSettings.IgnorePrepare;
551+
internal bool NoBackslashEscapes => m_connectionSettings.NoBackslashEscapes;
551552
internal bool TreatTinyAsBoolean => m_connectionSettings.TreatTinyAsBoolean;
552553
internal IOBehavior AsyncIOBehavior => GetConnectionSettings().ForceSynchronous ? IOBehavior.Synchronous : IOBehavior.Asynchronous;
553554

src/MySqlConnector/MySql.Data.MySqlClient/MySqlConnectionStringBuilder.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,12 @@ public uint Keepalive
269269
set => MySqlConnectionStringOption.Keepalive.SetValue(this, value);
270270
}
271271

272+
public bool NoBackslashEscapes
273+
{
274+
get => MySqlConnectionStringOption.NoBackslashEscapes.GetValue(this);
275+
set => MySqlConnectionStringOption.NoBackslashEscapes.SetValue(this, value);
276+
}
277+
272278
public bool OldGuids
273279
{
274280
get => MySqlConnectionStringOption.OldGuids.GetValue(this);
@@ -409,6 +415,7 @@ internal abstract class MySqlConnectionStringOption
409415
public static readonly MySqlConnectionStringOption<bool> IgnorePrepare;
410416
public static readonly MySqlConnectionStringOption<bool> InteractiveSession;
411417
public static readonly MySqlConnectionStringOption<uint> Keepalive;
418+
public static readonly MySqlConnectionStringOption<bool> NoBackslashEscapes;
412419
public static readonly MySqlConnectionStringOption<bool> OldGuids;
413420
public static readonly MySqlConnectionStringOption<bool> PersistSecurityInfo;
414421
public static readonly MySqlConnectionStringOption<string> ServerRsaPublicKeyFile;
@@ -608,6 +615,10 @@ static MySqlConnectionStringOption()
608615
keys: new[] { "Keep Alive", "Keepalive" },
609616
defaultValue: 0u));
610617

618+
AddOption(NoBackslashEscapes = new MySqlConnectionStringOption<bool>(
619+
keys: new[] { "No Backslash Escapes", "NoBackslashEscapes" },
620+
defaultValue: false));
621+
611622
AddOption(OldGuids = new MySqlConnectionStringOption<bool>(
612623
keys: new[] { "Old Guids", "OldGuids" },
613624
defaultValue: false));

tests/MySqlConnector.Tests/MySqlConnectionStringBuilderTests.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ public void Defaults()
5050
Assert.Equal(0u, csb.MinimumPoolSize);
5151
Assert.Equal("", csb.Password);
5252
Assert.Equal("MYSQL", csb.PipeName);
53+
#if !BASELINE
54+
Assert.False(csb.NoBackslashEscapes);
55+
#endif
5356
Assert.False(csb.OldGuids);
5457
Assert.False(csb.PersistSecurityInfo);
5558
Assert.True(csb.Pooling);
@@ -107,6 +110,7 @@ public void ParseConnectionString()
107110
"server rsa public key file=rsa.pem;" +
108111
"load balance=random;" +
109112
"guidformat=timeswapbinary16;" +
113+
"nobackslashescapes=true;" +
110114
"server spn=mariadb/[email protected];" +
111115
"use xa transactions=false;" +
112116
#endif
@@ -162,6 +166,7 @@ public void ParseConnectionString()
162166
Assert.Equal("rsa.pem", csb.ServerRsaPublicKeyFile);
163167
Assert.Equal(MySqlLoadBalance.Random, csb.LoadBalance);
164168
Assert.Equal(MySqlGuidFormat.TimeSwapBinary16, csb.GuidFormat);
169+
Assert.True(csb.NoBackslashEscapes);
165170
Assert.Equal("mariadb/[email protected]", csb.ServerSPN);
166171
Assert.False(csb.UseXaTransactions);
167172
#endif

tests/SideBySide/QueryTests.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,6 +1071,28 @@ public void CommandBehaviorSingleRow()
10711071
Assert.False(reader.Read());
10721072
}
10731073

1074+
#if !BASELINE
1075+
[Fact]
1076+
public void NoBackslashEscapes()
1077+
{
1078+
var csb = AppConfig.CreateConnectionStringBuilder();
1079+
csb.NoBackslashEscapes = true;
1080+
using var connection = new MySqlConnection(csb.ConnectionString);
1081+
connection.Open();
1082+
connection.Execute("SET @@sql_mode = CONCAT(@@sql_mode, ',NO_BACKSLASH_ESCAPES');");
1083+
var value = "\\'\"";
1084+
using var cmd = new MySqlCommand("SELECT @param;", connection)
1085+
{
1086+
Parameters =
1087+
{
1088+
new MySqlParameter("@param", value),
1089+
},
1090+
};
1091+
var result = cmd.ExecuteScalar();
1092+
Assert.Equal(value, result);
1093+
}
1094+
#endif
1095+
10741096
class BoolTest
10751097
{
10761098
public int Id { get; set; }

0 commit comments

Comments
 (0)