Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NpgsqlBatch does not properly set ConnectorPreparedOn property on its BatchCommands #5458

Closed
stojancho-jefremov opened this issue Nov 27, 2023 · 2 comments · Fixed by #5459
Closed
Assignees
Labels
Milestone

Comments

@stojancho-jefremov
Copy link

stojancho-jefremov commented Nov 27, 2023

Steps to reproduce

Add following two tests to https://github.com/npgsql/npgsql/blob/main/test/Npgsql.Tests/PrepareTests.cs file and run them.

[Test]
public void Batch_sets_properly_connector_prepared_on_for_its_batch_commands_auto_prepare()
{
    using var dataSource = CreateDataSource(csb =>
    {
        csb.MaxAutoPrepare = 5;
        csb.AutoPrepareMinUsages = 1;
    });
    using var conn = dataSource.OpenConnection();
    using (var batch = new NpgsqlBatch(conn) { BatchCommands = { new("SELECT 1"), new("SELECT 2") } })
    {
        AssertNumPreparedStatements(conn, 2);

        foreach (var batchCommand in batch.BatchCommands)
            Assert.IsNotNull(((NpgsqlBatchCommand)batchCommand).ConnectorPreparedOn);
    }
}

[Test]
public void Batch_sets_properly_connector_prepared_on_for_its_batch_commands()
{
    using var conn = OpenConnectionAndUnprepare();
    using (var batch = new NpgsqlBatch(conn) { BatchCommands = { new("SELECT 1"), new("SELECT 2") } })
    {
        batch.Prepare();
        AssertNumPreparedStatements(conn, 2);
        foreach (var batchCommand in batch.BatchCommands)
            Assert.IsNotNull(((NpgsqlBatchCommand)batchCommand).ConnectorPreparedOn);
    }
    conn.UnprepareAll();
}

The issue

After bumping Npgsql version from 7.0.1 to 7.0.4 we experienced a serious performance degradation in our performance benchmarks. We did an investigation, and the exact culprit seems to be this fix: #4821
It seems that preparation (for a given batch with batch commands) is unnecessary reset because of ConnectorPreparedOn property being incorrectly (almost) always null.

Further technical details

Please note that the issue is still there for the latest versions of npgsql and PostgresSql. Versions used for the tests from above:
Npgsql version: latest from main (8.0.0)
PostgreSQL version: 15.4
Operating system: Windows 10

@vonzshik vonzshik self-assigned this Nov 27, 2023
@vonzshik vonzshik added the bug label Nov 27, 2023
@vonzshik vonzshik added this to the 8.0.1 milestone Nov 27, 2023
@vonzshik
Copy link
Contributor

Hello. I'm not sure whether your first test is correct (since you never execute the batch none of the queries are going to be auto prepared, so ConnectorPreparedOn will indeed be null), the second test does show an issue with explicit prepare which I'm going to fix.

@stojancho-jefremov
Copy link
Author

stojancho-jefremov commented Nov 27, 2023

Hello @vonzshik! Regarding my first test, it seems that you are right. After I changed it to this:

[Test]
public void Batch_sets_properly_connector_prepared_on_for_its_batch_commands_auto_prepare()
{
    using var dataSource = CreateDataSource(csb =>
    {
        csb.MaxAutoPrepare = 5;
        csb.AutoPrepareMinUsages = 1;
    });
    using var conn = dataSource.OpenConnection();
    using (var batch = new NpgsqlBatch(conn) { BatchCommands = { new("SELECT 1"), new("SELECT 2") } })
    {
        using var reader = batch.ExecuteReader();

        foreach (var batchCommand in batch.BatchCommands)
            Assert.IsNotNull(((NpgsqlBatchCommand)batchCommand).ConnectorPreparedOn);
    }

    AssertNumPreparedStatements(conn, 2);
}

the test stopped failing.

Frankly, we don't use the auto prepare, so I reported that one because I thought there is similar issue as with the explicit prepare. I also looked a bit into the code, but it seems that I didn't get it completely right. Anyway. you can consider adding this test if you find it useful. Thanks!

vonzshik added a commit that referenced this issue Nov 27, 2023
vonzshik added a commit that referenced this issue Nov 27, 2023
vonzshik added a commit that referenced this issue Nov 27, 2023
vonzshik added a commit that referenced this issue Nov 27, 2023
vonzshik added a commit that referenced this issue Nov 27, 2023
JonasWestman pushed a commit to monitor-erp/npgsql that referenced this issue Dec 20, 2023
Fixes npgsql#5458

(cherry picked from commit 9e3a8df)
Signed-off-by: monjowe <jonas.westman@monitor.se>
JonasWestman pushed a commit to monitor-erp/npgsql that referenced this issue Dec 21, 2023
Fixes npgsql#5458

(cherry picked from commit 9e3a8df)
Signed-off-by: monjowe <jonas.westman@monitor.se>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants