Skip to content

Commit 90a7aea

Browse files
committed
Cancel COPY import if closing in middle of row
If a COPY importer was closed in the middle of a row, an exception was thrown. This broke the connection, and also masked the original exception by throwing a new one. Instead of throwing an exception from Dispose(), we simply cancel the current import. See npgsql#1646 for an additional related API change. Fixes npgsql#1645
1 parent 9db3d87 commit 90a7aea

2 files changed

Lines changed: 33 additions & 1 deletion

File tree

src/Npgsql/NpgsqlBinaryImporter.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,13 @@ public void Close()
275275
return;
276276

277277
if (_column != -1 && _column != NumColumns)
278-
throw new InvalidOperationException("Can't close writer, a row is still in progress, end it first");
278+
{
279+
Log.Error("Binary importer closed in the middle of a row, cancelling import.");
280+
_buf.Clear();
281+
Cancel();
282+
return;
283+
}
284+
279285
WriteTrailer();
280286
_buf.Flush();
281287
_buf.EndCopyMode();

test/Npgsql.Tests/BugTests.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Linq;
55
using System.Text;
66
using System.Threading.Tasks;
7+
using NpgsqlTypes;
78
using NUnit.Framework;
89
#if !NETCOREAPP1_1
910
using System.Transactions;
@@ -105,6 +106,31 @@ public void Bug1450()
105106
}
106107
}
107108

109+
[Test]
110+
public void Bug1645()
111+
{
112+
using (var conn = OpenConnection())
113+
{
114+
conn.ExecuteNonQuery("CREATE TEMP TABLE data (field_text TEXT, field_int2 SMALLINT, field_int4 INTEGER)");
115+
Assert.That(() =>
116+
{
117+
using (var writer = conn.BeginBinaryImport("COPY data (field_text, field_int4) FROM STDIN BINARY"))
118+
{
119+
writer.StartRow();
120+
writer.Write("foo");
121+
writer.Write(8);
122+
123+
writer.StartRow();
124+
throw new InvalidOperationException("Catch me outside the using statement if you can!");
125+
}
126+
}, Throws.Exception
127+
.TypeOf<InvalidOperationException>()
128+
.With.Property(nameof(InvalidOperationException.Message)).EqualTo("Catch me outside the using statement if you can!")
129+
);
130+
Assert.That(conn.ExecuteScalar("SELECT COUNT(*) FROM data"), Is.Zero);
131+
}
132+
}
133+
108134
#if !NETCOREAPP1_1
109135
[Test, IssueLink("https://github.com/npgsql/npgsql/issues/1497")]
110136
public void Bug1497()

0 commit comments

Comments
 (0)