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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +251 -3
- data/README.rdoc +1 -1
- data/lib/active_record.rb +1 -0
- data/lib/active_record/advisory_lock_base.rb +18 -0
- data/lib/active_record/aggregations.rb +0 -1
- data/lib/active_record/association_relation.rb +10 -8
- data/lib/active_record/associations.rb +2 -2
- data/lib/active_record/associations/alias_tracker.rb +0 -1
- data/lib/active_record/associations/association.rb +5 -1
- data/lib/active_record/associations/builder/collection_association.rb +2 -2
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -3
- data/lib/active_record/associations/collection_association.rb +6 -2
- data/lib/active_record/associations/collection_proxy.rb +2 -3
- data/lib/active_record/associations/has_many_association.rb +0 -1
- data/lib/active_record/associations/join_dependency.rb +23 -9
- data/lib/active_record/associations/join_dependency/join_association.rb +12 -3
- data/lib/active_record/associations/preloader.rb +2 -3
- data/lib/active_record/associations/preloader/association.rb +3 -1
- data/lib/active_record/attribute_assignment.rb +0 -1
- data/lib/active_record/attribute_decorators.rb +0 -2
- data/lib/active_record/attribute_methods.rb +0 -51
- data/lib/active_record/attribute_methods/before_type_cast.rb +0 -1
- data/lib/active_record/attribute_methods/dirty.rb +8 -3
- data/lib/active_record/attribute_methods/primary_key.rb +0 -2
- data/lib/active_record/attribute_methods/read.rb +0 -1
- data/lib/active_record/attribute_methods/serialization.rb +0 -1
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +0 -2
- data/lib/active_record/attribute_methods/write.rb +0 -1
- data/lib/active_record/attributes.rb +0 -1
- data/lib/active_record/autosave_association.rb +11 -7
- data/lib/active_record/callbacks.rb +1 -2
- data/lib/active_record/coders/yaml_column.rb +0 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +107 -13
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +21 -15
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +5 -5
- data/lib/active_record/connection_adapters/abstract/quoting.rb +53 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +1 -2
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +27 -27
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +55 -37
- data/lib/active_record/connection_adapters/abstract/transaction.rb +14 -7
- data/lib/active_record/connection_adapters/abstract_adapter.rb +62 -25
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +25 -32
- data/lib/active_record/connection_adapters/connection_specification.rb +3 -4
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -2
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +8 -12
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +0 -1
- data/lib/active_record/connection_adapters/mysql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +1 -2
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +3 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +8 -8
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -4
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +9 -3
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +39 -2
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +15 -29
- data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +17 -3
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +8 -7
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +38 -3
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +3 -3
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +23 -8
- data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
- data/lib/active_record/connection_handling.rb +17 -22
- data/lib/active_record/core.rb +8 -6
- data/lib/active_record/counter_cache.rb +4 -1
- data/lib/active_record/database_configurations.rb +60 -31
- data/lib/active_record/database_configurations/url_config.rb +0 -1
- data/lib/active_record/dynamic_matchers.rb +2 -3
- data/lib/active_record/enum.rb +9 -0
- data/lib/active_record/explain.rb +0 -1
- data/lib/active_record/fixture_set/table_row.rb +0 -1
- data/lib/active_record/fixture_set/table_rows.rb +0 -1
- data/lib/active_record/fixtures.rb +11 -9
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/inheritance.rb +0 -3
- data/lib/active_record/insert_all.rb +5 -6
- data/lib/active_record/internal_metadata.rb +1 -1
- data/lib/active_record/locking/optimistic.rb +0 -1
- data/lib/active_record/log_subscriber.rb +1 -1
- data/lib/active_record/middleware/database_selector.rb +3 -4
- data/lib/active_record/middleware/database_selector/resolver.rb +5 -8
- data/lib/active_record/migration.rb +43 -32
- data/lib/active_record/migration/command_recorder.rb +6 -18
- data/lib/active_record/migration/compatibility.rb +3 -3
- data/lib/active_record/migration/join_table.rb +0 -1
- data/lib/active_record/model_schema.rb +3 -2
- data/lib/active_record/nested_attributes.rb +0 -2
- data/lib/active_record/no_touching.rb +2 -2
- data/lib/active_record/null_relation.rb +0 -1
- data/lib/active_record/persistence.rb +4 -5
- data/lib/active_record/querying.rb +1 -1
- data/lib/active_record/railtie.rb +1 -2
- data/lib/active_record/railties/collection_cache_association_loading.rb +1 -1
- data/lib/active_record/railties/databases.rake +63 -23
- data/lib/active_record/reflection.rb +9 -9
- data/lib/active_record/relation.rb +13 -1
- data/lib/active_record/relation/batches.rb +0 -1
- data/lib/active_record/relation/calculations.rb +3 -5
- data/lib/active_record/relation/delegation.rb +7 -6
- data/lib/active_record/relation/finder_methods.rb +14 -4
- data/lib/active_record/relation/from_clause.rb +4 -0
- data/lib/active_record/relation/merger.rb +6 -3
- data/lib/active_record/relation/predicate_builder.rb +1 -5
- data/lib/active_record/relation/query_methods.rb +94 -55
- data/lib/active_record/relation/spawn_methods.rb +0 -1
- data/lib/active_record/relation/where_clause.rb +0 -1
- data/lib/active_record/result.rb +0 -1
- data/lib/active_record/sanitization.rb +30 -2
- data/lib/active_record/schema.rb +1 -1
- data/lib/active_record/schema_dumper.rb +5 -1
- data/lib/active_record/schema_migration.rb +1 -1
- data/lib/active_record/scoping.rb +0 -1
- data/lib/active_record/scoping/default.rb +0 -1
- data/lib/active_record/scoping/named.rb +3 -3
- data/lib/active_record/store.rb +1 -1
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +21 -10
- data/lib/active_record/tasks/database_tasks.rb +76 -8
- data/lib/active_record/tasks/mysql_database_tasks.rb +3 -2
- data/lib/active_record/tasks/postgresql_database_tasks.rb +0 -1
- data/lib/active_record/tasks/sqlite_database_tasks.rb +0 -1
- data/lib/active_record/test_databases.rb +1 -16
- data/lib/active_record/test_fixtures.rb +2 -1
- data/lib/active_record/timestamp.rb +26 -17
- data/lib/active_record/touch_later.rb +3 -2
- data/lib/active_record/transactions.rb +18 -19
- data/lib/active_record/type.rb +0 -1
- data/lib/active_record/type/adapter_specific_registry.rb +2 -5
- data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
- data/lib/active_record/type/serialized.rb +0 -1
- data/lib/active_record/type/type_map.rb +0 -1
- data/lib/active_record/type/unsigned_integer.rb +0 -1
- data/lib/active_record/type_caster/connection.rb +16 -10
- data/lib/active_record/validations.rb +3 -3
- data/lib/active_record/validations/associated.rb +1 -2
- data/lib/arel.rb +17 -6
- data/lib/arel/predications.rb +5 -6
- data/lib/arel/visitors/depth_first.rb +1 -2
- data/lib/arel/visitors/dot.rb +0 -1
- data/lib/arel/visitors/mssql.rb +0 -1
- data/lib/arel/visitors/oracle.rb +1 -2
- data/lib/arel/visitors/oracle12.rb +0 -1
- data/lib/arel/visitors/postgresql.rb +0 -1
- data/lib/arel/visitors/sqlite.rb +0 -1
- data/lib/arel/visitors/to_sql.rb +23 -27
- data/lib/arel/visitors/visitor.rb +9 -6
- data/lib/arel/visitors/where_sql.rb +0 -1
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
- data/lib/rails/generators/active_record/migration.rb +0 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +0 -1
- 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(
|
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(
|
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(
|
75
|
-
|
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")
|
@@ -5,11 +5,11 @@ module ActiveRecord
|
|
5
5
|
module MySQL
|
6
6
|
module Quoting # :nodoc:
|
7
7
|
def quote_column_name(name)
|
8
|
-
|
8
|
+
self.class.quoted_column_names[name] ||= "`#{super.gsub('`', '``')}`"
|
9
9
|
end
|
10
10
|
|
11
11
|
def quote_table_name(name)
|
12
|
-
|
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
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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.
|
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[-
|
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[-
|
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.
|
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
|
-
|
41
|
-
|
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(
|
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
|
168
|
-
|
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.
|
@@ -26,9 +26,9 @@ module ActiveRecord
|
|
26
26
|
|
27
27
|
value = value.sub(/^\((.+)\)$/, '-\1') # (4)
|
28
28
|
case value
|
29
|
-
when /^-?\D
|
29
|
+
when /^-?\D*[\d,]+\.\d{2}$/ # (1)
|
30
30
|
value.gsub!(/[^-\d.]/, "")
|
31
|
-
when /^-?\D
|
31
|
+
when /^-?\D*[\d.]+,\d{2}$/ # (2)
|
32
32
|
value.gsub!(/[^-\d,]/, "").sub!(/,/, ".")
|
33
33
|
end
|
34
34
|
|
@@ -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
|
-
|
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
|
-
|
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)
|