"Cached plan must not change result type" when using PreparedStatement cache across schemas #496
The java application sets the
This appears to lead to errors like this:
Looking at the code it seems like the problem could be with the re-use of PreparedStatements via the cache implemented in #319. The
All of the above may be moot, however, if the issue is instead with Postgres itself. See the Notes section for the behavior of
Thanks for your help.
The text was updated successfully, but these errors were encountered:
I think it is a driver's issue. It should not issue "execute server-prepared statement" commands and rely on backend to properly replan/pick cached version for the specific
I'm afraid your only workaround is to ether avoid "altering the schema_path", or disable server-prepared statements.
I think #451 would help you, however it is not yet merged in.
I think you are right here. Adding schema_path to the equation should help. Do you want to try implementing the fix?
Thanks for the help. Based on the patch that came out of that discussion, it looks like schema_path is the only other major thing that impacts the plan cache, aside from DDL changes.
How would you suggest fixing this? I assume it would be too expensive to get the current search path from postgres each time you cache a prepared statement, but relying on
I've started discussion on hackers list to get idea of "the proper fix": http://www.postgresql.org/message-id/flat/CAB=Je-GtFy=Qa1Eku1mgRZ8RabUfqnUE2Z6ye2CJJZNN9B3Odg@mail.gmail.com#CAB=Je-GtFy=Qa1Eku1mgRZ8RabUfqnUE2Z6ye2CJJZNN9B3Odg@mail.gmail.com
I think we can detect "SET" statements and renew
Here's sample trace:
Proper dependency tracking should detect that prepared statement is "not that valid". In other words, the result depends on the order of 3 & 4.
However, I think the case should not be wildly used in public, thus it can be neglected.
Alternative direction is to create a connection property that would disable server-side prepared statements caching across
…uery is detected fixes pgjdbc#496
Guys, I can steadily reproduce the same issue using the latest driver v42.0.0, server v9.5.1 and our integration tests. If a test class has a parameterized test which is executed multiple times with different parameters, every second test run fails (i.e. odds pass, evens fail). If there's a single run, then such test passes just fine.
I can't share our tests, but can help diagnosing this from my side.
Previously we were using driver v9.2-1002, and everything went just fine.
Sample stack trace:
@unix-junkie , I wonder if you can enable, capture and share pgjdbc trace logs: https://jdbc.postgresql.org/documentation/head/logging.html#configuration
For instance, add
Do you use
@vlsi First, thanks for the quick response.
I will capture the logs and send them to you this Thursday or Friday.
Speaking of DDL -- yes we do. Basically, it looks like prepared statements are not invalidated when tables they're related to get changed in an incompatible way (i.e. the same table gets recreated, but its columns have different (incompatible) types).
I observe the same when running parameterized prepared statements (the driver keeps using a stale cached instance instead of preparing a new one), with a slightly different error message:
-- this one showed up when inserting a timestamp after a similar test which was inserting an integer.
Unfortunately, backend does not notify clients which statements get invalidated by a particular DDL execution.
If it is just test code that fails, then you might have luck if you could issue
In case your production code requires that DDL, you might want to drop a message to PostgreSQL mailing list.
The third option is to keep adding "invalidate statement cache on each ALTER, CREATE, etc, etc". The flip side there is prepared statement cache improves performance a lot, so invalidating it here and there might hurt.