WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Conversation

@xitep
Copy link
Contributor

@xitep xitep commented Nov 19, 2025

Oracle supports small extensions to the standard MERGE syntax (that I'd need to support.) In particular:

  • ... WHEN MATCHED ... UPDATE ... ***[WHERE <expr>] [DELETE WHERE <expr>]***
  • ... WHEN NOT MATCHED ... INSERT ... ***[WHERE <expr>]***

Here's the documentation for reference.

Quoted column names

Additionally, Oracle also allows quoted names in MERGE INTO a.b ... INSERT (a.b.col1, a.b.col2) ... (or event ... INSERT (b.col1, b.col2) ... with the same meaning as ... INSERT (col1, col2) as long as a.b denotes the target table of the merge.

For the sake of compatibility, this draft PR makes a trade-off: the parser validates that "a.b." corresponds to the target table, and strips away the prefix in order to keep MergeInsertExpr::columns a Vec<Ident>. While preserving semantics, the implication is that such a parsed statements doesn't render back in the exact same form, though.

Not doing the validation and stripping, we'd probably need to end up with a Vec<QualifiedName>. I would be glad to hear your opinion how to move forward. Personally, I'd be fine with the Vec<QualifiedName> allowing me to re-produce the statement as originally written.

Note

  1. I have moved the MERGE parsing code to a dedicated sub-module (and make Parser::merge_parse_clauses private.)
  2. I have introduced a Merge struct akin to Insert, Update, ... this makes it easier to pass the merge-relevat data around in a type-safe way
  3. I'd greatly appreciate any feedback to be able to steer this into a desired direction.

Missing

  • Location information in error messages
  • Expose insert columns as Vec<ObjectName>
  • Entirely remove the "insert column" semantic validation

@xitep xitep force-pushed the merge-predicates branch 4 times, most recently from 9f705bc to f406386 Compare November 22, 2025 16:50
@xitep xitep marked this pull request as ready for review November 23, 2025 09:32
@iffyio
Copy link
Contributor

iffyio commented Nov 25, 2025

@xitep Re this and #2103 PRs, The parser currently doesn't support oracle as a dialect, so that it would be a bit confusing going forward having code specific to the dialect but being unable to guarantee its consistency/behavior. I'm thinking we could instead start by introducing oracle as a supported dialect here?

@xitep
Copy link
Contributor Author

xitep commented Nov 25, 2025

  • yeah, i think starting an OracleDialect would definitely be the proper way forward. (it's just a much broader change than i think i can manage right now.)
  • wrt: Preserve optional AS keyword in aliases #2103: i think that is not (very) oracle specific. (truth is, the "AS" keyword will break the queries on oracle DBs; an OracleDialect would surely need to do something about it.) but primarily i see the change as a step towards "...recover(ing) the original SQL text..." (README.md.)

@xitep xitep requested a review from iffyio November 25, 2025 17:51
@xitep xitep force-pushed the merge-predicates branch 2 times, most recently from 0d25537 to 0d30912 Compare November 26, 2025 12:05
@xitep
Copy link
Contributor Author

xitep commented Nov 28, 2025

so that it would be a bit confusing going forward having code specific to the dialect

i would have a draft of an OracleDialect here ... would you like to have it rather as a separate PR (or include in into this one?) there's surely quite some work left on full oracle support (eg. string literals with a quote_delimiter) but it would be a start at least.

@iffyio
Copy link
Contributor

iffyio commented Nov 29, 2025

Ah great, yeah I think we can start with the bare minimum and have it as a separate MR

@xitep xitep mentioned this pull request Nov 30, 2025
Copy link
Contributor

@iffyio iffyio left a comment

Choose a reason for hiding this comment

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

Thanks @xitep! The changes look good to me overall, left a minor comment

INSERT (ID, NAME) \
VALUES (FOO_IMPORT.ID, UPPER(FOO_IMPORT.NAME)) \
WHERE NOT FOO_IMPORT.NAME LIKE '%.DO_NOT_INSERT'";
all_dialects().verified_stmt(sql);
Copy link
Contributor

Choose a reason for hiding this comment

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

can we merge the test cases into the same test function e.g. fn test_merge()? since they belong to the same feature

Copy link
Contributor Author

@xitep xitep Dec 4, 2025

Choose a reason for hiding this comment

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

ok, i've put them together into test_merge.

but, quite honestly, i believe this is rather a negative; it's quite frustrating to make changes and rely on the extensive test suite, only to get a ...

...
---- parse_merge stdout ----

thread 'parse_merge' (1824796) panicked at src/test_utils.rs:166:13:
assertion `left == right` failed
  left: "MERGE INTO PLAYGROUND .FOO USING FOO_IMPORT ON (PLAYGROUND.FOO.ID = FOO_IMPORT.ID) WHEN NOT MATCHED THEN INSERT (PLAYGROUND.FOO.ID, PLAYGROUND.FOO.NAME) VALUES (1, 'abc')"
 right: "MERGE INTO PLAYGROUND.FOO USING FOO_IMPORT ON (PLAYGROUND.FOO.ID = FOO_IMPORT.ID) WHEN NOT MATCHED THEN INSERT (PLAYGROUND.FOO.ID, PLAYGROUND.FOO.NAME) VALUES (1, 'abc')"
...

... and then have to find out which assertion the change broke since test_utils.rs:166 simply is not helpful (the best chance is to re-run the tests with RUST_BACKTRACE=1 or ...=full.)

Copy link
Contributor

@iffyio iffyio left a comment

Choose a reason for hiding this comment

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

LGTM! Thanks @xitep!

@iffyio iffyio added this pull request to the merge queue Dec 6, 2025
Merged via the queue into apache:main with commit ca2d333 Dec 6, 2025
10 checks passed
@xitep xitep deleted the merge-predicates branch December 6, 2025 09:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants