提交 bf1494a1 编写于 作者: R Ryuta Kamizono

Fix GROUP BY with calculate longer name field to respect `table_alias_length`

Follow up of c9e4c848.
上级 57c7cbb1
......@@ -5,20 +5,24 @@
module ActiveRecord
module ConnectionAdapters # :nodoc:
module DatabaseLimits
def max_identifier_length # :nodoc:
64
end
# Returns the maximum length of a table alias.
def table_alias_length
255
max_identifier_length
end
# Returns the maximum length of a column name.
def column_name_length
64
max_identifier_length
end
deprecate :column_name_length
# Returns the maximum length of a table name.
def table_name_length
64
max_identifier_length
end
deprecate :table_name_length
......@@ -33,7 +37,7 @@ def allowed_index_name_length
# Returns the maximum length of an index name.
def index_name_length
64
max_identifier_length
end
# Returns the maximum number of columns per table.
......
......@@ -121,6 +121,10 @@ def type_to_sql(type, limit: nil, precision: nil, scale: nil, size: limit_to_siz
sql
end
def table_alias_length
256 # https://dev.mysql.com/doc/refman/8.0/en/identifiers.html
end
private
CHARSETS_OF_4BYTES_MAXLEN = ["utf8mb4", "utf16", "utf16le", "utf32"]
......
......@@ -400,8 +400,6 @@ def extensions
def max_identifier_length
@max_identifier_length ||= query_value("SHOW max_identifier_length", "SCHEMA").to_i
end
alias table_alias_length max_identifier_length
alias index_name_length max_identifier_length
# Set the authorized user for this session
def session_auth=(user)
......
......@@ -319,12 +319,11 @@ def execute_grouped_calculation(operation, column_name, distinct) #:nodoc:
group_aliases = group_fields.map { |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)
aggregate_alias = "#{operation}_#{column_name.to_s.downcase}"
aggregate_alias = column_alias_for(aggregate_alias) unless aggregate_alias.match?(/\A\w+\z/)
aggregate_alias = column_alias_for("#{operation}_#{column_name.to_s.downcase}")
select_values = [
operation_over_aggregate_column(
......@@ -369,7 +368,7 @@ def execute_grouped_calculation(operation, column_name, distinct) #:nodoc:
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:
#
# column_alias_for("users.id") # => "users_id"
......@@ -377,7 +376,9 @@ def execute_grouped_calculation(operation, column_name, distinct) #:nodoc:
# column_alias_for("count(distinct users.id)") # => "count_distinct_users_id"
# column_alias_for("count(*)") # => "count_all"
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!(/\W+/, " ")
column_alias.strip!
......
......@@ -363,6 +363,17 @@ def test_should_group_by_fields_with_table_alias
assert_equal 60, c[2]
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
assert_equal 6, Account.calculate(:count, "*")
assert_equal 6, Account.calculate(:count, :all)
......
......@@ -19,6 +19,7 @@
t.references :firm, index: false
t.string :firm_name
t.integer :credit_limit
t.integer "a" * max_identifier_length
end
create_table :admin_accounts, force: true do |t|
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册