Skip to content

Commit

Permalink
fix codegen error in value-type multimap #2005 (#2022)
Browse files Browse the repository at this point in the history
in horizontal multi-map, don't "returnValueLocal = null" for value-types (invalid IL)
fix #2005
  • Loading branch information
mgravell committed Jan 2, 2024
1 parent 4160c9f commit d7c1603
Show file tree
Hide file tree
Showing 11 changed files with 47 additions and 27 deletions.
11 changes: 7 additions & 4 deletions Dapper/SqlMapper.cs
Expand Up @@ -1944,7 +1944,7 @@ static DbDataReader GetDbDataReader(IDataReader reader)
}
return GetTypeDeserializer(type, reader, startBound, length, returnNullIfFirstMissing);
}
return GetStructDeserializer(type, underlyingType ?? type, startBound, useGetFieldValue);
return GetSimpleValueDeserializer(type, underlyingType ?? type, startBound, useGetFieldValue);
}

private static Func<DbDataReader, object> GetHandlerDeserializer(ITypeHandler handler, Type type, int startBound)
Expand Down Expand Up @@ -3049,7 +3049,7 @@ private static DbDataReader ExecuteReaderImpl(IDbConnection cnn, ref CommandDefi
return paramReader;
}

private static Func<DbDataReader, object> GetStructDeserializer(Type type, Type effectiveType, int index, bool useGetFieldValue)
private static Func<DbDataReader, object> GetSimpleValueDeserializer(Type type, Type effectiveType, int index, bool useGetFieldValue)
{
// no point using special per-type handling here; it boils down to the same, plus not all are supported anyway (see: SqlDataReader.GetChar - not supported!)
#pragma warning disable 618
Expand Down Expand Up @@ -3578,8 +3578,11 @@ private static void GenerateDeserializerFromMap(Type type, DbDataReader reader,
if (first && returnNullIfFirstMissing)
{
il.Emit(OpCodes.Pop);
il.Emit(OpCodes.Ldnull); // stack is now [null]
il.Emit(OpCodes.Stloc, returnValueLocal);
if (!type.IsValueType) // for struct, the retval is already initialized as default
{
il.Emit(OpCodes.Ldnull); // stack is now [null]
il.Emit(OpCodes.Stloc, returnValueLocal);
}
il.Emit(OpCodes.Br, allDone);
}

Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Expand Up @@ -21,7 +21,7 @@
<IncludeSymbols>false</IncludeSymbols>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<LangVersion>11</LangVersion>
<LangVersion>12</LangVersion>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
<PackageReadmeFile>readme.md</PackageReadmeFile>
Expand Down
30 changes: 15 additions & 15 deletions Directory.Packages.props
@@ -1,46 +1,46 @@
<Project>
<ItemGroup>
<!-- note: 6.2.0 has regressions; don't force the update -->
<PackageVersion Include="DuckDB.NET.Data.Full" Version="0.9.0.3" />
<PackageVersion Include="EntityFramework" Version="6.1.3" />
<PackageVersion Include="Microsoft.CSharp" Version="4.7.0" />
<PackageVersion Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="1.1.1" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<PackageVersion Include="Microsoft.SqlServer.Types" Version="14.0.1016.290" />
<PackageVersion Include="Nerdbank.GitVersioning" Version="3.6.133" />
<PackageVersion Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="3.3.4" />
<PackageVersion Include="System.Reflection.Emit.Lightweight" Version="4.7.0" />

<!-- tests -->
<PackageVersion Include="Belgrade.Sql.Client" Version="1.1.4" />
<PackageVersion Include="BenchmarkDotNet" Version="0.13.7" />
<PackageVersion Include="BenchmarkDotNet" Version="0.13.11" />
<PackageVersion Include="Dashing" Version="2.10.0" />
<PackageVersion Include="Dapper.Contrib" Version="2.0.78" />
<PackageVersion Include="DevExpress.Xpo" Version="23.1.4" />
<PackageVersion Include="FirebirdSql.Data.FirebirdClient" Version="9.1.1" />
<PackageVersion Include="GitHubActionsTestLogger" Version="2.3.2" />
<PackageVersion Include="DuckDB.NET.Data.Full" Version="0.9.2" />
<PackageVersion Include="DevExpress.Xpo" Version="23.2.3" />
<PackageVersion Include="FirebirdSql.Data.FirebirdClient" Version="10.0.0" />
<PackageVersion Include="GitHubActionsTestLogger" Version="2.3.3" />
<PackageVersion Include="Iesi.Collections" Version="4.0.5" />
<PackageVersion Include="linq2db.SqlServer" Version="3.7.0" />
<PackageVersion Include="Microsoft.Data.SqlClient" Version="5.1.1" />
<PackageVersion Include="Microsoft.Data.SqlClient" Version="5.1.2" />
<PackageVersion Include="Microsoft.Data.Sqlite" Version="8.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.7.1" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageVersion Include="Mighty" Version="3.2.0" />
<PackageVersion Include="MySqlConnector" Version="2.2.7" />
<PackageVersion Include="NHibernate" Version="5.4.5" />
<PackageVersion Include="Norm.net" Version="5.3.7" />
<PackageVersion Include="Npgsql" Version="7.0.4" />
<PackageVersion Include="MySqlConnector" Version="2.3.3" />
<PackageVersion Include="NHibernate" Version="5.5.0" />
<PackageVersion Include="Norm.net" Version="5.4.0" />
<PackageVersion Include="Npgsql" Version="8.0.1" />
<PackageVersion Include="PetaPoco" Version="5.1.306" />
<PackageVersion Include="RepoDb.SqlServer" Version="1.13.1" />
<PackageVersion Include="ServiceStack.OrmLite.SqlServer" Version="6.10.0" />
<PackageVersion Include="Snowflake.Data" Version="2.1.0" />
<PackageVersion Include="Snowflake.Data" Version="2.1.5" />
<PackageVersion Include="SqlMarshal" Version="0.4.4" />
<PackageVersion Include="SubSonic" Version="3.0.0.4" />
<PackageVersion Include="Susanoo.SqlServer" Version="1.2.4.2" />
<PackageVersion Include="System.Data.SqlClient" Version="4.8.5" />
<PackageVersion Include="System.Data.SQLite" Version="1.0.118" />
<PackageVersion Include="System.ValueTuple" Version="4.5.0" />
<PackageVersion Include="xunit" Version="2.5.0" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.0" />
<PackageVersion Include="xunit" Version="2.6.4" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.6" />
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion appveyor.yml
Expand Up @@ -7,7 +7,7 @@ skip_commits:
- '**/*.md'

install:
- choco install dotnet-sdk --version 7.0.402
- choco install dotnet-sdk --version 8.0.100

environment:
Appveyor: true
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/Dapper.Tests.Performance/DapperCacheImpact.cs
Expand Up @@ -10,7 +10,7 @@ public class DapperCacheImpact : BenchmarkBase
[GlobalSetup]
public void Setup() => BaseSetup();

private object args = new { Id = 42, Name = "abc" };
private readonly object args = new { Id = 42, Name = "abc" };

public class Foo
{
Expand Down
1 change: 1 addition & 0 deletions benchmarks/Dapper.Tests.Performance/LegacyTests.cs
Expand Up @@ -128,6 +128,7 @@ private static void Try(Action action, string blame)
}
}

[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1806:Do not ignore method results", Justification = "Intentional - just make sure we have something")]
public async Task RunAsync(int iterations)
{
using (var connection = GetOpenConnection())
Expand Down
5 changes: 5 additions & 0 deletions global.json
@@ -0,0 +1,5 @@
{
"sdk": {
"version": "8.0.100"
}
}
4 changes: 2 additions & 2 deletions tests/Dapper.Tests/Dapper.Tests.csproj
Expand Up @@ -2,9 +2,9 @@
<PropertyGroup>
<AssemblyName>Dapper.Tests</AssemblyName>
<Description>Dapper Core Test Suite</Description>
<TargetFrameworks>net472;net6.0;net7.0</TargetFrameworks>
<TargetFrameworks>net472;net6.0;net8.0</TargetFrameworks>
<DefineConstants>$(DefineConstants);MSSQLCLIENT</DefineConstants>
<NoWarn>$(NoWarn);IDE0017;IDE0034;IDE0037;IDE0039;IDE0042;IDE0044;IDE0051;IDE0052;IDE0059;IDE0060;IDE0063;IDE1006;xUnit1004;CA1806;CA1816;CA1822;CA1825;CA2208</NoWarn>
<NoWarn>$(NoWarn);IDE0017;IDE0034;IDE0037;IDE0039;IDE0042;IDE0044;IDE0051;IDE0052;IDE0059;IDE0060;IDE0063;IDE1006;xUnit1004;CA1806;CA1816;CA1822;CA1825;CA2208;CA1861</NoWarn>
<Nullable>enable</Nullable>
</PropertyGroup>

Expand Down
11 changes: 11 additions & 0 deletions tests/Dapper.Tests/MiscTests.cs
Expand Up @@ -1310,5 +1310,16 @@ public HazGetOnlyAndCtor(int idProperty, string nameProperty)
NameProperty = nameProperty;
}
}

internal record struct One(int OID);
internal record struct Two(int OID, string Name);

[Fact]
public async Task QuerySplitStruct() // https://github.com/DapperLib/Dapper/issues/2005
{
var results = await connection.QueryAsync<One, Two, (One,Two)>(@"SELECT 1 AS OID, 2 AS OID, 'Name' AS Name", (x,y) => (x,y), splitOn: "OID");

Assert.Single(results);
}
}
}
2 changes: 1 addition & 1 deletion tests/Dapper.Tests/Providers/FirebirdTests.cs
Expand Up @@ -33,7 +33,7 @@ public void Issue178_Firebird()
connection.Execute("insert into Issue178(id) values(42)");
// raw ADO.net
using (var sqlCmd = new FbCommand(sql, connection))
using (IDataReader reader1 = sqlCmd.ExecuteReader())
using (var reader1 = sqlCmd.ExecuteReader())
{
Assert.True(reader1.Read());
Assert.Equal(1, reader1.GetInt32(0));
Expand Down
4 changes: 2 additions & 2 deletions tests/Dapper.Tests/Providers/PostgresqlTests.cs
Expand Up @@ -49,7 +49,7 @@ public void TestPostgresqlArrayParameters()
{
using var conn = GetOpenNpgsqlConnection();

IDbTransaction transaction = conn.BeginTransaction();
var transaction = conn.BeginTransaction();
conn.Execute("create table tcat ( id serial not null, breed character varying(20) not null, name character varying (20) not null);");
conn.Execute("insert into tcat(breed, name) values(:Breed, :Name) ", Cats);

Expand All @@ -66,7 +66,7 @@ public void TestPostgresqlListParameters()
{
using var conn = GetOpenNpgsqlConnection();

IDbTransaction transaction = conn.BeginTransaction();
var transaction = conn.BeginTransaction();
conn.Execute("create table tcat ( id serial not null, breed character varying(20) not null, name character varying (20) not null);");
conn.Execute("insert into tcat(breed, name) values(:Breed, :Name) ", new List<Cat>(Cats));

Expand Down

0 comments on commit d7c1603

Please sign in to comment.