8000 Add MySQL 8.0.19+ VALUES alias support for ON DUPLICATE KEY UPDATE by hyukjin-lee · Pull Request #4268 · h2database/h2database · GitHub
[go: up one dir, main page]

Skip to content

Conversation

hyukjin-lee
Copy link

Summary

Implements support for MySQL 8.0.19+ VALUES alias syntax in INSERT ... ON DUPLICATE KEY UPDATE statements.

#4267

Implementation Details

New Classes:

  • ValuesAliasExpression - Expression for handling alias.column references
  • ValuesAliasResolver - ColumnResolver for resolving alias column references

Modified Classes:

  • Parser.java - Added parsing for AS alias_name after VALUES clause
  • CommandWithValues.java - Added valuesAlias and valuesAliasResolver fields
  • Insert.java - Extended to create and manage VALUES alias resolver

Key Features:

  • Only active in MySQL compatibility mode (database.getMode().onDuplicateKeyUpdate)
  • Supports complex expressions: counter = counter + alias.counter
  • Full backward compatibility with existing VALUES() function
  • Both syntaxes can be mixed in the same statement

Testing

Added comprehensive test class TestValuesAlias.java covering:

sql
-- Basic alias usage
INSERT INTO table (id, name) VALUES (1, 'John') AS new_user
ON DUPLICATE KEY UPDATE name = new_user.name;

-- Complex expressions
INSERT INTO stats (id, counter, total) VALUES (1, 3, 50.0) AS new_data
ON DUPLICATE KEY UPDATE counter = counter + new_data.counter, total = total + new_data.total;

-- Mixed syntax (new + old)
INSERT INTO table (id, name, value, extra) VALUES (1, 'test', 200, 'new') AS x
ON DUPLICATE KEY UPDATE name = x.name, value = VALUES(value), extra = x.extra;

-- Backward compatibility (old syntax still works)
INSERT INTO table (id, name) VALUES (1, 'test')
ON DUPLICATE KEY UPDATE name = VALUES(name);

…Y UPDATE

- Implement ValuesAliasExpression for handling alias.column references
- Add ValuesAliasResolver for column resolution and value retrieval
- Extend Parser to support INSERT ... VALUES ... AS alias syntax
- Modify CommandWithValues and Insert classes to handle VALUES aliases
- Maintain full backward compatibility with existing VALUES() function
- Add comprehensive test coverage for new functionality
- Follow H2 coding conventions and design patterns
- Use proper imports instead of fully qualified class names

This enhancement improves MySQL compatibility by supporting the modern
VALUES alias syntax introduced in MySQL 8.0.19, allowing developers to
use more readable and maintainable SQL code while preserving all
existing functionality.
@katzyn
Copy link
Contributor
katzyn commented Aug 27, 2025

Thank you for your contribution!

Please, try to create a MergeUsing command in the Parser.parseInsertCompatibility() with TableValueConstructor as a source table (there is a toTable() method, the returned table can be used in TableFilter) and return it instead of Insert command if any of these non-standard extensions were detected. The Insert command shouldn't have such logic. TableFilter instances have an alias, therefore changes in CommandWithValues aren't needed too.

Changes in readTermObjectDot() also look too intrusive, they need to be isolated into own method.

We also prefer pure SQL test cases, you can put them into insertIgnore.sql or create a new file.

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

0