Permalink
Browse files

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.
  • Loading branch information...
kamipo committed Jul 9, 2018
1 parent b67f57d commit 7fae8e3f5d9a09a8bd024e09f2e953e3b48e4d53
@@ -7,6 +7,10 @@ module SchemaStatements # :nodoc:
# 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 @@ def indexes(table_name)
where: where,
orders: orders
)
end
end.compact
end
def create_schema_dumper(options)
@@ -453,9 +453,6 @@ def copy_table(from, to, options = {})
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}"
@@ -305,6 +305,7 @@ def test_any_type_primary_key
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?

0 comments on commit 7fae8e3

Please sign in to comment.