activerecord 6.0.0.rc1 → 6.0.3.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (168) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +251 -3
  3. data/README.rdoc +1 -1
  4. data/lib/active_record.rb +1 -0
  5. data/lib/active_record/advisory_lock_base.rb +18 -0
  6. data/lib/active_record/aggregations.rb +0 -1
  7. data/lib/active_record/association_relation.rb +10 -8
  8. data/lib/active_record/associations.rb +2 -2
  9. data/lib/active_record/associations/alias_tracker.rb +0 -1
  10. data/lib/active_record/associations/association.rb +5 -1
  11. data/lib/active_record/associations/builder/collection_association.rb +2 -2
  12. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -3
  13. data/lib/active_record/associations/collection_association.rb +6 -2
  14. data/lib/active_record/associations/collection_proxy.rb +2 -3
  15. data/lib/active_record/associations/has_many_association.rb +0 -1
  16. data/lib/active_record/associations/join_dependency.rb +23 -9
  17. data/lib/active_record/associations/join_dependency/join_association.rb +12 -3
  18. data/lib/active_record/associations/preloader.rb +2 -3
  19. data/lib/active_record/associations/preloader/association.rb +3 -1
  20. data/lib/active_record/attribute_assignment.rb +0 -1
  21. data/lib/active_record/attribute_decorators.rb +0 -2
  22. data/lib/active_record/attribute_methods.rb +0 -51
  23. data/lib/active_record/attribute_methods/before_type_cast.rb +0 -1
  24. data/lib/active_record/attribute_methods/dirty.rb +8 -3
  25. data/lib/active_record/attribute_methods/primary_key.rb +0 -2
  26. data/lib/active_record/attribute_methods/read.rb +0 -1
  27. data/lib/active_record/attribute_methods/serialization.rb +0 -1
  28. data/lib/active_record/attribute_methods/time_zone_conversion.rb +0 -2
  29. data/lib/active_record/attribute_methods/write.rb +0 -1
  30. data/lib/active_record/attributes.rb +0 -1
  31. data/lib/active_record/autosave_association.rb +11 -7
  32. data/lib/active_record/callbacks.rb +1 -2
  33. data/lib/active_record/coders/yaml_column.rb +0 -1
  34. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +107 -13
  35. data/lib/active_record/connection_adapters/abstract/database_statements.rb +21 -15
  36. data/lib/active_record/connection_adapters/abstract/query_cache.rb +5 -5
  37. data/lib/active_record/connection_adapters/abstract/quoting.rb +53 -0
  38. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +1 -2
  39. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +27 -27
  40. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -1
  41. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +55 -37
  42. data/lib/active_record/connection_adapters/abstract/transaction.rb +14 -7
  43. data/lib/active_record/connection_adapters/abstract_adapter.rb +62 -25
  44. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +25 -32
  45. data/lib/active_record/connection_adapters/connection_specification.rb +3 -4
  46. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -2
  47. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  48. data/lib/active_record/connection_adapters/mysql/database_statements.rb +8 -12
  49. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +0 -1
  50. data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
  51. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +1 -2
  52. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +3 -1
  53. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +8 -8
  54. data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -4
  55. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +9 -3
  56. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +0 -1
  57. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  58. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +0 -1
  59. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +0 -1
  60. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
  61. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  62. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +0 -1
  63. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +0 -1
  64. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  65. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +0 -1
  66. data/lib/active_record/connection_adapters/postgresql/quoting.rb +39 -2
  67. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
  68. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +2 -2
  69. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +1 -1
  70. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
  71. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +15 -29
  72. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  73. data/lib/active_record/connection_adapters/postgresql_adapter.rb +17 -3
  74. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +8 -7
  75. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +38 -3
  76. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +3 -3
  77. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +23 -8
  78. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  79. data/lib/active_record/connection_handling.rb +17 -22
  80. data/lib/active_record/core.rb +8 -6
  81. data/lib/active_record/counter_cache.rb +4 -1
  82. data/lib/active_record/database_configurations.rb +60 -31
  83. data/lib/active_record/database_configurations/url_config.rb +0 -1
  84. data/lib/active_record/dynamic_matchers.rb +2 -3
  85. data/lib/active_record/enum.rb +9 -0
  86. data/lib/active_record/explain.rb +0 -1
  87. data/lib/active_record/fixture_set/table_row.rb +0 -1
  88. data/lib/active_record/fixture_set/table_rows.rb +0 -1
  89. data/lib/active_record/fixtures.rb +11 -9
  90. data/lib/active_record/gem_version.rb +1 -1
  91. data/lib/active_record/inheritance.rb +0 -3
  92. data/lib/active_record/insert_all.rb +5 -6
  93. data/lib/active_record/internal_metadata.rb +1 -1
  94. data/lib/active_record/locking/optimistic.rb +0 -1
  95. data/lib/active_record/log_subscriber.rb +1 -1
  96. data/lib/active_record/middleware/database_selector.rb +3 -4
  97. data/lib/active_record/middleware/database_selector/resolver.rb +5 -8
  98. data/lib/active_record/migration.rb +43 -32
  99. data/lib/active_record/migration/command_recorder.rb +6 -18
  100. data/lib/active_record/migration/compatibility.rb +3 -3
  101. data/lib/active_record/migration/join_table.rb +0 -1
  102. data/lib/active_record/model_schema.rb +3 -2
  103. data/lib/active_record/nested_attributes.rb +0 -2
  104. data/lib/active_record/no_touching.rb +2 -2
  105. data/lib/active_record/null_relation.rb +0 -1
  106. data/lib/active_record/persistence.rb +4 -5
  107. data/lib/active_record/querying.rb +1 -1
  108. data/lib/active_record/railtie.rb +1 -2
  109. data/lib/active_record/railties/collection_cache_association_loading.rb +1 -1
  110. data/lib/active_record/railties/databases.rake +63 -23
  111. data/lib/active_record/reflection.rb +9 -9
  112. data/lib/active_record/relation.rb +13 -1
  113. data/lib/active_record/relation/batches.rb +0 -1
  114. data/lib/active_record/relation/calculations.rb +3 -5
  115. data/lib/active_record/relation/delegation.rb +7 -6
  116. data/lib/active_record/relation/finder_methods.rb +14 -4
  117. data/lib/active_record/relation/from_clause.rb +4 -0
  118. data/lib/active_record/relation/merger.rb +6 -3
  119. data/lib/active_record/relation/predicate_builder.rb +1 -5
  120. data/lib/active_record/relation/query_methods.rb +94 -55
  121. data/lib/active_record/relation/spawn_methods.rb +0 -1
  122. data/lib/active_record/relation/where_clause.rb +0 -1
  123. data/lib/active_record/result.rb +0 -1
  124. data/lib/active_record/sanitization.rb +30 -2
  125. data/lib/active_record/schema.rb +1 -1
  126. data/lib/active_record/schema_dumper.rb +5 -1
  127. data/lib/active_record/schema_migration.rb +1 -1
  128. data/lib/active_record/scoping.rb +0 -1
  129. data/lib/active_record/scoping/default.rb +0 -1
  130. data/lib/active_record/scoping/named.rb +3 -3
  131. data/lib/active_record/store.rb +1 -1
  132. data/lib/active_record/suppressor.rb +2 -2
  133. data/lib/active_record/table_metadata.rb +21 -10
  134. data/lib/active_record/tasks/database_tasks.rb +76 -8
  135. data/lib/active_record/tasks/mysql_database_tasks.rb +3 -2
  136. data/lib/active_record/tasks/postgresql_database_tasks.rb +0 -1
  137. data/lib/active_record/tasks/sqlite_database_tasks.rb +0 -1
  138. data/lib/active_record/test_databases.rb +1 -16
  139. data/lib/active_record/test_fixtures.rb +2 -1
  140. data/lib/active_record/timestamp.rb +26 -17
  141. data/lib/active_record/touch_later.rb +3 -2
  142. data/lib/active_record/transactions.rb +18 -19
  143. data/lib/active_record/type.rb +0 -1
  144. data/lib/active_record/type/adapter_specific_registry.rb +2 -5
  145. data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
  146. data/lib/active_record/type/serialized.rb +0 -1
  147. data/lib/active_record/type/type_map.rb +0 -1
  148. data/lib/active_record/type/unsigned_integer.rb +0 -1
  149. data/lib/active_record/type_caster/connection.rb +16 -10
  150. data/lib/active_record/validations.rb +3 -3
  151. data/lib/active_record/validations/associated.rb +1 -2
  152. data/lib/arel.rb +17 -6
  153. data/lib/arel/predications.rb +5 -6
  154. data/lib/arel/visitors/depth_first.rb +1 -2
  155. data/lib/arel/visitors/dot.rb +0 -1
  156. data/lib/arel/visitors/mssql.rb +0 -1
  157. data/lib/arel/visitors/oracle.rb +1 -2
  158. data/lib/arel/visitors/oracle12.rb +0 -1
  159. data/lib/arel/visitors/postgresql.rb +0 -1
  160. data/lib/arel/visitors/sqlite.rb +0 -1
  161. data/lib/arel/visitors/to_sql.rb +23 -27
  162. data/lib/arel/visitors/visitor.rb +9 -6
  163. data/lib/arel/visitors/where_sql.rb +0 -1
  164. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  165. data/lib/rails/generators/active_record/migration.rb +0 -1
  166. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +1 -1
  167. data/lib/rails/generators/active_record/model/model_generator.rb +0 -1
  168. metadata +13 -9
@@ -5,7 +5,7 @@ module ActiveRecord
5
5
  module MySQL
6
6
  module DatabaseStatements
7
7
  # Returns an ActiveRecord::Result instance.
8
- def select_all(*) # :nodoc:
8
+ def select_all(*, **) # :nodoc:
9
9
  result = if ExplainRegistry.collect? && prepared_statements
10
10
  unprepared_statement { super }
11
11
  else
@@ -19,7 +19,9 @@ module ActiveRecord
19
19
  execute(sql, name).to_a
20
20
  end
21
21
 
22
- READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(:begin, :commit, :explain, :select, :set, :show, :release, :savepoint, :rollback) # :nodoc:
22
+ READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(
23
+ :begin, :commit, :explain, :select, :set, :show, :release, :savepoint, :rollback, :describe, :desc, :with
24
+ ) # :nodoc:
23
25
  private_constant :READ_QUERY
24
26
 
25
27
  def write_query?(sql) # :nodoc:
@@ -71,8 +73,10 @@ module ActiveRecord
71
73
  alias :exec_update :exec_delete
72
74
 
73
75
  private
74
- def execute_batch(sql, name = nil)
75
- super
76
+ def execute_batch(statements, name = nil)
77
+ combine_multi_statements(statements).each do |statement|
78
+ execute(statement, name)
79
+ end
76
80
  @connection.abandon_results!
77
81
  end
78
82
 
@@ -88,14 +92,6 @@ module ActiveRecord
88
92
  @connection.respond_to?(:set_server_option)
89
93
  end
90
94
 
91
- def build_truncate_statements(*table_names)
92
- if table_names.size == 1
93
- super.first
94
- else
95
- super
96
- end
97
- end
98
-
99
95
  def multi_statements_enabled?(flags)
100
96
  if flags.is_a?(Array)
101
97
  flags.include?("MULTI_STATEMENTS")
@@ -37,7 +37,6 @@ module ActiveRecord
37
37
  end
38
38
 
39
39
  private
40
-
41
40
  def compute_column_widths(result)
42
41
  [].tap do |widths|
43
42
  result.columns.each_with_index do |column, i|
@@ -5,11 +5,11 @@ module ActiveRecord
5
5
  module MySQL
6
6
  module Quoting # :nodoc:
7
7
  def quote_column_name(name)
8
- @quoted_column_names[name] ||= "`#{super.gsub('`', '``')}`"
8
+ self.class.quoted_column_names[name] ||= "`#{super.gsub('`', '``')}`"
9
9
  end
10
10
 
11
11
  def quote_table_name(name)
12
- @quoted_table_names[name] ||= super.gsub(".", "`.`").freeze
12
+ self.class.quoted_table_names[name] ||= super.gsub(".", "`.`").freeze
13
13
  end
14
14
 
15
15
  def unquoted_true
@@ -32,12 +32,49 @@ module ActiveRecord
32
32
  "x'#{value.hex}'"
33
33
  end
34
34
 
35
- def _type_cast(value)
36
- case value
37
- when Date, Time then value
38
- else super
39
- end
35
+ def column_name_matcher
36
+ COLUMN_NAME
37
+ end
38
+
39
+ def column_name_with_order_matcher
40
+ COLUMN_NAME_WITH_ORDER
40
41
  end
42
+
43
+ COLUMN_NAME = /
44
+ \A
45
+ (
46
+ (?:
47
+ # `table_name`.`column_name` | function(one or no argument)
48
+ ((?:\w+\.|`\w+`\.)?(?:\w+|`\w+`)) | \w+\((?:|\g<2>)\)
49
+ )
50
+ (?:\s+AS\s+(?:\w+|`\w+`))?
51
+ )
52
+ (?:\s*,\s*\g<1>)*
53
+ \z
54
+ /ix
55
+
56
+ COLUMN_NAME_WITH_ORDER = /
57
+ \A
58
+ (
59
+ (?:
60
+ # `table_name`.`column_name` | function(one or no argument)
61
+ ((?:\w+\.|`\w+`\.)?(?:\w+|`\w+`)) | \w+\((?:|\g<2>)\)
62
+ )
63
+ (?:\s+ASC|\s+DESC)?
64
+ )
65
+ (?:\s*,\s*\g<1>)*
66
+ \z
67
+ /ix
68
+
69
+ private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
70
+
71
+ private
72
+ def _type_cast(value)
73
+ case value
74
+ when Date, Time then value
75
+ else super
76
+ end
77
+ end
41
78
  end
42
79
  end
43
80
  end
@@ -7,7 +7,6 @@ module ActiveRecord
7
7
  delegate :add_sql_comment!, :mariadb?, to: :@conn, private: true
8
8
 
9
9
  private
10
-
11
10
  def visit_DropForeignKey(name)
12
11
  "DROP FOREIGN KEY #{name}"
13
12
  end
@@ -63,7 +62,7 @@ module ActiveRecord
63
62
  end
64
63
 
65
64
  def index_in_create(table_name, column_name, options)
66
- index_name, index_type, index_columns, _, _, index_using, comment = @conn.add_index_options(table_name, column_name, options)
65
+ index_name, index_type, index_columns, _, _, index_using, comment = @conn.add_index_options(table_name, column_name, **options)
67
66
  add_sql_comment!((+"#{index_type} INDEX #{quote_column_name(index_name)} #{index_using} (#{index_columns})"), comment)
68
67
  end
69
68
  end
@@ -41,13 +41,15 @@ module ActiveRecord
41
41
  case column.sql_type
42
42
  when /\Atimestamp\b/
43
43
  :timestamp
44
+ when /\A(?:enum|set)\b/
45
+ column.sql_type
44
46
  else
45
47
  super
46
48
  end
47
49
  end
48
50
 
49
51
  def schema_limit(column)
50
- super unless /\A(?:tiny|medium|long)?(?:text|blob)/.match?(column.sql_type)
52
+ super unless /\A(?:enum|set|(?:tiny|medium|long)?(?:text|blob))\b/.match?(column.sql_type)
51
53
  end
52
54
 
53
55
  def schema_precision(column)
@@ -51,26 +51,26 @@ module ActiveRecord
51
51
  end
52
52
 
53
53
  indexes.map do |index|
54
- options = index.last
54
+ options = index.pop
55
55
 
56
56
  if expressions = options.delete(:expressions)
57
57
  orders = options.delete(:orders)
58
58
  lengths = options.delete(:lengths)
59
59
 
60
- columns = index[-2].map { |name|
60
+ columns = index[-1].map { |name|
61
61
  [ name.to_sym, expressions[name] || +quote_column_name(name) ]
62
62
  }.to_h
63
63
 
64
- index[-2] = add_options_for_index_columns(
64
+ index[-1] = add_options_for_index_columns(
65
65
  columns, order: orders, length: lengths
66
66
  ).values.join(", ")
67
67
  end
68
68
 
69
- IndexDefinition.new(*index)
69
+ IndexDefinition.new(*index, **options)
70
70
  end
71
71
  end
72
72
 
73
- def remove_column(table_name, column_name, type = nil, options = {})
73
+ def remove_column(table_name, column_name, type = nil, **options)
74
74
  if foreign_key_exists?(table_name, column: column_name)
75
75
  remove_foreign_key(table_name, column: column_name)
76
76
  end
@@ -154,8 +154,8 @@ module ActiveRecord
154
154
  MySQL::SchemaCreation.new(self)
155
155
  end
156
156
 
157
- def create_table_definition(*args)
158
- MySQL::TableDefinition.new(self, *args)
157
+ def create_table_definition(*args, **options)
158
+ MySQL::TableDefinition.new(self, *args, **options)
159
159
  end
160
160
 
161
161
  def new_column_from_field(table_name, field)
@@ -196,7 +196,7 @@ module ActiveRecord
196
196
  end
197
197
 
198
198
  def add_options_for_index_columns(quoted_columns, **options)
199
- quoted_columns = add_index_length(quoted_columns, options)
199
+ quoted_columns = add_index_length(quoted_columns, **options)
200
200
  super
201
201
  end
202
202
 
@@ -8,6 +8,8 @@ require "mysql2"
8
8
 
9
9
  module ActiveRecord
10
10
  module ConnectionHandling # :nodoc:
11
+ ER_BAD_DB_ERROR = 1049
12
+
11
13
  # Establishes a connection to the database that's used by all Active Record objects.
12
14
  def mysql2_connection(config)
13
15
  config = config.symbolize_keys
@@ -22,7 +24,7 @@ module ActiveRecord
22
24
  client = Mysql2::Client.new(config)
23
25
  ConnectionAdapters::Mysql2Adapter.new(client, logger, nil, config)
24
26
  rescue Mysql2::Error => error
25
- if error.message.include?("Unknown database")
27
+ if error.error_number == ER_BAD_DB_ERROR
26
28
  raise ActiveRecord::NoDatabaseError
27
29
  else
28
30
  raise
@@ -37,11 +39,17 @@ module ActiveRecord
37
39
  include MySQL::DatabaseStatements
38
40
 
39
41
  def initialize(connection, logger, connection_options, config)
40
- super
41
- @prepared_statements = false unless config.key?(:prepared_statements)
42
+ superclass_config = config.reverse_merge(prepared_statements: false)
43
+ super(connection, logger, connection_options, superclass_config)
42
44
  configure_connection
43
45
  end
44
46
 
47
+ def self.database_exists?(config)
48
+ !!ActiveRecord::Base.mysql2_connection(config)
49
+ rescue ActiveRecord::NoDatabaseError
50
+ false
51
+ end
52
+
45
53
  def supports_json?
46
54
  !mariadb? && database_version >= "5.7.8"
47
55
  end
@@ -109,12 +117,12 @@ module ActiveRecord
109
117
  end
110
118
 
111
119
  def discard! # :nodoc:
120
+ super
112
121
  @connection.automatic_close = false
113
122
  @connection = nil
114
123
  end
115
124
 
116
125
  private
117
-
118
126
  def connect
119
127
  @connection = Mysql2::Client.new(@config)
120
128
  configure_connection
@@ -67,7 +67,9 @@ module ActiveRecord
67
67
  end
68
68
  end
69
69
 
70
- READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(:begin, :commit, :explain, :select, :set, :show, :release, :savepoint, :rollback) # :nodoc:
70
+ READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(
71
+ :begin, :commit, :explain, :select, :set, :show, :release, :savepoint, :rollback, :with
72
+ ) # :nodoc:
71
73
  private_constant :READ_QUERY
72
74
 
73
75
  def write_query?(sql) # :nodoc:
@@ -164,8 +166,12 @@ module ActiveRecord
164
166
  end
165
167
 
166
168
  private
167
- def build_truncate_statements(*table_names)
168
- "TRUNCATE TABLE #{table_names.map(&method(:quote_table_name)).join(", ")}"
169
+ def execute_batch(statements, name = nil)
170
+ execute(combine_multi_statements(statements))
171
+ end
172
+
173
+ def build_truncate_statements(table_names)
174
+ ["TRUNCATE TABLE #{table_names.map(&method(:quote_table_name)).join(", ")}"]
169
175
  end
170
176
 
171
177
  # Returns the current ID of a table's sequence.
@@ -77,7 +77,6 @@ module ActiveRecord
77
77
  end
78
78
 
79
79
  private
80
-
81
80
  def type_cast_array(value, method)
82
81
  if value.is_a?(::Array)
83
82
  value.map { |item| type_cast_array(item, method) }
@@ -10,7 +10,6 @@ module ActiveRecord
10
10
  end
11
11
 
12
12
  private
13
-
14
13
  def cast_value(value)
15
14
  value.to_s
16
15
  end
@@ -46,7 +46,6 @@ module ActiveRecord
46
46
  end
47
47
 
48
48
  private
49
-
50
49
  HstorePair = begin
51
50
  quoted_string = /"[^"\\]*(?:\\.[^"\\]*)*"/
52
51
  unquoted_string = /(?:\\.|[^\s,])[^\s=,\\]*(?:\\.[^\s=,\\]*|=[^,>])*/
@@ -34,7 +34,6 @@ module ActiveRecord
34
34
  end
35
35
 
36
36
  private
37
-
38
37
  def number_for_point(number)
39
38
  number.to_s.gsub(/\.0$/, "")
40
39
  end
@@ -26,9 +26,9 @@ module ActiveRecord
26
26
 
27
27
  value = value.sub(/^\((.+)\)$/, '-\1') # (4)
28
28
  case value
29
- when /^-?\D+[\d,]+\.\d{2}$/ # (1)
29
+ when /^-?\D*[\d,]+\.\d{2}$/ # (1)
30
30
  value.gsub!(/[^-\d.]/, "")
31
- when /^-?\D+[\d.]+,\d{2}$/ # (2)
31
+ when /^-?\D*[\d.]+,\d{2}$/ # (2)
32
32
  value.gsub!(/[^-\d,]/, "").sub!(/,/, ".")
33
33
  end
34
34
 
@@ -4,7 +4,7 @@ module ActiveRecord
4
4
  module ConnectionAdapters
5
5
  module PostgreSQL
6
6
  module OID # :nodoc:
7
- class Oid < Type::Integer # :nodoc:
7
+ class Oid < Type::UnsignedInteger # :nodoc:
8
8
  def type
9
9
  :oid
10
10
  end
@@ -50,7 +50,6 @@ module ActiveRecord
50
50
  end
51
51
 
52
52
  private
53
-
54
53
  def number_for_point(number)
55
54
  number.to_s.gsub(/\.0$/, "")
56
55
  end
@@ -58,7 +58,6 @@ module ActiveRecord
58
58
  end
59
59
 
60
60
  private
61
-
62
61
  def type_cast_single(value)
63
62
  infinity?(value) ? value : @subtype.deserialize(value)
64
63
  end
@@ -9,7 +9,7 @@ module ActiveRecord
9
9
 
10
10
  def initialize(type, **options)
11
11
  @type = type
12
- super(options)
12
+ super(**options)
13
13
  end
14
14
  end
15
15
  end
@@ -14,7 +14,6 @@ module ActiveRecord
14
14
  end
15
15
 
16
16
  private
17
-
18
17
  def cast_value(value)
19
18
  casted = value.to_s
20
19
  casted if casted.match?(ACCEPTABLE_UUID)
@@ -30,7 +30,7 @@ module ActiveRecord
30
30
  # - "schema.name".table_name
31
31
  # - "schema.name"."table.name"
32
32
  def quote_table_name(name) # :nodoc:
33
- @quoted_table_names[name] ||= Utils.extract_schema_qualified_name(name.to_s).quoted.freeze
33
+ self.class.quoted_table_names[name] ||= Utils.extract_schema_qualified_name(name.to_s).quoted.freeze
34
34
  end
35
35
 
36
36
  # Quotes schema names for use in SQL queries.
@@ -44,7 +44,7 @@ module ActiveRecord
44
44
 
45
45
  # Quotes column names for use in SQL queries.
46
46
  def quote_column_name(name) # :nodoc:
47
- @quoted_column_names[name] ||= PG::Connection.quote_ident(super).freeze
47
+ self.class.quoted_column_names[name] ||= PG::Connection.quote_ident(super).freeze
48
48
  end
49
49
 
50
50
  # Quote date/time values for use in SQL input.
@@ -78,6 +78,43 @@ module ActiveRecord
78
78
  type_map.lookup(column.oid, column.fmod, column.sql_type)
79
79
  end
80
80
 
81
+ def column_name_matcher
82
+ COLUMN_NAME
83
+ end
84
+
85
+ def column_name_with_order_matcher
86
+ COLUMN_NAME_WITH_ORDER
87
+ end
88
+
89
+ COLUMN_NAME = /
90
+ \A
91
+ (
92
+ (?:
93
+ # "table_name"."column_name"::type_name | function(one or no argument)::type_name
94
+ ((?:\w+\.|"\w+"\.)?(?:\w+|"\w+")(?:::\w+)?) | \w+\((?:|\g<2>)\)(?:::\w+)?
95
+ )
96
+ (?:\s+AS\s+(?:\w+|"\w+"))?
97
+ )
98
+ (?:\s*,\s*\g<1>)*
99
+ \z
100
+ /ix
101
+
102
+ COLUMN_NAME_WITH_ORDER = /
103
+ \A
104
+ (
105
+ (?:
106
+ # "table_name"."column_name"::type_name | function(one or no argument)::type_name
107
+ ((?:\w+\.|"\w+"\.)?(?:\w+|"\w+")(?:::\w+)?) | \w+\((?:|\g<2>)\)(?:::\w+)?
108
+ )
109
+ (?:\s+ASC|\s+DESC)?
110
+ (?:\s+NULLS\s+(?:FIRST|LAST))?
111
+ )
112
+ (?:\s*,\s*\g<1>)*
113
+ \z
114
+ /ix
115
+
116
+ private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
117
+
81
118
  private
82
119
  def lookup_cast_type(sql_type)
83
120
  super(query_value("SELECT #{quote(sql_type)}::regtype::oid", "SCHEMA").to_i)
@@ -26,7 +26,7 @@ Rails needs superuser privileges to disable referential integrity.
26
26
 
27
27
  cause: #{original_exception.try(:message)}
28
28
 
29
- WARNING
29
+ WARNING
30
30
  raise e
31
31
  end
32
32