{"record":{"id":"a74442fd367d8206","repo":"apache/seatunnel","slug":"oracle-insert-mode-append-values-only-supports-gen","errorCode":null,"errorMessage":"oracle_insert_mode=APPEND_VALUES only supports generated INSERT statements.","messagePattern":"oracle_insert_mode=APPEND_VALUES only supports generated INSERT statements\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/JdbcOutputFormatBuilder.java","lineNumber":365,"sourceCode":"            TableSchema databaseTableSchema,\n            JdbcRowConverter rowConverter) {\n        return new SimpleBatchStatementExecutor(\n                connection ->\n                        FieldNamedPreparedStatement.prepareStatement(\n                                connection, sql, tableSchema.getFieldNames()),\n                tableSchema,\n                databaseTableSchema,\n                rowConverter);\n    }\n\n    static String applyOracleAppendValuesHintIfNeeded(\n            JdbcSinkConfig jdbcSinkConfig, String insertSQL) {\n        if (!isOracleAppendValuesConfigured(jdbcSinkConfig)) {\n            return insertSQL;\n        }\n        final String insertPrefix = \"INSERT\";\n        if (!insertSQL.regionMatches(true, 0, insertPrefix, 0, insertPrefix.length())) {\n            throw new IllegalArgumentException(\n                    \"oracle_insert_mode=APPEND_VALUES only supports generated INSERT statements.\");\n        }\n        String appendValuesSQL =\n                insertPrefix + \" /*+ APPEND_VALUES */\" + insertSQL.substring(insertPrefix.length());\n        log.info(\"Oracle APPEND_VALUES insert mode is enabled, generated SQL: {}\", appendValuesSQL);\n        return appendValuesSQL;\n    }\n\n    private static void validateOracleInsertMode(\n            JdbcDialect dialect, JdbcSinkConfig jdbcSinkConfig, List<String> primaryKeys) {\n        if (!isOracleAppendValuesConfigured(jdbcSinkConfig)) {\n            return;\n        }\n        if (!DatabaseIdentifier.ORACLE.equals(dialect.dialectName())) {\n            throw new IllegalArgumentException(\n                    \"oracle_insert_mode=APPEND_VALUES only supports Oracle JDBC sink.\");\n        }\n        if (primaryKeys != null && !primaryKeys.isEmpty()) {","sourceCodeStart":347,"sourceCodeEnd":383,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/JdbcOutputFormatBuilder.java#L347-L383","documentation":"Thrown by JdbcOutputFormatBuilder.applyOracleAppendValuesHintIfNeeded when oracle_insert_mode=APPEND_VALUES is configured but the generated SQL does not start with INSERT. The APPEND_VALUES hint can only be injected into a plain INSERT statement, so any other statement shape is rejected as an IllegalArgumentException.","triggerScenarios":"Setting oracle_insert_mode=APPEND_VALUES while the builder produced a non-INSERT SQL statement (e.g. a custom/override SQL, or a statement generated for upsert semantics).","commonSituations":"Users copy a configuration using APPEND_VALUES onto a sink whose SQL was customized or auto-generated for MERGE/upsert mode; dialect changed from Oracle but the Oracle-specific option left in config.","solutions":["Remove the custom SQL override so the connector generates a standard INSERT statement","Set oracle_insert_mode to the default (INSERT) if the statement is not a plain INSERT","Ensure the dialect is Oracle and the sink is configured for insert-only writes"],"exampleFix":"// before\ngenerate_sink_sql = false\nsql = \"MERGE INTO t USING ...\"\n// after: let the connector generate INSERT\nsql = null\ngenerate_sink_sql = true","handlingStrategy":"validation","validationCode":"// config sanity check before build\nif (config.get(\"oracle_insert_mode\") == \"APPEND_VALUES\" && config.get(\"sql\") != null) {\n  throw new IllegalArgumentException(\"APPEND_VALUES requires generated INSERT SQL (no custom sql)\");\n}","typeGuard":null,"tryCatchPattern":"try { builder.build(); } catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"APPEND_VALUES\")) { /* fall back to default insert mode */ }\n}","preventionTips":["Only enable APPEND_VALUES with auto-generated INSERT SQL","Do not set oracle_insert_mode when overriding SQL","Keep Oracle-only options out of generic configs","Document the option's constraints for your team"],"tags":["oracle","jdbc","config","sql"],"backgroundTag":"conflicting-config-options","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}