FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Fixed preparing with an already cancelled token by vonzshik · Pull Request #3444 · npgsql/npgsql · GitHub

/ npgsql Public
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .cs  (2) All 1 file type selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
66 changes: 32 additions & 34 deletions src/Npgsql/NpgsqlCommand.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -595,24 +595,24 @@ Task Prepare(bool async, CancellationToken cancellationToken = default)

static async Task PrepareLong(NpgsqlCommand command, bool async, NpgsqlConnector connector, CancellationToken cancellationToken)
{
using (connector.StartUserAction(cancellationToken))
try
{
var sendTask = command.SendPrepare(connector, async, cancellationToken);
if (sendTask.IsFaulted)
sendTask.GetAwaiter().GetResult();

// Loop over statements, skipping those that are already prepared (because they were persisted)
var isFirst = true;
for (var i = 0; i < command._statements.Count; i++)
using (connector.StartUserAction(cancellationToken))
{
var statement = command._statements[i];
if (!statement.IsPreparing)
continue;

var pStatement = statement.PreparedStatement!;
var sendTask = command.SendPrepare(connector, async, cancellationToken);
if (sendTask.IsFaulted)
sendTask.GetAwaiter().GetResult();

try
// Loop over statements, skipping those that are already prepared (because they were persisted)
var isFirst = true;
for (var i = 0; i < command._statements.Count; i++)
{
var statement = command._statements[i];
if (!statement.IsPreparing)
continue;

var pStatement = statement.PreparedStatement!;

if (pStatement.StatementBeingReplaced != null)
{
Expect<CloseCompletedMessage>(await connector.ReadMessage(async), connector);
Expand Down Expand Up @@ -643,30 +643,28 @@ static async Task PrepareLong(NpgsqlCommand command, bool async, NpgsqlConnector
pStatement.CompletePrepare();
isFirst = false;
}
catch
{
// The statement wasn't prepared successfully, update the bookkeeping for it and
// all following statements
for (; i < command._statements.Count; i++)
{
statement = command._statements[i];
if (statement.IsPreparing)
{
statement.IsPreparing = false;
statement.PreparedStatement!.CompleteUnprepare();
}
}

throw;
Expect<ReadyForQueryMessage>(await connector.ReadMessage(async), connector);

if (async)
await sendTask;
else
sendTask.GetAwaiter().GetResult();
}
}
catch
{
// The statements weren't prepared successfully, update the bookkeeping for them
foreach (var statement in command._statements)
{
if (statement.IsPreparing)
{
statement.IsPreparing = false;
statement.PreparedStatement!.CompleteUnprepare();
}
}

Expect<ReadyForQueryMessage>(await connector.ReadMessage(async), connector);

if (async)
await sendTask;
else
sendTask.GetAwaiter().GetResult();
throw;
}
}
}
Expand Down
23 changes: 23 additions & 0 deletions test/Npgsql.Tests/PrepareTests.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Data;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using NpgsqlTypes;
using NUnit.Framework;
Expand Down Expand Up @@ -53,6 +54,28 @@ public async Task Async()
}
}

[Test, IssueLink("https://github.com/npgsql/npgsql/issues/3443")]
public void Bug3443()
{
using var conn = OpenConnectionAndUnprepare();
using var cmd = new NpgsqlCommand("SELECT 1", conn);
AssertNumPreparedStatements(conn, 0);
Assert.That(cmd.ExecuteScalar(), Is.EqualTo(1));
Assert.That(cmd.IsPrepared, Is.False);

using var cts = new CancellationTokenSource();
cts.Cancel();
Assert.ThrowsAsync<OperationCanceledException>(() => cmd.PrepareAsync(cts.Token));
AssertNumPreparedStatements(conn, 0);
Assert.That(cmd.IsPrepared, Is.False);

using var cmd2 = new NpgsqlCommand("SELECT 1", conn);
cmd2.Prepare();
Assert.That(cmd2.ExecuteScalar(), Is.EqualTo(1));
AssertNumPreparedStatements(conn, 1);
Assert.That(cmd2.IsPrepared, Is.True);
}

[Test]
public void Unprepare()
=> Unprepare(false).GetAwaiter().GetResult();
Expand Down

Back | FazBrowse Home | New Git URL