mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge pull request #7937 from arturopie/7914-defaults-on-domains-and-multiple-schemas
Fixes #7914 - PostgreSQL adapter doesn't fetch column defaults when using multiple schemas and domains
This commit is contained in:
commit
ca618d473d
6 changed files with 61 additions and 15 deletions
|
@ -1,5 +1,9 @@
|
|||
## Rails 4.0.0 (unreleased) ##
|
||||
|
||||
* PostgreSQL adapter correctly fetches default values when using multiple schemas and domains in a db. Fixes #7914
|
||||
|
||||
*Arturo Pie*
|
||||
|
||||
* Learn ActiveRecord::QueryMethods#order work with hash arguments
|
||||
|
||||
When symbol or hash passed we convert it to Arel::Nodes::Ordering.
|
||||
|
|
|
@ -280,16 +280,13 @@ module ActiveRecord
|
|||
end_sql
|
||||
|
||||
if result.nil? or result.empty?
|
||||
# If that fails, try parsing the primary key's default value.
|
||||
# Support the 7.x and 8.0 nextval('foo'::text) as well as
|
||||
# the 8.1+ nextval('foo'::regclass).
|
||||
result = query(<<-end_sql, 'SCHEMA')[0]
|
||||
SELECT attr.attname,
|
||||
CASE
|
||||
WHEN split_part(def.adsrc, '''', 2) ~ '.' THEN
|
||||
substr(split_part(def.adsrc, '''', 2),
|
||||
strpos(split_part(def.adsrc, '''', 2), '.')+1)
|
||||
ELSE split_part(def.adsrc, '''', 2)
|
||||
WHEN split_part(pg_get_expr(def.adbin, def.adrelid), '''', 2) ~ '.' THEN
|
||||
substr(split_part(pg_get_expr(def.adbin, def.adrelid), '''', 2),
|
||||
strpos(split_part(pg_get_expr(def.adbin, def.adrelid), '''', 2), '.')+1)
|
||||
ELSE split_part(pg_get_expr(def.adbin, def.adrelid), '''', 2)
|
||||
END
|
||||
FROM pg_class t
|
||||
JOIN pg_attribute attr ON (t.oid = attrelid)
|
||||
|
@ -297,7 +294,7 @@ module ActiveRecord
|
|||
JOIN pg_constraint cons ON (conrelid = adrelid AND adnum = conkey[1])
|
||||
WHERE t.oid = '#{quote_table_name(table)}'::regclass
|
||||
AND cons.contype = 'p'
|
||||
AND def.adsrc ~* 'nextval'
|
||||
AND pg_get_expr(def.adbin, def.adrelid) ~* 'nextval'
|
||||
end_sql
|
||||
end
|
||||
|
||||
|
|
|
@ -78,11 +78,8 @@ module ActiveRecord
|
|||
when /\A\(?(-?\d+(\.\d*)?\)?)\z/
|
||||
$1
|
||||
# Character types
|
||||
when /\A'(.*)'::(?:character varying|bpchar|text)\z/m
|
||||
when /\A\(?'(.*)'::.*\b(?:character varying|bpchar|text)\z/m
|
||||
$1
|
||||
# Character types (8.1 formatting)
|
||||
when /\AE'(.*)'::(?:character varying|bpchar|text)\z/m
|
||||
$1.gsub(/\\(\d\d\d)/) { $1.oct.chr }
|
||||
# Binary data types
|
||||
when /\A'(.*)'::bytea\z/m
|
||||
$1
|
||||
|
@ -763,7 +760,8 @@ module ActiveRecord
|
|||
# - ::regclass is a function that gives the id for a table name
|
||||
def column_definitions(table_name) #:nodoc:
|
||||
exec_query(<<-end_sql, 'SCHEMA').rows
|
||||
SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull, a.atttypid, a.atttypmod
|
||||
SELECT a.attname, format_type(a.atttypid, a.atttypmod),
|
||||
pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod
|
||||
FROM pg_attribute a LEFT JOIN pg_attrdef d
|
||||
ON a.attrelid = d.adrelid AND a.attnum = d.adnum
|
||||
WHERE a.attrelid = '#{quote_table_name(table_name)}'::regclass
|
||||
|
|
|
@ -72,7 +72,7 @@ class SchemaTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_schema_names
|
||||
assert_equal ["public", "test_schema", "test_schema2"], @connection.schema_names
|
||||
assert_equal ["public", "schema_1", "test_schema", "test_schema2"], @connection.schema_names
|
||||
end
|
||||
|
||||
def test_create_schema
|
||||
|
|
|
@ -109,3 +109,43 @@ if current_adapter?(:MysqlAdapter) or current_adapter?(:Mysql2Adapter)
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
if current_adapter?(:PostgreSQLAdapter)
|
||||
class DefaultsUsingMultipleSchemasAndDomainTest < ActiveSupport::TestCase
|
||||
def setup
|
||||
@connection = ActiveRecord::Base.connection
|
||||
|
||||
@old_search_path = @connection.schema_search_path
|
||||
@connection.schema_search_path = "schema_1, pg_catalog"
|
||||
@connection.create_table "defaults" do |t|
|
||||
t.text "text_col", :default => "some value"
|
||||
t.string "string_col", :default => "some value"
|
||||
end
|
||||
Default.reset_column_information
|
||||
end
|
||||
|
||||
def test_text_defaults_in_new_schema_when_overriding_domain
|
||||
assert_equal "some value", Default.new.text_col, "Default of text column was not correctly parse"
|
||||
end
|
||||
|
||||
def test_string_defaults_in_new_schema_when_overriding_domain
|
||||
assert_equal "some value", Default.new.string_col, "Default of string column was not correctly parse"
|
||||
end
|
||||
|
||||
def test_bpchar_defaults_in_new_schema_when_overriding_domain
|
||||
@connection.execute "ALTER TABLE defaults ADD bpchar_col bpchar DEFAULT 'some value'"
|
||||
Default.reset_column_information
|
||||
assert_equal "some value", Default.new.bpchar_col, "Default of bpchar column was not correctly parse"
|
||||
end
|
||||
|
||||
def test_text_defaults_after_updating_column_default
|
||||
@connection.execute "ALTER TABLE defaults ALTER COLUMN text_col SET DEFAULT 'some text'::schema_1.text"
|
||||
assert_equal "some text", Default.new.text_col, "Default of text column was not correctly parse after updating default using '::text' since postgreSQL will add parens to the default in db"
|
||||
end
|
||||
|
||||
def teardown
|
||||
@connection.schema_search_path = @old_search_path
|
||||
Default.reset_column_information
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,6 +12,8 @@ ActiveRecord::Schema.define do
|
|||
|
||||
execute 'DROP FUNCTION IF EXISTS partitioned_insert_trigger()'
|
||||
|
||||
execute "DROP SCHEMA IF EXISTS schema_1 CASCADE"
|
||||
|
||||
%w(accounts_id_seq developers_id_seq projects_id_seq topics_id_seq customers_id_seq orders_id_seq).each do |seq_name|
|
||||
execute "SELECT setval('#{seq_name}', 100)"
|
||||
end
|
||||
|
@ -37,7 +39,12 @@ ActiveRecord::Schema.define do
|
|||
);
|
||||
_SQL
|
||||
|
||||
execute <<_SQL
|
||||
execute "CREATE SCHEMA schema_1"
|
||||
execute "CREATE DOMAIN schema_1.text AS text"
|
||||
execute "CREATE DOMAIN schema_1.varchar AS varchar"
|
||||
execute "CREATE DOMAIN schema_1.bpchar AS bpchar"
|
||||
|
||||
execute <<_SQL
|
||||
CREATE TABLE geometrics (
|
||||
id serial primary key,
|
||||
a_point point,
|
||||
|
|
Loading…
Reference in a new issue