diff --git a/src/Npgsql/Internal/Converters/ArrayConverter.cs b/src/Npgsql/Internal/Converters/ArrayConverter.cs index 2d6d443329..b594f19823 100644 --- a/src/Npgsql/Internal/Converters/ArrayConverter.cs +++ b/src/Npgsql/Internal/Converters/ArrayConverter.cs @@ -619,45 +619,40 @@ protected override PgConverter CreateConverter(PgConverterResolution effectiv protected override PgConverterResolution? GetEffectiveResolution(T? values, PgTypeId? expectedEffectivePgTypeId) { PgConverterResolution? resolution = null; - if (values is null) + switch (values) { - resolution = EffectiveTypeInfo.GetDefaultResolution(expectedEffectivePgTypeId); - } - else - { - switch (values) - { - case TElement[] array: - foreach (var value in array) - { - var result = EffectiveTypeInfo.GetResolution(value, resolution?.PgTypeId ?? expectedEffectivePgTypeId); - resolution ??= result; - } - break; - case List list: - foreach (var value in list) - { - var result = EffectiveTypeInfo.GetResolution(value, resolution?.PgTypeId ?? expectedEffectivePgTypeId); - resolution ??= result; - } - break; - case IList list: - foreach (var value in list) - { - var result = EffectiveTypeInfo.GetResolution(value, resolution?.PgTypeId ?? expectedEffectivePgTypeId); - resolution ??= result; - } - break; - case Array array: - foreach (var value in array) - { - var result = EffectiveTypeInfo.GetResolutionAsObject(value, resolution?.PgTypeId ?? expectedEffectivePgTypeId); - resolution ??= result; - } - break; - default: - throw new NotSupportedException(); - } + case TElement[] array: + foreach (var value in array) + { + var result = EffectiveTypeInfo.GetResolution(value, resolution?.PgTypeId ?? expectedEffectivePgTypeId); + resolution ??= result; + } + break; + case List list: + foreach (var value in list) + { + var result = EffectiveTypeInfo.GetResolution(value, resolution?.PgTypeId ?? expectedEffectivePgTypeId); + resolution ??= result; + } + break; + case IList list: + foreach (var value in list) + { + var result = EffectiveTypeInfo.GetResolution(value, resolution?.PgTypeId ?? expectedEffectivePgTypeId); + resolution ??= result; + } + break; + case Array array: + foreach (var value in array) + { + var result = EffectiveTypeInfo.GetResolutionAsObject(value, resolution?.PgTypeId ?? expectedEffectivePgTypeId); + resolution ??= result; + } + break; + case null: + break; + default: + throw new NotSupportedException(); } return resolution; diff --git a/src/Npgsql/Internal/Converters/NullableConverter.cs b/src/Npgsql/Internal/Converters/NullableConverter.cs index 57a12e005f..b4d5689da7 100644 --- a/src/Npgsql/Internal/Converters/NullableConverter.cs +++ b/src/Npgsql/Internal/Converters/NullableConverter.cs @@ -50,7 +50,7 @@ sealed class NullableConverterResolver(PgResolverTypeInfo effectiveTypeInfo) => new NullableConverter(effectiveResolution.GetConverter()); protected override PgConverterResolution? GetEffectiveResolution(T? value, PgTypeId? expectedEffectivePgTypeId) - => value is null - ? EffectiveTypeInfo.GetDefaultResolution(expectedEffectivePgTypeId) - : EffectiveTypeInfo.GetResolution(value.GetValueOrDefault(), expectedEffectivePgTypeId); + => value is { } inner + ? EffectiveTypeInfo.GetResolution(inner, expectedEffectivePgTypeId) + : null; } diff --git a/test/Npgsql.Tests/Types/DateTimeTests.cs b/test/Npgsql.Tests/Types/DateTimeTests.cs index d9bed9baac..bed9b9e7f6 100644 --- a/test/Npgsql.Tests/Types/DateTimeTests.cs +++ b/test/Npgsql.Tests/Types/DateTimeTests.cs @@ -469,6 +469,18 @@ await AssertType(datasource, @"{""1998-04-12 15:26:38+02"",NULL}", "timestamp with time zone[]"); + // Make sure delayed converter resolution works when null precedes a non-null value. + // We expect the resolution of null values to not lock in the default type timestamp. + // This would cause the subsequent non-null value to fail to convert, as it requires timestamptz. + await AssertType(datasource, + new DateTime?[] + { + null, + new DateTime(1998, 4, 12, 13, 26, 38, DateTimeKind.Utc) + }, + @"{NULL,""1998-04-12 15:26:38+02""}", + "timestamp with time zone[]"); + await AssertType(datasource, new DateTime?[] {