Skip to content

Commit 35d388b

Browse files
authored
Merge pull request rails#35890 from kamipo/except_table_name_from_column
Except `table_name` from column objects
2 parents 61073e3 + f185e0e commit 35d388b

File tree

7 files changed

+48
-49
lines changed

7 files changed

+48
-49
lines changed

activerecord/lib/active_record/connection_adapters/column.rb

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module ActiveRecord
55
module ConnectionAdapters
66
# An abstract definition of a column in a table.
77
class Column
8-
attr_reader :name, :default, :sql_type_metadata, :null, :table_name, :default_function, :collation, :comment
8+
attr_reader :name, :default, :sql_type_metadata, :null, :default_function, :collation, :comment
99

1010
delegate :precision, :scale, :limit, :type, :sql_type, to: :sql_type_metadata, allow_nil: true
1111

@@ -15,9 +15,8 @@ class Column
1515
# +default+ is the type-casted default value, such as +new+ in <tt>sales_stage varchar(20) default 'new'</tt>.
1616
# +sql_type_metadata+ is various information about the type of the column
1717
# +null+ determines if this column allows +NULL+ values.
18-
def initialize(name, default, sql_type_metadata = nil, null = true, table_name = nil, default_function = nil, collation = nil, comment: nil, **)
18+
def initialize(name, default, sql_type_metadata = nil, null = true, default_function = nil, collation: nil, comment: nil, **)
1919
@name = name.freeze
20-
@table_name = table_name
2120
@sql_type_metadata = sql_type_metadata
2221
@null = null
2322
@default = default
@@ -44,7 +43,6 @@ def human_name
4443

4544
def init_with(coder)
4645
@name = coder["name"]
47-
@table_name = coder["table_name"]
4846
@sql_type_metadata = coder["sql_type_metadata"]
4947
@null = coder["null"]
5048
@default = coder["default"]
@@ -55,7 +53,6 @@ def init_with(coder)
5553

5654
def encode_with(coder)
5755
coder["name"] = @name
58-
coder["table_name"] = @table_name
5956
coder["sql_type_metadata"] = @sql_type_metadata
6057
coder["null"] = @null
6158
coder["default"] = @default
@@ -77,7 +74,7 @@ def hash
7774
protected
7875

7976
def attributes_for_hash
80-
[self.class, name, default, sql_type_metadata, null, table_name, default_function, collation]
77+
[self.class, name, default, sql_type_metadata, null, default_function, collation, comment]
8178
end
8279
end
8380

activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def schema_precision(column)
5555
end
5656

5757
def schema_collation(column)
58-
if column.collation && table_name = column.table_name
58+
if column.collation
5959
@table_collation_cache ||= {}
6060
@table_collation_cache[table_name] ||=
6161
@connection.exec_query("SHOW TABLE STATUS LIKE #{@connection.quote(table_name)}", "SCHEMA").first["Collation"]
@@ -65,13 +65,13 @@ def schema_collation(column)
6565

6666
def extract_expression_for_virtual_column(column)
6767
if @connection.mariadb? && @connection.database_version < "10.2.5"
68-
create_table_info = @connection.send(:create_table_info, column.table_name)
68+
create_table_info = @connection.send(:create_table_info, table_name)
6969
column_name = @connection.quote_column_name(column.name)
7070
if %r/#{column_name} #{Regexp.quote(column.sql_type)}(?: COLLATE \w+)? AS \((?<expression>.+?)\) #{column.extra}/ =~ create_table_info
7171
$~[:expression].inspect
7272
end
7373
else
74-
scope = @connection.send(:quoted_scope, column.table_name)
74+
scope = @connection.send(:quoted_scope, table_name)
7575
column_name = @connection.quote(column.name)
7676
sql = "SELECT generation_expression FROM information_schema.columns" \
7777
" WHERE table_schema = #{scope[:schema]}" \

activerecord/lib/active_record/connection_adapters/mysql/schema_statements.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,8 @@ def new_column_from_field(table_name, field)
174174
default,
175175
type_metadata,
176176
field[:Null] == "YES",
177-
table_name,
178177
default_function,
179-
field[:Collation],
178+
collation: field[:Collation],
180179
comment: field[:Comment].presence
181180
)
182181
end

activerecord/lib/active_record/connection_adapters/postgresql/column.rb

Lines changed: 12 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,21 @@
22

33
module ActiveRecord
44
module ConnectionAdapters
5-
# PostgreSQL-specific extensions to column definitions in a table.
6-
class PostgreSQLColumn < Column #:nodoc:
7-
delegate :array, :oid, :fmod, to: :sql_type_metadata
8-
alias :array? :array
9-
10-
def initialize(*, max_identifier_length: 63, **)
11-
super
12-
@max_identifier_length = max_identifier_length
13-
end
14-
15-
def serial?
16-
return unless default_function
17-
18-
if %r{\Anextval\('"?(?<sequence_name>.+_(?<suffix>seq\d*))"?'::regclass\)\z} =~ default_function
19-
sequence_name_from_parts(table_name, name, suffix) == sequence_name
5+
module PostgreSQL
6+
class Column < ConnectionAdapters::Column # :nodoc:
7+
delegate :array, :oid, :fmod, to: :sql_type_metadata
8+
alias :array? :array
9+
10+
def initialize(*, serial: nil, **)
11+
super
12+
@serial = serial
2013
end
21-
end
2214

23-
private
24-
attr_reader :max_identifier_length
25-
26-
def sequence_name_from_parts(table_name, column_name, suffix)
27-
over_length = [table_name, column_name, suffix].map(&:length).sum + 2 - max_identifier_length
28-
29-
if over_length > 0
30-
column_name_length = [(max_identifier_length - suffix.length - 2) / 2, column_name.length].min
31-
over_length -= column_name.length - column_name_length
32-
column_name = column_name[0, column_name_length - [over_length, 0].min]
33-
end
34-
35-
if over_length > 0
36-
table_name = table_name[0, table_name.length - over_length]
37-
end
38-
39-
"#{table_name}_#{column_name}_#{suffix}"
15+
def serial?
16+
@serial
4017
end
18+
end
4119
end
20+
PostgreSQLColumn = PostgreSQL::Column # :nodoc:
4221
end
4322
end

activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -650,16 +650,19 @@ def new_column_from_field(table_name, field)
650650
default_value = extract_value_from_default(default)
651651
default_function = extract_default_function(default_value, default)
652652

653-
PostgreSQLColumn.new(
653+
if match = default_function&.match(/\Anextval\('"?(?<sequence_name>.+_(?<suffix>seq\d*))"?'::regclass\)\z/)
654+
serial = sequence_name_from_parts(table_name, column_name, match[:suffix]) == match[:sequence_name]
655+
end
656+
657+
PostgreSQL::Column.new(
654658
column_name,
655659
default_value,
656660
type_metadata,
657661
!notnull,
658-
table_name,
659662
default_function,
660-
collation,
663+
collation: collation,
661664
comment: comment.presence,
662-
max_identifier_length: max_identifier_length
665+
serial: serial
663666
)
664667
end
665668

@@ -675,6 +678,22 @@ def fetch_type_metadata(column_name, sql_type, oid, fmod)
675678
PostgreSQLTypeMetadata.new(simple_type, oid: oid, fmod: fmod)
676679
end
677680

681+
def sequence_name_from_parts(table_name, column_name, suffix)
682+
over_length = [table_name, column_name, suffix].sum(&:length) + 2 - max_identifier_length
683+
684+
if over_length > 0
685+
column_name_length = [(max_identifier_length - suffix.length - 2) / 2, column_name.length].min
686+
over_length -= column_name.length - column_name_length
687+
column_name = column_name[0, column_name_length - [over_length, 0].min]
688+
end
689+
690+
if over_length > 0
691+
table_name = table_name[0, table_name.length - over_length]
692+
end
693+
694+
"#{table_name}_#{column_name}_#{suffix}"
695+
end
696+
678697
def extract_foreign_key_action(specifier)
679698
case specifier
680699
when "c"; :cascade

activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ def new_column_from_field(table_name, field)
105105
end
106106

107107
type_metadata = fetch_type_metadata(field["type"])
108-
Column.new(field["name"], default, type_metadata, field["notnull"].to_i == 0, table_name, nil, field["collation"])
108+
Column.new(field["name"], default, type_metadata, field["notnull"].to_i == 0, collation: field["collation"])
109109
end
110110

111111
def data_source_sql(name = nil, type: nil)

activerecord/lib/active_record/schema_dumper.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ def dump(stream)
4747
end
4848

4949
private
50+
attr_accessor :table_name
5051

5152
def initialize(connection, options = {})
5253
@connection = connection
@@ -110,6 +111,8 @@ def tables(stream)
110111
def table(table, stream)
111112
columns = @connection.columns(table)
112113
begin
114+
self.table_name = table
115+
113116
tbl = StringIO.new
114117

115118
# first dump primary key column
@@ -159,6 +162,8 @@ def table(table, stream)
159162
stream.puts "# Could not dump table #{table.inspect} because of following #{e.class}"
160163
stream.puts "# #{e.message}"
161164
stream.puts
165+
ensure
166+
self.table_name = nil
162167
end
163168
end
164169

0 commit comments

Comments
 (0)