mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Fix GROUP BY with calculate longer name field to respect table_alias_length
Follow up of c9e4c848ee
.
This commit is contained in:
parent
57c7cbb162
commit
bf1494a101
6 changed files with 30 additions and 11 deletions
|
@ -5,20 +5,24 @@ require "active_support/deprecation"
|
||||||
module ActiveRecord
|
module ActiveRecord
|
||||||
module ConnectionAdapters # :nodoc:
|
module ConnectionAdapters # :nodoc:
|
||||||
module DatabaseLimits
|
module DatabaseLimits
|
||||||
|
def max_identifier_length # :nodoc:
|
||||||
|
64
|
||||||
|
end
|
||||||
|
|
||||||
# Returns the maximum length of a table alias.
|
# Returns the maximum length of a table alias.
|
||||||
def table_alias_length
|
def table_alias_length
|
||||||
255
|
max_identifier_length
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the maximum length of a column name.
|
# Returns the maximum length of a column name.
|
||||||
def column_name_length
|
def column_name_length
|
||||||
64
|
max_identifier_length
|
||||||
end
|
end
|
||||||
deprecate :column_name_length
|
deprecate :column_name_length
|
||||||
|
|
||||||
# Returns the maximum length of a table name.
|
# Returns the maximum length of a table name.
|
||||||
def table_name_length
|
def table_name_length
|
||||||
64
|
max_identifier_length
|
||||||
end
|
end
|
||||||
deprecate :table_name_length
|
deprecate :table_name_length
|
||||||
|
|
||||||
|
@ -33,7 +37,7 @@ module ActiveRecord
|
||||||
|
|
||||||
# Returns the maximum length of an index name.
|
# Returns the maximum length of an index name.
|
||||||
def index_name_length
|
def index_name_length
|
||||||
64
|
max_identifier_length
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the maximum number of columns per table.
|
# Returns the maximum number of columns per table.
|
||||||
|
|
|
@ -121,6 +121,10 @@ module ActiveRecord
|
||||||
sql
|
sql
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def table_alias_length
|
||||||
|
256 # https://dev.mysql.com/doc/refman/8.0/en/identifiers.html
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
CHARSETS_OF_4BYTES_MAXLEN = ["utf8mb4", "utf16", "utf16le", "utf32"]
|
CHARSETS_OF_4BYTES_MAXLEN = ["utf8mb4", "utf16", "utf16le", "utf32"]
|
||||||
|
|
||||||
|
|
|
@ -400,8 +400,6 @@ module ActiveRecord
|
||||||
def max_identifier_length
|
def max_identifier_length
|
||||||
@max_identifier_length ||= query_value("SHOW max_identifier_length", "SCHEMA").to_i
|
@max_identifier_length ||= query_value("SHOW max_identifier_length", "SCHEMA").to_i
|
||||||
end
|
end
|
||||||
alias table_alias_length max_identifier_length
|
|
||||||
alias index_name_length max_identifier_length
|
|
||||||
|
|
||||||
# Set the authorized user for this session
|
# Set the authorized user for this session
|
||||||
def session_auth=(user)
|
def session_auth=(user)
|
||||||
|
|
|
@ -319,12 +319,11 @@ module ActiveRecord
|
||||||
|
|
||||||
group_aliases = group_fields.map { |field|
|
group_aliases = group_fields.map { |field|
|
||||||
field = connection.visitor.compile(field) if Arel.arel_node?(field)
|
field = connection.visitor.compile(field) if Arel.arel_node?(field)
|
||||||
column_alias_for(field)
|
column_alias_for(field.to_s.downcase)
|
||||||
}
|
}
|
||||||
group_columns = group_aliases.zip(group_fields)
|
group_columns = group_aliases.zip(group_fields)
|
||||||
|
|
||||||
aggregate_alias = "#{operation}_#{column_name.to_s.downcase}"
|
aggregate_alias = column_alias_for("#{operation}_#{column_name.to_s.downcase}")
|
||||||
aggregate_alias = column_alias_for(aggregate_alias) unless aggregate_alias.match?(/\A\w+\z/)
|
|
||||||
|
|
||||||
select_values = [
|
select_values = [
|
||||||
operation_over_aggregate_column(
|
operation_over_aggregate_column(
|
||||||
|
@ -369,7 +368,7 @@ module ActiveRecord
|
||||||
end]
|
end]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Converts the given keys to the value that the database adapter returns as
|
# Converts the given field to the value that the database adapter returns as
|
||||||
# a usable column name:
|
# a usable column name:
|
||||||
#
|
#
|
||||||
# column_alias_for("users.id") # => "users_id"
|
# column_alias_for("users.id") # => "users_id"
|
||||||
|
@ -377,7 +376,9 @@ module ActiveRecord
|
||||||
# column_alias_for("count(distinct users.id)") # => "count_distinct_users_id"
|
# column_alias_for("count(distinct users.id)") # => "count_distinct_users_id"
|
||||||
# column_alias_for("count(*)") # => "count_all"
|
# column_alias_for("count(*)") # => "count_all"
|
||||||
def column_alias_for(field)
|
def column_alias_for(field)
|
||||||
column_alias = field.to_s.downcase
|
return field if field.match?(/\A\w{,#{connection.table_alias_length}}\z/)
|
||||||
|
|
||||||
|
column_alias = +field
|
||||||
column_alias.gsub!(/\*/, "all")
|
column_alias.gsub!(/\*/, "all")
|
||||||
column_alias.gsub!(/\W+/, " ")
|
column_alias.gsub!(/\W+/, " ")
|
||||||
column_alias.strip!
|
column_alias.strip!
|
||||||
|
|
|
@ -363,6 +363,17 @@ class CalculationsTest < ActiveRecord::TestCase
|
||||||
assert_equal 60, c[2]
|
assert_equal 60, c[2]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_should_calculate_grouped_with_longer_field
|
||||||
|
field = "a" * Account.connection.max_identifier_length
|
||||||
|
|
||||||
|
Account.update_all("#{field} = credit_limit")
|
||||||
|
|
||||||
|
c = Account.group(:firm_id).sum(field)
|
||||||
|
assert_equal 50, c[1]
|
||||||
|
assert_equal 105, c[6]
|
||||||
|
assert_equal 60, c[2]
|
||||||
|
end
|
||||||
|
|
||||||
def test_should_calculate_with_invalid_field
|
def test_should_calculate_with_invalid_field
|
||||||
assert_equal 6, Account.calculate(:count, "*")
|
assert_equal 6, Account.calculate(:count, "*")
|
||||||
assert_equal 6, Account.calculate(:count, :all)
|
assert_equal 6, Account.calculate(:count, :all)
|
||||||
|
|
|
@ -19,6 +19,7 @@ ActiveRecord::Schema.define do
|
||||||
t.references :firm, index: false
|
t.references :firm, index: false
|
||||||
t.string :firm_name
|
t.string :firm_name
|
||||||
t.integer :credit_limit
|
t.integer :credit_limit
|
||||||
|
t.integer "a" * max_identifier_length
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table :admin_accounts, force: true do |t|
|
create_table :admin_accounts, force: true do |t|
|
||||||
|
|
Loading…
Reference in a new issue