activerecord 5.2.5 → 6.0.4.6
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 +913 -549
- data/MIT-LICENSE +3 -1
- data/README.rdoc +5 -3
- data/examples/performance.rb +1 -1
- data/lib/active_record/advisory_lock_base.rb +18 -0
- data/lib/active_record/aggregations.rb +4 -3
- data/lib/active_record/association_relation.rb +10 -8
- data/lib/active_record/associations/alias_tracker.rb +0 -1
- data/lib/active_record/associations/association.rb +55 -19
- data/lib/active_record/associations/association_scope.rb +11 -7
- data/lib/active_record/associations/belongs_to_association.rb +36 -42
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +0 -4
- data/lib/active_record/associations/builder/association.rb +14 -18
- data/lib/active_record/associations/builder/belongs_to.rb +19 -52
- data/lib/active_record/associations/builder/collection_association.rb +3 -13
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -40
- data/lib/active_record/associations/builder/has_many.rb +2 -0
- data/lib/active_record/associations/builder/has_one.rb +35 -1
- data/lib/active_record/associations/builder/singular_association.rb +2 -0
- data/lib/active_record/associations/collection_association.rb +19 -23
- data/lib/active_record/associations/collection_proxy.rb +14 -17
- data/lib/active_record/associations/foreign_association.rb +7 -0
- data/lib/active_record/associations/has_many_association.rb +2 -11
- data/lib/active_record/associations/has_many_through_association.rb +14 -14
- data/lib/active_record/associations/has_one_association.rb +28 -30
- data/lib/active_record/associations/has_one_through_association.rb +5 -5
- data/lib/active_record/associations/join_dependency/join_association.rb +16 -10
- data/lib/active_record/associations/join_dependency/join_part.rb +4 -4
- data/lib/active_record/associations/join_dependency.rb +47 -30
- data/lib/active_record/associations/preloader/association.rb +61 -41
- data/lib/active_record/associations/preloader/through_association.rb +48 -39
- data/lib/active_record/associations/preloader.rb +44 -33
- data/lib/active_record/associations/singular_association.rb +2 -16
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +21 -16
- data/lib/active_record/attribute_assignment.rb +7 -11
- data/lib/active_record/attribute_decorators.rb +0 -2
- data/lib/active_record/attribute_methods/before_type_cast.rb +4 -2
- data/lib/active_record/attribute_methods/dirty.rb +111 -40
- data/lib/active_record/attribute_methods/primary_key.rb +15 -24
- data/lib/active_record/attribute_methods/query.rb +2 -3
- data/lib/active_record/attribute_methods/read.rb +15 -54
- data/lib/active_record/attribute_methods/serialization.rb +1 -2
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -3
- data/lib/active_record/attribute_methods/write.rb +17 -25
- data/lib/active_record/attribute_methods.rb +28 -100
- data/lib/active_record/attributes.rb +13 -1
- data/lib/active_record/autosave_association.rb +12 -14
- data/lib/active_record/base.rb +2 -3
- data/lib/active_record/callbacks.rb +6 -21
- data/lib/active_record/coders/yaml_column.rb +0 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +109 -18
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -4
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +102 -124
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +18 -9
- data/lib/active_record/connection_adapters/abstract/quoting.rb +68 -17
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +20 -14
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +105 -72
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +1 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +175 -79
- data/lib/active_record/connection_adapters/abstract/transaction.rb +96 -57
- data/lib/active_record/connection_adapters/abstract_adapter.rb +197 -43
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +149 -217
- data/lib/active_record/connection_adapters/column.rb +17 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +54 -45
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +6 -10
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +70 -14
- 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 +4 -6
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +40 -32
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +14 -6
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +139 -19
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +6 -10
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +26 -10
- data/lib/active_record/connection_adapters/postgresql/column.rb +17 -31
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +26 -1
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +44 -7
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +14 -3
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +63 -75
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +24 -27
- data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +168 -75
- data/lib/active_record/connection_adapters/schema_cache.rb +37 -14
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +11 -8
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +43 -12
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +137 -147
- data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
- data/lib/active_record/connection_handling.rb +139 -26
- data/lib/active_record/core.rb +107 -66
- data/lib/active_record/counter_cache.rb +8 -30
- data/lib/active_record/database_configurations/database_config.rb +37 -0
- data/lib/active_record/database_configurations/hash_config.rb +50 -0
- data/lib/active_record/database_configurations/url_config.rb +78 -0
- data/lib/active_record/database_configurations.rb +233 -0
- data/lib/active_record/dynamic_matchers.rb +3 -4
- data/lib/active_record/enum.rb +44 -7
- data/lib/active_record/errors.rb +15 -7
- data/lib/active_record/explain.rb +1 -2
- data/lib/active_record/fixture_set/model_metadata.rb +33 -0
- data/lib/active_record/fixture_set/render_context.rb +17 -0
- data/lib/active_record/fixture_set/table_row.rb +152 -0
- data/lib/active_record/fixture_set/table_rows.rb +46 -0
- data/lib/active_record/fixtures.rb +144 -474
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +13 -6
- data/lib/active_record/insert_all.rb +179 -0
- data/lib/active_record/integration.rb +68 -16
- data/lib/active_record/internal_metadata.rb +11 -3
- data/lib/active_record/locking/optimistic.rb +14 -7
- data/lib/active_record/locking/pessimistic.rb +3 -3
- data/lib/active_record/log_subscriber.rb +8 -27
- data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
- data/lib/active_record/middleware/database_selector.rb +74 -0
- data/lib/active_record/migration/command_recorder.rb +54 -22
- data/lib/active_record/migration/compatibility.rb +79 -52
- data/lib/active_record/migration/join_table.rb +0 -1
- data/lib/active_record/migration.rb +104 -85
- data/lib/active_record/model_schema.rb +62 -11
- data/lib/active_record/nested_attributes.rb +2 -4
- data/lib/active_record/no_touching.rb +9 -2
- data/lib/active_record/null_relation.rb +0 -1
- data/lib/active_record/persistence.rb +232 -29
- data/lib/active_record/query_cache.rb +11 -4
- data/lib/active_record/querying.rb +33 -21
- data/lib/active_record/railtie.rb +80 -43
- data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
- data/lib/active_record/railties/controller_runtime.rb +30 -35
- data/lib/active_record/railties/databases.rake +199 -46
- data/lib/active_record/reflection.rb +51 -51
- data/lib/active_record/relation/batches.rb +13 -11
- data/lib/active_record/relation/calculations.rb +55 -49
- data/lib/active_record/relation/delegation.rb +35 -50
- data/lib/active_record/relation/finder_methods.rb +23 -28
- data/lib/active_record/relation/from_clause.rb +4 -0
- data/lib/active_record/relation/merger.rb +12 -17
- data/lib/active_record/relation/predicate_builder/array_handler.rb +5 -4
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +1 -4
- data/lib/active_record/relation/predicate_builder/base_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -4
- data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
- data/lib/active_record/relation/predicate_builder.rb +5 -11
- data/lib/active_record/relation/query_attribute.rb +13 -8
- data/lib/active_record/relation/query_methods.rb +232 -69
- data/lib/active_record/relation/spawn_methods.rb +1 -2
- data/lib/active_record/relation/where_clause.rb +14 -11
- data/lib/active_record/relation/where_clause_factory.rb +1 -2
- data/lib/active_record/relation.rb +326 -81
- data/lib/active_record/result.rb +30 -12
- data/lib/active_record/sanitization.rb +32 -40
- data/lib/active_record/schema.rb +2 -11
- data/lib/active_record/schema_dumper.rb +22 -7
- data/lib/active_record/schema_migration.rb +6 -2
- data/lib/active_record/scoping/default.rb +4 -6
- data/lib/active_record/scoping/named.rb +25 -16
- data/lib/active_record/scoping.rb +8 -9
- data/lib/active_record/statement_cache.rb +30 -3
- data/lib/active_record/store.rb +87 -8
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +23 -15
- data/lib/active_record/tasks/database_tasks.rb +194 -25
- data/lib/active_record/tasks/mysql_database_tasks.rb +5 -6
- data/lib/active_record/tasks/postgresql_database_tasks.rb +5 -8
- data/lib/active_record/tasks/sqlite_database_tasks.rb +2 -9
- data/lib/active_record/test_databases.rb +23 -0
- data/lib/active_record/test_fixtures.rb +243 -0
- data/lib/active_record/timestamp.rb +39 -26
- data/lib/active_record/touch_later.rb +5 -4
- data/lib/active_record/transactions.rb +64 -73
- data/lib/active_record/translation.rb +1 -1
- data/lib/active_record/type/adapter_specific_registry.rb +3 -13
- 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/time.rb +10 -0
- 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.rb +3 -5
- data/lib/active_record/type_caster/connection.rb +15 -14
- data/lib/active_record/type_caster/map.rb +1 -4
- data/lib/active_record/validations/associated.rb +0 -1
- data/lib/active_record/validations/uniqueness.rb +15 -27
- data/lib/active_record/validations.rb +3 -3
- data/lib/active_record.rb +10 -2
- data/lib/arel/alias_predication.rb +9 -0
- data/lib/arel/attributes/attribute.rb +37 -0
- data/lib/arel/attributes.rb +22 -0
- data/lib/arel/collectors/bind.rb +24 -0
- data/lib/arel/collectors/composite.rb +31 -0
- data/lib/arel/collectors/plain_string.rb +20 -0
- data/lib/arel/collectors/sql_string.rb +20 -0
- data/lib/arel/collectors/substitute_binds.rb +28 -0
- data/lib/arel/crud.rb +42 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/errors.rb +9 -0
- data/lib/arel/expressions.rb +29 -0
- data/lib/arel/factory_methods.rb +49 -0
- data/lib/arel/insert_manager.rb +49 -0
- data/lib/arel/math.rb +45 -0
- data/lib/arel/nodes/and.rb +32 -0
- data/lib/arel/nodes/ascending.rb +23 -0
- data/lib/arel/nodes/binary.rb +52 -0
- data/lib/arel/nodes/bind_param.rb +36 -0
- data/lib/arel/nodes/case.rb +55 -0
- data/lib/arel/nodes/casted.rb +50 -0
- data/lib/arel/nodes/comment.rb +29 -0
- data/lib/arel/nodes/count.rb +12 -0
- data/lib/arel/nodes/delete_statement.rb +45 -0
- data/lib/arel/nodes/descending.rb +23 -0
- data/lib/arel/nodes/equality.rb +18 -0
- data/lib/arel/nodes/extract.rb +24 -0
- data/lib/arel/nodes/false.rb +16 -0
- data/lib/arel/nodes/full_outer_join.rb +8 -0
- data/lib/arel/nodes/function.rb +44 -0
- data/lib/arel/nodes/grouping.rb +8 -0
- data/lib/arel/nodes/in.rb +8 -0
- data/lib/arel/nodes/infix_operation.rb +80 -0
- data/lib/arel/nodes/inner_join.rb +8 -0
- data/lib/arel/nodes/insert_statement.rb +37 -0
- data/lib/arel/nodes/join_source.rb +20 -0
- data/lib/arel/nodes/matches.rb +18 -0
- data/lib/arel/nodes/named_function.rb +23 -0
- data/lib/arel/nodes/node.rb +50 -0
- data/lib/arel/nodes/node_expression.rb +13 -0
- data/lib/arel/nodes/outer_join.rb +8 -0
- data/lib/arel/nodes/over.rb +15 -0
- data/lib/arel/nodes/regexp.rb +16 -0
- data/lib/arel/nodes/right_outer_join.rb +8 -0
- data/lib/arel/nodes/select_core.rb +67 -0
- data/lib/arel/nodes/select_statement.rb +41 -0
- data/lib/arel/nodes/sql_literal.rb +16 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/table_alias.rb +27 -0
- data/lib/arel/nodes/terminal.rb +16 -0
- data/lib/arel/nodes/true.rb +16 -0
- data/lib/arel/nodes/unary.rb +45 -0
- data/lib/arel/nodes/unary_operation.rb +20 -0
- data/lib/arel/nodes/unqualified_column.rb +22 -0
- data/lib/arel/nodes/update_statement.rb +41 -0
- data/lib/arel/nodes/values_list.rb +9 -0
- data/lib/arel/nodes/window.rb +126 -0
- data/lib/arel/nodes/with.rb +11 -0
- data/lib/arel/nodes.rb +68 -0
- data/lib/arel/order_predications.rb +13 -0
- data/lib/arel/predications.rb +256 -0
- data/lib/arel/select_manager.rb +271 -0
- data/lib/arel/table.rb +110 -0
- data/lib/arel/tree_manager.rb +72 -0
- data/lib/arel/update_manager.rb +34 -0
- data/lib/arel/visitors/depth_first.rb +203 -0
- data/lib/arel/visitors/dot.rb +296 -0
- data/lib/arel/visitors/ibm_db.rb +34 -0
- data/lib/arel/visitors/informix.rb +62 -0
- data/lib/arel/visitors/mssql.rb +156 -0
- data/lib/arel/visitors/mysql.rb +83 -0
- data/lib/arel/visitors/oracle.rb +158 -0
- data/lib/arel/visitors/oracle12.rb +65 -0
- data/lib/arel/visitors/postgresql.rb +109 -0
- data/lib/arel/visitors/sqlite.rb +38 -0
- data/lib/arel/visitors/to_sql.rb +888 -0
- data/lib/arel/visitors/visitor.rb +45 -0
- data/lib/arel/visitors/where_sql.rb +22 -0
- data/lib/arel/visitors.rb +20 -0
- data/lib/arel/window_predications.rb +9 -0
- data/lib/arel.rb +62 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
- data/lib/rails/generators/active_record/migration/migration_generator.rb +2 -5
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +1 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -2
- data/lib/rails/generators/active_record/migration.rb +14 -2
- data/lib/rails/generators/active_record/model/model_generator.rb +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
- metadata +115 -29
- data/lib/active_record/collection_cache_key.rb +0 -53
@@ -11,8 +11,6 @@ require "active_record/connection_adapters/mysql/schema_dumper"
|
|
11
11
|
require "active_record/connection_adapters/mysql/schema_statements"
|
12
12
|
require "active_record/connection_adapters/mysql/type_metadata"
|
13
13
|
|
14
|
-
require "active_support/core_ext/string/strip"
|
15
|
-
|
16
14
|
module ActiveRecord
|
17
15
|
module ConnectionAdapters
|
18
16
|
class AbstractMysqlAdapter < AbstractAdapter
|
@@ -31,7 +29,7 @@ module ActiveRecord
|
|
31
29
|
NATIVE_DATABASE_TYPES = {
|
32
30
|
primary_key: "bigint auto_increment PRIMARY KEY",
|
33
31
|
string: { name: "varchar", limit: 255 },
|
34
|
-
text: { name: "text"
|
32
|
+
text: { name: "text" },
|
35
33
|
integer: { name: "int", limit: 4 },
|
36
34
|
float: { name: "float", limit: 24 },
|
37
35
|
decimal: { name: "decimal" },
|
@@ -39,41 +37,43 @@ module ActiveRecord
|
|
39
37
|
timestamp: { name: "timestamp" },
|
40
38
|
time: { name: "time" },
|
41
39
|
date: { name: "date" },
|
42
|
-
binary: { name: "blob"
|
40
|
+
binary: { name: "blob" },
|
41
|
+
blob: { name: "blob" },
|
43
42
|
boolean: { name: "tinyint", limit: 1 },
|
44
43
|
json: { name: "json" },
|
45
44
|
}
|
46
45
|
|
47
46
|
class StatementPool < ConnectionAdapters::StatementPool # :nodoc:
|
48
|
-
private
|
49
|
-
stmt
|
50
|
-
|
47
|
+
private
|
48
|
+
def dealloc(stmt)
|
49
|
+
stmt.close
|
50
|
+
end
|
51
51
|
end
|
52
52
|
|
53
53
|
def initialize(connection, logger, connection_options, config)
|
54
54
|
super(connection, logger, config)
|
55
|
-
|
56
|
-
@statements = StatementPool.new(self.class.type_cast_config_to_integer(config[:statement_limit]))
|
57
|
-
|
58
|
-
if version < "5.1.10"
|
59
|
-
raise "Your version of MySQL (#{version_string}) is too old. Active Record supports MySQL >= 5.1.10."
|
60
|
-
end
|
61
55
|
end
|
62
56
|
|
63
|
-
def
|
64
|
-
|
57
|
+
def get_database_version #:nodoc:
|
58
|
+
full_version_string = get_full_version
|
59
|
+
version_string = version_string(full_version_string)
|
60
|
+
Version.new(version_string, full_version_string)
|
65
61
|
end
|
66
62
|
|
67
63
|
def mariadb? # :nodoc:
|
68
64
|
/mariadb/i.match?(full_version)
|
69
65
|
end
|
70
66
|
|
71
|
-
def supports_bulk_alter?
|
67
|
+
def supports_bulk_alter?
|
72
68
|
true
|
73
69
|
end
|
74
70
|
|
75
71
|
def supports_index_sort_order?
|
76
|
-
!mariadb? &&
|
72
|
+
!mariadb? && database_version >= "8.0.1"
|
73
|
+
end
|
74
|
+
|
75
|
+
def supports_expression_index?
|
76
|
+
!mariadb? && database_version >= "8.0.13"
|
77
77
|
end
|
78
78
|
|
79
79
|
def supports_transaction_isolation?
|
@@ -97,18 +97,23 @@ module ActiveRecord
|
|
97
97
|
end
|
98
98
|
|
99
99
|
def supports_datetime_with_precision?
|
100
|
-
|
101
|
-
version >= "5.3.0"
|
102
|
-
else
|
103
|
-
version >= "5.6.4"
|
104
|
-
end
|
100
|
+
mariadb? || database_version >= "5.6.4"
|
105
101
|
end
|
106
102
|
|
107
103
|
def supports_virtual_columns?
|
104
|
+
mariadb? || database_version >= "5.7.5"
|
105
|
+
end
|
106
|
+
|
107
|
+
# See https://dev.mysql.com/doc/refman/8.0/en/optimizer-hints.html for more details.
|
108
|
+
def supports_optimizer_hints?
|
109
|
+
!mariadb? && database_version >= "5.7.7"
|
110
|
+
end
|
111
|
+
|
112
|
+
def supports_common_table_expressions?
|
108
113
|
if mariadb?
|
109
|
-
|
114
|
+
database_version >= "10.2.1"
|
110
115
|
else
|
111
|
-
|
116
|
+
database_version >= "8.0.1"
|
112
117
|
end
|
113
118
|
end
|
114
119
|
|
@@ -116,6 +121,14 @@ module ActiveRecord
|
|
116
121
|
true
|
117
122
|
end
|
118
123
|
|
124
|
+
def supports_insert_on_duplicate_skip?
|
125
|
+
true
|
126
|
+
end
|
127
|
+
|
128
|
+
def supports_insert_on_duplicate_update?
|
129
|
+
true
|
130
|
+
end
|
131
|
+
|
119
132
|
def get_advisory_lock(lock_name, timeout = 0) # :nodoc:
|
120
133
|
query_value("SELECT GET_LOCK(#{quote(lock_name.to_s)}, #{timeout})") == 1
|
121
134
|
end
|
@@ -129,7 +142,7 @@ module ActiveRecord
|
|
129
142
|
end
|
130
143
|
|
131
144
|
def index_algorithms
|
132
|
-
{ default: "ALGORITHM = DEFAULT"
|
145
|
+
{ default: +"ALGORITHM = DEFAULT", copy: +"ALGORITHM = COPY", inplace: +"ALGORITHM = INPLACE" }
|
133
146
|
end
|
134
147
|
|
135
148
|
# HELPER METHODS ===========================================
|
@@ -161,10 +174,9 @@ module ActiveRecord
|
|
161
174
|
|
162
175
|
# CONNECTION MANAGEMENT ====================================
|
163
176
|
|
164
|
-
|
165
|
-
def clear_cache!
|
177
|
+
def clear_cache! # :nodoc:
|
166
178
|
reload_type_map
|
167
|
-
|
179
|
+
super
|
168
180
|
end
|
169
181
|
|
170
182
|
#--
|
@@ -173,15 +185,17 @@ module ActiveRecord
|
|
173
185
|
|
174
186
|
def explain(arel, binds = [])
|
175
187
|
sql = "EXPLAIN #{to_sql(arel, binds)}"
|
176
|
-
start =
|
188
|
+
start = Concurrent.monotonic_time
|
177
189
|
result = exec_query(sql, "EXPLAIN", binds)
|
178
|
-
elapsed =
|
190
|
+
elapsed = Concurrent.monotonic_time - start
|
179
191
|
|
180
192
|
MySQL::ExplainPrettyPrinter.new.pp(result, elapsed)
|
181
193
|
end
|
182
194
|
|
183
195
|
# Executes the SQL statement in the context of this connection.
|
184
196
|
def execute(sql, name = nil)
|
197
|
+
materialize_transactions
|
198
|
+
|
185
199
|
log(sql, name) do
|
186
200
|
ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
|
187
201
|
@connection.query(sql)
|
@@ -213,19 +227,7 @@ module ActiveRecord
|
|
213
227
|
execute "ROLLBACK"
|
214
228
|
end
|
215
229
|
|
216
|
-
|
217
|
-
# query. However, this does not allow for LIMIT, OFFSET and ORDER. To support
|
218
|
-
# these, we must use a subquery.
|
219
|
-
def join_to_update(update, select, key) # :nodoc:
|
220
|
-
if select.limit || select.offset || select.orders.any?
|
221
|
-
super
|
222
|
-
else
|
223
|
-
update.table select.source
|
224
|
-
update.wheres = select.constraints
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
def empty_insert_statement_value
|
230
|
+
def empty_insert_statement_value(primary_key = nil)
|
229
231
|
"VALUES ()"
|
230
232
|
end
|
231
233
|
|
@@ -241,7 +243,7 @@ module ActiveRecord
|
|
241
243
|
end
|
242
244
|
|
243
245
|
# Create a new MySQL database with optional <tt>:charset</tt> and <tt>:collation</tt>.
|
244
|
-
# Charset defaults to
|
246
|
+
# Charset defaults to utf8mb4.
|
245
247
|
#
|
246
248
|
# Example:
|
247
249
|
# create_database 'charset_test', charset: 'latin1', collation: 'latin1_bin'
|
@@ -250,8 +252,12 @@ module ActiveRecord
|
|
250
252
|
def create_database(name, options = {})
|
251
253
|
if options[:collation]
|
252
254
|
execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT COLLATE #{quote_table_name(options[:collation])}"
|
255
|
+
elsif options[:charset]
|
256
|
+
execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT CHARACTER SET #{quote_table_name(options[:charset])}"
|
257
|
+
elsif row_format_dynamic_by_default?
|
258
|
+
execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT CHARACTER SET `utf8mb4`"
|
253
259
|
else
|
254
|
-
|
260
|
+
raise "Configure a supported :charset and ensure innodb_large_prefix is enabled to support indexes on varchar(255) string columns."
|
255
261
|
end
|
256
262
|
end
|
257
263
|
|
@@ -277,14 +283,10 @@ module ActiveRecord
|
|
277
283
|
show_variable "collation_database"
|
278
284
|
end
|
279
285
|
|
280
|
-
def truncate(table_name, name = nil)
|
281
|
-
execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
|
282
|
-
end
|
283
|
-
|
284
286
|
def table_comment(table_name) # :nodoc:
|
285
287
|
scope = quoted_scope(table_name)
|
286
288
|
|
287
|
-
query_value(
|
289
|
+
query_value(<<~SQL, "SCHEMA").presence
|
288
290
|
SELECT table_comment
|
289
291
|
FROM information_schema.tables
|
290
292
|
WHERE table_schema = #{scope[:schema]}
|
@@ -292,22 +294,8 @@ module ActiveRecord
|
|
292
294
|
SQL
|
293
295
|
end
|
294
296
|
|
295
|
-
def
|
296
|
-
|
297
|
-
table, arguments = args.shift, args
|
298
|
-
method = :"#{command}_for_alter"
|
299
|
-
|
300
|
-
if respond_to?(method, true)
|
301
|
-
send(method, table, *arguments)
|
302
|
-
else
|
303
|
-
raise "Unknown method called : #{method}(#{arguments.inspect})"
|
304
|
-
end
|
305
|
-
end.join(", ")
|
306
|
-
|
307
|
-
execute("ALTER TABLE #{quote_table_name(table_name)} #{sqls}")
|
308
|
-
end
|
309
|
-
|
310
|
-
def change_table_comment(table_name, comment) #:nodoc:
|
297
|
+
def change_table_comment(table_name, comment_or_changes) # :nodoc:
|
298
|
+
comment = extract_new_comment_value(comment_or_changes)
|
311
299
|
comment = "" if comment.nil?
|
312
300
|
execute("ALTER TABLE #{quote_table_name(table_name)} COMMENT #{quote(comment)}")
|
313
301
|
end
|
@@ -363,7 +351,8 @@ module ActiveRecord
|
|
363
351
|
change_column table_name, column_name, nil, null: null
|
364
352
|
end
|
365
353
|
|
366
|
-
def change_column_comment(table_name, column_name,
|
354
|
+
def change_column_comment(table_name, column_name, comment_or_changes) # :nodoc:
|
355
|
+
comment = extract_new_comment_value(comment_or_changes)
|
367
356
|
change_column table_name, column_name, nil, comment: comment
|
368
357
|
end
|
369
358
|
|
@@ -377,8 +366,8 @@ module ActiveRecord
|
|
377
366
|
end
|
378
367
|
|
379
368
|
def add_index(table_name, column_name, options = {}) #:nodoc:
|
380
|
-
index_name, index_type, index_columns, _, index_algorithm, index_using, comment = add_index_options(table_name, column_name, options)
|
381
|
-
sql = "CREATE #{index_type} INDEX #{quote_column_name(index_name)} #{index_using} ON #{quote_table_name(table_name)} (#{index_columns}) #{index_algorithm}"
|
369
|
+
index_name, index_type, index_columns, _, index_algorithm, index_using, comment = add_index_options(table_name, column_name, **options)
|
370
|
+
sql = +"CREATE #{index_type} INDEX #{quote_column_name(index_name)} #{index_using} ON #{quote_table_name(table_name)} (#{index_columns}) #{index_algorithm}"
|
382
371
|
execute add_sql_comment!(sql, comment)
|
383
372
|
end
|
384
373
|
|
@@ -392,7 +381,7 @@ module ActiveRecord
|
|
392
381
|
|
393
382
|
scope = quoted_scope(table_name)
|
394
383
|
|
395
|
-
fk_info = exec_query(
|
384
|
+
fk_info = exec_query(<<~SQL, "SCHEMA")
|
396
385
|
SELECT fk.referenced_table_name AS 'to_table',
|
397
386
|
fk.referenced_column_name AS 'primary_key',
|
398
387
|
fk.column_name AS 'column',
|
@@ -429,12 +418,13 @@ module ActiveRecord
|
|
429
418
|
create_table_info = create_table_info(table_name)
|
430
419
|
|
431
420
|
# strip create_definitions and partition_options
|
432
|
-
|
421
|
+
# Be aware that `create_table_info` might not include any table options due to `NO_TABLE_OPTIONS` sql mode.
|
422
|
+
raw_table_options = create_table_info.sub(/\A.*\n\) ?/m, "").sub(/\n\/\*!.*\*\/\n\z/m, "").strip
|
433
423
|
|
434
424
|
# strip AUTO_INCREMENT
|
435
425
|
raw_table_options.sub!(/(ENGINE=\w+)(?: AUTO_INCREMENT=\d+)/, '\1')
|
436
426
|
|
437
|
-
table_options[:options] = raw_table_options
|
427
|
+
table_options[:options] = raw_table_options unless raw_table_options.blank?
|
438
428
|
|
439
429
|
# strip COMMENT
|
440
430
|
if raw_table_options.sub!(/ COMMENT='.+'/, "")
|
@@ -444,30 +434,6 @@ module ActiveRecord
|
|
444
434
|
table_options
|
445
435
|
end
|
446
436
|
|
447
|
-
# Maps logical Rails types to MySQL-specific data types.
|
448
|
-
def type_to_sql(type, limit: nil, precision: nil, scale: nil, unsigned: nil, **) # :nodoc:
|
449
|
-
sql = \
|
450
|
-
case type.to_s
|
451
|
-
when "integer"
|
452
|
-
integer_to_sql(limit)
|
453
|
-
when "text"
|
454
|
-
text_to_sql(limit)
|
455
|
-
when "blob"
|
456
|
-
binary_to_sql(limit)
|
457
|
-
when "binary"
|
458
|
-
if (0..0xfff) === limit
|
459
|
-
"varbinary(#{limit})"
|
460
|
-
else
|
461
|
-
binary_to_sql(limit)
|
462
|
-
end
|
463
|
-
else
|
464
|
-
super
|
465
|
-
end
|
466
|
-
|
467
|
-
sql = "#{sql} unsigned" if unsigned && type != :primary_key
|
468
|
-
sql
|
469
|
-
end
|
470
|
-
|
471
437
|
# SHOW VARIABLES LIKE 'name'
|
472
438
|
def show_variable(name)
|
473
439
|
query_value("SELECT @@#{name}", "SCHEMA")
|
@@ -480,19 +446,36 @@ module ActiveRecord
|
|
480
446
|
|
481
447
|
scope = quoted_scope(table_name)
|
482
448
|
|
483
|
-
query_values(
|
449
|
+
query_values(<<~SQL, "SCHEMA")
|
484
450
|
SELECT column_name
|
485
|
-
FROM information_schema.
|
486
|
-
WHERE
|
451
|
+
FROM information_schema.statistics
|
452
|
+
WHERE index_name = 'PRIMARY'
|
487
453
|
AND table_schema = #{scope[:schema]}
|
488
454
|
AND table_name = #{scope[:name]}
|
489
|
-
ORDER BY
|
455
|
+
ORDER BY seq_in_index
|
490
456
|
SQL
|
491
457
|
end
|
492
458
|
|
493
|
-
def
|
459
|
+
def default_uniqueness_comparison(attribute, value, klass) # :nodoc:
|
460
|
+
column = column_for_attribute(attribute)
|
461
|
+
|
462
|
+
if column.collation && !column.case_sensitive? && !value.nil?
|
463
|
+
ActiveSupport::Deprecation.warn(<<~MSG.squish)
|
464
|
+
Uniqueness validator will no longer enforce case sensitive comparison in Rails 6.1.
|
465
|
+
To continue case sensitive comparison on the :#{attribute.name} attribute in #{klass} model,
|
466
|
+
pass `case_sensitive: true` option explicitly to the uniqueness validator.
|
467
|
+
MSG
|
468
|
+
attribute.eq(Arel::Nodes::Bin.new(value))
|
469
|
+
else
|
470
|
+
super
|
471
|
+
end
|
472
|
+
end
|
473
|
+
|
474
|
+
def case_sensitive_comparison(attribute, value) # :nodoc:
|
475
|
+
column = column_for_attribute(attribute)
|
476
|
+
|
494
477
|
if column.collation && !column.case_sensitive?
|
495
|
-
|
478
|
+
attribute.eq(Arel::Nodes::Bin.new(value))
|
496
479
|
else
|
497
480
|
super
|
498
481
|
end
|
@@ -510,7 +493,7 @@ module ActiveRecord
|
|
510
493
|
def columns_for_distinct(columns, orders) # :nodoc:
|
511
494
|
order_columns = orders.reject(&:blank?).map { |s|
|
512
495
|
# Convert Arel node to string
|
513
|
-
s = s
|
496
|
+
s = visitor.compile(s) unless s.is_a?(String)
|
514
497
|
# Remove any ASC/DESC modifiers
|
515
498
|
s.gsub(/\s+(?:ASC|DESC)\b/i, "")
|
516
499
|
}.reject(&:blank?).map.with_index { |column, i| "#{column} AS alias_#{i}" }
|
@@ -526,40 +509,27 @@ module ActiveRecord
|
|
526
509
|
index.using == :btree || super
|
527
510
|
end
|
528
511
|
|
529
|
-
def
|
530
|
-
|
531
|
-
super { discard_remaining_results }
|
532
|
-
end
|
533
|
-
end
|
512
|
+
def build_insert_sql(insert) # :nodoc:
|
513
|
+
sql = +"INSERT #{insert.into} #{insert.values_list}"
|
534
514
|
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
total_sql_chunks << sql
|
542
|
-
else
|
543
|
-
previous_packet << sql
|
544
|
-
end
|
545
|
-
end
|
515
|
+
if insert.skip_duplicates?
|
516
|
+
no_op_column = quote_column_name(insert.keys.first)
|
517
|
+
sql << " ON DUPLICATE KEY UPDATE #{no_op_column}=#{no_op_column}"
|
518
|
+
elsif insert.update_duplicates?
|
519
|
+
sql << " ON DUPLICATE KEY UPDATE "
|
520
|
+
sql << insert.updatable_columns.map { |column| "#{column}=VALUES(#{column})" }.join(",")
|
546
521
|
end
|
547
522
|
|
548
|
-
|
549
|
-
|
550
|
-
raise ActiveRecordError, "Fixtures set is too large #{current_packet.bytesize}. Consider increasing the max_allowed_packet variable."
|
551
|
-
elsif previous_packet.nil?
|
552
|
-
false
|
553
|
-
else
|
554
|
-
(current_packet.bytesize + previous_packet.bytesize) > max_allowed_packet
|
555
|
-
end
|
556
|
-
end
|
523
|
+
sql
|
524
|
+
end
|
557
525
|
|
558
|
-
|
559
|
-
|
560
|
-
|
526
|
+
def check_version # :nodoc:
|
527
|
+
if database_version < "5.5.8"
|
528
|
+
raise "Your version of MySQL (#{database_version}) is too old. Active Record supports MySQL >= 5.5.8."
|
561
529
|
end
|
530
|
+
end
|
562
531
|
|
532
|
+
private
|
563
533
|
def initialize_type_map(m = type_map)
|
564
534
|
super
|
565
535
|
|
@@ -587,24 +557,24 @@ module ActiveRecord
|
|
587
557
|
m.alias_type %r(bit)i, "binary"
|
588
558
|
|
589
559
|
m.register_type(%r(enum)i) do |sql_type|
|
590
|
-
limit = sql_type[/^enum\((.+)\)/i, 1]
|
560
|
+
limit = sql_type[/^enum\s*\((.+)\)/i, 1]
|
591
561
|
.split(",").map { |enum| enum.strip.length - 2 }.max
|
592
562
|
MysqlString.new(limit: limit)
|
593
563
|
end
|
594
564
|
|
595
565
|
m.register_type(%r(^set)i) do |sql_type|
|
596
|
-
limit = sql_type[/^set\((.+)\)/i, 1]
|
566
|
+
limit = sql_type[/^set\s*\((.+)\)/i, 1]
|
597
567
|
.split(",").map { |set| set.strip.length - 1 }.sum - 1
|
598
568
|
MysqlString.new(limit: limit)
|
599
569
|
end
|
600
570
|
end
|
601
571
|
|
602
|
-
def register_integer_type(mapping, key, options)
|
572
|
+
def register_integer_type(mapping, key, **options)
|
603
573
|
mapping.register_type(key) do |sql_type|
|
604
574
|
if /\bunsigned\b/.match?(sql_type)
|
605
|
-
Type::UnsignedInteger.new(options)
|
575
|
+
Type::UnsignedInteger.new(**options)
|
606
576
|
else
|
607
|
-
Type::Integer.new(options)
|
577
|
+
Type::Integer.new(**options)
|
608
578
|
end
|
609
579
|
end
|
610
580
|
end
|
@@ -618,9 +588,13 @@ module ActiveRecord
|
|
618
588
|
end
|
619
589
|
|
620
590
|
# See https://dev.mysql.com/doc/refman/5.7/en/error-messages-server.html
|
591
|
+
ER_FILSORT_ABORT = 1028
|
621
592
|
ER_DUP_ENTRY = 1062
|
622
593
|
ER_NOT_NULL_VIOLATION = 1048
|
594
|
+
ER_NO_REFERENCED_ROW = 1216
|
595
|
+
ER_ROW_IS_REFERENCED = 1217
|
623
596
|
ER_DO_NOT_HAVE_DEFAULT = 1364
|
597
|
+
ER_ROW_IS_REFERENCED_2 = 1451
|
624
598
|
ER_NO_REFERENCED_ROW_2 = 1452
|
625
599
|
ER_DATA_TOO_LONG = 1406
|
626
600
|
ER_OUT_OF_RANGE = 1264
|
@@ -630,35 +604,36 @@ module ActiveRecord
|
|
630
604
|
ER_LOCK_WAIT_TIMEOUT = 1205
|
631
605
|
ER_QUERY_INTERRUPTED = 1317
|
632
606
|
ER_QUERY_TIMEOUT = 3024
|
607
|
+
ER_FK_INCOMPATIBLE_COLUMNS = 3780
|
633
608
|
|
634
|
-
def translate_exception(exception, message)
|
609
|
+
def translate_exception(exception, message:, sql:, binds:)
|
635
610
|
case error_number(exception)
|
636
611
|
when ER_DUP_ENTRY
|
637
|
-
RecordNotUnique.new(message)
|
638
|
-
when ER_NO_REFERENCED_ROW_2
|
639
|
-
InvalidForeignKey.new(message)
|
640
|
-
when ER_CANNOT_ADD_FOREIGN
|
641
|
-
mismatched_foreign_key(message)
|
612
|
+
RecordNotUnique.new(message, sql: sql, binds: binds)
|
613
|
+
when ER_NO_REFERENCED_ROW, ER_ROW_IS_REFERENCED, ER_ROW_IS_REFERENCED_2, ER_NO_REFERENCED_ROW_2
|
614
|
+
InvalidForeignKey.new(message, sql: sql, binds: binds)
|
615
|
+
when ER_CANNOT_ADD_FOREIGN, ER_FK_INCOMPATIBLE_COLUMNS
|
616
|
+
mismatched_foreign_key(message, sql: sql, binds: binds)
|
642
617
|
when ER_CANNOT_CREATE_TABLE
|
643
618
|
if message.include?("errno: 150")
|
644
|
-
mismatched_foreign_key(message)
|
619
|
+
mismatched_foreign_key(message, sql: sql, binds: binds)
|
645
620
|
else
|
646
621
|
super
|
647
622
|
end
|
648
623
|
when ER_DATA_TOO_LONG
|
649
|
-
ValueTooLong.new(message)
|
624
|
+
ValueTooLong.new(message, sql: sql, binds: binds)
|
650
625
|
when ER_OUT_OF_RANGE
|
651
|
-
RangeError.new(message)
|
626
|
+
RangeError.new(message, sql: sql, binds: binds)
|
652
627
|
when ER_NOT_NULL_VIOLATION, ER_DO_NOT_HAVE_DEFAULT
|
653
|
-
NotNullViolation.new(message)
|
628
|
+
NotNullViolation.new(message, sql: sql, binds: binds)
|
654
629
|
when ER_LOCK_DEADLOCK
|
655
|
-
Deadlocked.new(message)
|
630
|
+
Deadlocked.new(message, sql: sql, binds: binds)
|
656
631
|
when ER_LOCK_WAIT_TIMEOUT
|
657
|
-
LockWaitTimeout.new(message)
|
658
|
-
when ER_QUERY_TIMEOUT
|
659
|
-
StatementTimeout.new(message)
|
632
|
+
LockWaitTimeout.new(message, sql: sql, binds: binds)
|
633
|
+
when ER_QUERY_TIMEOUT, ER_FILSORT_ABORT
|
634
|
+
StatementTimeout.new(message, sql: sql, binds: binds)
|
660
635
|
when ER_QUERY_INTERRUPTED
|
661
|
-
QueryCanceled.new(message)
|
636
|
+
QueryCanceled.new(message, sql: sql, binds: binds)
|
662
637
|
else
|
663
638
|
super
|
664
639
|
end
|
@@ -681,7 +656,7 @@ module ActiveRecord
|
|
681
656
|
end
|
682
657
|
|
683
658
|
td = create_table_definition(table_name)
|
684
|
-
cd = td.new_column_definition(column.name, type, options)
|
659
|
+
cd = td.new_column_definition(column.name, type, **options)
|
685
660
|
schema_creation.accept(ChangeColumnDefinition.new(cd, column.name))
|
686
661
|
end
|
687
662
|
|
@@ -695,14 +670,15 @@ module ActiveRecord
|
|
695
670
|
|
696
671
|
current_type = exec_query("SHOW COLUMNS FROM #{quote_table_name(table_name)} LIKE #{quote(column_name)}", "SCHEMA").first["Type"]
|
697
672
|
td = create_table_definition(table_name)
|
698
|
-
cd = td.new_column_definition(new_column_name, current_type, options)
|
673
|
+
cd = td.new_column_definition(new_column_name, current_type, **options)
|
699
674
|
schema_creation.accept(ChangeColumnDefinition.new(cd, column.name))
|
700
675
|
end
|
701
676
|
|
702
677
|
def add_index_for_alter(table_name, column_name, options = {})
|
703
|
-
index_name, index_type, index_columns, _, index_algorithm, index_using = add_index_options(table_name, column_name, options)
|
678
|
+
index_name, index_type, index_columns, _, index_algorithm, index_using, comment = add_index_options(table_name, column_name, **options)
|
704
679
|
index_algorithm[0, 0] = ", " if index_algorithm.present?
|
705
|
-
"ADD #{index_type} INDEX #{quote_column_name(index_name)} #{index_using} (#{index_columns})#{index_algorithm}"
|
680
|
+
sql = +"ADD #{index_type} INDEX #{quote_column_name(index_name)} #{index_using} (#{index_columns})#{index_algorithm}"
|
681
|
+
add_sql_comment!(sql, comment)
|
706
682
|
end
|
707
683
|
|
708
684
|
def remove_index_for_alter(table_name, options = {})
|
@@ -710,30 +686,12 @@ module ActiveRecord
|
|
710
686
|
"DROP INDEX #{quote_column_name(index_name)}"
|
711
687
|
end
|
712
688
|
|
713
|
-
def add_timestamps_for_alter(table_name, options = {})
|
714
|
-
[add_column_for_alter(table_name, :created_at, :datetime, options), add_column_for_alter(table_name, :updated_at, :datetime, options)]
|
715
|
-
end
|
716
|
-
|
717
|
-
def remove_timestamps_for_alter(table_name, options = {})
|
718
|
-
[remove_column_for_alter(table_name, :updated_at), remove_column_for_alter(table_name, :created_at)]
|
719
|
-
end
|
720
|
-
|
721
|
-
# MySQL is too stupid to create a temporary table for use subquery, so we have
|
722
|
-
# to give it some prompting in the form of a subsubquery. Ugh!
|
723
|
-
def subquery_for(key, select)
|
724
|
-
subselect = select.clone
|
725
|
-
subselect.projections = [key]
|
726
|
-
|
727
|
-
# Materialize subquery by adding distinct
|
728
|
-
# to work with MySQL 5.7.6 which sets optimizer_switch='derived_merge=on'
|
729
|
-
subselect.distinct unless select.limit || select.offset || select.orders.any?
|
730
|
-
|
731
|
-
key_name = quote_column_name(key.name)
|
732
|
-
Arel::SelectManager.new(subselect.as("__active_record_temp")).project(Arel.sql(key_name))
|
733
|
-
end
|
734
|
-
|
735
689
|
def supports_rename_index?
|
736
|
-
mariadb?
|
690
|
+
if mariadb?
|
691
|
+
database_version >= "10.5.2"
|
692
|
+
else
|
693
|
+
database_version >= "5.7.6"
|
694
|
+
end
|
737
695
|
end
|
738
696
|
|
739
697
|
def configure_connection
|
@@ -770,7 +728,7 @@ module ActiveRecord
|
|
770
728
|
# https://dev.mysql.com/doc/refman/5.7/en/set-names.html
|
771
729
|
# (trailing comma because variable_assignments will always have content)
|
772
730
|
if @config[:encoding]
|
773
|
-
encoding = "NAMES #{@config[:encoding]}"
|
731
|
+
encoding = +"NAMES #{@config[:encoding]}"
|
774
732
|
encoding << " COLLATE #{@config[:collation]}" if @config[:collation]
|
775
733
|
encoding << ", "
|
776
734
|
end
|
@@ -786,7 +744,7 @@ module ActiveRecord
|
|
786
744
|
end.compact.join(", ")
|
787
745
|
|
788
746
|
# ...and send them all in one query
|
789
|
-
execute
|
747
|
+
execute("SET #{encoding} #{sql_mode_assignment} #{variable_assignments}", "SCHEMA")
|
790
748
|
end
|
791
749
|
|
792
750
|
def column_definitions(table_name) # :nodoc:
|
@@ -803,15 +761,21 @@ module ActiveRecord
|
|
803
761
|
Arel::Visitors::MySQL.new(self)
|
804
762
|
end
|
805
763
|
|
806
|
-
def
|
764
|
+
def build_statement_pool
|
765
|
+
StatementPool.new(self.class.type_cast_config_to_integer(@config[:statement_limit]))
|
766
|
+
end
|
767
|
+
|
768
|
+
def mismatched_foreign_key(message, sql:, binds:)
|
807
769
|
match = %r/
|
808
770
|
(?:CREATE|ALTER)\s+TABLE\s*(?:`?\w+`?\.)?`?(?<table>\w+)`?.+?
|
809
771
|
FOREIGN\s+KEY\s*\(`?(?<foreign_key>\w+)`?\)\s*
|
810
772
|
REFERENCES\s*(`?(?<target_table>\w+)`?)\s*\(`?(?<primary_key>\w+)`?\)
|
811
|
-
/xmi.match(
|
773
|
+
/xmi.match(sql)
|
812
774
|
|
813
775
|
options = {
|
814
776
|
message: message,
|
777
|
+
sql: sql,
|
778
|
+
binds: binds,
|
815
779
|
}
|
816
780
|
|
817
781
|
if match
|
@@ -822,42 +786,11 @@ module ActiveRecord
|
|
822
786
|
options[:primary_key_column] = column_for(match[:target_table], match[:primary_key])
|
823
787
|
end
|
824
788
|
|
825
|
-
MismatchedForeignKey.new(options)
|
789
|
+
MismatchedForeignKey.new(**options)
|
826
790
|
end
|
827
791
|
|
828
|
-
def
|
829
|
-
|
830
|
-
when 1; "tinyint"
|
831
|
-
when 2; "smallint"
|
832
|
-
when 3; "mediumint"
|
833
|
-
when nil, 4; "int"
|
834
|
-
when 5..8; "bigint"
|
835
|
-
else raise(ActiveRecordError, "No integer type has byte size #{limit}. Use a decimal with scale 0 instead.")
|
836
|
-
end
|
837
|
-
end
|
838
|
-
|
839
|
-
def text_to_sql(limit) # :nodoc:
|
840
|
-
case limit
|
841
|
-
when 0..0xff; "tinytext"
|
842
|
-
when nil, 0x100..0xffff; "text"
|
843
|
-
when 0x10000..0xffffff; "mediumtext"
|
844
|
-
when 0x1000000..0xffffffff; "longtext"
|
845
|
-
else raise(ActiveRecordError, "No text type has byte length #{limit}")
|
846
|
-
end
|
847
|
-
end
|
848
|
-
|
849
|
-
def binary_to_sql(limit) # :nodoc:
|
850
|
-
case limit
|
851
|
-
when 0..0xff; "tinyblob"
|
852
|
-
when nil, 0x100..0xffff; "blob"
|
853
|
-
when 0x10000..0xffffff; "mediumblob"
|
854
|
-
when 0x1000000..0xffffffff; "longblob"
|
855
|
-
else raise(ActiveRecordError, "No binary type has byte length #{limit}")
|
856
|
-
end
|
857
|
-
end
|
858
|
-
|
859
|
-
def version_string
|
860
|
-
full_version.match(/^(?:5\.5\.5-)?(\d+\.\d+\.\d+)/)[1]
|
792
|
+
def version_string(full_version_string)
|
793
|
+
full_version_string.match(/^(?:5\.5\.5-)?(\d+\.\d+\.\d+)/)[1]
|
861
794
|
end
|
862
795
|
|
863
796
|
class MysqlString < Type::String # :nodoc:
|
@@ -870,7 +803,6 @@ module ActiveRecord
|
|
870
803
|
end
|
871
804
|
|
872
805
|
private
|
873
|
-
|
874
806
|
def cast_value(value)
|
875
807
|
case value
|
876
808
|
when true then "1"
|