prestodb/presto · error · PrestoException

INVALID_TABLE_PROPERTY

INVALID_TABLE_PROPERTY

Error message

Invalid sorted_by definition

What it means

parseSortFields validates the sorted_by table property and builds an Iceberg SortOrder. If the builder fails (duplicate fields, invalid transform/direction pairs, bad structure), the RuntimeException is wrapped as PrestoException(INVALID_TABLE_PROPERTY, "Invalid sorted_by definition"). It guards the table-creation DDL against malformed sort specifications.

Source

Thrown at presto-iceberg/src/main/java/com/facebook/presto/iceberg/SortFieldUtils.java:60

{
    private SortFieldUtils() {}

    private static final Pattern PATTERN = Pattern.compile(
            "\\s*(?<identifier>" + PartitionFields.IDENTIFIER + ")"
                    + "(?i:\\s+(?<ordering>ASC|DESC))?"
                    + "(?i:\\s+NULLS\\s+(?<nullOrder>FIRST|LAST))?"
                    + "\\s*");

    public static SortOrder parseSortFields(Schema schema, List<String> fields)
    {
        SortOrder.Builder builder = SortOrder.builderFor(schema);
        parseSortFields(builder, fields);
        SortOrder sortOrder;
        try {
            sortOrder = builder.build();
        }
        catch (RuntimeException e) {
            throw new PrestoException(INVALID_TABLE_PROPERTY, "Invalid " + SORTED_BY_PROPERTY + " definition", e);
        }

        Set<Integer> baseColumnFieldIds = schema.columns().stream()
                .map(Types.NestedField::fieldId)
                .collect(toImmutableSet());
        for (SortField field : sortOrder.fields()) {
            if (!baseColumnFieldIds.contains(field.sourceId())) {
                throw new PrestoException(COLUMN_NOT_FOUND, "Column not found: " + schema.findColumnName(field.sourceId()));
            }
        }

        return sortOrder;
    }

    public static void parseSortFields(SortOrderBuilder<?> sortOrderBuilder, List<String> fields)
    {
        fields.forEach(field -> parseSortField(sortOrderBuilder, field));
    }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Check the wrapped cause exception in the PrestoException to see exactly which sort field failed to build
  2. Simplify sorted_by entries to the documented form: [ASC|DESC] optionally with transforms, e.g. 'id ASC', 'bucket(16, user_id) DESC'
  3. Remove duplicate columns from sorted_by — each column may appear only once
  4. Create the table without sorted_by, then validate each entry individually before re-adding

Example fix

// before
WITH (sorted_by = ARRAY['id ASC', 'id DESC'])
// after
WITH (sorted_by = ARRAY['id ASC'])
Defensive patterns

Strategy: validation

Validate before calling

// Validate sorted_by before DDL: unique columns, known transforms, valid directions
Set<String> seen = new HashSet<>();
for (String f : sortedBy) {
    String col = f.split("\\s+")[0];
    if (!seen.add(col)) throw new IllegalArgumentException("Duplicate sort column: " + col);
}

Try / catch

try { /* CREATE TABLE with sorted_by */ } catch (PrestoException e) {
    if (e.getErrorCode().getName().equals("INVALID_TABLE_PROPERTY")) {
        // inspect e.getCause() for which sort field failed
    } else { throw e; }
}

Prevention

When it happens

Trigger: CREATE TABLE ... WITH (sorted_by = ARRAY[...]) where an entry parses (passes regex) but fails semantic validation when building the SortOrder — e.g. duplicate sort fields, an invalid transform, or an internally inconsistent field spec.

Common situations: Copy-pasted sorted_by values from other engines; typos in transform syntax that still match the grammar but not semantics; combining transforms not allowed by Iceberg on the column type.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/27b70979194bfd5d. Report an issue: GitHub.