Commit 344de889 authored by Marc Gravell's avatar Marc Gravell

Fix for #569

parent ce4d015d
...@@ -3302,7 +3302,19 @@ public void PseudoPositionalParameters_ReusedParameter() ...@@ -3302,7 +3302,19 @@ public void PseudoPositionalParameters_ReusedParameter()
} }
} }
} }
[Fact]
public void Issue569_SO38527197_PseudoPositionalParameters_In()
{
using (var connection = ConnectViaOledb())
{
int[] ids = { 1, 2, 5, 7 };
var list = connection.Query<int>("select * from string_split('1,2,3,4,5',',') where value in ?ids?", new { ids }).AsList();
list.Sort();
string.Join(",", list).IsEqualTo("1,2,5");
}
}
[Fact] [Fact]
public void PseudoPositionalParameters_ExecSingle() public void PseudoPositionalParameters_ExecSingle()
{ {
......
...@@ -1831,7 +1831,9 @@ internal static int GetListPaddingExtraCount(int count) ...@@ -1831,7 +1831,9 @@ internal static int GetListPaddingExtraCount(int count)
return intoBlock == 0 ? 0 : (padFactor - intoBlock); return intoBlock == 0 ? 0 : (padFactor - intoBlock);
} }
private static string GetInListRegex(string name) => @"([?@:]" + Regex.Escape(name) + @")(?!\w)(\s+(?i)unknown(?-i))?"; private static string GetInListRegex(string name, bool byPosition) => byPosition
? (@"(\?)" + Regex.Escape(name) + @"\?(?!\w)(\s+(?i)unknown(?-i))?")
: (@"([?@:]" + Regex.Escape(name) + @")(?!\w)(\s+(?i)unknown(?-i))?");
/// <summary> /// <summary>
/// Internal use only /// Internal use only
/// </summary> /// </summary>
...@@ -1854,6 +1856,7 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj ...@@ -1854,6 +1856,7 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj
} }
else else
{ {
bool byPosition = ShouldPassByPosition(command.CommandText);
var list = value as IEnumerable; var list = value as IEnumerable;
var count = 0; var count = 0;
bool isString = value is IEnumerable<string>; bool isString = value is IEnumerable<string>;
...@@ -1862,7 +1865,7 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj ...@@ -1862,7 +1865,7 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj
int splitAt = SqlMapper.Settings.InListStringSplitCount; int splitAt = SqlMapper.Settings.InListStringSplitCount;
bool viaSplit = splitAt >= 0 bool viaSplit = splitAt >= 0
&& TryStringSplit(ref list, splitAt, namePrefix, command); && TryStringSplit(ref list, splitAt, namePrefix, command, byPosition);
if (list != null && !viaSplit) if (list != null && !viaSplit)
{ {
...@@ -1934,7 +1937,7 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj ...@@ -1934,7 +1937,7 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj
} }
else else
{ {
var regexIncludingUnknown = GetInListRegex(namePrefix); var regexIncludingUnknown = GetInListRegex(namePrefix, byPosition);
if (count == 0) if (count == 0)
{ {
command.CommandText = Regex.Replace(command.CommandText, regexIncludingUnknown, match => command.CommandText = Regex.Replace(command.CommandText, regexIncludingUnknown, match =>
...@@ -1974,10 +1977,13 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj ...@@ -1974,10 +1977,13 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj
} }
else else
{ {
var sb = GetStringBuilder().Append('(').Append(variableName).Append(1);
var sb = GetStringBuilder().Append('(').Append(variableName);
if(!byPosition) sb.Append(1);
for (int i = 2; i <= count; i++) for (int i = 2; i <= count; i++)
{ {
sb.Append(',').Append(variableName).Append(i); sb.Append(',').Append(variableName);
if (!byPosition) sb.Append(i);
} }
return sb.Append(')').__ToStringRecycle(); return sb.Append(')').__ToStringRecycle();
} }
...@@ -1987,20 +1993,20 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj ...@@ -1987,20 +1993,20 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj
} }
} }
private static bool TryStringSplit(ref IEnumerable list, int splitAt, string namePrefix, IDbCommand command) private static bool TryStringSplit(ref IEnumerable list, int splitAt, string namePrefix, IDbCommand command, bool byPosition)
{ {
if (list == null || splitAt < 0) return false; if (list == null || splitAt < 0) return false;
if (list is IEnumerable<int>) return TryStringSplit<int>(ref list, splitAt, namePrefix, command, "int", if (list is IEnumerable<int>) return TryStringSplit<int>(ref list, splitAt, namePrefix, command, "int", byPosition,
(sb, i) => sb.Append(i.ToString(CultureInfo.InvariantCulture))); (sb, i) => sb.Append(i.ToString(CultureInfo.InvariantCulture)));
if (list is IEnumerable<long>) return TryStringSplit<long>(ref list, splitAt, namePrefix, command, "bigint", if (list is IEnumerable<long>) return TryStringSplit<long>(ref list, splitAt, namePrefix, command, "bigint", byPosition,
(sb, i) => sb.Append(i.ToString(CultureInfo.InvariantCulture))); (sb, i) => sb.Append(i.ToString(CultureInfo.InvariantCulture)));
if (list is IEnumerable<short>) return TryStringSplit<short>(ref list, splitAt, namePrefix, command, "smallint", if (list is IEnumerable<short>) return TryStringSplit<short>(ref list, splitAt, namePrefix, command, "smallint", byPosition,
(sb, i) => sb.Append(i.ToString(CultureInfo.InvariantCulture))); (sb, i) => sb.Append(i.ToString(CultureInfo.InvariantCulture)));
if (list is IEnumerable<byte>) return TryStringSplit<byte>(ref list, splitAt, namePrefix, command, "tinyint", if (list is IEnumerable<byte>) return TryStringSplit<byte>(ref list, splitAt, namePrefix, command, "tinyint", byPosition,
(sb, i) => sb.Append(i.ToString(CultureInfo.InvariantCulture))); (sb, i) => sb.Append(i.ToString(CultureInfo.InvariantCulture)));
return false; return false;
} }
private static bool TryStringSplit<T>(ref IEnumerable list, int splitAt, string namePrefix, IDbCommand command, string colType, private static bool TryStringSplit<T>(ref IEnumerable list, int splitAt, string namePrefix, IDbCommand command, string colType, bool byPosition,
Action<StringBuilder, T> append) Action<StringBuilder, T> append)
{ {
ICollection<T> typed = list as ICollection<T>; ICollection<T> typed = list as ICollection<T>;
...@@ -2012,7 +2018,7 @@ private static bool TryStringSplit(ref IEnumerable list, int splitAt, string nam ...@@ -2012,7 +2018,7 @@ private static bool TryStringSplit(ref IEnumerable list, int splitAt, string nam
if (typed.Count < splitAt) return false; if (typed.Count < splitAt) return false;
string varName = null; string varName = null;
var regexIncludingUnknown = GetInListRegex(namePrefix); var regexIncludingUnknown = GetInListRegex(namePrefix, byPosition);
var sql = Regex.Replace(command.CommandText, regexIncludingUnknown, match => var sql = Regex.Replace(command.CommandText, regexIncludingUnknown, match =>
{ {
var variableName = match.Groups[1].Value; var variableName = match.Groups[1].Value;
......
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