Skip to content

[Improve][Connector-V2][Jdbc] Support Oracle append values insert mode - #10996

Merged
chl-wxp merged 2 commits into
apache:devfrom
zhangshenghang:zsh/oracle-append-values
Jun 4, 2026
Merged

[Improve][Connector-V2][Jdbc] Support Oracle append values insert mode#10996
chl-wxp merged 2 commits into
apache:devfrom
zhangshenghang:zsh/oracle-append-values

Conversation

@zhangshenghang

Copy link
Copy Markdown
Member

Purpose of this pull request

Add an opt-in Oracle JDBC sink insert optimization option:

oracle_insert_mode = APPEND_VALUES

When enabled for supported Oracle insert-only generated SQL writes, SeaTunnel injects the Oracle APPEND_VALUES hint into the generated insert statement:

INSERT /*+ APPEND_VALUES */ INTO ...

The default mode is CONVENTIONAL, so existing jobs keep the current JDBC insert behavior unless users explicitly enable this option.

Does this PR introduce any user-facing change?

Yes.

This PR adds a new optional JDBC sink config oracle_insert_mode, with default value CONVENTIONAL. Existing jobs are not affected by default.

APPEND_VALUES is restricted to Oracle insert-only generated SQL writes and requires:

  • generate_sink_sql = true
  • auto_commit = true
  • no custom query
  • no primary_keys
  • is_exactly_once = false
  • support_upsert_by_insert_only = false

How was this patch tested?

./mvnw -pl seatunnel-api -DskipTests -Dspotless.check.skip=true -Dmaven.gitcommitid.skip=true install
./mvnw -pl seatunnel-connectors-v2/connector-jdbc \
  -Dtest=JdbcOutputFormatBuilderTest \
  -DfailIfNoTests=false \
  -Dmaven.gitcommitid.skip=true test

Result: Tests run: 9, Failures: 0, Errors: 0, Skipped: 0.

./mvnw -pl seatunnel-connectors-v2/connector-jdbc \
  -DskipTests \
  -Dmaven.gitcommitid.skip=true verify

Result: BUILD SUCCESS.

./mvnw -pl seatunnel-e2e/seatunnel-connector-v2-e2e/connector-jdbc-e2e/connector-jdbc-e2e-part-1 \
  -DskipTests \
  -Dmaven.gitcommitid.skip=true package

Result: BUILD SUCCESS.

Attempted Oracle E2E locally:

./mvnw -pl seatunnel-e2e/seatunnel-connector-v2-e2e/connector-jdbc-e2e/connector-jdbc-e2e-part-1 \
  -Dtest=JdbcOracleIT \
  -DfailIfNoTests=false \
  -Dmaven.gitcommitid.skip=true test

It reached JdbcOracleIT startup but failed before running the test cases because the local machine has no valid Docker/Testcontainers environment:

Could not find a valid Docker environment

Check list

  • Added no new Jar dependency
  • Updated docs/en and docs/zh
  • No incompatible change, default behavior remains unchanged
  • Added unit tests and Oracle JDBC E2E coverage

@DanielLeens DanielLeens left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this. I reviewed the latest head from scratch and traced the generated insert SQL path, the validation guards, and the insert-only runtime boundary.

What this PR solves

  • User pain: Oracle users may want to use INSERT /*+ APPEND_VALUES */ for append-only bulk writes, but SeaTunnel currently only emits the conventional insert form.
  • Fix approach: add an explicit oracle_insert_mode option, inject the APPEND_VALUES hint only on the generated insert SQL path, and fail fast for unsupported combinations.
  • One-line summary: the latest head keeps the feature boundary tight, and I did not find a new blocker on the Oracle append-values path.

Runtime path I checked

sink construction
  -> JdbcOutputFormatBuilder.build() [60-109]
      -> validateOracleInsertMode(...)
      -> choose generated insert-only path only when the config is compatible

generated insert SQL path
  -> createSimpleBufferedExecutor(...) [112-124]
      -> dialect.getInsertIntoStatement(...)
      -> applyOracleAppendValuesHintIfNeeded(...) [358-...]

guard rails
  -> reject non-Oracle dialect
  -> reject custom query
  -> reject exactly-once
  -> reject auto_commit=false
  -> reject primary-key / upsert-style modes

Review result

  • JdbcOutputFormatBuilder.java:63-90 validates the mode before any executor selection, which is the right place to keep the feature boundary explicit.
  • The hint injection is limited to the generated insert SQL path, so it does not silently mutate custom SQL.
  • The tests in JdbcOutputFormatBuilderTest.java:137-248 cover the important allowed/forbidden combinations.
  • I did not find a new source-level blocker on the latest head.

Tests / CI

  • The new unit coverage is targeted and stable.
  • I did not see a flaky-test pattern in the added tests.
  • The current GitHub Build is still in progress, but I do not have a source-level blocker to add on top of the latest code.

Conclusion: can merge

  1. Blocking items
  • None from my side on the latest head.
  1. Suggested non-blocking follow-up
  • None from my side on this code path.

From the code-review side this looks good.

@DanielLeens DanielLeens left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the update. I re-reviewed the latest head from scratch, including the new head commit, and traced the Oracle insert-only sink path again.

What this PR solves

  • User pain: Oracle users may want INSERT /*+ APPEND_VALUES */ for append-only bulk writes, but SeaTunnel currently emits only the conventional insert form.
  • Fix approach: add oracle_insert_mode, keep the hint injection on the generated insert-only SQL path, and fail fast for unsupported combinations.
  • One-line summary: the latest head keeps the feature boundary tight, and the follow-up JdbcHiveIT fix does not reopen the Oracle sink path.

Runtime chain I checked

sink construction
  -> JdbcSinkFactory.createSink(...)
  -> JdbcOutputFormatBuilder.build()
      -> validateOracleInsertMode(...)
      -> createSimpleBufferedExecutor(...)
          -> dialect.getInsertIntoStatement(...)
          -> applyOracleAppendValuesHintIfNeeded(...)

Re-review result

  • The Oracle logic is still correctly guarded in JdbcOutputFormatBuilder.java:63-168,355-413.
  • The latest head commit only updates JdbcHiveIT for the catalog-utils signature and does not change the Oracle runtime path.
  • The UT / E2E additions remain aligned with the intended insert-only boundary.

Tests / stability

  • The added UTs are stable: no fixed sleeps, no hard-coded shared ports, and the assertions target deterministic guard-rail behavior.
  • The Oracle IT still covers the generated insert path.
  • I do not have a new source-level blocker on the latest head.

Conclusion: can merge

  1. Blocking items
  • None from my side on the latest head.
  1. Suggested non-blocking follow-up
  • None.

From the code-review side this looks good to merge.

@chl-wxp chl-wxp left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@chl-wxp
chl-wxp merged commit f9730fa into apache:dev Jun 4, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants