aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Jones <al2o3cr@gmail.com>2015-02-08 18:36:11 -0500
committerMatt Jones <al2o3cr@gmail.com>2015-02-08 19:06:52 -0500
commit1a836b21b93acd6851bcb4f83c8b2678282d9122 (patch)
treed8c5a57a97b9e53b22d67dafebe3690ce2017541
parent6f8d9bd6da6349d3d179f2e72db5bc7044a8e5c1 (diff)
downloadrails-1a836b21b93acd6851bcb4f83c8b2678282d9122.tar.gz
rails-1a836b21b93acd6851bcb4f83c8b2678282d9122.tar.bz2
rails-1a836b21b93acd6851bcb4f83c8b2678282d9122.zip
Match table names exactly on MySQL
The `SHOW TABLES LIKE` command accepts metacharacters `%` and `_` in potentially unexpected ways. This can be avoided by querying `information_schema.tables` directly. Fixes #17897
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb8
-rw-r--r--activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb8
-rw-r--r--activerecord/test/cases/adapters/mysql2/schema_test.rb8
-rw-r--r--activerecord/test/cases/test_case.rb2
4 files changed, 8 insertions, 18 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index 5c8c4b883a..48e1ec008b 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -422,9 +422,11 @@ module ActiveRecord
end
def tables(name = nil, database = nil, like = nil) #:nodoc:
- sql = "SHOW TABLES "
- sql << "IN #{quote_table_name(database)} " if database
- sql << "LIKE #{quote(like)}" if like
+ database ||= current_database
+
+ sql = "SELECT table_name FROM information_schema.tables "
+ sql << "WHERE table_schema = #{quote(database)}"
+ sql << " AND table_name = #{quote(like)}" if like
execute_and_free(sql, 'SCHEMA') do |result|
result.collect(&:first)
diff --git a/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb b/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb
index 7d0bd24ba7..95980ef0b3 100644
--- a/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb
+++ b/activerecord/test/cases/adapters/mysql/mysql_adapter_test.rb
@@ -66,12 +66,8 @@ module ActiveRecord
end
end
- def test_tables_quoting
- @conn.tables(nil, "foo-bar", nil)
- flunk
- rescue => e
- # assertion for *quoted* database properly
- assert_match(/database 'foo-bar'/, e.inspect)
+ def test_table_exists_with_like_metacharacters
+ assert_not @conn.table_exists?('aut_ors'), 'nonexistent table should not exist'
end
def test_pk_and_sequence_for
diff --git a/activerecord/test/cases/adapters/mysql2/schema_test.rb b/activerecord/test/cases/adapters/mysql2/schema_test.rb
index 47707b7d4f..cbabe1592f 100644
--- a/activerecord/test/cases/adapters/mysql2/schema_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/schema_test.rb
@@ -36,14 +36,6 @@ module ActiveRecord
assert(!@connection.table_exists?("#{@db_name}.zomg"), "table should not exist")
end
- def test_tables_quoting
- @connection.tables(nil, "foo-bar", nil)
- flunk
- rescue => e
- # assertion for *quoted* database properly
- assert_match(/database 'foo-bar'/, e.inspect)
- end
-
def test_dump_indexes
index_a_name = 'index_key_tests_on_snack'
index_b_name = 'index_key_tests_on_pizza'
diff --git a/activerecord/test/cases/test_case.rb b/activerecord/test/cases/test_case.rb
index e0b01ae8e0..fae52195e4 100644
--- a/activerecord/test/cases/test_case.rb
+++ b/activerecord/test/cases/test_case.rb
@@ -79,7 +79,7 @@ module ActiveRecord
# ignored SQL, or better yet, use a different notification for the queries
# instead examining the SQL content.
oracle_ignored = [/^select .*nextval/i, /^SAVEPOINT/, /^ROLLBACK TO/, /^\s*select .* from all_triggers/im, /^\s*select .* from all_constraints/im, /^\s*select .* from all_tab_cols/im]
- mysql_ignored = [/^SHOW TABLES/i, /^SHOW FULL FIELDS/, /^SHOW CREATE TABLE /i, /^SHOW VARIABLES /]
+ mysql_ignored = [/^SHOW TABLES/i, /^SHOW FULL FIELDS/, /^SHOW CREATE TABLE /i, /^SHOW VARIABLES /, /^SELECT DATABASE\(\) as db$/, /^SELECT table_name FROM information_schema\.tables/]
postgresql_ignored = [/^\s*select\b.*\bfrom\b.*pg_namespace\b/im, /^\s*select tablename\b.*from pg_tables\b/im, /^\s*select\b.*\battname\b.*\bfrom\b.*\bpg_attribute\b/im, /^SHOW search_path/i]
sqlite3_ignored = [/^\s*SELECT name\b.*\bFROM sqlite_master/im]