prestodb/presto · error · PrestoException
GENERIC_USER_ERROR
GENERIC_USER_ERROR
Error message
Table property ${PARTITION_BY_HASH_COLUMNS_2} is only allowed if there is also ${PARTITION_BY_HASH_COLUMNS} What it means
KuduTableProperties.getPartitionDesign builds the partition design from table properties. partition_by_hash_buckets_2 / partition_by_hash_columns_2 define a second hash partitioning, which is only meaningful alongside a primary hash partitioning. Specifying the second property without the first is rejected as a GENERIC_USER_ERROR.
Source
Thrown at presto-kudu/src/main/java/com/facebook/presto/kudu/properties/KuduTableProperties.java:198
{
requireNonNull(tableProperties);
List<String> hashColumns = (List) tableProperties.get(PARTITION_BY_HASH_COLUMNS);
List<String> hashColumns2 = (List) tableProperties.get(PARTITION_BY_HASH_COLUMNS_2);
PartitionDesign design = new PartitionDesign();
if (!hashColumns.isEmpty()) {
List<HashPartitionDefinition> hashPartitions = new ArrayList<>();
HashPartitionDefinition hash1 = getHashPartitionDefinition(tableProperties, hashColumns, PARTITION_BY_HASH_BUCKETS);
hashPartitions.add(hash1);
if (!hashColumns2.isEmpty()) {
HashPartitionDefinition hash2 = getHashPartitionDefinition(tableProperties, hashColumns2, PARTITION_BY_HASH_BUCKETS_2);
hashPartitions.add(hash2);
}
design.setHash(hashPartitions);
}
else if (!hashColumns2.isEmpty()) {
throw new PrestoException(GENERIC_USER_ERROR, "Table property " + PARTITION_BY_HASH_COLUMNS_2 + " is only allowed if there is also " + PARTITION_BY_HASH_COLUMNS);
}
List<String> rangeColumns = (List) tableProperties.get(PARTITION_BY_RANGE_COLUMNS);
if (!rangeColumns.isEmpty()) {
RangePartitionDefinition range = new RangePartitionDefinition();
range.setColumns(rangeColumns);
design.setRange(range);
}
return design;
}
public static ColumnDesign getColumnDesign(Map<String, Object> columnProperties)
{
requireNonNull(columnProperties);
if (columnProperties.isEmpty()) {
return ColumnDesign.DEFAULT;
}View on GitHub (pinned to 55bb57d202)
Solutions
- Add partition_by_hash_columns and partition_by_hash_buckets alongside the _2 properties
- Remove the _2 properties if only one hash partitioning is wanted
Example fix
-- before WITH (partition_by_hash_columns_2 = ARRAY['b'], partition_by_hash_buckets_2 = 8) -- after WITH (partition_by_hash_columns = ARRAY['a'], partition_by_hash_buckets = 4, partition_by_hash_columns_2 = ARRAY['b'], partition_by_hash_buckets_2 = 8)
Defensive patterns
Strategy: validation
Validate before calling
Map<String,Object> props = getTableProperties();
if (!props.getOrDefault("partition_by_hash_columns", List.of()).isEmpty() == false
&& !props.getOrDefault("partition_by_hash_columns_2", List.of()).isEmpty()) {
throw new IllegalArgumentException("partition_by_hash_columns_2 requires partition_by_hash_columns");
} Try / catch
try {
createTable(ddl);
} catch (PrestoException e) {
if (e.getMessage().contains("is only allowed if there is also")) {
throw new IllegalArgumentException("Add partition_by_hash_columns before using _2 properties", e);
}
throw e;
} Prevention
- Always define the primary hash partition before the secondary one
- Build WITH clauses from a template that pairs columns/buckets with _2 variants
- Lint table property sets before submitting DDL
When it happens
Trigger: CREATE TABLE ... WITH (partition_by_hash_columns_2 = ARRAY['x'], partition_by_hash_buckets_2 = 8) without partition_by_hash_columns / partition_by_hash_buckets.
Common situations: Users only want two hash bucketings and skip the primary one, not realizing the second is an additional level; copy-paste of partial WITH clauses.
Related errors
- QUERY_REJECTED
- INVALID_TABLE_PROPERTY
- HIVE_COLUMN_ORDER_MISMATCH
- INVALID_TABLE_PROPERTY
- GENERIC_INTERNAL_ERROR
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/5d92c6ea73d3c3d3.
Report an issue: GitHub.