diff --git a/grammar.js b/grammar.js index aa2bbfad..1f6236bc 100644 --- a/grammar.js +++ b/grammar.js @@ -124,6 +124,7 @@ module.exports = grammar({ keyword_start: _ => make_keyword("start"), keyword_restart: _ => make_keyword("restart"), keyword_key: _ => make_keyword("key"), + keyword_duplicate: _ => make_keyword("duplicate"), keyword_as: _ => make_keyword("as"), keyword_distinct: _ => make_keyword("distinct"), keyword_constraint: _ => make_keyword("constraint"), @@ -2150,24 +2151,42 @@ module.exports = grammar({ $._set_values, ), optional( - seq( - $.keyword_on, - $.keyword_conflict, + choice( + $._on_conflict, + $._on_duplicate_key_update, + ), + ), + ), + + _on_conflict: $ => seq( + $.keyword_on, + $.keyword_conflict, + seq( + $.keyword_do, + choice( + $.keyword_nothing, seq( - $.keyword_do, - choice( - $.keyword_nothing, - seq( - $.keyword_update, - $._set_values, - optional($.where), - ), - ), + $.keyword_update, + $._set_values, + optional($.where), ), ), ), ), + _on_duplicate_key_update: $ => seq( + $.keyword_on, + $.keyword_duplicate, + $.keyword_key, + $.keyword_update, + $.assignment_list, + ), + + assignment_list: $ => seq( + $.assignment, + repeat(seq(',', $.assignment)), + ), + _insert_values: $ => seq( optional(alias($._column_list, $.list)), choice( diff --git a/test/corpus/insert.txt b/test/corpus/insert.txt index 7d225b2f..5ec111e8 100644 --- a/test/corpus/insert.txt +++ b/test/corpus/insert.txt @@ -140,7 +140,8 @@ RETURNING *; (returning (keyword_returning) (select_expression - (term value: (all_fields)))))) + (term + value: (all_fields)))))) ================================================================================ Insert returning single column @@ -449,7 +450,8 @@ FROM (select (keyword_select) (select_expression - (term (all_fields)))) + (term + (all_fields)))) (from (keyword_from) (relation @@ -513,7 +515,8 @@ FROM (select (keyword_select) (select_expression - (term (all_fields)))) + (term + (all_fields)))) (from (keyword_from) (relation @@ -561,3 +564,64 @@ INSERT INTO some_table (select_expression (term (literal)))))))) + +================================================================================ +ON DUPLICATE KEY UPDATE +================================================================================ + +INSERT INTO table_1 (pk, col1, col2) +VALUES + (1, 1, 1), + (2, 2, 2) +ON DUPLICATE KEY UPDATE + pk = VALUES(pk), + col1 = 1, + col2 = "foo"; + +-------------------------------------------------------------------------------- + +(program + (statement + (insert + (keyword_insert) + (keyword_into) + (object_reference + name: (identifier)) + (list + (column + (identifier)) + (column + (identifier)) + (column + (identifier))) + (keyword_values) + (list + (literal) + (literal) + (literal)) + (list + (literal) + (literal) + (literal)) + (keyword_on) + (keyword_duplicate) + (keyword_key) + (keyword_update) + (assignment_list + (assignment + left: (field + name: (identifier)) + right: (invocation + (object_reference + name: (identifier)) + parameter: (term + value: (field + name: (identifier))))) + (assignment + left: (field + name: (identifier)) + right: (literal)) + (assignment + left: (field + name: (identifier)) + right: (literal))))))