Bump minimum SQLite version to 3.8 #32923
Conversation
(@rails-bot has picked a reviewer for you, use r? to override) |
@@ -48,9 +48,7 @@ def visit_TableDefinition(o) | |||
statements.concat(o.indexes.map { |column_name, options| index_in_create(o.name, column_name, options) }) | |||
end | |||
|
|||
if supports_foreign_keys_in_create? |
matthewd
May 18, 2018
Member
This isn't true for the abstract adapter, so I think we still need the conditional for now. (Or, if we're okay to declare that a baseline requirement, it'd need to change there too.)
This isn't true for the abstract adapter, so I think we still need the conditional for now. (Or, if we're okay to declare that a baseline requirement, it'd need to change there too.)
yahonda
May 20, 2018
Author
Contributor
Make sense. Reverted this change.
Make sense. Reverted this change.
@@ -1062,13 +1062,7 @@ def assume_migrated_upto_version(version, migrations_paths) | |||
if (duplicate = inserting.detect { |v| inserting.count(v) > 1 }) | |||
raise "Duplicate migration #{duplicate}. Please renumber your migrations to resolve the conflict." | |||
end | |||
if supports_multi_insert? |
matthewd
May 18, 2018
Member
👍 happy to kill this one
@@ -140,7 +144,7 @@ def supports_json? | |||
end | |||
|
|||
def supports_multi_insert? |
matthewd
May 18, 2018
Member
I think we can just delete this method and leave the inherited one. And as we're removing the caller, I think we should deprecate the method in the abstract adapter.
I think we can just delete this method and leave the inherited one. And as we're removing the caller, I think we should deprecate the method in the abstract adapter.
yahonda
May 20, 2018
Author
Contributor
Agreed. deprecated supports_multi_insert?
method.
Agreed. deprecated supports_multi_insert?
method.
@@ -192,7 +174,7 @@ def test_schema_dumps_index_columns_in_right_order | |||
|
|||
def test_schema_dumps_partial_indices | |||
index_definition = dump_table_schema("companies").split(/\n/).grep(/t\.index.*company_partial_index/).first.strip | |||
if current_adapter?(:PostgreSQLAdapter, :SQLite3Adapter) && ActiveRecord::Base.connection.supports_partial_index? | |||
if current_adapter?(:PostgreSQLAdapter, :SQLite3Adapter) |
matthewd
May 18, 2018
Member
I'm not sure whether this should be using an adapter type check, or the supports_partial_index?
condition (as we do for index sort order below). Agree it definitely shouldn't be both.
I'm not sure whether this should be using an adapter type check, or the supports_partial_index?
condition (as we do for index sort order below). Agree it definitely shouldn't be both.
yahonda
May 20, 2018
Author
Contributor
Changed the condition to use ActiveRecord::Base.connection.supports_partial_index?
only.
Changed the condition to use ActiveRecord::Base.connection.supports_partial_index?
only.
@@ -104,6 +104,10 @@ def initialize(connection, logger, connection_options, config) | |||
@active = true | |||
@statements = StatementPool.new(self.class.type_cast_config_to_integer(config[:statement_limit])) | |||
|
|||
if sqlite_version < "3.8.0" | |||
raise "Your version of SQLite (#{sqlite_version.inspect.match(/(\[\d+\,\ \d+\,\ \d+\])/)[0]}) is too old. Active Record supports SQLite >= 3.8." |
matthewd
May 18, 2018
Member
Let's add a to_s
to AbstractAdapter::Version.
Let's add a to_s
to AbstractAdapter::Version.
yahonda
May 20, 2018
Author
Contributor
I'm adding to_s
method to AbstractAdapter::Version
. Still, I need to call sqlite_version.to_s
and users will not see unnecessary exceptions here.
I'm adding to_s
method to AbstractAdapter::Version
. Still, I need to call sqlite_version.to_s
and users will not see unnecessary exceptions here.
@@ -137,6 +137,10 @@ def initialize(version_string) | |||
def <=>(version_string) | |||
@version <=> version_string.split(".").map(&:to_i) | |||
end | |||
|
|||
def to_s | |||
@version.to_s |
kamipo
May 20, 2018
Member
@version.join(".")
@version.join(".")
yahonda
May 20, 2018
Author
Contributor
Updated.
Updated.
$stderr.puts <<-EOS.squish | ||
"Your version of SQLite (#{sqlite_version.to_s}) is too old. Active Record supports SQLite >= 3.8." | ||
EOS | ||
exit 1 |
kamipo
May 20, 2018
Member
Is there any reason not to use raise
unlike other adapters?
Is there any reason not to use raise
unlike other adapters?
yahonda
May 20, 2018
Author
Contributor
I'm thinking about implementing version check like #28939 just showing a necessary message for users by omitting stack traces like this.
$ sqlite3 --version
3.7.9 2011-11-01 00:52:41 c7c6050ef060877ebe77b41d959e9df13f8c9b5e
$ bundle exec ruby -w -Itest test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
Using sqlite3
"Your version of SQLite (3.7.9) is too old. Active Record supports SQLite >= 3.8."
$
I'd like to get some feedback on this change. I agree to make all bundled adapters behave similarly for the database version check. then I'll revert this change or open another pull request to change mysql2 and posgresql adapter version checks.
I'm thinking about implementing version check like #28939 just showing a necessary message for users by omitting stack traces like this.
$ sqlite3 --version
3.7.9 2011-11-01 00:52:41 c7c6050ef060877ebe77b41d959e9df13f8c9b5e
$ bundle exec ruby -w -Itest test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
Using sqlite3
"Your version of SQLite (3.7.9) is too old. Active Record supports SQLite >= 3.8."
$
I'd like to get some feedback on this change. I agree to make all bundled adapters behave similarly for the database version check. then I'll revert this change or open another pull request to change mysql2 and posgresql adapter version checks.
kamipo
May 20, 2018
Member
Usually, a library does/should not terminate a process itself.
If a library may terminate a process itself, it hard to handle that case by users.
Usually, a library does/should not terminate a process itself.
If a library may terminate a process itself, it hard to handle that case by users.
yahonda
May 20, 2018
Author
Contributor
Understood. Thanks for the comment.
Understood. Thanks for the comment.
@@ -104,6 +104,13 @@ def initialize(connection, logger, connection_options, config) | |||
@active = true | |||
@statements = StatementPool.new(self.class.type_cast_config_to_integer(config[:statement_limit])) | |||
|
|||
if sqlite_version < "3.8.0" | |||
$stderr.puts <<-EOS.squish | |||
"Your version of SQLite (#{sqlite_version.to_s}) is too old. Active Record supports SQLite >= 3.8." |
kamipo
May 20, 2018
Member
Unneeded the redundant to_s
in string interpolation.
Unneeded the redundant to_s
in string interpolation.
These OS versions have SQLite 3.8 or higher by default. - macOS 10.10 (Yosemite) or higher - Ubuntu 14.04 LTS or higher Raising the minimum version of SQLite 3.8 introduces these changes: - All of bundled adapters support `supports_multi_insert?` - SQLite 3.8 always satisifies `supports_foreign_keys_in_create?` and `supports_partial_index?` - sqlite adapter can support `alter_table` method for foreign key referenced tables by #32865 - Deprecated `supports_multi_insert?` method
To prevent redundant `to_s` like #32923 (comment) automatically in the future.
Unlike other databases, changing SQLite3 table definitions need to create a temporary table. While changing table operations, the original table needs dropped which caused `SQLite3::ConstraintException: FOREIGN KEY constraint failed` if the table is referenced by foreign keys. This pull request disables foreign keys by `disable_referential_integrity`. Also `disable_referential_integrity` method needs to execute `defer_foreign_keys = ON` to defer re-enabling foreign keys until the transaction is committed. https://www.sqlite.org/pragma.html#pragma_defer_foreign_keys Fixes rails#31988 - This `defer_foreign_keys = ON` has been supported since SQLite 3.8.0 https://www.sqlite.org/releaselog/3_8_0.html and Rails 6 requires SQLite 3.8 rails#32923 now - <Models>.reset_column_information added to address `ActiveModel::UnknownAttributeError` ``` Error: ActiveRecord::Migration::ForeignKeyChangeColumnTest#test_change_column_of_parent_table: ActiveModel::UnknownAttributeError: unknown attribute 'name' for ActiveRecord::Migration::ForeignKeyChangeColumnTest::Post. ```
Summary
These OS versions have SQLite 3.8 or higher by default.
Raising the minimum version of SQLite 3.8 introduces these changes:
supports_multi_insert?
supports_foreign_keys_in_create?
andsupports_partial_index?
alter_table
method for foreign key referenced tables by #32865