-
Notifications
You must be signed in to change notification settings - Fork 861
Milestone
Description
Steps to reproduce
Test code:
using Npgsql;
using System.Data;
namespace NpgsqlBinaryImporterTest
{
internal class Program
{
static void Main(string[] args)
{
if (args.Length == 0)
{
Console.WriteLine("Connection string argument missing");
return;
}
using var connection = new NpgsqlConnection(args[0]);
connection.Open();
// create table
using var command = new NpgsqlCommand("drop table if exists test; create table test(id int not null, name text);", connection);
command.ExecuteNonQuery();
// get table structure
var table = new DataTable();
using var adapter = new NpgsqlDataAdapter("select * from test", connection);
adapter.FillSchema(table, SchemaType.Mapped);
// fill data
table.Rows.Add(1, DBNull.Value);
table.Rows.Add(2, "test");
// write data
try
{
WriteTable(connection, table);
Console.WriteLine("Ok");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
public static void WriteTable(NpgsqlConnection connection, DataTable table)
{
if (table.Rows.Count > 0)
{
var columns = table.Columns.Cast<DataColumn>().Select(p => p.ColumnName).ToArray();
using var importer = connection.BeginBinaryImport("copy " + table.TableName + " (" + string.Join(",", columns) + ") from stdin (format binary)");
importer.Timeout = TimeSpan.Zero;
foreach (DataRow row in table.Select())
{
importer.StartRow();
foreach (var column in columns)
importer.Write(row[column]);
}
importer.Complete();
importer.Close();
}
}
}
}
The issue
Starting from version 8.0.3, when attempting to write a NOT NULL value to a nullable column, the NpgsqlBinaryImporter.Write(T value) method may throw an InvalidOperationException.
An exception is only thrown if the first row contained a NULL value for that column.
This did not happen in previous versions.
Exception message:
System.InvalidOperationException: Write for column 1 resolves to a different PostgreSQL type: OID 25 than the first row resolved to (OID 0). Please make sure to use clr types that resolve to the same PostgreSQL type across rows. Alternatively pass the same NpgsqlDbType or DataTypeName to ensure the PostgreSQL type ends up to be identical.
at Npgsql.NpgsqlBinaryImporter.<Write>g__Core|26_0[T](Boolean async, T value, Nullable`1 npgsqlDbType, String dataTypeName, CancellationToken cancellationToken)
at Npgsql.NpgsqlBinaryImporter.Write[T](T value)
at NpgsqlBinaryImporterTest.Program.WriteTable(NpgsqlConnection connection, DataTable table) in D:\Projects\Lotrack\[CrossPlatform]\Tests\NpgsqlBinaryImporterTest\Program.cs:line 57
at NpgsqlBinaryImporterTest.Program.Main(String[] args) in D:\Projects\Lotrack\[CrossPlatform]\Tests\NpgsqlBinaryImporterTest\Program.cs:line 35
Further technical details
Npgsql version: 8.0.3
PostgreSQL version: 13.2
Operating system: Windows 10
Metadata
Metadata
Assignees
Labels
No labels