Permalink
Browse files

Remove custom table_exists? implementations

It is not safe for table_exists? to check the schema for a matching
entry.  The only safe way to operate is to issue a query selecting
from the table name given and see if it raises an exception.

Both the postgres and oracle shared adapters had code that checked
against the database schema, which was fine in the past where
table_exists? also checked for a cached database schema value.
The change for PostgreSQL is not backwards compatible as its custom
implementation accepted an optional options hash.

The PostgreSQL implementation is also not backwards compatible in
that previously, if you were using a table outside the schema search
path, without qualifying it with a schema name, it would return
true instead of false, even though attempting to actually select
from the table would raise an error (since it wouldn't specify the
schema).

Try to be reasonably backwards compatible by automatically using
a default_schema if one exists in table_exists?
  • Loading branch information...
1 parent 61dc406 commit daa3ff1c4f22bfb36ff732c28d95f6a74697c904 @jeremyevans committed Jul 5, 2011
@@ -26,10 +26,6 @@ def tables(opts={})
ds.map{|r| ds.send(:output_identifier, r[:tname])}
end
- def table_exists?(name)
- from(:tab).filter(:tname =>dataset.send(:input_identifier, name), :tabtype => 'TABLE').count > 0
- end
-
def views(opts={})
ds = from(:tab).server(opts[:server]).select(:tname).filter(:tabtype => 'VIEW')
ds.map{|r| ds.send(:output_identifier, r[:tname])}
@@ -368,18 +368,6 @@ def supports_transaction_isolation_levels?
true
end
- # Whether the given table exists in the database
- #
- # Options:
- # * :schema - The schema to search (default_schema by default)
- # * :server - The server to use
- def table_exists?(table, opts={})
- im = input_identifier_meth
- schema, table = schema_and_table(table)
- opts[:schema] ||= schema
- tables(opts){|ds| !ds.first(:relname=>im.call(table)).nil?}
- end
-
# Array of symbols specifying table names in the current database.
# The dataset used is yielded to the block if one is provided,
# otherwise, an array of symbols of table names is returned.
@@ -170,12 +170,12 @@ def schema(table, opts={})
#
# DB.table_exists?(:foo) # => false
def table_exists?(name)
- begin
- from(name).first
- true
- rescue
- false
- end
+ sch, table_name = schema_and_table(name)
+ name = SQL::QualifiedIdentifier.new(sch, table_name) if sch
+ from(name).first
+ true
+ rescue
+ false
end
# Return all tables in the database as an array of symbols.
@@ -606,12 +606,6 @@ def logger.method_missing(m, msg)
POSTGRES_DB.drop_table(:domains)
end
- specify "#table_exists? should not include tables from the default non-public schemas" do
- POSTGRES_DB.create_table(:schema_test__schema_test){integer :i}
- POSTGRES_DB.table_exists?(:schema_test).should == true
- POSTGRES_DB.table_exists?(:domain_udt_usage).should == false
- end
-
specify "#table_exists? should see if the table is in a given schema" do
POSTGRES_DB.create_table(:schema_test__schema_test){integer :i}
POSTGRES_DB.table_exists?(:schema_test__schema_test).should == true

0 comments on commit daa3ff1

Please sign in to comment.