Skip to content

Commit

Permalink
Make the table name too long error message more explicit for PostgreSQL
Browse files Browse the repository at this point in the history
* Explain why the enforced limit is less than the Postgres limit

Extract the table name too long error message out into its own method

Fix tests for new table name too long error message

Update error message from Postgres to PostgreSQL
  • Loading branch information
adampal committed Oct 10, 2023
1 parent 358d3d3 commit 31b5c11
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1767,16 +1767,20 @@ def check_constraint_for!(table_name, expression: nil, **options)

def validate_index_length!(table_name, new_name, internal = false)
if new_name.length > index_name_length
raise ArgumentError, "Index name '#{new_name}' on table '#{table_name}' is too long; the limit is #{index_name_length} characters"
raise ArgumentError, "Index name '#{new_name}' on table '#{table_name}' is too long; the limit is #{index_name_length} characters."
end
end

def validate_table_length!(table_name)
if table_name.length > table_name_length
raise ArgumentError, "Table name '#{table_name}' is too long; the limit is #{table_name_length} characters"
raise ArgumentError, table_name_too_long_error_message(table_name)
end
end

def table_name_too_long_error_message(table_name)
"Table name '#{table_name}' is too long; the limit is #{table_name_length} characters"
end

def extract_new_default_value(default_or_changes)
if default_or_changes.is_a?(Hash) && default_or_changes.has_key?(:from) && default_or_changes.has_key?(:to)
default_or_changes[:to]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,10 @@ def table_name_length
max_identifier_length - "_pkey".length
end

def table_name_too_long_error_message(table_name)
"Table name '#{table_name}' is too long; PostgreSQL allows a maximum length of #{max_identifier_length} characters, but we also need to allow for the `_pkey` suffix that PostgreSQL adds to table names when creating default indexes, so our effective limit is #{table_name_length} characters."
end

# Set the authorized user for this session
def session_auth=(user)
clear_cache!
Expand Down
7 changes: 6 additions & 1 deletion activerecord/test/cases/migration/rename_table_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,18 @@ def test_rename_table

def test_rename_table_raises_for_long_table_names
name_limit = connection.table_name_length
max_identifier_length = connection.max_identifier_length
long_name = "a" * (name_limit + 1)
short_name = "a" * name_limit

error = assert_raises(ArgumentError) do
connection.rename_table :test_models, long_name
end
assert_equal "Table name '#{long_name}' is too long; the limit is #{name_limit} characters", error.message
if current_adapter?(:PostgreSQLAdapter)
assert_equal "Table name '#{long_name}' is too long; PostgreSQL allows a maximum length of #{max_identifier_length} characters, but we also need to allow for the `_pkey` suffix that PostgreSQL adds to table names when creating default indexes, so our effective limit is #{name_limit} characters.", error.message
else
assert_equal "Table name '#{long_name}' is too long; the limit is #{name_limit} characters", error.message
end

connection.rename_table :test_models, short_name
assert connection.table_exists?(short_name)
Expand Down
7 changes: 6 additions & 1 deletion activerecord/test/cases/migration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -200,13 +200,18 @@ def test_create_table_with_if_not_exists_true
def test_create_table_raises_for_long_table_names
connection = Person.connection
name_limit = connection.table_name_length
max_identifier_length = connection.max_identifier_length
long_name = "a" * (name_limit + 1)
short_name = "a" * name_limit

error = assert_raises(ArgumentError) do
connection.create_table(long_name)
end
assert_equal "Table name '#{long_name}' is too long; the limit is #{name_limit} characters", error.message
if current_adapter?(:PostgreSQLAdapter)
assert_equal "Table name '#{long_name}' is too long; PostgreSQL allows a maximum length of #{max_identifier_length} characters, but we also need to allow for the `_pkey` suffix that PostgreSQL adds to table names when creating default indexes, so our effective limit is #{name_limit} characters.", error.message
else
assert_equal "Table name '#{long_name}' is too long; the limit is #{name_limit} characters", error.message
end

connection.create_table(short_name)
assert connection.table_exists?(short_name)
Expand Down

0 comments on commit 31b5c11

Please sign in to comment.