prestodb/presto · error · SQLFeatureNotSupportedException

createStruct

Error message

createStruct

What it means

PrestoConnection.createStruct(String typeName, Object[] attributes) unconditionally throws SQLFeatureNotSupportedException("createStruct"). The driver does not implement java.sql.Struct creation, so the stub always fails locally. Presto ROW-type values cannot be constructed through this API.

Source

Thrown at presto-jdbc/src/main/java/com/facebook/presto/jdbc/PrestoConnection.java:588

        Properties properties = new Properties();
        for (Map.Entry<String, String> entry : clientInfo.entrySet()) {
            properties.setProperty(entry.getKey(), entry.getValue());
        }
        return properties;
    }

    @Override
    public Array createArrayOf(String typeName, Object[] elements)
            throws SQLException
    {
        throw new SQLFeatureNotSupportedException("createArrayOf");
    }

    @Override
    public Struct createStruct(String typeName, Object[] attributes)
            throws SQLException
    {
        throw new SQLFeatureNotSupportedException("createStruct");
    }

    @Override
    public void setSchema(String schema)
            throws SQLException
    {
        checkOpen();
        this.schema.set(schema);
    }

    @Override
    public String getSchema()
            throws SQLException
    {
        checkOpen();
        return schema.get();
    }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Pass attributes as Object[] via setObject and CAST(? AS ROW(...)) in the SQL text
  2. Encode ROW values as JSON strings and cast on the server side
  3. Refactor schemas/queries to avoid ROW-typed bind parameters where possible

Example fix

// before
Struct st = connection.createStruct("address", attrs);
ps.setObject(1, st);
// after
ps.setObject(1, attrs);
// sql: INSERT ... VALUES (CAST(? AS ROW(city VARCHAR, zip VARCHAR)))
Defensive patterns

Strategy: try-catch

Validate before calling

DatabaseMetaData meta = connection.getMetaData();
if (meta.getDriverName().contains("Presto")) {
    // bind ROW values via Object[] + CAST, not createStruct
}

Type guard

static boolean supportsCreateStruct(DatabaseMetaData meta) throws SQLException {
    return !meta.getDriverName().contains("Presto");
}

Try / catch

try {
    Struct st = connection.createStruct("address", attrs);
    ps.setObject(1, st);
} catch (SQLFeatureNotSupportedException e) {
    ps.setObject(1, attrs); // pair with CAST(? AS ROW(...)) in SQL
}

Prevention

When it happens

Trigger: Calling connection.createStruct("typename", attrs) and passing the result to setObject/setObject-with-target-type.

Common situations: ORMs or ETL frameworks mapping structured/composite columns through Struct; migrations from Oracle-style drivers.

Related errors


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