提交 544492d0 编写于 作者: R Ryuta Kamizono

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.
上级 f7c5a8ce
...@@ -7,6 +7,10 @@ module SchemaStatements # :nodoc: ...@@ -7,6 +7,10 @@ module SchemaStatements # :nodoc:
# Returns an array of indexes for the given table. # Returns an array of indexes for the given table.
def indexes(table_name) def indexes(table_name)
exec_query("PRAGMA index_list(#{quote_table_name(table_name)})", "SCHEMA").map do |row| 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") index_sql = query_value(<<-SQL, "SCHEMA")
SELECT sql SELECT sql
FROM sqlite_master FROM sqlite_master
...@@ -40,7 +44,7 @@ def indexes(table_name) ...@@ -40,7 +44,7 @@ def indexes(table_name)
where: where, where: where,
orders: orders orders: orders
) )
end end.compact
end end
def create_schema_dumper(options) def create_schema_dumper(options)
......
...@@ -457,9 +457,6 @@ def copy_table(from, to, options = {}) ...@@ -457,9 +457,6 @@ def copy_table(from, to, options = {})
def copy_table_indexes(from, to, rename = {}) def copy_table_indexes(from, to, rename = {})
indexes(from).each do |index| indexes(from).each do |index|
name = index.name 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}" if to == "a#{from}"
name = "t#{name}" name = "t#{name}"
elsif from == "a#{to}" elsif from == "a#{to}"
......
...@@ -305,6 +305,7 @@ def test_any_type_primary_key ...@@ -305,6 +305,7 @@ def test_any_type_primary_key
test "schema dump primary key includes type and options" do test "schema dump primary key includes type and options" do
schema = dump_table_schema "barcodes" schema = dump_table_schema "barcodes"
assert_match %r{create_table "barcodes", primary_key: "code", id: :string, limit: 42}, schema assert_match %r{create_table "barcodes", primary_key: "code", id: :string, limit: 42}, schema
assert_no_match %r{t\.index \["code"\]}, schema
end end
if current_adapter?(:Mysql2Adapter) && subsecond_precision_supported? if current_adapter?(:Mysql2Adapter) && subsecond_precision_supported?
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册