Skip to content

AddNamedParameter sends a UTC DateTime as 'timestamp without time zone' and throws at execution #403

Description

@jeremydmiller

Split out of #398 / #402.

Repro

await using var conn = new NpgsqlConnection(cs);
await conn.OpenAsync();
await using var cmd = new NpgsqlCommand("select @n", conn);
cmd.AddNamedParameter("n", DateTime.UtcNow);
await cmd.ExecuteScalarAsync();
ArgumentException: Cannot write DateTime with Kind=UTC to PostgreSQL type
'timestamp without time zone', consider using 'timestamp with time zone'.
(Parameter 'value')

Verified against a live Postgres. DateTime.Now (Kind=Local) works; DateTime.UtcNow does not.

Cause

DatabaseProvider.AddNamedParameter types the parameter from the value's CLR type when the caller supplies no explicit type:

else if (value != null)
{
    SetParameterType(parameter, ToParameterType(value.GetType()));
}

PostgresqlProvider maps typeof(DateTime) to NpgsqlDbType.Timestamp unconditionally. But Postgres' choice depends on the value, not the type: Npgsql resolves Kind=Utc to timestamptz and Kind=Local/Unspecified to timestamp. A per-type mapping cannot express that, so every UTC DateTime gets the wrong type.

value Npgsql resolves Weasel stamps
DateTime.UtcNow TimestampTz Timestamp
DateTime.Now Timestamp Timestamp

DateTime is the only divergence across the common CLR types — string, char, int, long, short, double, float, decimal, bool, Guid, DateTimeOffset, TimeSpan, DateOnly, TimeOnly, byte[], string[], int[], List<int>, IPAddress all agree.

The sibling AddParameter(cmd, DateTime.UtcNow) works, because it stamps nothing and lets Npgsql resolve per value. See the companion issue on that asymmetry.

Likely also affects DateTime[] / IEnumerable<DateTime> parameters via the array branch.

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