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

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

parent 9071f652
......@@ -32,5 +32,5 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.22.0.0")]
[assembly: AssemblyFileVersion("1.22.0.0")]
[assembly: AssemblyVersion("1.23.0.0")]
[assembly: AssemblyFileVersion("1.23.0.0")]
......@@ -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)
{
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
{
command.CommandText = Regex.Replace(command.CommandText, @"[?@:]" + Regex.Escape(namePrefix), match =>
command.CommandText = Regex.Replace(command.CommandText, regexIncludingUnkown, match =>
{
var grp = match.Value;
var sb = new StringBuilder("(").Append(grp).Append(1);
for (int i = 2; i <= count; i++)
var variableName = match.Groups[1].Value;
if (match.Groups[2].Success)
{
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 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.22.0.0")]
[assembly: AssemblyFileVersion("1.22.0.0")]
[assembly: AssemblyVersion("1.23.0.0")]
[assembly: AssemblyFileVersion("1.23.0.0")]
......@@ -31,5 +31,5 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.22.0.0")]
[assembly: AssemblyFileVersion("1.22.0.0")]
[assembly: AssemblyVersion("1.23.0.0")]
[assembly: AssemblyFileVersion("1.23.0.0")]
......@@ -31,5 +31,5 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.22.0.0")]
[assembly: AssemblyFileVersion("1.22.0.0")]
[assembly: AssemblyVersion("1.23.0.0")]
[assembly: AssemblyFileVersion("1.23.0.0")]
......@@ -31,5 +31,5 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.22.0.0")]
[assembly: AssemblyFileVersion("1.22.0.0")]
[assembly: AssemblyVersion("1.23.0.0")]
[assembly: AssemblyFileVersion("1.23.0.0")]
......@@ -31,5 +31,5 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.22.0.0")]
[assembly: AssemblyFileVersion("1.22.0.0")]
[assembly: AssemblyVersion("1.23.0.0")]
[assembly: AssemblyFileVersion("1.23.0.0")]
......@@ -31,5 +31,5 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.22.0.0")]
[assembly: AssemblyFileVersion("1.22.0.0")]
[assembly: AssemblyVersion("1.23.0.0")]
[assembly: AssemblyFileVersion("1.23.0.0")]
......@@ -2731,6 +2731,28 @@ public void LiteralIn()
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()
{
......
......@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata schemaVersion="2">
<id>Dapper</id>
<version>1.22</version>
<version>1.23</version>
<title>Dapper dot net</title>
<authors>Sam Saffron,Marc Gravell</authors>
<owners>Sam Saffron,Marc Gravell</owners>
......@@ -19,6 +19,7 @@
<frameworkAssembly assemblyName="Microsoft.CSharp" targetFramework=".NETFramework4.0-Client, .NETFramework4.0" />
</frameworkAssemblies>
<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.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);
......
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