prestodb/presto · error · UnsupportedOperationException

Inserting into an unpartitioned table that were added, alter

Error message

Inserting into an unpartitioned table that were added, altered, or inserted into in the same transaction is not supported

What it means

finishInsertIntoExistingTable handles inserts into unpartitioned tables. If the table's pending action in this transaction is ADD, ALTER, or INSERT_EXISTING, the buffered-action model cannot combine that with another data insert, so it throws UnsupportedOperationException at finish time.

Source

Thrown at presto-hive-metastore/src/main/java/com/facebook/presto/hive/metastore/SemiTransactionalHiveMetastore.java:579

                                    table,
                                    Optional.empty(),
                                    Optional.of(currentLocation),
                                    Optional.of(fileNames),
                                    false,
                                    merge(currentStatistics, statisticsUpdate),
                                    statisticsUpdate,
                                    emptyList()),
                            context));
            return;
        }

        switch (oldTableAction.getType()) {
            case DROP:
                throw new TableNotFoundException(schemaTableName);
            case ADD:
            case ALTER:
            case INSERT_EXISTING:
                throw new UnsupportedOperationException("Inserting into an unpartitioned table that were added, altered, or inserted into in the same transaction is not supported");
            default:
                throw new IllegalStateException("Unknown action type");
        }
    }

    public synchronized void truncateUnpartitionedTable(ConnectorSession session, String databaseName, String tableName)
    {
        checkReadable();
        Optional<Table> table = getTable(
                new MetastoreContext(
                        session.getIdentity(),
                        session.getQueryId(),
                        session.getClientInfo(),
                        session.getClientTags(),
                        session.getSource(),
                        getMetastoreHeaders(session),
                        isUserDefinedTypeEncodingEnabled(session),
                        columnConverterProvider,

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Combine multiple inserts into a single INSERT (e.g. via a UNION query) so only one insert action is recorded
  2. Commit between inserts, using a fresh transaction for each
  3. Create the table and do exactly one insert per transaction; use INSERT_EXISTING only once per transaction

Example fix

// before
INSERT INTO t SELECT ...;
INSERT INTO t SELECT ...; // same transaction
// after
INSERT INTO t SELECT ... UNION ALL SELECT ...; // single statement
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure only one insert action per unpartitioned table per transaction
if (insertedTablesInTx.contains(tableName) && isUnpartitioned(table)) {
    throw new IllegalStateException("Combine inserts or commit between them");
}

Try / catch

try {
    metastore.finishInsertIntoExistingTable(ctx, handle, ...);
} catch (UnsupportedOperationException e) {
    // restructure: merge inserts into one statement, or commit between inserts
    throw new IllegalStateException("Only one insert per unpartitioned table per transaction", e);
}

Prevention

When it happens

Trigger: Two or more INSERT INTO statements targeting the same unpartitioned Hive table within one transaction, or an insert following createTable/alterTable of that table in the same transaction.

Common situations: Multi-statement ETL scripts appending to the same target table several times in one session; jobs that create a table then insert into it twice; union-all style loading implemented as sequential inserts.

Related errors


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