aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRick Olson <technoweenie@gmail.com>2008-04-09 16:20:15 +0000
committerRick Olson <technoweenie@gmail.com>2008-04-09 16:20:15 +0000
commit8a5a9dcbf64843f064b6e8a0b9c6eea8f0b8536e (patch)
tree27064d2d5ebccdd40bf5c4f43fcf5b2e3e7e57f3
parent78c2d9fc223e7a9945aee65c838f7ce78e9ddb3e (diff)
downloadrails-8a5a9dcbf64843f064b6e8a0b9c6eea8f0b8536e.tar.gz
rails-8a5a9dcbf64843f064b6e8a0b9c6eea8f0b8536e.tar.bz2
rails-8a5a9dcbf64843f064b6e8a0b9c6eea8f0b8536e.zip
Add support for interleaving migrations by storing which migrations have run in the new schema_migrations table. Closes #11493 [jordi]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@9244 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
-rw-r--r--activerecord/CHANGELOG2
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb50
-rw-r--r--activerecord/lib/active_record/migration.rb83
-rw-r--r--activerecord/lib/active_record/schema.rb17
-rw-r--r--activerecord/lib/active_record/schema_dumper.rb6
-rw-r--r--activerecord/test/cases/ar_schema_test.rb4
-rw-r--r--activerecord/test/cases/migration_test.rb52
-rw-r--r--activerecord/test/cases/schema_dumper_test.rb6
-rw-r--r--activerecord/test/migrations/interleaved/pass_1/3_innocent_jointable.rb12
-rw-r--r--activerecord/test/migrations/interleaved/pass_2/1_people_have_last_names.rb9
-rw-r--r--activerecord/test/migrations/interleaved/pass_2/3_innocent_jointable.rb12
-rw-r--r--activerecord/test/migrations/interleaved/pass_3/1_people_have_last_names.rb9
-rw-r--r--activerecord/test/migrations/interleaved/pass_3/2_i_raise_on_down.rb8
-rw-r--r--activerecord/test/migrations/interleaved/pass_3/3_innocent_jointable.rb12
-rw-r--r--activerecord/test/schema/sybase.drop.sql2
15 files changed, 204 insertions, 80 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index b4ebf3de48..dfe6f988c2 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*
+* Add support for interleaving migrations by storing which migrations have run in the new schema_migrations table. Closes #11493 [jordi]
+
* ActiveRecord::Base#sum defaults to 0 if no rows are returned. Closes #11550 [kamal]
* Ensure that respond_to? considers dynamic finder methods. Closes #11538. [floehopper]
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
index 393d5c130e..c986f0c6f1 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -232,33 +232,41 @@ module ActiveRecord
# Should not be called normally, but this operation is non-destructive.
# The migrations module handles this automatically.
- def initialize_schema_information(current_version=0)
- begin
- execute "CREATE TABLE #{quote_table_name(ActiveRecord::Migrator.schema_info_table_name)} (version #{type_to_sql(:string)})"
- execute "INSERT INTO #{quote_table_name(ActiveRecord::Migrator.schema_info_table_name)} (version) VALUES(#{current_version})"
- rescue ActiveRecord::StatementInvalid
- # Schema has been initialized, make sure version is a string
- version_column = columns(:schema_info).detect { |c| c.name == "version" }
-
- # can't just alter the table, since SQLite can't deal
- unless version_column.type == :string
- version = ActiveRecord::Migrator.current_version
- execute "DROP TABLE #{quote_table_name(ActiveRecord::Migrator.schema_info_table_name)}"
- initialize_schema_information(version)
+ def initialize_schema_migrations_table
+ sm_table = ActiveRecord::Migrator.schema_migrations_table_name
+
+ unless tables.detect { |t| t == sm_table }
+ create_table(sm_table, :id => false) do |schema_migrations_table|
+ schema_migrations_table.column :version, :string, :null => false
end
- end
- end
+ add_index sm_table, :version, :unique => true,
+ :name => 'unique_schema_migrations'
+
+ # Backwards-compatibility: if we find schema_info, assume we've
+ # migrated up to that point:
+ si_table = Base.table_name_prefix + 'schema_info' + Base.table_name_suffix
+
+ if tables.detect { |t| t == si_table }
- def dump_schema_information #:nodoc:
- begin
- if (current_schema = ActiveRecord::Migrator.current_version) > 0
- return "INSERT INTO #{quote_table_name(ActiveRecord::Migrator.schema_info_table_name)} (version) VALUES (#{current_schema})"
+ old_version = select_value("SELECT version FROM #{quote_table_name(si_table)}").to_i
+ assume_migrated_upto_version(old_version)
+ drop_table(si_table)
end
- rescue ActiveRecord::StatementInvalid
- # No Schema Info
end
end
+ def assume_migrated_upto_version(version)
+ sm_table = quote_table_name(ActiveRecord::Migrator.schema_migrations_table_name)
+ migrated = select_values("SELECT version FROM #{sm_table}").map(&:to_i)
+ versions = Dir['db/migrate/[0-9]*_*.rb'].map do |filename|
+ filename.split('/').last.split('_').first.to_i
+ end
+
+ execute "INSERT INTO #{sm_table} (version) VALUES ('#{version}')" unless migrated.include?(version.to_i)
+ (versions - migrated).select { |v| v < version.to_i }.each do |v|
+ execute "INSERT INTO #{sm_table} (version) VALUES ('#{v}')"
+ end
+ end
def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
if native = native_database_types[type]
diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb
index 4c10cd806c..573c6a4f02 100644
--- a/activerecord/lib/active_record/migration.rb
+++ b/activerecord/lib/active_record/migration.rb
@@ -123,7 +123,8 @@ module ActiveRecord
#
# To run migrations against the currently configured database, use
# <tt>rake db:migrate</tt>. This will update the database by running all of the
- # pending migrations, creating the <tt>schema_info</tt> table if missing.
+ # pending migrations, creating the <tt>schema_migrations</tt> table
+ # (see "About the schema_migrations table" section below) if missing.
#
# To roll the database back to a previous migration version, use
# <tt>rake db:migrate VERSION=X</tt> where <tt>X</tt> is the version to which
@@ -216,6 +217,21 @@ module ActiveRecord
#
# The phrase "Updating salaries..." would then be printed, along with the
# benchmark for the block when the block completes.
+ #
+ # == About the schema_migrations table
+ #
+ # Rails versions 2.0 and prior used to create a table called
+ # <tt>schema_info</tt> when using migrations. This table contained the
+ # version of the schema as of the last applied migration.
+ #
+ # Starting with Rails 2.1, the <tt>schema_info</tt> table is
+ # (automatically) replaced by the <tt>schema_migrations</tt> table, which
+ # contains the version numbers of all the migrations applied.
+ #
+ # As a result, it is now possible to add migration files that are numbered
+ # lower than the current schema version: when migrating up, those
+ # never-applied "interleaved" migrations will be automatically applied, and
+ # when migrating down, never-applied "interleaved" migrations will be skipped.
class Migration
@@verbose = true
cattr_accessor :verbose
@@ -315,15 +331,12 @@ module ActiveRecord
class << self
def migrate(migrations_path, target_version = nil)
case
- when target_version.nil?, current_version < target_version
- up(migrations_path, target_version)
- when current_version > target_version
- down(migrations_path, target_version)
- when current_version == target_version
- return # You're on the right version
+ when target_version.nil? then up(migrations_path, target_version)
+ when current_version > target_version then down(migrations_path, target_version)
+ else up(migrations_path, target_version)
end
end
-
+
def rollback(migrations_path, steps=1)
migrator = self.new(:down, migrations_path)
start_index = migrator.migrations.index(migrator.current_migration)
@@ -346,12 +359,13 @@ module ActiveRecord
self.new(direction, migrations_path, target_version).run
end
- def schema_info_table_name
- Base.table_name_prefix + "schema_info" + Base.table_name_suffix
+ def schema_migrations_table_name
+ Base.table_name_prefix + 'schema_migrations' + Base.table_name_suffix
end
def current_version
- Base.connection.select_value("SELECT version FROM #{schema_info_table_name}").to_i
+ Base.connection.select_values(
+ "SELECT version FROM #{schema_migrations_table_name}").map(&:to_i).max || 0
end
def proper_table_name(name)
@@ -362,7 +376,7 @@ module ActiveRecord
def initialize(direction, migrations_path, target_version = nil)
raise StandardError.new("This database does not yet support migrations") unless Base.connection.supports_migrations?
- Base.connection.initialize_schema_information
+ Base.connection.initialize_schema_migrations_table
@direction, @migrations_path, @target_version = direction, migrations_path, target_version
end
@@ -383,25 +397,31 @@ module ActiveRecord
def migrate
current = migrations.detect { |m| m.version == current_version }
target = migrations.detect { |m| m.version == @target_version }
-
+
if target.nil? && !@target_version.nil? && @target_version > 0
raise UnknownMigrationVersionError.new(@target_version)
end
- start = migrations.index(current) || 0
- finish = migrations.index(target) || migrations.size - 1
+ start = up? ? 0 : (migrations.index(current) || 0)
+ finish = migrations.index(target) || migrations.size - 1
runnable = migrations[start..finish]
- # skip the current migration if we're heading upwards
- runnable.shift if up? && runnable.first == current
-
# skip the last migration if we're headed down, but not ALL the way down
runnable.pop if down? && !target.nil?
runnable.each do |migration|
Base.logger.info "Migrating to #{migration} (#{migration.version})"
- migration.migrate(@direction)
- set_schema_version_after_migrating(migration)
+
+ # On our way up, we skip migrating the ones we've already migrated
+ # On our way down, we skip reverting the ones we've never migrated
+ next if up? && migrated.include?(migration.version.to_i)
+
+ if down? && !migrated.include?(migration.version.to_i)
+ migration.announce 'never migrated, skipping'; migration.write
+ else
+ migration.migrate(@direction)
+ record_version_state_after_migrating(migration.version)
+ end
end
end
@@ -412,7 +432,7 @@ module ActiveRecord
migrations = files.inject([]) do |klasses, file|
version, name = file.scan(/([0-9]+)_([_a-z0-9]*).rb/).first
- raise IllegalMigrationNameError.new(f) unless version
+ raise IllegalMigrationNameError.new(file) unless version
version = version.to_i
if klasses.detect { |m| m.version == version }
@@ -433,19 +453,24 @@ module ActiveRecord
end
def pending_migrations
- migrations.select { |m| m.version > current_version }
+ already_migrated = migrated
+ migrations.reject { |m| already_migrated.include?(m.version.to_i) }
+ end
+
+ def migrated
+ sm_table = self.class.schema_migrations_table_name
+ Base.connection.select_values("SELECT version FROM #{sm_table}").map(&:to_i).sort
end
private
- def set_schema_version_after_migrating(migration)
- version = migration.version
-
+ def record_version_state_after_migrating(version)
+ sm_table = self.class.schema_migrations_table_name
+
if down?
- after = migrations[migrations.index(migration) + 1]
- version = after ? after.version : 0
+ Base.connection.update("DELETE FROM #{sm_table} WHERE version = '#{version}'")
+ else
+ Base.connection.insert("INSERT INTO #{sm_table} (version) VALUES ('#{version}')")
end
-
- Base.connection.update("UPDATE #{self.class.schema_info_table_name} SET version = #{version}")
end
def up?
diff --git a/activerecord/lib/active_record/schema.rb b/activerecord/lib/active_record/schema.rb
index 9d50efb74f..d6b254fcf9 100644
--- a/activerecord/lib/active_record/schema.rb
+++ b/activerecord/lib/active_record/schema.rb
@@ -34,24 +34,17 @@ module ActiveRecord
# #add_index, etc.).
#
# The +info+ hash is optional, and if given is used to define metadata
- # about the current schema (like the schema's version):
+ # about the current schema (currently, only the schema's version):
#
- # ActiveRecord::Schema.define(:version => 15) do
+ # ActiveRecord::Schema.define(:version => 20380119000001) do
# ...
# end
def self.define(info={}, &block)
instance_eval(&block)
- unless info.empty?
- initialize_schema_information
- cols = columns('schema_info')
-
- info = info.map do |k,v|
- v = Base.connection.quote(v, cols.detect { |c| c.name == k.to_s })
- "#{k} = #{v}"
- end
-
- Base.connection.update "UPDATE #{Migrator.schema_info_table_name} SET #{info.join(", ")}"
+ unless info[:version].blank?
+ initialize_schema_migrations_table
+ assume_migrated_upto_version info[:version]
end
end
end
diff --git a/activerecord/lib/active_record/schema_dumper.rb b/activerecord/lib/active_record/schema_dumper.rb
index 286306874e..826662d3ee 100644
--- a/activerecord/lib/active_record/schema_dumper.rb
+++ b/activerecord/lib/active_record/schema_dumper.rb
@@ -30,11 +30,11 @@ module ActiveRecord
def initialize(connection)
@connection = connection
@types = @connection.native_database_types
- @info = @connection.select_one("SELECT * FROM schema_info") rescue nil
+ @version = Migrator::current_version rescue nil
end
def header(stream)
- define_params = @info ? ":version => #{@info['version']}" : ""
+ define_params = @version ? ":version => #{@version}" : ""
stream.puts <<HEADER
# This file is auto-generated from the current state of the database. Instead of editing this file,
@@ -59,7 +59,7 @@ HEADER
def tables(stream)
@connection.tables.sort.each do |tbl|
- next if ["schema_info", ignore_tables].flatten.any? do |ignored|
+ next if ['schema_migrations', ignore_tables].flatten.any? do |ignored|
case ignored
when String; tbl == ignored
when Regexp; tbl =~ ignored
diff --git a/activerecord/test/cases/ar_schema_test.rb b/activerecord/test/cases/ar_schema_test.rb
index 9fdd8398b7..431dc7a141 100644
--- a/activerecord/test/cases/ar_schema_test.rb
+++ b/activerecord/test/cases/ar_schema_test.rb
@@ -25,8 +25,8 @@ if ActiveRecord::Base.connection.supports_migrations?
end
assert_nothing_raised { @connection.select_all "SELECT * FROM fruits" }
- assert_nothing_raised { @connection.select_all "SELECT * FROM schema_info" }
- assert_equal 7, @connection.select_one("SELECT version FROM schema_info")['version'].to_i
+ assert_nothing_raised { @connection.select_all "SELECT * FROM schema_migrations" }
+ assert_equal 7, ActiveRecord::Migrator::current_version
end
end
diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb
index eb6723bbf3..885d89b6da 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -7,6 +7,7 @@ require 'models/topic'
require MIGRATIONS_ROOT + "/valid/1_people_have_last_names"
require MIGRATIONS_ROOT + "/valid/2_we_need_reminders"
require MIGRATIONS_ROOT + "/decimal/1_give_me_big_numbers"
+require MIGRATIONS_ROOT + "/interleaved/pass_3/2_i_raise_on_down"
if ActiveRecord::Base.connection.supports_migrations?
class BigNumber < ActiveRecord::Base; end
@@ -34,8 +35,8 @@ if ActiveRecord::Base.connection.supports_migrations?
end
def teardown
- ActiveRecord::Base.connection.initialize_schema_information
- ActiveRecord::Base.connection.update "UPDATE #{ActiveRecord::Migrator.schema_info_table_name} SET version = 0"
+ ActiveRecord::Base.connection.initialize_schema_migrations_table
+ ActiveRecord::Base.connection.execute "DELETE FROM #{ActiveRecord::Migrator.schema_migrations_table_name}"
%w(reminders people_reminders prefix_reminders_suffix).each do |table|
Reminder.connection.drop_table(table) rescue nil
@@ -779,6 +780,39 @@ if ActiveRecord::Base.connection.supports_migrations?
assert !Reminder.table_exists?
end
+ def test_finds_migrations
+ migrations = ActiveRecord::Migrator.new(:up, MIGRATIONS_ROOT + "/valid").migrations
+ [['1', 'people_have_last_names'],
+ ['2', 'we_need_reminders'],
+ ['3', 'innocent_jointable']].each_with_index do |pair, i|
+ migrations[i].version == pair.first
+ migrations[1].name == pair.last
+ end
+ end
+
+ def test_finds_pending_migrations
+ ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/interleaved/pass_2", 1)
+ migrations = ActiveRecord::Migrator.new(:up, MIGRATIONS_ROOT + "/interleaved/pass_2").pending_migrations
+ assert_equal 1, migrations.size
+ migrations[0].version == '3'
+ migrations[0].name == 'innocent_jointable'
+ end
+
+ def test_migrator_interleaved_migrations
+ ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/interleaved/pass_1")
+
+ assert_nothing_raised do
+ ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/interleaved/pass_2")
+ end
+
+ Person.reset_column_information
+ assert Person.column_methods_hash.include?(:last_name)
+
+ assert_nothing_raised do
+ ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/interleaved/pass_3")
+ end
+ end
+
def test_migrator_verbosity
ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1)
assert PeopleHaveLastNames.message_count > 0
@@ -817,16 +851,16 @@ if ActiveRecord::Base.connection.supports_migrations?
assert_equal(3, ActiveRecord::Migrator.current_version)
ActiveRecord::Migrator.rollback(MIGRATIONS_ROOT + "/valid")
- assert_equal(2, ActiveRecord::Migrator.current_version)
+ assert_equal(2, ActiveRecord::Migrator.current_version)
ActiveRecord::Migrator.rollback(MIGRATIONS_ROOT + "/valid")
- assert_equal(1, ActiveRecord::Migrator.current_version)
+ assert_equal(1, ActiveRecord::Migrator.current_version)
ActiveRecord::Migrator.rollback(MIGRATIONS_ROOT + "/valid")
- assert_equal(0, ActiveRecord::Migrator.current_version)
+ assert_equal(0, ActiveRecord::Migrator.current_version)
ActiveRecord::Migrator.rollback(MIGRATIONS_ROOT + "/valid")
- assert_equal(0, ActiveRecord::Migrator.current_version)
+ assert_equal(0, ActiveRecord::Migrator.current_version)
end
def test_migrator_run
@@ -839,15 +873,15 @@ if ActiveRecord::Base.connection.supports_migrations?
assert_equal(0, ActiveRecord::Migrator.current_version)
end
- def test_schema_info_table_name
+ def test_schema_migrations_table_name
ActiveRecord::Base.table_name_prefix = "prefix_"
ActiveRecord::Base.table_name_suffix = "_suffix"
Reminder.reset_table_name
- assert_equal "prefix_schema_info_suffix", ActiveRecord::Migrator.schema_info_table_name
+ assert_equal "prefix_schema_migrations_suffix", ActiveRecord::Migrator.schema_migrations_table_name
ActiveRecord::Base.table_name_prefix = ""
ActiveRecord::Base.table_name_suffix = ""
Reminder.reset_table_name
- assert_equal "schema_info", ActiveRecord::Migrator.schema_info_table_name
+ assert_equal "schema_migrations", ActiveRecord::Migrator.schema_migrations_table_name
ensure
ActiveRecord::Base.table_name_prefix = ""
ActiveRecord::Base.table_name_suffix = ""
diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb
index d96bd62e56..ba8bff3b44 100644
--- a/activerecord/test/cases/schema_dumper_test.rb
+++ b/activerecord/test/cases/schema_dumper_test.rb
@@ -16,7 +16,7 @@ if ActiveRecord::Base.connection.respond_to?(:tables)
output = standard_dump
assert_match %r{create_table "accounts"}, output
assert_match %r{create_table "authors"}, output
- assert_no_match %r{create_table "schema_info"}, output
+ assert_no_match %r{create_table "schema_migrations"}, output
end
def test_schema_dump_excludes_sqlite_sequence
@@ -81,7 +81,7 @@ if ActiveRecord::Base.connection.respond_to?(:tables)
output = stream.string
assert_no_match %r{create_table "accounts"}, output
assert_match %r{create_table "authors"}, output
- assert_no_match %r{create_table "schema_info"}, output
+ assert_no_match %r{create_table "schema_migrations"}, output
end
def test_schema_dump_with_regexp_ignored_table
@@ -92,7 +92,7 @@ if ActiveRecord::Base.connection.respond_to?(:tables)
output = stream.string
assert_no_match %r{create_table "accounts"}, output
assert_match %r{create_table "authors"}, output
- assert_no_match %r{create_table "schema_info"}, output
+ assert_no_match %r{create_table "schema_migrations"}, output
end
def test_schema_dump_illegal_ignored_table_value
diff --git a/activerecord/test/migrations/interleaved/pass_1/3_innocent_jointable.rb b/activerecord/test/migrations/interleaved/pass_1/3_innocent_jointable.rb
new file mode 100644
index 0000000000..21c9ca5328
--- /dev/null
+++ b/activerecord/test/migrations/interleaved/pass_1/3_innocent_jointable.rb
@@ -0,0 +1,12 @@
+class InnocentJointable < ActiveRecord::Migration
+ def self.up
+ create_table("people_reminders", :id => false) do |t|
+ t.column :reminder_id, :integer
+ t.column :person_id, :integer
+ end
+ end
+
+ def self.down
+ drop_table "people_reminders"
+ end
+end \ No newline at end of file
diff --git a/activerecord/test/migrations/interleaved/pass_2/1_people_have_last_names.rb b/activerecord/test/migrations/interleaved/pass_2/1_people_have_last_names.rb
new file mode 100644
index 0000000000..81af5fef5e
--- /dev/null
+++ b/activerecord/test/migrations/interleaved/pass_2/1_people_have_last_names.rb
@@ -0,0 +1,9 @@
+class PeopleHaveLastNames < ActiveRecord::Migration
+ def self.up
+ add_column "people", "last_name", :string
+ end
+
+ def self.down
+ remove_column "people", "last_name"
+ end
+end \ No newline at end of file
diff --git a/activerecord/test/migrations/interleaved/pass_2/3_innocent_jointable.rb b/activerecord/test/migrations/interleaved/pass_2/3_innocent_jointable.rb
new file mode 100644
index 0000000000..21c9ca5328
--- /dev/null
+++ b/activerecord/test/migrations/interleaved/pass_2/3_innocent_jointable.rb
@@ -0,0 +1,12 @@
+class InnocentJointable < ActiveRecord::Migration
+ def self.up
+ create_table("people_reminders", :id => false) do |t|
+ t.column :reminder_id, :integer
+ t.column :person_id, :integer
+ end
+ end
+
+ def self.down
+ drop_table "people_reminders"
+ end
+end \ No newline at end of file
diff --git a/activerecord/test/migrations/interleaved/pass_3/1_people_have_last_names.rb b/activerecord/test/migrations/interleaved/pass_3/1_people_have_last_names.rb
new file mode 100644
index 0000000000..81af5fef5e
--- /dev/null
+++ b/activerecord/test/migrations/interleaved/pass_3/1_people_have_last_names.rb
@@ -0,0 +1,9 @@
+class PeopleHaveLastNames < ActiveRecord::Migration
+ def self.up
+ add_column "people", "last_name", :string
+ end
+
+ def self.down
+ remove_column "people", "last_name"
+ end
+end \ No newline at end of file
diff --git a/activerecord/test/migrations/interleaved/pass_3/2_i_raise_on_down.rb b/activerecord/test/migrations/interleaved/pass_3/2_i_raise_on_down.rb
new file mode 100644
index 0000000000..9b1ce9f017
--- /dev/null
+++ b/activerecord/test/migrations/interleaved/pass_3/2_i_raise_on_down.rb
@@ -0,0 +1,8 @@
+class IRaiseOnDown < ActiveRecord::Migration
+ def self.up
+ end
+
+ def self.down
+ raise
+ end
+end \ No newline at end of file
diff --git a/activerecord/test/migrations/interleaved/pass_3/3_innocent_jointable.rb b/activerecord/test/migrations/interleaved/pass_3/3_innocent_jointable.rb
new file mode 100644
index 0000000000..21c9ca5328
--- /dev/null
+++ b/activerecord/test/migrations/interleaved/pass_3/3_innocent_jointable.rb
@@ -0,0 +1,12 @@
+class InnocentJointable < ActiveRecord::Migration
+ def self.up
+ create_table("people_reminders", :id => false) do |t|
+ t.column :reminder_id, :integer
+ t.column :person_id, :integer
+ end
+ end
+
+ def self.down
+ drop_table "people_reminders"
+ end
+end \ No newline at end of file
diff --git a/activerecord/test/schema/sybase.drop.sql b/activerecord/test/schema/sybase.drop.sql
index ebb91931fb..1a2cc9ff56 100644
--- a/activerecord/test/schema/sybase.drop.sql
+++ b/activerecord/test/schema/sybase.drop.sql
@@ -31,5 +31,5 @@ DROP TABLE legacy_things
DROP TABLE numeric_data
DROP TABLE mixed_case_monkeys
DROP TABLE minimalistics
-DROP TABLE schema_info
+DROP TABLE schema_migrations
go