aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test
Commit message (Collapse)AuthorAgeFilesLines
* SQLite3 adapter supports expression indexesgkemmey2018-09-132-5/+49
|
* Merge pull request #33378 from numbata/subclass-redefine-autosave-callbacksRafael Mendonça França2018-09-132-0/+25
|\ | | | | | | Allow subclasses to redefine autosave callbacks for associated records
| * Allow subclasses to redefine autosave callbacks for associated recordsAndrey Subbota2018-07-272-0/+25
| |
* | Merge pull request #33844 from kamipo/too_many_eager_load_idsRyuta Kamizono2018-09-134-0/+19
|\ \ | | | | | | Eager loading/preloading should be worked regardless of large number of records
| * | Eager loading/preloading should be worked regardless of large number of recordsRyuta Kamizono2018-09-124-0/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Since 213796f, bind params are used for IN clause if enabled prepared statements. Unfortunately, most adapter modules have a limitation for # of bind params (mysql2 65535, pg 65535, sqlite3 250000). So if eager loading large number of records at once, that query couldn't be sent to the database. Since eager loading/preloading queries are auto-generated by Active Record itself, so it should be worked regardless of large number of records like as before. Fixes #33702.
* | | DRY `activerecord/lib/active_record/core.rb` and fix testsbogdanvlviv2018-09-121-14/+18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - Move ``` filter_attributes = self.filter_attributes.map(&:to_s).to_set filter_attributes.include?(attribute_name) && !read_attribute(attribute_name).nil? ``` to private method. - Fix tests in `activerecord/test/cases/filter_attributes_test.rb` - Ensure that `teardown` sets `ActiveRecord::Base.filter_attributes` to previous state. - Ensure that `Admin::Account.filter_attributes` is set to previous state in the "filter_attributes could be overwritten by models" test. Follow up #33756
* | | Use utf8mb4 character set by default for MySQL database (#33608)Yasuo Honda2018-09-114-7/+7
|/ / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Use utf8mb4 character set by default `utf8mb4` character set supports supplementary characters including emoji. `utf8` character set with 3-Byte encoding is not enough to support them. There was a downside of 4-Byte length character set with MySQL 5.5 and 5.6: "ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes" for Rails string data type which is mapped to varchar(255) type. MySQL 5.7 supports 3072 byte key prefix length by default. * Remove `DEFAULT COLLATE` from Active Record unit test databases There should be no "one size fits all" collation in MySQL 5.7. Let MySQL server choose the default collation for Active Record unit test databases. Users can choose their best collation for their databases by setting `options[:collation]` based on their requirements. * InnoDB FULLTEXT indexes support since MySQL 5.6 it does not have to use MyISAM storage engine whose maximum key length is 1000 bytes. Using MyISAM storag engine with utf8mb4 character set would cause "Specified key was too long; max key length is 1000 bytes" https://dev.mysql.com/doc/refman/5.6/en/innodb-fulltext-index.html * References "10.9.1 The utf8mb4 Character Set (4-Byte UTF-8 Unicode Encoding)" https://dev.mysql.com/doc/refman/5.7/en/charset-unicode-utf8mb4.html "10.9.2 The utf8mb3 Character Set (3-Byte UTF-8 Unicode Encoding)" https://dev.mysql.com/doc/refman/5.7/en/charset-unicode-utf8.html "14.8.1.7 Limits on InnoDB Tables" https://dev.mysql.com/doc/refman/5.7/en/innodb-restrictions.html > If innodb_large_prefix is enabled (the default), the index key prefix limit is 3072 bytes > for InnoDB tables that use DYNAMIC or COMPRESSED row format. * CI against MySQL 5.7 Followed this instruction and changed root password to empty string. https://docs.travis-ci.com/user/database-setup/#MySQL-57 * The recommended minimum version of MySQL is 5.7.9 to support utf8mb4 character set and `innodb_default_row_format` MySQL 5.7.9 introduces `innodb_default_row_format` to support 3072 byte length index by default. Users do not have to change MySQL database configuration to support Rails string type. https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_default_row_format https://dev.mysql.com/doc/refman/5.7/en/innodb-restrictions.html > If innodb_large_prefix is enabled (the default), > the index key prefix limit is 3072 bytes for InnoDB tables that use DYNAMIC or COMPRESSED row format. * The recommended minimum version of MariaDB is 10.2.2 MariaDB 10.2.2 is the first version of MariaDB supporting `innodb_default_row_format` Also MariaDB says "MySQL 5.7 is compatible with MariaDB 10.2". - innodb_default_row_format https://mariadb.com/kb/en/library/xtradbinnodb-server-system-variables/#innodb_default_row_format - "MariaDB versus MySQL - Compatibility" https://mariadb.com/kb/en/library/mariadb-vs-mysql-compatibility/ > MySQL 5.7 is compatible with MariaDB 10.2 - "Supported Character Sets and Collations" https://mariadb.com/kb/en/library/supported-character-sets-and-collations/
* | Don't expose `current_scope` for internal useRyuta Kamizono2018-09-111-2/+2
| |
* | Fixes #33610Darwin D Wu2018-09-113-0/+39
| | | | | | | | | | | | | | | | | | | | | | | | In order to avoid double assignments of nested_attributes for `has_many` relations during record initialization, nested_attributes in `create_with` should not be passed into `klass.new` and have them populate during `initialize_internals_callback` with scope attributes. However, `create_with` keys should always have precedence over where clauses, so if there are same keys in both `create_with` and `where_values_hash`, the value in `create_with` should be the one that's used.
* | `supports_xxx?` returns whether a feature is supported by the backendRyuta Kamizono2018-09-084-41/+25
| | | | | | | | Rather than a configuration on the connection.
* | Configuration item `config.filter_parameters` could also filter out ↵Zhang Kang2018-09-071-0/+80
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | sensitive value of database column when call `#inspect` * Why Some sensitive data will be exposed in log accidentally by calling `#inspect`, e.g. ```ruby @account = Account.find params[:id] payload = { account: @account } logger.info "payload will be #{ payload }" ``` All the information of `@account` will be exposed in log. * Solution Add a class attribute filter_attributes to specify which values of columns shouldn't be exposed. This attribute equals to `Rails.application.config.filter_parameters` by default. ```ruby Rails.application.config.filter_parameters += [:credit_card_number] Account.last.insepct # => #<Account id: 123, credit_card_number: [FILTERED] ...> ```
* | Deprecate most methods which were never used in `DatabaseLimits`Ryuta Kamizono2018-09-051-0/+28
| | | | | | | | | | | | | | | | | | `DatabaseLimits` and those methods were introduced at 3809c80, but most methods were never used and never tested from the beginning (except `table_alias_length`, `index_name_length`, and `in_clause_length` (since 66c09372)). There is no reason to maintain unused those methods for about 8 years.
* | Fix tests in `activerecord/test/cases/tasks/database_tasks_test.rb`bogdanvlviv2018-09-042-684/+120
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | After #33637 some tests in `activerecord/test/cases/tasks/database_tasks_test.rb` don't assert anything. We used to stub `ActiveRecord::Base::configurations` method in those tests like `ActiveRecord::Base.stub(:configurations, @configurations) {}`. Since #33637 `ActiveRecord::Base::configurations` is a `ActiveRecord::DatabaseConfigurations` object(not a Hash object) we can't do so anymore. `ActiveRecord::DatabaseConfigurations` object builds during `ActiveRecord::Base::configurations=`. We can replace `ActiveRecord::Base.stub(:configurations, @configurations) {}` to ``` begin old_configurations = ActiveRecord::Base.configurations ActiveRecord::Base.configurations = @configurations # ... ensure ActiveRecord::Base.configurations = old_configurations end ``` Also I fixed tests in `activerecord/test/cases/tasks/legacy_database_tasks_test.rb` But currently It looks like duplication of `activerecord/test/cases/tasks/database_tasks_test.rb`. We should improve those tests or remove them. I've tried (in `activerecord/test/cases/tasks/legacy_database_tasks_test.rb` file): ``` def with_stubbed_configurations old_configurations = ActiveRecord::Base.configurations.to_h ActiveRecord::Base.configurations = @configurations ActiveRecord::Base.stub(:configurations, ActiveRecord::Base.configurations.to_h) do yield end ensure ActiveRecord::Base.configurations = old_configurations end ``` but it causes erros in tests cases. After discussion we decided to remove `activerecord/test/cases/tasks/legacy_database_tasks_test.rb` Related to #33637
* | Merge pull request #33673 from ↵Ryuta Kamizono2018-09-033-1/+26
|\ \ | | | | | | | | | | | | tgxworld/regression_setting_children_record_in_parent_before_save Fix regression setting children record in parent before_save callback.
| * | Fix regression setting children record in parent before_save callback.Guo Xiang Tan2018-09-033-1/+26
| | |
* | | add mysql and sqlite3 default testkenjiszk2018-09-013-3/+23
|/ / | | | | | | [Gannon McGibbon + Kenji Suzuki]
* | Remove redundant `travel_back`yuuji.yaginuma2018-08-311-2/+0
| | | | | | | | Since #29860, `travel_back` automatically called at the end of the test.
* | Just delegate `update` with ids on a relation to `klass.update`Ryuta Kamizono2018-08-311-0/+18
| | | | | | | | | | | | | | | | | | | | | | | | This restores an ability that `update` with ids on a relation which is described at https://github.com/rails/rails/issues/33470#issuecomment-411203013. I personally think that the `update` with two arguments on a relation is not a designed feature, since that is totally not using a relation state, and also is not documented. But removing any feature should not be suddenly happened in a stable version even if that is not documented.
* | Merge pull request #33637 from eileencodes/ar-connection-management-refactoringEileen M. Uchitelle2018-08-306-74/+731
|\ \ | | | | | | Refactor Active Record configurations
| * | Refactors Active Record connection managementEileen Uchitelle2018-08-306-74/+731
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | While the three-tier config makes it easier to define databases for multiple database applications, it quickly became clear to offer full support for multiple databases we need to change the way the connections hash was handled. A three-tier config means that when Rails needed to choose a default configuration (in the case a user doesn't ask for a specific configuration) it wasn't clear to Rails which the default was. I [bandaid fixed this so the rake tasks could work](#32271) but that fix wasn't correct because it actually doubled up the configuration hashes. Instead of attemping to manipulate the hashes @tenderlove and I decided that it made more sense if we converted the hashes to objects so we can easily ask those object questions. In a three tier config like this: ``` development: primary: database: "my_primary_db" animals: database; "my_animals_db" ``` We end up with an object like this: ``` @configurations=[ #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",@spec_name="primary", @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>, #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90 @env_name="development",@spec_name="animals", @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}> ]> ``` The configurations setter takes the database configuration set by your application and turns them into an `ActiveRecord::DatabaseConfigurations` object that has one getter - `@configurations` which is an array of all the database objects. The configurations getter returns this object by default since it acts like a hash in most of the cases we need. For example if you need to access the default `development` database we can simply request it as we did before: ``` ActiveRecord::Base.configurations["development"] ``` This will return primary development database configuration hash: ``` { "database" => "my_primary_db" } ``` Internally all of Active Record has been converted to use the new objects. I've built this to be backwards compatible but allow for accessing the hash if needed for a deprecation period. To get the original hash instead of the object you can either add `to_h` on the configurations call or pass `legacy: true` to `configurations. ``` ActiveRecord::Base.configurations.to_h => { "development => { "database" => "my_primary_db" } } ActiveRecord::Base.configurations(legacy: true) => { "development => { "database" => "my_primary_db" } } ``` The new configurations object allows us to iterate over the Active Record configurations without losing the known environment or specification name for that configuration. You can also select all the configs for an env or env and spec. With this we can always ask any object what environment it belongs to: ``` db_configs = ActiveRecord::Base.configurations.configurations_for("development") => #<ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800 @configurations=[ #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",@spec_name="primary", @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}>, #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90 @env_name="development",@spec_name="animals", @config={"adapter"=>"sqlite3", "database"=>"db/development.sqlite3"}> ]> db_config.env_name => "development" db_config.spec_name => "primary" db_config.config => { "adapter"=>"sqlite3", "database"=>"db/development.sqlite3" } ``` The configurations object is more flexible than the configurations hash and will allow us to build on top of the connection management in order to add support for primary/replica connections, sharding, and constructing queries for associations that live in multiple databases.
* | | Add missing requireyuuji.yaginuma2018-08-301-0/+1
| | | | | | | | | | | | | | | Without this, `inverse_associations_test.rb` breaks when running in isolation. https://travis-ci.org/rails/rails/jobs/422266840#L1894-L1899
* | | Merge pull request #33729 from kddeisz/plural-automatic-inverseRafael França2018-08-291-0/+11
|\ \ \ | |/ / |/| | Find inverse associations with plural names
| * | Find inverse associations with plural namesKevin Deisz2018-08-271-0/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously ActiveRecord couldn't find inverse associations if they were plural, which is a pretty standard use case. This commit changes the behavior to first attempt to find the singular version, then attempt to find the plural version. That makes it work and find plural associations as in the example below: ``` class Post has_many :comments end class Comment belongs_to :post end ``` Previously the `:post` association reflection would only attempt to find a `comment` inverse, as opposed to both a `comment` and `comments` inverse.
* | | Prevent leaking of user's DB credentials on `rails db:create` failurebogdanvlviv2018-08-292-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Issue #27852 reports that when `rails db:create` fails, it causes leaking of user's DB credentials to $stderr. We print a DB's configuration hash in order to help users more quickly to figure out what could be wrong with his configuration. This commit changes message from "Couldn't create database for #{configuration.inspect}" to "Couldn't create '#{configuration['database']}' database. Please check your configuration.". There are two PRs that fixing it #27878, #27879, but they need a bit more work. I decided help to finish this and added Author of those PRs credit in this commit. Since it is a security issue, I think we should backport it to `5-2-stable`, and `5-1-stable`. Guided by https://edgeguides.rubyonrails.org/maintenance_policy.html#security-issues Fixes #27852 Closes #27879 Related to #27878 [Alexander Marrs & bogdanvlviv]
* | | Merge pull request #33718 from kddeisz/permit-listMatthew Draper2018-08-293-5/+5
|\ \ \ | | | | | | | | Finish converting whitelist and blacklist references
| * | | Permit list usage cleanup and clearer documentationKevin Deisz2018-08-273-5/+5
| | | |
| * | | Convert remaining usage of whitelist and blacklistKevin Deisz2018-08-241-3/+3
| | | |
| * | | Convert over the rest of the whitelist referencesKevin Deisz2018-08-242-2/+2
| | | |
* | | | Mutation tracker should be cleared before continuing around callbacksYuya Tanaka2018-08-281-0/+20
| |/ / |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `changes_applied` should be called before continuing around callback chain. Otherwise the mutation tracker returns old value for methods like `changed`? or `id_in_database` in around callbacks. Also methods depend on `id_in_database`, like `update_column`, are not working in `around_create` callbacks. ``` class Foo < ActiveRecord::Base around_create :around_create_callback def around_create_callback ... yield p id_in_database # => nil update_column(:generated_column, generate_value) # silently fails end ... end ```
* | | Remove unused requiresRyuta Kamizono2018-08-251-3/+1
| | |
* | | Merge pull request #33661 from jychen7/33428-test-has-many-association-enumRyuta Kamizono2018-08-251-0/+22
|\ \ \ | |/ / |/| | Add test case to test enum in has_many
| * | Add test case to test enum in has_manyRich2018-08-251-0/+22
| | | | | | | | | | | | | | | | | | There is test in has_one to test enum, but there is no for has_many. [Rich Chen]
* | | Merge pull request #31696 from BrentWheeldon/bmw-connection-pool-load-deadlockMatthew Draper2018-08-241-0/+38
|\ \ \ | |/ / |/| | Prevent deadlocks when waiting for connection from pool.
| * | Prevent deadlocks when waiting for connection from pool.Brent Wheeldon2018-03-231-0/+38
| | | | | | | | | | | | | | | When a thread that had the load interlock but was blocked waiting to check a connection out of the connection pool but all of the threads using the available connections were blocked waiting to obtain the load interlock an `ActiveRecord::ConnectionTimeoutError` exception was be thrown by the thread waiting for the connection. When waiting for the connection to check out we should allow loading to proceed to avoid this deadlock.
* | | Fix typo s/Topic/Tag/Ryuta Kamizono2018-08-231-1/+1
| | | | | | | | | | | | `Topic` isn't loaded in this test file.
* | | Merge pull request #32647 from eugeneius/lazy_transactionsMatthew Draper2018-08-238-3/+82
|\ \ \ | | | | | | | | Omit BEGIN/COMMIT statements for empty transactions
| * | | Omit BEGIN/COMMIT statements for empty transactionsEugene Kenny2018-08-138-3/+82
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If a transaction is opened and closed without any queries being run, we can safely omit the `BEGIN` and `COMMIT` statements, as they only exist to modify the connection's behaviour inside the transaction. This removes the overhead of those statements when saving a record with no changes, which makes workarounds like `save if changed?` unnecessary. This implementation buffers transactions inside the transaction manager and materializes them the next time the connection is used. For this to work, the adapter needs to guard all connection use with a call to `materialize_transactions`. Because of this, adapters must opt in to get this new behaviour by implementing `supports_lazy_transactions?`. If `raw_connection` is used to get a reference to the underlying database connection, the behaviour is disabled and transactions are opened eagerly, as we can't know how the connection will be used. However when the connection is checked back into the pool, we can assume that the application won't use the reference again and reenable lazy transactions. This prevents a single `raw_connection` call from disabling lazy transactions for the lifetime of the connection.
* | | | Merge pull request #33162 from utilum/stop_using_mochaKasper Timm Hansen2018-08-227-53/+88
|\ \ \ \ | | | | | | | | | | Stop using Mocha
| * | | | Add method_call_assertions and use them instead of Mochautilum2018-08-134-36/+58
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Six Mocha calls prove quite resistant to Minitestification. For example, if we replace ``` ActiveRecord::Associations::HasManyAssociation .any_instance .expects(:reader) .never ``` with `assert_not_called`, Minitest wisely raises ``` NameError: undefined method `reader' for class `ActiveRecord::Associations::HasManyAssociation' ``` as `:reader` comes from a deeply embedded abstract class, `ActiveRecord::Associations::CollectionAssociation`. This patch tackles this difficulty by adding `ActiveSupport::Testing::MethodCallAsserts#assert_called_on_instance_of` which injects a stubbed method into `klass`, and verifies the number of times it is called, similar to `assert_called`. It also adds a convenience method, `assert_not_called_on_instance_of`, mirroring `assert_not_called`. It uses the new method_call_assertions to replace the remaining Mocha calls in `ActiveRecord` tests. [utilum + bogdanvlviv + kspath]
| * | | | Stub with Minitest and test with MethodCallAssertionsutilum2018-08-133-17/+30
| |/ / /
* | | | Add database configuration to disable advisory locks.Guo Xiang Tan2018-08-223-0/+41
| | | | | | | | | | | | | | | | https://github.com/rails/rails/issues/31190
* | | | Fix merging relation that order including `?`Ryuta Kamizono2018-08-211-0/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The `Relation::Merger` has a problem that order values would be merged as nested array. That was caused an issue #33664 since if array value is passed to `order` and first element in the array includes `?`, the array is regarded as a prepared statement and bind variables. https://api.rubyonrails.org/classes/ActiveRecord/Sanitization/ClassMethods.html#method-i-sanitize_sql_for_order Just merging that as splat args like other values would fix the issue. Fixes #33664.
* | | | Merge pull request #33652 from tgxworld/improve_tests_pool_configRyuta Kamizono2018-08-202-5/+50
|\ \ \ \ | | | | | | | | | | Improve tests for ActiveRecord::ConnectionAdapters::ConnectionPool co…
| * | | | Speed up slow ConnectionPool test case.Guo Xiang Tan2018-08-201-11/+19
| | | | |
| * | | | Improve tests for ActiveRecord::ConnectionAdapters::ConnectionPool ↵Guo Xiang Tan2018-08-192-2/+39
| | | | | | | | | | | | | | | | | | | | configurations.
* | | | | Merge pull request #33657 from jychen7/fix-test-association-enumRyuta Kamizono2018-08-201-0/+3
|\ \ \ \ \ | | | | | | | | | | | | Improve test case to test enum correctly
| * | | | | Improve test case to test enum correctlyRich2018-08-201-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | without define the enum in class “SpecialBook”, any string status will be casted to integer 0. Then the test have no meaning. [Rich Chen]
* | | | | | SQLite3: Fix rename reference column not to lose foreign key constraintRyuta Kamizono2018-08-201-0/+16
|/ / / / / | | | | | | | | | | | | | | | Fixes #33520.
* / / / / Address intermittent CI failure due to non-determined sort orderRyuta Kamizono2018-08-191-1/+1
|/ / / / | | | | | | | | | | | | https://travis-ci.org/rails/rails/jobs/417783260#L1173-L1179
* | | | Ensure `foreign_keys` assertions after alter tableRyuta Kamizono2018-08-191-1/+5
| | | | | | | | | | | | | | | | | | | | If `foreign_keys` is fetched before alter table, it couldn't notice whether foreign keys are broken or not after alter table.