提交 8877492d 编写于 作者: R Ryuta Kamizono 提交者: GitHub

Fix longer sequence name detection for serial columns (#28339)

We already found the longer sequence name, but we could not consider
whether it was the sequence name created by serial type due to missed a
max identifier length limitation. I've addressed the sequence name
consideration to respect the max identifier length.

Fixes #28332.
上级 26f99545
* Fix longer sequence name detection for serial columns.
Fixes #28332.
*Ryuta Kamizono*
* MySQL: Don't lose `auto_increment: true` in the `db/schema.rb`.
Fixes #30894.
......
......@@ -15,7 +15,7 @@ class Column
# +default+ is the type-casted default value, such as +new+ in <tt>sales_stage varchar(20) default 'new'</tt>.
# +sql_type_metadata+ is various information about the type of the column
# +null+ determines if this column allows +NULL+ values.
def initialize(name, default, sql_type_metadata = nil, null = true, table_name = nil, default_function = nil, collation = nil, comment: nil)
def initialize(name, default, sql_type_metadata = nil, null = true, table_name = nil, default_function = nil, collation = nil, comment: nil, **)
@name = name.freeze
@table_name = table_name
@sql_type_metadata = sql_type_metadata
......
......@@ -7,6 +7,11 @@ class PostgreSQLColumn < Column #:nodoc:
delegate :array, :oid, :fmod, to: :sql_type_metadata
alias :array? :array
def initialize(*, max_identifier_length: 63, **)
super
@max_identifier_length = max_identifier_length
end
def serial?
return unless default_function
......@@ -15,8 +20,23 @@ def serial?
end
end
protected
attr_reader :max_identifier_length
private
def sequence_name_from_parts(table_name, column_name, suffix)
over_length = [table_name, column_name, suffix].map(&:length).sum + 2 - max_identifier_length
if over_length > 0
column_name_length = [(max_identifier_length - suffix.length - 2) / 2, column_name.length].min
over_length -= column_name.length - column_name_length
column_name = column_name[0, column_name_length - [over_length, 0].min]
end
if over_length > 0
table_name = table_name[0, table_name.length - over_length]
end
"#{table_name}_#{column_name}_#{suffix}"
end
end
......
......@@ -617,7 +617,8 @@ def new_column_from_field(table_name, field)
table_name,
default_function,
collation,
comment: comment.presence
comment: comment.presence,
max_identifier_length: max_identifier_length
)
end
......
......@@ -352,10 +352,11 @@ def extensions
end
# Returns the configured supported identifier length supported by PostgreSQL
def table_alias_length
def max_identifier_length
@max_identifier_length ||= query_value("SHOW max_identifier_length", "SCHEMA").to_i
end
alias index_name_length table_alias_length
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)
......
......@@ -121,4 +121,36 @@ def test_schema_dump_with_collided_sequence_name
assert_match %r{t\.bigserial\s+"bar_baz_id",\s+null: false$}, output
end
end
class LongerSequenceNameDetectionTest < ActiveRecord::PostgreSQLTestCase
include SchemaDumpingHelper
def setup
@table_name = "long_table_name_to_test_sequence_name_detection_for_serial_cols"
@connection = ActiveRecord::Base.connection
@connection.create_table @table_name, force: true do |t|
t.serial :seq
t.bigserial :bigseq
end
end
def teardown
@connection.drop_table @table_name, if_exists: true
end
def test_serial_columns
columns = @connection.columns(@table_name)
columns.each do |column|
assert_equal :integer, column.type
assert column.serial?
end
end
def test_schema_dump_with_long_table_name
output = dump_table_schema @table_name
assert_match %r{create_table "#{@table_name}", force: :cascade}, output
assert_match %r{t\.serial\s+"seq",\s+null: false$}, output
assert_match %r{t\.bigserial\s+"bigseq",\s+null: false$}, output
end
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册