apache/shardingsphere · error · FirebirdProtocolException

Unsupported format type %s

Error message

Unsupported format type %s

What it means

MySQL error 1295 (ER_UNSUPPORTED_PS) thrown by MySQLComStmtPrepareExecutor.failedIfContainsMultiStatements(): preparing a statement is rejected when the session has multi-statements enabled (CLIENT_MULTI_STATEMENTS negotiated and SET OPTION multi_statements=1) and the SQL string contains a ';'. Because the SQL parser cannot yet reliably identify multi-statement SQL, a literal semicolon is treated as a probable multi-statement payload, which the prepared-statement protocol path does not support.

Source

Thrown at database/protocol/dialect/firebird/src/main/java/org/apache/shardingsphere/database/protocol/firebird/constant/buffer/FirebirdParameterBuffer.java:74

    }
    
    private Object parseValue(final ByteBuf parameterBuffer, final FirebirdParameterBufferType type) {
        boolean traditionalStyle = isTraditionalType.apply(version);
        switch (type.getFormat()) {
            case INT:
                if (traditionalStyle) {
                    parameterBuffer.skipBytes(1);
                } else {
                    parameterBuffer.skipBytes(4);
                }
                return parameterBuffer.readIntLE();
            case BOOLEAN:
                return true;
            case STRING:
                int length = traditionalStyle ? parameterBuffer.readByte() : parameterBuffer.readIntLE();
                return parameterBuffer.readSlice(length).toString(StandardCharsets.UTF_8);
            default:
                throw new FirebirdProtocolException("Unsupported format type %s", type.getFormat().name());
        }
    }
    
    /**
     * Get property value.
     *
     * @param key property key
     * @param <T> class type of return value
     * @return property value or null
     */
    @SuppressWarnings("unchecked")
    public <T> T getValue(final FirebirdParameterBufferType key) {
        return (T) parameterBuffer.get(key);
    }
}

View on GitHub (pinned to e952770a21)

Solutions

  1. Prepare each statement separately — split the SQL on ';' and issue one COM_STMT_PREPARE per statement.
  2. Turn multi-statements off for the connection (SET OPTION multi_statements = 0 / disable CLIENT_MULTI_STATEMENTS in the driver) before preparing.
  3. If the semicolon is not a statement separator (e.g. inside a string literal the substring check still trips on), restructure the SQL to avoid ';' or execute via COM_QUERY instead of the prepared protocol.
  4. Ensure only one statement per prepared SQL; the prepared-statement protocol is single-statement by design.

Example fix

-- before: multi-statements ON + prepare
PREPARE stmt FROM 'SELECT * FROM t WHERE id=?; SELECT 1';

-- after: one statement per prepare
PREPARE stmt FROM 'SELECT * FROM t WHERE id=?';
PREPARE stmt2 FROM 'SELECT 1';
Defensive patterns

Strategy: validation

Validate before calling

// Client-side: reject multi-statement SQL before prepare when multi-statements is ON
if (connectionHasMultiStatementsOn() && sql.contains(";")) {
    throw new IllegalArgumentException("Prepared statements must contain a single statement (no ';'): " + sql);
}

Try / catch

// Vendor code 1295 on prepare
try {
    PreparedStatement ps = conn.prepareStatement(sql);
} catch (SQLException e) {
    if (e.getErrorCode() == 1295 && sql.contains(";")) {
        String[] parts = sql.split(";");
        // fall back to preparing each statement individually
        return prepareIndividually(conn, parts);
    }
    throw e;
}

Prevention

When it happens

Trigger: Issuing COM_STMT_PREPARE with SQL containing ';' while OPTION_MULTI_STATEMENTS is ON for the connection: e.g. preparing 'SELECT 1; SELECT 2' or SQL that merely contains a semicolon inside the text (the check is substring-based).

Common situations: Frameworks or clients that default to multi-statements enabled (some connectors set it for pipelining); developers preparing batch SQL separated by ';'; stored procedure bodies or hints containing semicolons caught by the naive substring check after multi-statements was switched on by another statement.

Related errors


AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14). Data as JSON: /api/errors/d9b6845bf246f6d4. Report an issue: GitHub.