Skip to content

feat: show MERGE INTO details in EXPLAIN - #26038

Open
wirybeaver wants to merge 1 commit into
apache:mainfrom
wirybeaver:mergeExplain
Open

wirybeaver wants to merge 1 commit into
apache:mainfrom
wirybeaver:mergeExplain

Conversation

@wirybeaver

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Follow-up to the MERGE INTO review in #22988 and split from #24195. No separate issue.

Rationale for this change

Logical-plan output for MERGE INTO currently shows only op=[MergeInto]. It omits the ON condition and WHEN actions, which makes EXPLAIN less useful for understanding or debugging a merge plan.

What changes are included in this PR?

  • Adds display implementations for MERGE operations, clause kinds, clauses, and actions.
  • Includes the ON condition and ordered WHEN ... THEN ... clauses in indented logical-plan output.
  • Adds the same information to PostgreSQL JSON output and identifies DML nodes as Dml rather than Projection.
  • Adds text and JSON assertions covering aliases, quoted columns, predicates, updates, deletes, and inserts.

This PR is independent of #24195 and targets main directly. The two PRs only modify separate expectations in the shared merge_into.slt test file.

What is the testing strategy for this PR?

  • cargo fmt --all
  • cargo check -p datafusion-expr -p datafusion-sql
  • cargo test -p datafusion-expr write_op_merge_into_name_and_display -- --nocapture
  • cargo test -p datafusion-sql plan_merge_into_preserves_target_qualifier_and_quoted_columns -- --nocapture
  • cargo test --profile ci --test sqllogictests -- merge_into.slt --nocapture
  • cargo clippy --all-targets --all-features -- -D warnings
  • Full extended workspace test command from the contributor guide

Are there any user-facing changes?

Yes. EXPLAIN text and PostgreSQL JSON output for MERGE INTO now include the merge condition and clauses. There are no public API signature changes.

@github-actions github-actions Bot added sql SQL Planner logical-expr Logical plan and expressions sqllogictest SQL Logic Tests (.slt) labels Oct 4, 2026
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 76.38889% with 17 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.66%. Comparing base (c3ef346) to head (4d15378).

Files with missing lines Patch % Lines
datafusion/expr/src/logical_plan/dml.rs 73.58% 2 Missing and 12 partials ⚠️
datafusion/expr/src/logical_plan/plan.rs 60.00% 0 Missing and 2 partials ⚠️
datafusion/expr/src/logical_plan/display.rs 92.85% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main   #26038   +/-   ##
=======================================
  Coverage   82.66%   82.66%           
=======================================
  Files        1147     1147           
  Lines      446357   446426   +69     
  Branches   446357   446426   +69     
=======================================
+ Hits       368971   369041   +70     
+ Misses      54997    54982   -15     
- Partials    22389    22403   +14     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@wirybeaver wirybeaver mentioned this pull request Oct 8, 2026
4 of 6 tasks

@kosiew kosiew 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.

@wirybeaver,

Thanks for improving the MERGE INTO logical-plan display. The change addresses the issue by exposing the ON condition and ordered WHEN clauses in both text and PostgreSQL JSON output. The approach is appropriate, and the additional regression coverage exercises the main formatting paths.

The formatting responsibility stays with the types that own the merge details, while the logical-plan display layers decide how to present them. This preserves the existing planning and execution boundaries, avoids duplicating action formatting, and keeps non-MERGE text output unchanged. The additional complexity is justified by the diagnostic value.

I'm approving because the issue requirements are satisfied and I found no blocking correctness concerns. I left two non-blocking suggestions concerning identifier quoting and stronger JSON contract tests, including coverage of the broader DML node-type change.

Comment thread datafusion/expr/src/logical_plan/dml.rs Outdated
if i > 0 {
write!(f, ", ")?;
}
write!(f, "{column} = {value}")?;

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.

Could we use datafusion_common::utils::quote_identifier for UPDATE assignment targets and INSERT column names when quoting is needed? Currently First Name loses its identifier boundaries, and a name like a, b would look like two columns. Please adjust the existing test and include a comma or embedded-quote identifier. This is a readability improvement, not an execution issue.

Comment thread datafusion/sql/tests/sql_integration.rs Outdated
"Dml: op=[MergeInto] table=[person_quoted_cols] on=[t.id = s.j2_id] clauses=[WHEN MATCHED THEN UPDATE SET First Name = s.j2_string, WHEN NOT MATCHED THEN INSERT (id, Age) VALUES (s.j2_id, Int64(42))]"
);

let json = plan.display_pg_json().to_string();

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.

Could we parse the JSON and assert the root Clauses array contains both expected strings in SQL order, along with On, Operation, and Table Name? The substring checks miss the array shape, second clause, and ordering. It would also help to test non-MERGE DML for the changed Node Type and absence of MERGE-only keys, and confirm that the broader node-type change is intentional.

Include the ON condition and WHEN clauses in text and PostgreSQL JSON logical-plan output for MERGE INTO.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

logical-expr Logical plan and expressions sql SQL Planner sqllogictest SQL Logic Tests (.slt)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants