pentaho/pentaho-kettle · error · KettleDatabaseException
error opening resultset for query: " + sql
Error message
error opening resultset for query: " + sql
What it means
Database.openQuery() could not open a JDBC ResultSet for the given SQL string. The method returns a RowMetaAndData on success, but if the query produced no row or the execution failed, Kettle wraps the failure in a KettleDatabaseException that includes the offending SQL so the developer can see exactly which statement broke.
Solutions
- Log or print the exact 'sql' string in the message and run it directly against the database to see the underlying driver error
- Verify the table and column names exist in the connected database/schema
- Check the database connection settings and test with Database.connect() before querying
- Enable Kettle debug logging to capture the driver-level exception that preceded this throw
Example fix
// before
RowMetaAndData r = db.openQuery("SELECT * FROM LOGG_TBL");
// after
RowMetaAndData r = db.openQuery("SELECT * FROM LOG_TABLE"); // corrected table name Defensive patterns
Strategy: try-catch
Validate before calling
if (db == null || !db.isAutoCommit() && db.getConnection() == null) throw new IllegalStateException("connect first");
// validate table exists:
if (!db.checkTableExistsUnquoted(schema, table)) throw new IllegalStateException("table missing: " + table); Type guard
boolean isQueryReady(Database db) { try { return db.getConnection() != null && !db.getConnection().isClosed(); } catch (SQLException e) { return false; } } Try / catch
try {
RowMetaAndData r = db.openQuery(sql);
// consume r
} catch (KettleDatabaseException e) {
log.error("openQuery failed for SQL: " + sql, e);
throw new RuntimeException("Query failed, SQL=" + sql, e);
} Prevention
- Run generated SQL against the target DB in a dev environment before deploying
- Use database metadata (tableExists) to verify objects before querying
- Always pass connection-tested Database instances to query methods
- Enable Kettle SQL logging during development to spot bad SQL early
When it happens
Trigger: Calling Database.openQuery(sql) with SQL that fails to execute (syntax error, missing table/column, bad connection) or that returns no rows, so the 'if (row != null)' branch is skipped and the else-branch throws.
Common situations: Typos in generated SQL, querying a table that does not exist on the target database, insufficient privileges, using a dialect-specific SQL that the connected DB rejects, or a closed/failed connection.
Understand the failure class
Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.
Related errors
- An error occurred executing SQL:
- Couldn't execute SQL:
- Couldn't find any rows because of an error :
- Couldn't get a result because of an error :
- Couldn't prepare statement:
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/ee922cc7aa38f1e7.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/core/database/Database.java:3633
if ( pstmt != null ) {
try {
pstmt.close();
} catch ( Exception e ) {
throw new KettleDatabaseException( "Unable to close prepared statement pstmt", e );
}
pstmt = null;
}
if ( selStmt != null ) {
try {
selStmt.close();
} catch ( Exception e ) {
throw new KettleDatabaseException( "Unable to close prepared statement sel_stmt", e );
}
selStmt = null;
}
return new RowMetaAndData( rowMeta, row );
} else {
throw new KettleDatabaseException( "error opening resultset for query: " + sql );
}
}
public RowMeta getMetaFromRow( Object[] row, ResultSetMetaData md ) throws SQLException, KettleDatabaseException {
RowMeta meta = new RowMeta();
for ( int i = 0; i < md.getColumnCount(); i++ ) {
ValueMetaInterface valueMeta = getValueFromSQLType( md, i + 1, true, false );
meta.addValueMeta( valueMeta );
}
return meta;
}
public RowMetaAndData getOneRow( String sql, RowMetaInterface param, Object[] data ) throws KettleDatabaseException {
ResultSet rs = openQuery( sql, param, data );
if ( rs != null ) {
Object[] row = getRow( rs ); // One value: a number;View on GitHub (pinned to f3058517a1)