Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/Weasel.Postgresql.Tests/PostgresqlProviderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,34 @@ public void ipnetwork_resolves_to_cidr()
.ShouldBe("cidr");
}

[Fact]
public void ipnetwork_is_claimed_by_exactly_one_mapping()
{
// Guards the test above. IPNetwork used to be declared on both the cidr and the inet
// mapping, and GetTypeMapping breaks a tie with LastOrDefault over a Cache backed by
// an ImHashMap -- so "cidr" was winning on hash layout, not on anything declared.
// weasel#405.
NpgsqlTypeMapper.Mappings
.Count(mapping => mapping.ClrTypes.Contains(typeof(IPNetwork)))
.ShouldBe(1);
}

[Fact]
public void no_clr_type_is_claimed_by_more_than_one_mapping()
{
// Any CLR type reachable from two mappings has an order-dependent, effectively
// arbitrary resolution. Keep that structurally impossible rather than relying on
// enumeration order. weasel#405.
var doubleClaimed = NpgsqlTypeMapper.Mappings
.SelectMany(mapping => mapping.ClrTypes.Select(clrType => (clrType, mapping)))
.GroupBy(x => x.clrType)
.Where(g => g.Count() > 1)
.Select(g => $"{g.Key.Name} <- {string.Join(", ", g.Select(x => x.mapping.NpgsqlDbType))}")
.ToArray();

doubleClaimed.ShouldBeEmpty();
}

[Fact]
public void canonicizesql_supports_tabs_as_whitespace()
{
Expand Down
5 changes: 4 additions & 1 deletion src/Weasel.Postgresql/NpgsqlTypeMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,12 @@ public class NpgsqlTypeMapper
{NpgsqlDbType.Multirange | NpgsqlDbType.TimestampTz, new NpgsqlTypeMapping(NpgsqlDbType.Multirange | NpgsqlDbType.TimestampTz, DbType.Object, "tstzmultirange")},

// Network types
// IPNetwork belongs to cidr only. It used to be listed on inet as well, and which of
// the two won was decided by LastOrDefault over a hash-ordered ImHashMap -- i.e. by
// accident rather than by declaration. See weasel#405.
{NpgsqlDbType.Cidr, new NpgsqlTypeMapping(NpgsqlDbType.Cidr, DbType.Object, "cidr", typeof(IPNetwork))},
{NpgsqlDbType.Inet, new NpgsqlTypeMapping(NpgsqlDbType.Inet, DbType.Object, "inet", typeof(IPAddress),
typeof((IPAddress Address, int Subnet)), typeof(NpgsqlInet), typeof(IPNetwork), IPAddress.Loopback.GetType())},
typeof((IPAddress Address, int Subnet)), typeof(NpgsqlInet), IPAddress.Loopback.GetType())},
{NpgsqlDbType.MacAddr, new NpgsqlTypeMapping(NpgsqlDbType.MacAddr, DbType.Object, "macaddr", typeof(PhysicalAddress))},
{NpgsqlDbType.MacAddr8, new NpgsqlTypeMapping(NpgsqlDbType.MacAddr8, DbType.Object, "macaddr8")},

Expand Down
Loading