Skip to content

Commit

Permalink
Extract check for VALUES syntax
Browse files Browse the repository at this point in the history
The change to upserts (rails#51274) is causing
an issue with Vitess, since it doesn't support the `row_alias` syntax added
in MySQL 8.0.19.

There is an ongoing work (vitessio/vitess#15510)
to add that support and it is likely to be included into Vitess v20,
but in the meantime it would be nice to have an ability to control that
behavior in the existing apps.
  • Loading branch information
maxprokopiev committed Mar 19, 2024
1 parent 0f3465c commit 6a4fd54
Showing 1 changed file with 18 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -643,33 +643,33 @@ def build_insert_sql(insert) # :nodoc:

# MySQL 8.0.19 replaces `VALUES(<expression>)` clauses with row and column alias names, see https://dev.mysql.com/worklog/task/?id=6312 .
# then MySQL 8.0.20 deprecates the `VALUES(<expression>)` see https://dev.mysql.com/worklog/task/?id=13325 .
if !mariadb? && database_version >= "8.0.19"
values_alias = quote_table_name("#{insert.model.table_name}_values")
sql = +"INSERT #{insert.into} #{insert.values_list} AS #{values_alias}"
if supports_values_syntax?
sql = +"INSERT #{insert.into} #{insert.values_list}"

if insert.skip_duplicates?
sql << " ON DUPLICATE KEY UPDATE #{no_op_column}=#{values_alias}.#{no_op_column}"
sql << " ON DUPLICATE KEY UPDATE #{no_op_column}=#{no_op_column}"
elsif insert.update_duplicates?
sql << " ON DUPLICATE KEY UPDATE "
if insert.raw_update_sql?
sql = +"INSERT #{insert.into} #{insert.values_list} ON DUPLICATE KEY UPDATE #{insert.raw_update_sql}"
sql << insert.raw_update_sql
else
sql << " ON DUPLICATE KEY UPDATE "
sql << insert.touch_model_timestamps_unless { |column| "#{insert.model.quoted_table_name}.#{column}<=>#{values_alias}.#{column}" }
sql << insert.updatable_columns.map { |column| "#{column}=#{values_alias}.#{column}" }.join(",")
sql << insert.touch_model_timestamps_unless { |column| "#{column}<=>VALUES(#{column})" }
sql << insert.updatable_columns.map { |column| "#{column}=VALUES(#{column})" }.join(",")
end
end
else
sql = +"INSERT #{insert.into} #{insert.values_list}"
values_alias = quote_table_name("#{insert.model.table_name}_values")
sql = +"INSERT #{insert.into} #{insert.values_list} AS #{values_alias}"

if insert.skip_duplicates?
sql << " ON DUPLICATE KEY UPDATE #{no_op_column}=#{no_op_column}"
sql << " ON DUPLICATE KEY UPDATE #{no_op_column}=#{values_alias}.#{no_op_column}"
elsif insert.update_duplicates?
sql << " ON DUPLICATE KEY UPDATE "
if insert.raw_update_sql?
sql << insert.raw_update_sql
sql = +"INSERT #{insert.into} #{insert.values_list} ON DUPLICATE KEY UPDATE #{insert.raw_update_sql}"
else
sql << insert.touch_model_timestamps_unless { |column| "#{column}<=>VALUES(#{column})" }
sql << insert.updatable_columns.map { |column| "#{column}=VALUES(#{column})" }.join(",")
sql << " ON DUPLICATE KEY UPDATE "
sql << insert.touch_model_timestamps_unless { |column| "#{insert.model.quoted_table_name}.#{column}<=>#{values_alias}.#{column}" }
sql << insert.updatable_columns.map { |column| "#{column}=#{values_alias}.#{column}" }.join(",")
end
end
end
Expand Down Expand Up @@ -894,6 +894,10 @@ def remove_index_for_alter(table_name, column_name = nil, **options)
"DROP INDEX #{quote_column_name(index_name)}"
end

def supports_insert_values_syntax?
!mariadb? && database_version >= "8.0.19"
end

def supports_rename_index?
if mariadb?
database_version >= "10.5.2"
Expand Down

0 comments on commit 6a4fd54

Please sign in to comment.