Skip to content

Commit

Permalink
feat: support schema search path
Browse files Browse the repository at this point in the history
Fixes #276
  • Loading branch information
BuonOmo committed Sep 6, 2023
1 parent 41fff74 commit 3d9a893
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 87 deletions.
55 changes: 31 additions & 24 deletions lib/active_record/connection_adapters/cockroachdb/database_tasks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,37 +10,44 @@ def structure_dump(filename, extra_flags=nil)
"https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/new"
end

case ActiveRecord.dump_schemas
when :all, String
raise "Custom schemas are not supported in CockroachDB. " \
"See https://github.com/cockroachdb/cockroach/issues/26443."
when :schema_search_path
if configuration_hash[:schema_search_path]
raise "Custom schemas are not supported in CockroachDB. " \
"See https://github.com/cockroachdb/cockroach/issues/26443."
# "See https://github.com/cockroachdb/cockroach/issues/26443."
search_path =
case ActiveRecord.dump_schemas
when :schema_search_path
configuration_hash[:schema_search_path]
when :all
nil
when String
ActiveRecord.dump_schemas
end
end

conn = ActiveRecord::Base.connection
File.open(filename, "w") do |file|
%w(SCHEMAS TYPES).each do |object_kind|
ActiveRecord::Base.connection.execute("SHOW CREATE ALL #{object_kind}").each_row { file.puts _1 }
end
begin
old_search_path = conn.schema_search_path
conn.schema_search_path = search_path
File.open(filename, "w") do |file|
%w(SCHEMAS TYPES).each do |object_kind|
ActiveRecord::Base.connection.execute("SHOW CREATE ALL #{object_kind}").each_row { file.puts _1 }
end

ignore_tables = ActiveRecord::SchemaDumper.ignore_tables.to_set
ignore_tables = ActiveRecord::SchemaDumper.ignore_tables.to_set

conn.execute("SHOW CREATE ALL TABLES").each_row do |(sql)|
if sql.start_with?("CREATE")
table_name = sql[/CREATE TABLE (?:.*?\.)?\"?(.*?)[\" ]/, 1]
next if ignore_tables.member?(table_name)
elsif sql.start_with?("ALTER")
table_name = sql[/ALTER TABLE (?:.*?\.)?\"?(.*?)[\" ]/, 1]
ref_table_name = sql[/REFERENCES (?:.*?\.)?\"?(.*?)[\" ]/, 1]
next if ignore_tables.member?(table_name) || ignore_tables.member?(ref_table_name)
end
conn.execute("SHOW CREATE ALL TABLES").each_row do |(sql)|
if sql.start_with?("CREATE")
table_name = sql[/CREATE TABLE (?:.*?\.)?\"?(.*?)[\" ]/, 1]
next if ignore_tables.member?(table_name)
elsif sql.start_with?("ALTER")
table_name = sql[/ALTER TABLE (?:.*?\.)?\"?(.*?)[\" ]/, 1]
ref_table_name = sql[/REFERENCES (?:.*?\.)?\"?(.*?)[\" ]/, 1]
next if ignore_tables.member?(table_name) || ignore_tables.member?(ref_table_name)
end

file.puts sql
file.puts sql
end
file.puts "SET seach_path TO #{conn.schema_search_path};\n\n"
end
ensure
conn.schema_search_path = old_search_path
end
end

Expand Down
17 changes: 7 additions & 10 deletions lib/active_record/connection_adapters/cockroachdb_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -517,14 +517,8 @@ def column_definitions(table_name)

# Use regex comparison because if a type is an array it will
# have [] appended to the end of it.
target_types = [
/geometry/,
/geography/,
/interval/,
/numeric/
]

re = Regexp.union(target_types)
re = /\A(?:geometry|geography|interval|numeric)/

fields.map do |field|
dtype = field[1]
field[1] = crdb_fields[field[0]][2].downcase if re.match(dtype)
Expand All @@ -549,11 +543,14 @@ def column_definitions(table_name)
# precision, and scale information in the type.
# Ex. geometry -> geometry(point, 4326)
def crdb_column_definitions(table_name)
table_name = PostgreSQL::Utils.extract_schema_qualified_name(table_name)
table = table_name.identifier
with_schema = " AND c.table_schema = #{quote(table_name.schema)}" if table_name.schema
fields = \
query(<<~SQL, "SCHEMA")
SELECT c.column_name, c.column_comment, c.crdb_sql_type, c.is_hidden::BOOLEAN
FROM information_schema.columns c
WHERE c.table_name = #{quote(table_name)}
FROM information_schema.columns c
WHERE c.table_name = #{quote(table)}#{with_schema}
SQL

fields.reduce({}) do |a, e|
Expand Down
13 changes: 7 additions & 6 deletions test/excludes/DefaultsUsingMultipleSchemasAndDomainTest.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
exclude :test_text_defaults_in_new_schema_when_overriding_domain, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_string_defaults_in_new_schema_when_overriding_domain, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_decimal_defaults_in_new_schema_when_overriding_domain, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_bpchar_defaults_in_new_schema_when_overriding_domain, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_text_defaults_after_updating_column_default, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_default_containing_quote_and_colons, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
message = "Custom domains are not supported. See https://github.com/cockroachdb/cockroach/issues/27796"
exclude :test_text_defaults_in_new_schema_when_overriding_domain, message
exclude :test_string_defaults_in_new_schema_when_overriding_domain, message
exclude :test_decimal_defaults_in_new_schema_when_overriding_domain, message
exclude :test_bpchar_defaults_in_new_schema_when_overriding_domain, message
exclude :test_text_defaults_after_updating_column_default, message
exclude :test_default_containing_quote_and_colons, message
18 changes: 12 additions & 6 deletions test/excludes/SchemaAuthorizationTest.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
exclude :test_schema_invisible, "Custom schemas (and schema authorizations) are not supported by CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_session_auth=, "Custom schemas (and schema authorizations) are not supported by CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_setting_auth_clears_stmt_cache, "Custom schemas (and schema authorizations) are not supported by CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_auth_with_bind, "Custom schemas (and schema authorizations) are not supported by CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_sequence_schema_caching, "Custom schemas (and schema authorizations) are not supported by CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_tables_in_current_schemas, "Custom schemas (and schema authorizations) are not supported by CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
message = 'CockroachDB does not support variable session authorization. ' \
'See https://github.com/cockroachdb/cockroach/issues/40283'
exclude :test_sequence_schema_caching, message
exclude :test_session_auth=, message
exclude :test_schema_invisible, message
exclude :test_schema_invisible, message
exclude :test_tables_in_current_schemas, message
exclude :test_tables_in_current_schemas, message
exclude :test_auth_with_bind, message
exclude :test_auth_with_bind, message
exclude :test_setting_auth_clears_stmt_cache, message
exclude :test_setting_auth_clears_stmt_cache, message
1 change: 0 additions & 1 deletion test/excludes/SchemaForeignKeyTest.rb

This file was deleted.

81 changes: 43 additions & 38 deletions test/excludes/SchemaTest.rb
Original file line number Diff line number Diff line change
@@ -1,38 +1,43 @@
exclude :test_schema_names, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_create_schema, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_raise_create_schema_with_existing_schema, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_drop_schema, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_drop_schema_if_exists, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_habtm_table_name_with_schema, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_drop_schema_with_nonexisting_schema, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_raise_wrapped_exception_on_bad_prepare, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_schema_change_with_prepared_stmt, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_data_source_exists?, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_data_source_exists_when_on_schema_search_path, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_data_source_exists_when_not_on_schema_search_path, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_data_source_exists_wrong_schema, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_data_source_exists_quoted_names, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_data_source_exists_quoted_table, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_with_schema_prefixed_table_name, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_with_schema_prefixed_capitalized_table_name, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_with_schema_search_path, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_proper_encoding_of_table_name, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_classes_with_qualified_schema_name, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_raise_on_unquoted_schema_name, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_without_schema_search_path, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_ignore_nil_schema_search_path, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_index_name_exists, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_dump_indexes_for_schema_one, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_dump_indexes_for_schema_two, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_dump_indexes_for_schema_multiple_schemas_in_search_path, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_dump_indexes_for_table_with_scheme_specified_in_name, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_with_uppercase_index_name, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_remove_index_when_schema_specified, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_primary_key_with_schema_specified, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_primary_key_assuming_schema_search_path, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_pk_and_sequence_for_with_schema_specified, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_current_schema, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_prepared_statements_with_multiple_schemas, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_schema_exists?, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_reset_pk_sequence, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_set_pk_sequence, "Custom schemas are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/26443."
exclude :test_set_pk_sequence, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48"
exclude :test_pk_and_sequence_for_with_schema_specified, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48"
# This hack allows us to redefine the
# setup. We are using various weird
# routes that might be simplified:
# 1. We use `Ext` to prepend to the
# current class to be sure `#setup`
# is overriden.
# 2. Current is a reference to self to
# access it in `Ext`
# 3. const_missing is used to avoid
# having to rewrite every constant.
Current = self
module Ext
def self.const_missing(const)
Current.const_get(const)
end

def setup
@connection = ActiveRecord::Base.connection
@connection.execute "CREATE SCHEMA #{SCHEMA_NAME}"
@connection.execute "CREATE TABLE #{SCHEMA_NAME}.#{TABLE_NAME} (#{COLUMNS.join(',')})"
@connection.execute "CREATE TABLE #{SCHEMA_NAME}.\"#{TABLE_NAME}.table\" (#{COLUMNS.join(',')})"
@connection.execute "CREATE TABLE #{SCHEMA_NAME}.\"#{CAPITALIZED_TABLE_NAME}\" (#{COLUMNS.join(',')})"
@connection.execute "CREATE SCHEMA #{SCHEMA2_NAME}"
@connection.execute "CREATE TABLE #{SCHEMA2_NAME}.#{TABLE_NAME} (#{COLUMNS.join(',')})"
@connection.execute "CREATE INDEX #{INDEX_A_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING btree (#{INDEX_A_COLUMN});"
@connection.execute "CREATE INDEX #{INDEX_A_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING btree (#{INDEX_A_COLUMN});"
@connection.execute "CREATE INDEX #{INDEX_B_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING btree (#{INDEX_B_COLUMN_S1});"
@connection.execute "CREATE INDEX #{INDEX_B_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING btree (#{INDEX_B_COLUMN_S2});"
@connection.execute "CREATE INDEX #{INDEX_C_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING gin (#{INDEX_C_COLUMN});"
@connection.execute "CREATE INDEX #{INDEX_C_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING gin (#{INDEX_C_COLUMN});"
@connection.execute "CREATE INDEX #{INDEX_D_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING btree (#{INDEX_D_COLUMN} DESC);"
@connection.execute "CREATE INDEX #{INDEX_D_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING btree (#{INDEX_D_COLUMN} DESC);"
@connection.execute "CREATE INDEX #{INDEX_E_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING gin (#{INDEX_E_COLUMN});"
@connection.execute "CREATE INDEX #{INDEX_E_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING gin (#{INDEX_E_COLUMN});"
@connection.execute "CREATE TABLE #{SCHEMA_NAME}.#{PK_TABLE_NAME} (id serial primary key)"
@connection.execute "CREATE TABLE #{SCHEMA2_NAME}.#{PK_TABLE_NAME} (id serial primary key)"
@connection.execute "CREATE SEQUENCE #{SCHEMA_NAME}.#{UNMATCHED_SEQUENCE_NAME}"
@connection.execute "CREATE TABLE #{SCHEMA_NAME}.#{UNMATCHED_PK_TABLE_NAME} (id integer NOT NULL DEFAULT nextval('#{SCHEMA_NAME}.#{UNMATCHED_SEQUENCE_NAME}'::regclass), CONSTRAINT unmatched_pkey PRIMARY KEY (id))"
end
end
prepend Ext
2 changes: 0 additions & 2 deletions test/excludes/SchemaWithDotsTest.rb

This file was deleted.

0 comments on commit 3d9a893

Please sign in to comment.