Skip to content

GetTypeMapping resolves a doubly-claimed CLR type by LastOrDefault over an unordered map (IPNetwork) #405

Description

@jeremydmiller

Split out of #398 / #402.

PostgresqlProvider.GetTypeMapping picks a mapping for a CLR type with:

NpgsqlTypeMapper.Mappings.LastOrDefault(mapping => mapping.ClrTypes.Contains(type));

LastOrDefault only means something over an ordered sequence. NpgsqlTypeMapper.Mappings is a JasperFx.Core.Cache, which is backed by an ImHashMap — enumeration is in hash-tree order, not insertion order:

first 8 in enumeration order : <2 custom>, Bigint, Boolean, Box, Bytea, Circle, Char
source declares              : Smallint, Integer, Bigint, Real, Double, Numeric, Money, Text

Today exactly one CLR type is claimed by two mappings — IPNetwork, in both Cidr (line 85) and Inet (line 86–87):

mappings claiming IPNetwork : Inet/inet  |  Cidr/cidr   (LastOrDefault wins)
GetDatabaseType(IPNetwork)  : cidr

cidr is the right answer, and ipnetwork_resolves_to_cidr passes — but only incidentally. The source declares Cidr before Inet, so under genuine insertion order LastOrDefault would return inet and that test would fail. It passes because the hash layout happens to enumerate Cidr last.

That makes the result a function of the current key set rather than of anything declared. Adding mappings — which consuming code is explicitly invited to do — can rebalance the tree.

Suggested fix: drop the stray typeof(IPNetwork) from the Inet mapping so no CLR type is claimed twice, and make the ambiguity structurally impossible rather than order-dependent. IPAddress, NpgsqlInet and the (IPAddress, int) tuple stay on Inet. Worth also considering whether GetTypeMapping should assert on a double claim instead of silently picking one.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions