rein
rein copied to clipboard
Schema-prefixed table names cause error
Description
If I try and add a length constraint to a table whose name is given with an explicit schema, the generate SQL is not valid:
add_length_constraint 'myschema.my_relations', :test_field, less_than_or_equal_to: 10
leads to:
ALTER TABLE "myschema.my_relations" ADD CONSTRAINT myschema.my_relations_test_field_length CHECK (length("test_field") <= 10)
Which fails with:
PG::SyntaxError: ERROR: syntax error at or near "." (ActiveRecord::StatementInvalid)
LINE 1: ...LE "myschema.my_relations" ADD CONSTRAINT myschema.my_relati...
^
The correct quoting of the table name is:
ALTER TABLE "myschema"."my_relations"
and the constraint name would reasonably be called myschema_my_relations_test_field_length. This can be achieved with:
add_length_constraint '"myschema"."my_relations"', :test_field, less_than_or_equal_to: 10, name: :myschema_my_relations_test_field_length
but I think it would be nicer if rein handled this itself.
ActiveRecord::ConnectionAdapters::PostgreSQL::Quoting#quote_table_name seems like it solves some of the same issues - maybe it can be reused?
Reproduction
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
gem "activerecord", "5.2.0"
gem "rein"
gem "pg"
end
require "active_record"
require "pg"
require "rein"
ActiveRecord::Base.establish_connection(
adapter: "postgresql",
database: "rein_schema_issue",
username: ENV.fetch('PGUSER'),
password: ENV.fetch('PGPASSWORD')
)
ActiveRecord::Base.logger = Logger.new(STDOUT)
class CreateMyRelation < ActiveRecord::Migration[5.0]
def up
execute "CREATE SCHEMA myschema"
create_table 'myschema.my_relations' do |t|
t.string :test_field
end
# Syntax error...
add_length_constraint(
'myschema.my_relations',
:test_field, less_than_or_equal_to: 10
)
# Works fine
# add_length_constraint(
# '"myschema"."my_relations"',
# :test_field,
# less_than_or_equal_to: 10, name: :myschema_my_relations_test_field_length
# )
end
end
CreateMyRelation.migrate(:up)
Must be run with PGUSER and PGPASSWORD set in the environment, and the rein_schema_issue DB already existing