Commit 977bbb0a authored by Marc Gravell's avatar Marc Gravell

"@foo unknown" detection and handling (query optimizer hints)

parent 9071f652
...@@ -32,5 +32,5 @@ ...@@ -32,5 +32,5 @@
// //
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
[assembly: AssemblyVersion("1.22.0.0")] [assembly: AssemblyVersion("1.23.0.0")]
[assembly: AssemblyFileVersion("1.22.0.0")] [assembly: AssemblyFileVersion("1.23.0.0")]
...@@ -2081,21 +2081,53 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj ...@@ -2081,21 +2081,53 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj
} }
} }
var regexIncludingUnkown = @"([?@:]" + Regex.Escape(namePrefix) + @")(\s*(?i)unknown(?-i))?";
if (count == 0) if (count == 0)
{ {
command.CommandText = Regex.Replace(command.CommandText, @"[?@:]" + Regex.Escape(namePrefix), "(SELECT NULL WHERE 1 = 0)"); command.CommandText = Regex.Replace(command.CommandText, regexIncludingUnkown, match =>
{
var variableName = match.Groups[1].Value;
if (match.Groups[2].Success)
{
// looks like an optimize hint; leave it alone!
return match.Value;
}
else
{
return "(SELECT " + variableName + " WHERE 1 = 0)";
};
});
var dummyParam = command.CreateParameter();
dummyParam.ParameterName = namePrefix;
dummyParam.Value = DBNull.Value;
command.Parameters.Add(dummyParam);
} }
else else
{ {
command.CommandText = Regex.Replace(command.CommandText, @"[?@:]" + Regex.Escape(namePrefix), match => command.CommandText = Regex.Replace(command.CommandText, regexIncludingUnkown, match =>
{ {
var grp = match.Value; var variableName = match.Groups[1].Value;
var sb = new StringBuilder("(").Append(grp).Append(1); if (match.Groups[2].Success)
for (int i = 2; i <= count; i++)
{ {
sb.Append(',').Append(grp).Append(i); // looks like an optimize hint; expand it
var suffix = match.Groups[2].Value;
var sb = new StringBuilder(variableName).Append(1).Append(suffix);
for (int i = 2; i <= count; i++)
{
sb.Append(',').Append(variableName).Append(i).Append(suffix);
}
return sb.ToString();
}
else
{
var sb = new StringBuilder("(").Append(variableName).Append(1);
for (int i = 2; i <= count; i++)
{
sb.Append(',').Append(variableName).Append(i);
}
return sb.Append(')').ToString();
} }
return sb.Append(')').ToString();
}); });
} }
} }
......
...@@ -31,5 +31,5 @@ ...@@ -31,5 +31,5 @@
// //
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
[assembly: AssemblyVersion("1.22.0.0")] [assembly: AssemblyVersion("1.23.0.0")]
[assembly: AssemblyFileVersion("1.22.0.0")] [assembly: AssemblyFileVersion("1.23.0.0")]
...@@ -31,5 +31,5 @@ ...@@ -31,5 +31,5 @@
// //
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
[assembly: AssemblyVersion("1.22.0.0")] [assembly: AssemblyVersion("1.23.0.0")]
[assembly: AssemblyFileVersion("1.22.0.0")] [assembly: AssemblyFileVersion("1.23.0.0")]
...@@ -31,5 +31,5 @@ ...@@ -31,5 +31,5 @@
// //
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
[assembly: AssemblyVersion("1.22.0.0")] [assembly: AssemblyVersion("1.23.0.0")]
[assembly: AssemblyFileVersion("1.22.0.0")] [assembly: AssemblyFileVersion("1.23.0.0")]
...@@ -31,5 +31,5 @@ ...@@ -31,5 +31,5 @@
// //
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
[assembly: AssemblyVersion("1.22.0.0")] [assembly: AssemblyVersion("1.23.0.0")]
[assembly: AssemblyFileVersion("1.22.0.0")] [assembly: AssemblyFileVersion("1.23.0.0")]
...@@ -31,5 +31,5 @@ ...@@ -31,5 +31,5 @@
// //
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
[assembly: AssemblyVersion("1.22.0.0")] [assembly: AssemblyVersion("1.23.0.0")]
[assembly: AssemblyFileVersion("1.22.0.0")] [assembly: AssemblyFileVersion("1.23.0.0")]
...@@ -31,5 +31,5 @@ ...@@ -31,5 +31,5 @@
// //
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
[assembly: AssemblyVersion("1.22.0.0")] [assembly: AssemblyVersion("1.23.0.0")]
[assembly: AssemblyFileVersion("1.22.0.0")] [assembly: AssemblyFileVersion("1.23.0.0")]
...@@ -2731,6 +2731,28 @@ public void LiteralIn() ...@@ -2731,6 +2731,28 @@ public void LiteralIn()
count.IsEqualTo(2); count.IsEqualTo(2);
} }
public void ParameterizedInWithOptimizeHint()
{
const string sql = @"
select count(1)
from(
select 1 as x
union all select 2
union all select 5) y
where y.x in @vals
option (optimize for (@vals unKnoWn))";
int count = connection.Query<int>(sql, new { vals = new[] { 1, 2, 3, 4 } }).Single();
count.IsEqualTo(2);
count = connection.Query<int>(sql, new { vals = new[] { 1 } }).Single();
count.IsEqualTo(1);
count = connection.Query<int>(sql, new { vals = new int[0] }).Single();
count.IsEqualTo(0);
}
public void TestProcedureWithTimeParameter() public void TestProcedureWithTimeParameter()
{ {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata schemaVersion="2"> <metadata schemaVersion="2">
<id>Dapper</id> <id>Dapper</id>
<version>1.22</version> <version>1.23</version>
<title>Dapper dot net</title> <title>Dapper dot net</title>
<authors>Sam Saffron,Marc Gravell</authors> <authors>Sam Saffron,Marc Gravell</authors>
<owners>Sam Saffron,Marc Gravell</owners> <owners>Sam Saffron,Marc Gravell</owners>
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
<frameworkAssembly assemblyName="Microsoft.CSharp" targetFramework=".NETFramework4.0-Client, .NETFramework4.0" /> <frameworkAssembly assemblyName="Microsoft.CSharp" targetFramework=".NETFramework4.0-Client, .NETFramework4.0" />
</frameworkAssemblies> </frameworkAssemblies>
<releaseNotes> <releaseNotes>
* 1.23 - Improved support for optimize hints (@foo unknown) with list expansions
* 1.22 - Literal support now extends to enumerable types (for "in" etc usage); move to command-flags model for "buffered" etc * 1.22 - Literal support now extends to enumerable types (for "in" etc usage); move to command-flags model for "buffered" etc
* 1.21 - Limit literals to numeric types; for enums, use value not name * 1.21 - Limit literals to numeric types; for enums, use value not name
* 1.20 - Improved async support in .NET 4.5 (lots of contributions from users here, including JasonPunyon, kwaclaw, tugberkugurlu, and mgravell); * 1.20 - Improved async support in .NET 4.5 (lots of contributions from users here, including JasonPunyon, kwaclaw, tugberkugurlu, and mgravell);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment