diff options
Diffstat (limited to 'activerecord/lib')
4 files changed, 34 insertions, 15 deletions
diff --git a/activerecord/lib/active_record/collection_cache_key.rb b/activerecord/lib/active_record/collection_cache_key.rb index 43784b70e3..1e1de1863a 100644 --- a/activerecord/lib/active_record/collection_cache_key.rb +++ b/activerecord/lib/active_record/collection_cache_key.rb @@ -7,17 +7,27 @@ module ActiveRecord if collection.loaded? size = collection.size if size > 0 - timestamp = collection.max_by(×tamp_column).public_send(timestamp_column) + timestamp = collection.max_by(×tamp_column)._read_attribute(timestamp_column) end else column_type = type_for_attribute(timestamp_column.to_s) column = "#{connection.quote_table_name(collection.table_name)}.#{connection.quote_column_name(timestamp_column)}" + select_values = "COUNT(*) AS #{connection.quote_column_name("size")}, MAX(%s) AS timestamp" - query = collection - .unscope(:select) - .select("COUNT(*) AS #{connection.quote_column_name("size")}", "MAX(#{column}) AS timestamp") - .unscope(:order) - result = connection.select_one(query) + if collection.limit_value || collection.offset_value + query = collection.spawn + query.select_values = [column] + subquery_alias = "subquery_for_cache_key" + subquery_column = "#{subquery_alias}.#{timestamp_column}" + subquery = query.arel.as(subquery_alias) + arel = Arel::SelectManager.new(query.engine).project(select_values % subquery_column).from(subquery) + else + query = collection.unscope(:order) + query.select_values = [select_values % column] + arel = query.arel + end + + result = connection.select_one(arel, nil, query.bound_attributes) if result.blank? size = 0 diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb index 7cafbb7e12..46d7f84efd 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -2,7 +2,7 @@ module ActiveRecord module ConnectionAdapters #:nodoc: # Abstract representation of an index definition on a table. Instances of # this type are typically created and returned by methods in database - # adapters. e.g. ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter#indexes + # adapters. e.g. ActiveRecord::ConnectionAdapters::MySQL::SchemaStatements#indexes class IndexDefinition # :nodoc: attr_reader :table, :name, :unique, :columns, :lengths, :orders, :where, :type, :using, :comment diff --git a/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb b/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb index 3e0afd9761..e2ba0ba1a0 100644 --- a/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb @@ -55,13 +55,14 @@ module ActiveRecord def extract_expression_for_virtual_column(column) if mariadb? create_table_info = create_table_info(column.table_name) - if %r/#{quote_column_name(column.name)} #{Regexp.quote(column.sql_type)} AS \((?<expression>.+?)\) #{column.extra}/m =~ create_table_info + if %r/#{quote_column_name(column.name)} #{Regexp.quote(column.sql_type)}(?: COLLATE \w+)? AS \((?<expression>.+?)\) #{column.extra}/ =~ create_table_info $~[:expression].inspect end else + scope = quoted_scope(column.table_name) sql = "SELECT generation_expression FROM information_schema.columns" \ - " WHERE table_schema = #{quote(@config[:database])}" \ - " AND table_name = #{quote(column.table_name)}" \ + " WHERE table_schema = #{scope[:schema]}" \ + " AND table_name = #{scope[:name]}" \ " AND column_name = #{quote(column.name)}" select_value(sql, "SCHEMA").inspect end diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb index 4e1df1432c..51c82f4ced 100644 --- a/activerecord/lib/active_record/migration.rb +++ b/activerecord/lib/active_record/migration.rb @@ -1104,13 +1104,21 @@ module ActiveRecord def move(direction, migrations_paths, steps) migrator = new(direction, migrations(migrations_paths)) - start_index = migrator.migrations.index(migrator.current_migration) - if start_index - finish = migrator.migrations[start_index + steps] - version = finish ? finish.version : 0 - send(direction, migrations_paths, version) + if current_version != 0 && !migrator.current_migration + raise UnknownMigrationVersionError.new(current_version) end + + start_index = + if current_version == 0 + 0 + else + migrator.migrations.index(migrator.current_migration) + end + + finish = migrator.migrations[start_index + steps] + version = finish ? finish.version : 0 + send(direction, migrations_paths, version) end end |