pentaho/pentaho-kettle · error · KettleDatabaseException
MondrianInputErrorOnlyTabular
MondrianInputErrorOnlyTabular
Error message
MondrianInputErrorOnlyTabular
What it means
MondrianHelper.createRectangularOutput() flattens an MDX result into rectangular headings/rows, which only works for a 2-axis (rows x columns) result. If the query's result has any number of axes other than 2, it throws KettleDatabaseException with the localized MondrianInputErrorOnlyTabular message. Used by MondrianInput's getFields and runtime output building.
Solutions
- Rewrite the MDX so it produces exactly two axes: a columns axis and a rows axis (e.g. SELECT ... ON COLUMNS, ... ON ROWS).
- Avoid DRILLTHROUGH / single-cell queries in the Mondrian Input step; use a JDBC/relational step for tabular data instead.
- Log result.getAxes().length during development to confirm the shape.
- Check Mondrian schema/cube definitions if axis count is unexpectedly different.
Example fix
// before: single axis query mdx = "SELECT [Measures].[Sales] ON COLUMNS FROM Sales"; // after: two-axis (tabular) query mdx = "SELECT [Measures].[Sales] ON COLUMNS, [Product].[Product].Members ON ROWS FROM Sales";
Defensive patterns
Strategy: validation
Validate before calling
// Inspect the MDX result shape before flattening
Result result = olap4jConnection.createStatement().executeOlapQuery(mdx);
if (result.getAxes().size() != 2) {
throw new IllegalStateException("MDX must return exactly 2 axes, got " + result.getAxes().size());
} Try / catch
try {
helper.createRectangularOutput();
} catch (KettleDatabaseException e) {
logError("MDX result is not tabular (axes != 2): " + e.getMessage(), e);
} Prevention
- Always write MDX with explicit ON COLUMNS and ON ROWS axes
- Avoid DRILLTHROUGH and scalar queries in Mondrian Input
- Test the MDX in a query tool to confirm a 2-axis result
When it happens
Trigger: Executing an MDX query whose result has axes.length != 2 — e.g. a query with 0 axes (scalar cell), 1 axis, or 3+ axes — then calling createRectangularOutput (directly or via getFields).
Common situations: MDX queries using DRILLTHROUGH or single-value queries; OLAP cubes configured so the Mondrian result returns one axis; users writing MDX meant for raw tabular output instead of a cross-tab.
Related errors
- Error setting catalog for MDX statement: ''
- Failed to add Cell Row:
- Failed to clear Cube
- Failed to process some row
- MondrianInputErrorUnhandledType
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/8254eba01144723c.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/mondrianinput/impl/src/main/java/org/pentaho/di/trans/steps/mondrianinput/MondrianHelper.java:193
if ( ( log != null ) && ( log.isDebug() ) ) {
log.logDebug( ignored.getMessage() );
}
}
connection = null;
}
}
/**
* Outputs one row per tuple on the rows axis.
*
* @throws KettleDatabaseException
* in case some or other error occurs
*/
public void createRectangularOutput() throws KettleDatabaseException {
final Axis[] axes = result.getAxes();
if ( axes.length != 2 ) {
throw new KettleDatabaseException( BaseMessages.getString( PKG, "MondrianInputErrorOnlyTabular" ) );
}
headings = new ArrayList<>();
rows = new ArrayList<>();
final Axis rowsAxis = axes[1];
final Axis columnsAxis = axes[0];
int rowOrdinal = -1;
int[] coords = { 0, 0 };
for ( Position rowPos : rowsAxis.getPositions() ) {
++rowOrdinal;
coords[1] = rowOrdinal;
if ( rowOrdinal == 0 ) {
// Generate headings on the first row. Note that if there are
// zero rows, we don't have enough metadata to generate
// headings.
// First headings are for the members on the rows axis.View on GitHub (pinned to f3058517a1)