NationalSecurityAgency/ghidra · error · SQLException
Unable to obtain vector id for insert
Error message
Unable to obtain vector id for insert
What it means
Thrown as an SQLException by H2VectorTable.insert() when getGeneratedKeys() returns an empty ResultSet after a successful INSERT. The insert reported 1 affected row, but the H2 driver did not provide a generated key, leaving the new vector's auto-generated ID unavailable.
Source
Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/file/H2VectorTable.java:106
LSHVector vec = (LSHVector) arguments[1];
PreparedStatement s = insert_stmt.prepareIfNeeded(() -> db.prepareStatement(
"INSERT INTO " + TABLE_NAME + " (count,vec_hash,vec) VALUES(?,?,?)",
Statement.RETURN_GENERATED_KEYS));
StringBuilder vecBuf = new StringBuilder();
vec.saveBase64(vecBuf, Base64Lite.encode);
s.setInt(1, count);
s.setLong(2, vec.calcUniqueHash());
s.setString(3, vecBuf.toString());
if (s.executeUpdate() != 1) {
throw new SQLException("Insert failed for vector table");
}
long id;
try (ResultSet rs = s.getGeneratedKeys()) {
if (!rs.next()) {
throw new SQLException("Unable to obtain vector id for insert");
}
id = rs.getLong(1);
}
vectorStore.update(
new VectorStoreEntry(id, vec, count, vectorFactory.getSelfSignificance(vec)));
return id;
}
/**
* Read all vectors from table and generate an ID-based vector map
* @return vector map (ID->VectorStoreEntry)
* @throws SQLException if error occurs
*/
public Map<Long, VectorStoreEntry> readVectors() throws SQLException {
char[] vectorDecodeBuffer = Base64VectorFactory.allocateBuffer();
HashMap<Long, VectorStoreEntry> map = new HashMap<>();
try (Statement st = db.createStatement();
ResultSet rs = st.executeQuery("SELECT id,count,vec FROM " + TABLE_NAME)) {View on GitHub (pinned to d5f144c24d)
Solutions
- Verify the H2 JDBC driver version matches what Ghidra bundles/expects.
- Check that the PreparedStatement was created with Statement.RETURN_GENERATED_KEYS (it is in the current code).
- If the issue persists, query the last inserted ID via an alternative method (e.g., IDENTITY() or SELECT MAX(id)).
- Rebuild the database if the schema or driver was changed mid-stream.
Example fix
// before
try (ResultSet rs = s.getGeneratedKeys()) {
if (!rs.next()) {
throw new SQLException("Unable to obtain vector id for insert");
}
id = rs.getLong(1);
}
// after (fallback: query by vec_hash to get the assigned id)
try (ResultSet rs = s.getGeneratedKeys()) {
if (rs.next()) {
id = rs.getLong(1);
} else {
try (PreparedStatement q = db.prepareStatement(
"SELECT id FROM " + TABLE_NAME + " WHERE vec_hash = ?")) {
q.setLong(1, vec.calcUniqueHash());
try (ResultSet qr = q.executeQuery()) {
qr.next();
id = qr.getLong(1);
}
}
}
} Defensive patterns
Strategy: fallback
Try / catch
long id;
try (ResultSet rs = s.getGeneratedKeys()) {
if (rs.next()) {
id = rs.getLong(1);
} else {
// Fallback: retrieve ID via the unique vec_hash
try (PreparedStatement q = db.prepareStatement(
"SELECT id FROM " + TABLE_NAME + " WHERE vec_hash = ?")) {
q.setLong(1, vec.calcUniqueHash());
try (ResultSet qr = q.executeQuery()) {
if (!qr.next()) throw new SQLException("Vector insert succeeded but ID unrecoverable");
id = qr.getLong(1);
}
}
}
} Prevention
- Ensure the H2 JDBC driver version supports RETURN_GENERATED_KEYS for SERIAL columns.
- Do not downgrade the H2 driver after a database is in use.
- Monitor for this error after Ghidra or driver updates.
- Consider a vec_hash-based ID lookup fallback if generated keys are unreliable.
When it happens
Trigger: Occurs when the INSERT succeeded (returned 1) but Statement.getGeneratedKeys() yields no rows. This happens when: the PreparedStatement was not created with RETURN_GENERATED_KEYS properly, the H2 driver version doesn't support generated keys for the SERIAL/CLOB combination, or there is a driver-level bug in key retrieval.
Common situations: H2 JDBC driver version incompatibility with Ghidra's BSim module. The SERIAL PRIMARY KEY column doesn't properly report generated keys in certain H2 modes. H2 running in a compatibility mode (e.g., PostgreSQL emulation) that alters generated key behavior.
Related errors
- Insert failed for vector table
- Did not get desctable sequence number after insertion
- Did not get exetable sequence number after insertion
- Error during insertion
- Bad vector table rowid
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/1ae8053f93d842b5.
Report an issue: GitHub.