Skip to content

Detect and upgrade from macaddr to macaddr8 #428

@austindrenski

Description

@austindrenski

Background

While working on #407, I'm finding it difficult to send PhysicalAddress parameters to PostgreSQL functions that expect a macaddr8 because the default mapping is for macaddr.

Based on the docs, it looks like these types are intended to interoperate smoothly:

This type can accept both 6 and 8 byte length MAC addresses and stores them in 8 byte length format. MAC addresses given in 6 byte format will be stored in 8 byte length format with the 4th and 5th bytes set to FF and FE, respectively.

This would normally be handled by setting a different CLR type as the default mapping for macaddr8. However, since PhysicalAddress can accommodate the 8-byte width, I would like to avoid introducing another provider-specific type just for the new width.

Question

Is it be possible for MacaddrHandler to forward to Macaddr8Handler on write operations when a PhysicalAddress parameter has a byte length of 8?

Example

public class NetTestEntity
{
    // This is the default mapping.
    [Column(TypeName = "macaddr")]
    public PhysicalAddress Macaddr { get; set; }

    [Column(TypeName = "macaddr8")]
    public PhysicalAddress Macaddr8 { get; set; }
}

// Passes
[Fact]
public void PhysicalAddress_macaddr_LessThan_macaddr()
{
    using (NetContext context = Fixture.CreateContext())
    {
        PhysicalAddress macaddr = new PhysicalAddress(new byte[6]);

        NetTestEntity[] _ =
            context.NetTestEntities
                   .Where(x => EF.Functions.LessThan(x.Macaddr, macaddr))
                   .ToArray();

        AssertContainsSql("WHERE (x.\"Macaddr\" < @__macaddr_1) = TRUE");
    }
}

// Passes
[Fact]
public void PhysicalAddress_macaddr8_LessThan_macaddr8()
{
    using (NetContext context = Fixture.CreateContext())
    {
        NetTestEntity[] _ =
            context.NetTestEntities
                   .Where(x => EF.Functions.LessThan(x.Macaddr8, x.Macaddr8))
                   .ToArray();

        AssertContainsSql("WHERE (x.\"Macaddr8\" < x.\"Macaddr8\") = TRUE");
    }
}

// Fails:
//
//  System.FormatException : MAC addresses must have length 6 in PostgreSQL
//    at Npgsql.TypeHandlers
//             .NetworkHandlers
//             .MacaddrHandler
//             .ValidateAndGetLength(PhysicalAddress value, NpgsqlParameter parameter)
[Fact]
public void PhysicalAddress_macaddr8_LessThan_macaddr8_parameter()
{
    using (NetContext context = Fixture.CreateContext())
    {
        PhysicalAddress macaddr8 = new PhysicalAddress(new byte[8]);

        NetTestEntity[] _ =
            context.NetTestEntities
                   .Where(x => EF.Functions.LessThan(x.Macaddr8, macaddr8))
                   .ToArray();

        AssertContainsSql("WHERE (x.\"Macaddr8\" < @__macaddr8_1) = TRUE");
    }
}

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