aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyuta Kamizono <kamipo@gmail.com>2018-07-09 11:23:37 +0900
committerRyuta Kamizono <kamipo@gmail.com>2018-07-09 11:23:37 +0900
commit544492d04f10beb007df0db968c24bed140a1c4f (patch)
treeb6c5e9dce107ea93e5bc7b89e70d2fd9caef916f
parentf7c5a8ce262cf16ad8d7c0b0d631a4b88afec414 (diff)
downloadrails-544492d04f10beb007df0db968c24bed140a1c4f.tar.gz
rails-544492d04f10beb007df0db968c24bed140a1c4f.tar.bz2
rails-544492d04f10beb007df0db968c24bed140a1c4f.zip
SQLite: Don't leak internal schema objects
Related #31201. If creating custom primary key (like a string) in SQLite, it would also create an internal index implicitly which named begin with "sqlite_". It need to be hidden since the internal object names are reserved and prohibited for public use. See https://www.sqlite.org/fileformat2.html#intschema Fixes #33320.
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements.rb6
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb3
-rw-r--r--activerecord/test/cases/primary_keys_test.rb1
3 files changed, 6 insertions, 4 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements.rb
index 58e5138e02..24e7bc65fa 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements.rb
@@ -7,6 +7,10 @@ module ActiveRecord
# Returns an array of indexes for the given table.
def indexes(table_name)
exec_query("PRAGMA index_list(#{quote_table_name(table_name)})", "SCHEMA").map do |row|
+ # Indexes SQLite creates implicitly for internal use start with "sqlite_".
+ # See https://www.sqlite.org/fileformat2.html#intschema
+ next if row["name"].starts_with?("sqlite_")
+
index_sql = query_value(<<-SQL, "SCHEMA")
SELECT sql
FROM sqlite_master
@@ -40,7 +44,7 @@ module ActiveRecord
where: where,
orders: orders
)
- end
+ end.compact
end
def create_schema_dumper(options)
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
index 844af952c1..bee74dc33d 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
@@ -457,9 +457,6 @@ module ActiveRecord
def copy_table_indexes(from, to, rename = {})
indexes(from).each do |index|
name = index.name
- # indexes sqlite creates for internal use start with `sqlite_` and
- # don't need to be copied
- next if name.starts_with?("sqlite_")
if to == "a#{from}"
name = "t#{name}"
elsif from == "a#{to}"
diff --git a/activerecord/test/cases/primary_keys_test.rb b/activerecord/test/cases/primary_keys_test.rb
index 60dac91ec9..4ed7469039 100644
--- a/activerecord/test/cases/primary_keys_test.rb
+++ b/activerecord/test/cases/primary_keys_test.rb
@@ -305,6 +305,7 @@ class PrimaryKeyAnyTypeTest < ActiveRecord::TestCase
test "schema dump primary key includes type and options" do
schema = dump_table_schema "barcodes"
assert_match %r{create_table "barcodes", primary_key: "code", id: :string, limit: 42}, schema
+ assert_no_match %r{t\.index \["code"\]}, schema
end
if current_adapter?(:Mysql2Adapter) && subsecond_precision_supported?