Sto riscontrando un problema interessante con PostgreSQL tramite JDBC (non è stato possibile riprodurlo al di fuori di JDBC) dove sto ottenendo un"ERRORE: il piano memorizzato nella cache non deve modificare il tipo di risultato" durante il mix DDL con SELECT via JDBC
“ERROR: cached plan must not change result type”
il modo più semplice per riprodurre il problema è quello di utilizzare il seguente codice:
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();
}
il fatto che il seguente codice funziona porta bene a me assumendo questo è un molto sottile bug nel driver JDBC (nota, ho semplicemente rimosso la sesta istruzione DDL nel batch):
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();
}
sembrerebbe che scartando tutti i piani memorizzati nella cache tramite DISCARD ALL
dovrebbe funzionare, ma rende le cose peggiori:
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'm running into another error message
“ERROR: prepared statement "S_1" doesn't exist”
Qualcuno sa una soluzione? O un puntatore che documenta questo bug? Bit interessante, sembra essere correlato allo default prepare threshold of 5
Hai provato con altri nomi di variabili? Forse 'f' è una sorta di parola chiave riservata? Inoltre, sarebbero utili le tracce di stack complete. –
@a_horse_with_no_name: È, ma questa è la versione semplificata del problema reale in cui rimuovere la dichiarazione preparata dal gioco è meno semplice –
@aguibert;) Buon punto. Ci ho provato, ma no. La versione reale usa le virgolette sui nomi comunque ... –