Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bump minimum SQLite version to 3.8 #32923

Merged
merged 1 commit into from
May 21, 2018

Conversation

yahonda
Copy link
Member

@yahonda yahonda commented May 17, 2018

Summary

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:

@rails-bot
Copy link

r? @rafaelfranca

(@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?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 happy to kill this one

@@ -140,7 +144,7 @@ def supports_json?
end

def supports_multi_insert?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add a to_s to AbstractAdapter::Version.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@yahonda yahonda force-pushed the bump_sqlite3_version_to_38 branch from 3e1c66d to b2e1e67 Compare May 20, 2018 13:24
@@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@version.join(".")

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason not to use raise unlike other adapters?

if version < "5.1.10"
raise "Your version of MySQL (#{version_string}) is too old. Active Record supports MySQL >= 5.1.10."
end

if postgresql_version < 90100
raise "Your version of PostgreSQL (#{postgresql_version}) is too old. Active Record supports PostgreSQL >= 9.1."
end

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unneeded the redundant to_s in string interpolation.

@yahonda yahonda force-pushed the bump_sqlite3_version_to_38 branch 2 times, most recently from 56cd2de to c13883f Compare May 20, 2018 23:58
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 rails#32865
- Deprecated `supports_multi_insert?` method
@yahonda yahonda force-pushed the bump_sqlite3_version_to_38 branch from c13883f to d1a74c1 Compare May 21, 2018 04:57
kamipo added a commit that referenced this pull request May 21, 2018
To prevent redundant `to_s` like #32923 (comment)
automatically in the future.
@kamipo kamipo merged commit 054893d into rails:master May 21, 2018
yahonda added a commit to yahonda/rails that referenced this pull request May 22, 2018
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.
```
@yahonda yahonda deleted the bump_sqlite3_version_to_38 branch May 31, 2018 03:41
yahonda added a commit to yahonda/rails that referenced this pull request Jun 1, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants