I am having an interesting problem with PostgreSQL through JDBC (I cannot play it outside of JDBC), where I get
"ERROR: cached plan should not change the type of result"
The easiest way to reproduce this problem is to use the following code:
Connection c = getConnection(); c.setAutoCommit(true); List<String> statements = Arrays.asList( "create table t(a int)", "select * from t", "alter table t add b int", "select * from t", "alter table t add c int", "select * from t", "alter table t add d int", "select * from t", "alter table t add e int", "select * from t", "alter table t add f int", "select * from t" ); for (String statement : statements) try (PreparedStatement s = c.prepareStatement(statement)) { System.out.println(s); s.execute(); }
The fact that the following code works fine leads to the fact that this is a very subtle error in the JDBC driver (note, I just deleted the sixth DDL statement in the package):
Connection c = getConnection(); c.setAutoCommit(true); List<String> statements = Arrays.asList( "create table t(a int)", "select * from t", "alter table t add b int", "select * from t", "alter table t add c int", "select * from t", "alter table t add d int", "select * from t", "alter table t add e int", "select * from t" ); for (String statement : statements) try (PreparedStatement s = c.prepareStatement(statement)) { System.out.println(s); s.execute(); }
It seems that dropping all cached plans using DISCARD ALL should work, but this makes the situation worse:
Connection c = getConnection(); c.setAutoCommit(true); List<String> statements = Arrays.asList( "create table t(a int)", "select * from t", "alter table t add b int", "select * from t", "alter table t add c int", "select * from t", "alter table t add d int", "select * from t", "alter table t add e int", "select * from t", "alter table t add f int", "discard all", "select * from t" ); for (String statement : statements) try (PreparedStatement s = c.prepareStatement(statement)) { System.out.println(s); s.execute(); }
I came across another error message
"ERROR: prepared statement" S_1 "does not exist"
Does anyone know a workaround? Or a pointer documenting this error? An interesting bit seems to be related to the default training threshold of 5