prestodb/presto · error · IllegalArgumentException
Table %s does not have column %s
Error message
Table %s does not have column %s
What it means
TpchMetadata.getColumnMetadata scans the TPC-H table metadata for a column matching the requested name and throws IllegalArgumentException 'Table %s does not have column %s' when none matches. It indicates the caller supplied a column name/handle that does not exist in the given TPC-H table.
Source
Thrown at presto-tpch/src/main/java/com/facebook/presto/tpch/TpchMetadata.java:476
@VisibleForTesting
TpchColumnHandle toColumnHandle(TpchColumn<?> column)
{
return new TpchColumnHandle(columnNaming.getName(column), getPrestoType(column));
}
@Override
public ColumnMetadata getColumnMetadata(ConnectorSession session, ConnectorTableHandle tableHandle, ColumnHandle columnHandle)
{
ConnectorTableMetadata tableMetadata = getTableMetadata(session, tableHandle);
String columnName = ((TpchColumnHandle) columnHandle).getColumnName();
for (ColumnMetadata column : tableMetadata.getColumns()) {
if (column.getName().equals(columnName)) {
return column;
}
}
throw new IllegalArgumentException(String.format("Table %s does not have column %s", tableMetadata.getTable(), columnName));
}
@Override
public List<SchemaTableName> listTables(ConnectorSession session, Optional<String> filterSchema)
{
ImmutableList.Builder<SchemaTableName> builder = ImmutableList.builder();
for (String schemaName : getSchemaNames(session, filterSchema)) {
for (TpchTable<?> tpchTable : TpchTable.getTables()) {
builder.add(new SchemaTableName(schemaName, tpchTable.getTableName()));
}
}
return builder.build();
}
private TupleDomain<ColumnHandle> toTupleDomain(Map<TpchColumnHandle, Set<NullableValue>> predicate)
{
return TupleDomain.withColumnDomains(predicate.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, entry -> {View on GitHub (pinned to 55bb57d202)
Solutions
- Verify the exact column name against the TPC-H table (e.g. 'nationkey', not 'nationKey')
- List actual columns via listTableColumns before lookup
- Re-acquire ColumnHandle objects from the connector metadata instead of caching across restarts/upgrades
- Check that the table handle refers to the intended table
Example fix
// before metadata.getColumnMetadata(session, ordersHandle, "totalprice2"); // after metadata.getColumnMetadata(session, ordersHandle, "totalprice");
Defensive patterns
Strategy: validation
Validate before calling
Set<String> cols = metadata.listTableColumns(session, SchemaTablePrefix.of(schema, table)).get(SchemaTableName.of(schema, table))
.stream().map(ColumnMetadata::getName).collect(Collectors.toSet());
if (!cols.contains(columnName)) throw new IllegalArgumentException("Column " + columnName + " not in " + table); Try / catch
try {
ColumnMetadata cm = metadata.getColumnMetadata(session, tableHandle, columnName);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("does not have column")) {
// fall back to listing columns and matching case-insensitively
} else { throw e; }
} Prevention
- Use lowercase column names for TPC-H tables (nationkey, totalprice)
- Never reuse ColumnHandle across tables or Presto versions
- Discover columns dynamically instead of hardcoding names
When it happens
Trigger: Calling connector getColumnMetadata with a columnName absent from the table's metadata, e.g. a ColumnHandle from a different table, a misnamed column, or a stale handle after version change.
Common situations: Case mismatch in column name (TPC-H columns are lowercase like 'nationkey'); using a column from lineitem on an orders table handle; deserialized handles from an older Presto version.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/0e80809993f3470e.
Report an issue: GitHub.