aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases/adapters/postgresql
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/test/cases/adapters/postgresql')
-rw-r--r--activerecord/test/cases/adapters/postgresql/active_schema_test.rb4
-rw-r--r--activerecord/test/cases/adapters/postgresql/array_test.rb49
-rw-r--r--activerecord/test/cases/adapters/postgresql/bytea_test.rb15
-rw-r--r--activerecord/test/cases/adapters/postgresql/case_insensitive_test.rb26
-rw-r--r--activerecord/test/cases/adapters/postgresql/collation_test.rb4
-rw-r--r--activerecord/test/cases/adapters/postgresql/connection_test.rb32
-rw-r--r--activerecord/test/cases/adapters/postgresql/datatype_test.rb10
-rw-r--r--activerecord/test/cases/adapters/postgresql/explain_test.rb4
-rw-r--r--activerecord/test/cases/adapters/postgresql/geometric_test.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/hstore_test.rb55
-rw-r--r--activerecord/test/cases/adapters/postgresql/infinity_test.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/json_test.rb190
-rw-r--r--activerecord/test/cases/adapters/postgresql/numbers_test.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb34
-rw-r--r--activerecord/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb25
-rw-r--r--activerecord/test/cases/adapters/postgresql/prepared_statements_test.rb21
-rw-r--r--activerecord/test/cases/adapters/postgresql/quoting_test.rb7
-rw-r--r--activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb19
-rw-r--r--activerecord/test/cases/adapters/postgresql/schema_test.rb41
-rw-r--r--activerecord/test/cases/adapters/postgresql/statement_pool_test.rb8
-rw-r--r--activerecord/test/cases/adapters/postgresql/timestamp_test.rb4
-rw-r--r--activerecord/test/cases/adapters/postgresql/transaction_test.rb71
-rw-r--r--activerecord/test/cases/adapters/postgresql/type_lookup_test.rb2
-rw-r--r--activerecord/test/cases/adapters/postgresql/utils_test.rb10
-rw-r--r--activerecord/test/cases/adapters/postgresql/uuid_test.rb98
25 files changed, 346 insertions, 389 deletions
diff --git a/activerecord/test/cases/adapters/postgresql/active_schema_test.rb b/activerecord/test/cases/adapters/postgresql/active_schema_test.rb
index d3c65f3d94..b787de8453 100644
--- a/activerecord/test/cases/adapters/postgresql/active_schema_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/active_schema_test.rb
@@ -39,6 +39,10 @@ class PostgresqlActiveSchemaTest < ActiveRecord::PostgreSQLTestCase
expected = %(CREATE INDEX CONCURRENTLY "index_people_on_last_name" ON "people" ("last_name"))
assert_equal expected, add_index(:people, :last_name, algorithm: :concurrently)
+ expected = %(CREATE INDEX "index_people_on_last_name_and_first_name" ON "people" ("last_name" DESC, "first_name" ASC))
+ assert_equal expected, add_index(:people, [:last_name, :first_name], order: { last_name: :desc, first_name: :asc })
+ assert_equal expected, add_index(:people, ["last_name", :first_name], order: { last_name: :desc, "first_name" => :asc })
+
%w(gin gist hash btree).each do |type|
expected = %(CREATE INDEX "index_people_on_last_name" ON "people" USING #{type} ("last_name"))
assert_equal expected, add_index(:people, :last_name, using: type)
diff --git a/activerecord/test/cases/adapters/postgresql/array_test.rb b/activerecord/test/cases/adapters/postgresql/array_test.rb
index 97960b6c51..c78c6178ff 100644
--- a/activerecord/test/cases/adapters/postgresql/array_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/array_test.rb
@@ -16,10 +16,12 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase
@connection.transaction do
@connection.create_table("pg_arrays") do |t|
- t.string "tags", array: true
+ t.string "tags", array: true, limit: 255
t.integer "ratings", array: true
t.datetime :datetimes, array: true
t.hstore :hstores, array: true
+ t.decimal :decimals, array: true, default: [], precision: 10, scale: 2
+ t.timestamp :timestamps, array: true, default: [], precision: 6
end
end
PgArray.reset_column_information
@@ -34,7 +36,7 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase
def test_column
assert_equal :string, @column.type
- assert_equal "character varying", @column.sql_type
+ assert_equal "character varying(255)", @column.sql_type
assert @column.array?
assert_not @type.binary?
@@ -110,22 +112,23 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase
def test_schema_dump_with_shorthand
output = dump_table_schema "pg_arrays"
- assert_match %r[t\.string\s+"tags",\s+array: true], output
+ assert_match %r[t\.string\s+"tags",\s+limit: 255,\s+array: true], output
assert_match %r[t\.integer\s+"ratings",\s+array: true], output
+ assert_match %r[t\.decimal\s+"decimals",\s+precision: 10,\s+scale: 2,\s+default: \[\],\s+array: true], output
end
def test_select_with_strings
@connection.execute "insert into pg_arrays (tags) VALUES ('{1,2,3}')"
x = PgArray.first
- assert_equal(["1","2","3"], x.tags)
+ assert_equal(["1", "2", "3"], x.tags)
end
def test_rewrite_with_strings
@connection.execute "insert into pg_arrays (tags) VALUES ('{1,2,3}')"
x = PgArray.first
- x.tags = ["1","2","3","4"]
+ x.tags = ["1", "2", "3", "4"]
x.save!
- assert_equal ["1","2","3","4"], x.reload.tags
+ assert_equal ["1", "2", "3", "4"], x.reload.tags
end
def test_select_with_integers
@@ -163,28 +166,28 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase
end
def test_strings_with_quotes
- assert_cycle(:tags, ["this has",'some "s that need to be escaped"'])
+ assert_cycle(:tags, ["this has", 'some "s that need to be escaped"'])
end
def test_strings_with_commas
- assert_cycle(:tags, ["this,has","many,values"])
+ assert_cycle(:tags, ["this,has", "many,values"])
end
def test_strings_with_array_delimiters
- assert_cycle(:tags, ["{","}"])
+ assert_cycle(:tags, ["{", "}"])
end
def test_strings_with_null_strings
- assert_cycle(:tags, ["NULL","NULL"])
+ assert_cycle(:tags, ["NULL", "NULL"])
end
def test_contains_nils
- assert_cycle(:tags, ["1",nil,nil])
+ assert_cycle(:tags, ["1", nil, nil])
end
def test_insert_fixture
tag_values = ["val1", "val2", "val3_with_'_multiple_quote_'_chars"]
- @connection.insert_fixture({ "tags" => tag_values }, "pg_arrays" )
+ @connection.insert_fixture({ "tags" => tag_values }, "pg_arrays")
assert_equal(PgArray.last.tags, tag_values)
end
@@ -211,7 +214,7 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase
x = PgArray.create!(tags: tags)
x.reload
- assert_equal x.tags_before_type_cast, PgArray.type_for_attribute("tags").serialize(tags)
+ refute x.changed?
end
def test_quoting_non_standard_delimiters
@@ -219,9 +222,10 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase
oid = ActiveRecord::ConnectionAdapters::PostgreSQL::OID
comma_delim = oid::Array.new(ActiveRecord::Type::String.new, ",")
semicolon_delim = oid::Array.new(ActiveRecord::Type::String.new, ";")
+ conn = PgArray.connection
- assert_equal %({"hello,",world;}), comma_delim.serialize(strings)
- assert_equal %({hello,;"world;"}), semicolon_delim.serialize(strings)
+ assert_equal %({"hello,",world;}), conn.type_cast(comma_delim.serialize(strings))
+ assert_equal %({hello,;"world;"}), conn.type_cast(semicolon_delim.serialize(strings))
end
def test_mutate_array
@@ -312,9 +316,18 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase
end
def test_encoding_arrays_of_utf8_strings
- string_with_utf8 = "nový"
- assert_equal [string_with_utf8], @type.deserialize(@type.serialize([string_with_utf8]))
- assert_equal [[string_with_utf8]], @type.deserialize(@type.serialize([[string_with_utf8]]))
+ arrays_of_utf8_strings = %w(nový ファイル)
+ assert_equal arrays_of_utf8_strings, @type.deserialize(@type.serialize(arrays_of_utf8_strings))
+ assert_equal [arrays_of_utf8_strings], @type.deserialize(@type.serialize([arrays_of_utf8_strings]))
+ end
+
+ def test_precision_is_respected_on_timestamp_columns
+ time = Time.now.change(usec: 123)
+ record = PgArray.create!(timestamps: [time])
+
+ assert_equal 123, record.timestamps.first.usec
+ record.reload
+ assert_equal 123, record.timestamps.first.usec
end
private
diff --git a/activerecord/test/cases/adapters/postgresql/bytea_test.rb b/activerecord/test/cases/adapters/postgresql/bytea_test.rb
index dc0df8715a..539c90f0bc 100644
--- a/activerecord/test/cases/adapters/postgresql/bytea_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/bytea_test.rb
@@ -32,9 +32,9 @@ class PostgresqlByteaTest < ActiveRecord::PostgreSQLTestCase
end
def test_binary_columns_are_limitless_the_upper_limit_is_one_GB
- assert_equal "bytea", @connection.type_to_sql(:binary, 100_000)
+ assert_equal "bytea", @connection.type_to_sql(:binary, limit: 100_000)
assert_raise ActiveRecord::ActiveRecordError do
- @connection.type_to_sql :binary, 4294967295
+ @connection.type_to_sql(:binary, limit: 4294967295)
end
end
@@ -52,7 +52,7 @@ class PostgresqlByteaTest < ActiveRecord::PostgreSQLTestCase
end
def test_type_case_nil
- assert_equal(nil, @type.deserialize(nil))
+ assert_nil(@type.deserialize(nil))
end
def test_read_value
@@ -66,7 +66,7 @@ class PostgresqlByteaTest < ActiveRecord::PostgreSQLTestCase
def test_read_nil_value
@connection.execute "insert into bytea_data_type (payload) VALUES (null)"
record = ByteaDataType.first
- assert_equal(nil, record.payload)
+ assert_nil(record.payload)
record.delete
end
@@ -89,13 +89,14 @@ class PostgresqlByteaTest < ActiveRecord::PostgreSQLTestCase
Thread.new do
other_conn = ActiveRecord::Base.connection
other_conn.execute("SET standard_conforming_strings = off")
+ other_conn.execute("SET escape_string_warning = off")
end.join
test_via_to_sql
end
def test_write_binary
- data = File.read(File.join(File.dirname(__FILE__), "..", "..", "..", "assets", "example.log"))
+ data = File.read(File.join(__dir__, "..", "..", "..", "assets", "example.log"))
assert(data.size > 1)
record = ByteaDataType.create(payload: data)
assert_not record.new_record?
@@ -106,8 +107,8 @@ class PostgresqlByteaTest < ActiveRecord::PostgreSQLTestCase
def test_write_nil
record = ByteaDataType.create(payload: nil)
assert_not record.new_record?
- assert_equal(nil, record.payload)
- assert_equal(nil, ByteaDataType.where(id: record.id).first.payload)
+ assert_nil(record.payload)
+ assert_nil(ByteaDataType.where(id: record.id).first.payload)
end
class Serializer
diff --git a/activerecord/test/cases/adapters/postgresql/case_insensitive_test.rb b/activerecord/test/cases/adapters/postgresql/case_insensitive_test.rb
new file mode 100644
index 0000000000..03b44feab6
--- /dev/null
+++ b/activerecord/test/cases/adapters/postgresql/case_insensitive_test.rb
@@ -0,0 +1,26 @@
+require "cases/helper"
+
+class PostgresqlCaseInsensitiveTest < ActiveRecord::PostgreSQLTestCase
+ class Default < ActiveRecord::Base; end
+
+ def test_case_insensitiveness
+ connection = ActiveRecord::Base.connection
+ table = Default.arel_table
+
+ column = Default.columns_hash["char1"]
+ comparison = connection.case_insensitive_comparison table, :char1, column, nil
+ assert_match(/lower/i, comparison.to_sql)
+
+ column = Default.columns_hash["char2"]
+ comparison = connection.case_insensitive_comparison table, :char2, column, nil
+ assert_match(/lower/i, comparison.to_sql)
+
+ column = Default.columns_hash["char3"]
+ comparison = connection.case_insensitive_comparison table, :char3, column, nil
+ assert_match(/lower/i, comparison.to_sql)
+
+ column = Default.columns_hash["multiline_default"]
+ comparison = connection.case_insensitive_comparison table, :multiline_default, column, nil
+ assert_match(/lower/i, comparison.to_sql)
+ end
+end
diff --git a/activerecord/test/cases/adapters/postgresql/collation_test.rb b/activerecord/test/cases/adapters/postgresql/collation_test.rb
index b39e298a5d..a603221d8f 100644
--- a/activerecord/test/cases/adapters/postgresql/collation_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/collation_test.rb
@@ -47,7 +47,7 @@ class PostgresqlCollationTest < ActiveRecord::PostgreSQLTestCase
test "schema dump includes collation" do
output = dump_table_schema("postgresql_collations")
- assert_match %r{t.string\s+"string_c",\s+collation: "C"$}, output
- assert_match %r{t.text\s+"text_posix",\s+collation: "POSIX"$}, output
+ assert_match %r{t\.string\s+"string_c",\s+collation: "C"$}, output
+ assert_match %r{t\.text\s+"text_posix",\s+collation: "POSIX"$}, output
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/connection_test.rb b/activerecord/test/cases/adapters/postgresql/connection_test.rb
index 48c82cb7b9..32afe331fa 100644
--- a/activerecord/test/cases/adapters/postgresql/connection_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/connection_test.rb
@@ -31,15 +31,21 @@ module ActiveRecord
end
def test_encoding
- assert_not_nil @connection.encoding
+ assert_queries(1) do
+ assert_not_nil @connection.encoding
+ end
end
def test_collation
- assert_not_nil @connection.collation
+ assert_queries(1) do
+ assert_not_nil @connection.collation
+ end
end
def test_ctype
- assert_not_nil @connection.ctype
+ assert_queries(1) do
+ assert_not_nil @connection.ctype
+ end
end
def test_default_client_min_messages
@@ -90,22 +96,22 @@ module ActiveRecord
end
def test_tables_logs_name
- ActiveSupport::Deprecation.silence { @connection.tables("hello") }
+ @connection.tables
assert_equal "SCHEMA", @subscriber.logged[0][1]
end
def test_indexes_logs_name
- @connection.indexes("items", "hello")
+ assert_deprecated { @connection.indexes("items", "hello") }
assert_equal "SCHEMA", @subscriber.logged[0][1]
end
def test_table_exists_logs_name
- ActiveSupport::Deprecation.silence { @connection.table_exists?("items") }
+ @connection.table_exists?("items")
assert_equal "SCHEMA", @subscriber.logged[0][1]
end
def test_table_alias_length_logs_name
- @connection.instance_variable_set("@table_alias_length", nil)
+ @connection.instance_variable_set("@max_identifier_length", nil)
@connection.table_alias_length
assert_equal "SCHEMA", @subscriber.logged[0][1]
end
@@ -127,8 +133,8 @@ module ActiveRecord
if ActiveRecord::Base.connection.prepared_statements
def test_statement_key_is_logged
- bind = Relation::QueryAttribute.new(nil, 1, Type::Value.new)
- @connection.exec_query("SELECT $1::integer", "SQL", [bind], prepare: true)
+ binds = [bind_attribute(nil, 1)]
+ @connection.exec_query("SELECT $1::integer", "SQL", binds, prepare: true)
name = @subscriber.payloads.last[:statement_name]
assert name
res = @connection.exec_query("EXPLAIN (FORMAT JSON) EXECUTE #{name}(1)")
@@ -156,7 +162,7 @@ module ActiveRecord
secondary_connection.query("select pg_terminate_backend(#{original_connection_pid.first.first})")
ActiveRecord::Base.connection_pool.checkin(secondary_connection)
elsif ARTest.config["with_manual_interventions"]
- puts "Kill the connection now (e.g. by restarting the PostgreSQL " +
+ puts "Kill the connection now (e.g. by restarting the PostgreSQL " \
'server with the "-m fast" option) and then press enter.'
$stdin.gets
else
@@ -175,9 +181,9 @@ module ActiveRecord
new_connection_pid = @connection.query("select pg_backend_pid()")
assert_not_equal original_connection_pid, new_connection_pid,
- "umm -- looks like you didn't break the connection, because we're still " +
+ "umm -- looks like you didn't break the connection, because we're still " \
"successfully querying with the same connection pid."
-
+ ensure
# Repair all fixture connections so other tests won't break.
@fixture_connections.each(&:verify!)
end
@@ -245,7 +251,7 @@ module ActiveRecord
end
end
- protected
+ private
def with_warning_suppression
log_level = @connection.client_min_messages
diff --git a/activerecord/test/cases/adapters/postgresql/datatype_test.rb b/activerecord/test/cases/adapters/postgresql/datatype_test.rb
index 0ac8b7339b..0725fde5ae 100644
--- a/activerecord/test/cases/adapters/postgresql/datatype_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/datatype_test.rb
@@ -28,12 +28,12 @@ class PostgresqlDataTypeTest < ActiveRecord::PostgreSQLTestCase
end
def test_data_type_of_time_types
- assert_equal :string, @first_time.column_for_attribute(:time_interval).type
- assert_equal :string, @first_time.column_for_attribute(:scaled_time_interval).type
+ assert_equal :interval, @first_time.column_for_attribute(:time_interval).type
+ assert_equal :interval, @first_time.column_for_attribute(:scaled_time_interval).type
end
def test_data_type_of_oid_types
- assert_equal :integer, @first_oid.column_for_attribute(:obj_id).type
+ assert_equal :oid, @first_oid.column_for_attribute(:obj_id).type
end
def test_time_values
@@ -61,9 +61,9 @@ class PostgresqlDataTypeTest < ActiveRecord::PostgreSQLTestCase
end
def test_text_columns_are_limitless_the_upper_limit_is_one_GB
- assert_equal "text", @connection.type_to_sql(:text, 100_000)
+ assert_equal "text", @connection.type_to_sql(:text, limit: 100_000)
assert_raise ActiveRecord::ActiveRecordError do
- @connection.type_to_sql :text, 4294967295
+ @connection.type_to_sql(:text, limit: 4294967295)
end
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/explain_test.rb b/activerecord/test/cases/adapters/postgresql/explain_test.rb
index 7493bce4fb..d79fbccf47 100644
--- a/activerecord/test/cases/adapters/postgresql/explain_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/explain_test.rb
@@ -7,14 +7,14 @@ class PostgreSQLExplainTest < ActiveRecord::PostgreSQLTestCase
def test_explain_for_one_query
explain = Developer.where(id: 1).explain
- assert_match %r(EXPLAIN for: SELECT "developers".* FROM "developers" WHERE "developers"."id" = (?:\$1 \[\["id", 1\]\]|1)), explain
+ assert_match %r(EXPLAIN for: SELECT "developers"\.\* FROM "developers" WHERE "developers"\."id" = (?:\$1 \[\["id", 1\]\]|1)), explain
assert_match %(QUERY PLAN), explain
end
def test_explain_with_eager_loading
explain = Developer.where(id: 1).includes(:audit_logs).explain
assert_match %(QUERY PLAN), explain
- assert_match %r(EXPLAIN for: SELECT "developers".* FROM "developers" WHERE "developers"."id" = (?:\$1 \[\["id", 1\]\]|1)), explain
+ assert_match %r(EXPLAIN for: SELECT "developers"\.\* FROM "developers" WHERE "developers"\."id" = (?:\$1 \[\["id", 1\]\]|1)), explain
assert_match %(EXPLAIN for: SELECT "audit_logs".* FROM "audit_logs" WHERE "audit_logs"."developer_id" = 1), explain
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/geometric_test.rb b/activerecord/test/cases/adapters/postgresql/geometric_test.rb
index a65d4d1ad9..c1f3a4ae2c 100644
--- a/activerecord/test/cases/adapters/postgresql/geometric_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/geometric_test.rb
@@ -96,7 +96,7 @@ class PostgresqlPointTest < ActiveRecord::PostgreSQLTestCase
assert_nothing_raised { PostgresqlPoint.new(x: "") }
p = PostgresqlPoint.new(x: "")
- assert_equal nil, p.x
+ assert_nil p.x
end
def test_array_of_points_round_trip
diff --git a/activerecord/test/cases/adapters/postgresql/hstore_test.rb b/activerecord/test/cases/adapters/postgresql/hstore_test.rb
index 9236a67b11..f9cce10fb8 100644
--- a/activerecord/test/cases/adapters/postgresql/hstore_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/hstore_test.rb
@@ -10,6 +10,12 @@ if ActiveRecord::Base.connection.supports_extensions?
store_accessor :settings, :language, :timezone
end
+ class FakeParameters
+ def to_unsafe_h
+ { "hi" => "hi" }
+ end
+ end
+
def setup
@connection = ActiveRecord::Base.connection
@@ -64,8 +70,8 @@ if ActiveRecord::Base.connection.supports_extensions?
@connection.add_column "hstores", "permissions", :hstore, default: '"users"=>"read", "articles"=>"write"'
Hstore.reset_column_information
- assert_equal({ "users"=>"read", "articles"=>"write" }, Hstore.column_defaults["permissions"])
- assert_equal({ "users"=>"read", "articles"=>"write" }, Hstore.new.permissions)
+ assert_equal({ "users" => "read", "articles" => "write" }, Hstore.column_defaults["permissions"])
+ assert_equal({ "users" => "read", "articles" => "write" }, Hstore.new.permissions)
ensure
Hstore.reset_column_information
end
@@ -113,8 +119,8 @@ if ActiveRecord::Base.connection.supports_extensions?
def test_type_cast_hstore
assert_equal({ "1" => "2" }, @type.deserialize("\"1\"=>\"2\""))
assert_equal({}, @type.deserialize(""))
- assert_equal({ "key"=>nil }, @type.deserialize("key => NULL"))
- assert_equal({ "c"=>"}",'"a"'=>'b "a b' }, @type.deserialize(%q(c=>"}", "\"a\""=>"b \"a b")))
+ assert_equal({ "key" => nil }, @type.deserialize("key => NULL"))
+ assert_equal({ "c" => "}", '"a"' => 'b "a b' }, @type.deserialize(%q(c=>"}", "\"a\""=>"b \"a b")))
end
def test_with_store_accessors
@@ -165,24 +171,43 @@ if ActiveRecord::Base.connection.supports_extensions?
assert_not hstore.changed?
end
+ def test_dirty_from_user_equal
+ settings = { "alongkey" => "anything", "key" => "value" }
+ hstore = Hstore.create!(settings: settings)
+
+ hstore.settings = { "key" => "value", "alongkey" => "anything" }
+ assert_equal settings, hstore.settings
+ refute hstore.changed?
+ end
+
+ def test_hstore_dirty_from_database_equal
+ settings = { "alongkey" => "anything", "key" => "value" }
+ hstore = Hstore.create!(settings: settings)
+ hstore.reload
+
+ assert_equal settings, hstore.settings
+ hstore.settings = settings
+ refute hstore.changed?
+ end
+
def test_gen1
- assert_equal('" "=>""', @type.serialize(" "=>""))
+ assert_equal('" "=>""', @type.serialize(" " => ""))
end
def test_gen2
- assert_equal('","=>""', @type.serialize(","=>""))
+ assert_equal('","=>""', @type.serialize("," => ""))
end
def test_gen3
- assert_equal('"="=>""', @type.serialize("="=>""))
+ assert_equal('"="=>""', @type.serialize("=" => ""))
end
def test_gen4
- assert_equal('">"=>""', @type.serialize(">"=>""))
+ assert_equal('">"=>""', @type.serialize(">" => ""))
end
def test_parse1
- assert_equal({ "a"=>nil,"b"=>nil,"c"=>"NuLl","null"=>"c" }, @type.deserialize('a=>null,b=>NuLl,c=>"NuLl",null=>c'))
+ assert_equal({ "a" => nil, "b" => nil, "c" => "NuLl", "null" => "c" }, @type.deserialize('a=>null,b=>NuLl,c=>"NuLl",null=>c'))
end
def test_parse2
@@ -194,19 +219,19 @@ if ActiveRecord::Base.connection.supports_extensions?
end
def test_parse4
- assert_equal({ "=a"=>"q=w" }, @type.deserialize('\=a=>q=w'))
+ assert_equal({ "=a" => "q=w" }, @type.deserialize('\=a=>q=w'))
end
def test_parse5
- assert_equal({ "=a"=>"q=w" }, @type.deserialize('"=a"=>q\=w'))
+ assert_equal({ "=a" => "q=w" }, @type.deserialize('"=a"=>q\=w'))
end
def test_parse6
- assert_equal({ "\"a"=>"q>w" }, @type.deserialize('"\"a"=>q>w'))
+ assert_equal({ "\"a" => "q>w" }, @type.deserialize('"\"a"=>q>w'))
end
def test_parse7
- assert_equal({ "\"a"=>"q\"w" }, @type.deserialize('\"a=>q"w'))
+ assert_equal({ "\"a" => "q\"w" }, @type.deserialize('\"a=>q"w'))
end
def test_rewrite
@@ -321,6 +346,10 @@ if ActiveRecord::Base.connection.supports_extensions?
assert_match %r[t\.hstore "tags",\s+default: {}], output
end
+ def test_supports_to_unsafe_h_values
+ assert_equal("\"hi\"=>\"hi\"", @type.serialize(FakeParameters.new))
+ end
+
private
def assert_array_cycle(array)
# test creation
diff --git a/activerecord/test/cases/adapters/postgresql/infinity_test.rb b/activerecord/test/cases/adapters/postgresql/infinity_test.rb
index 19b00258b6..b9e177e6ec 100644
--- a/activerecord/test/cases/adapters/postgresql/infinity_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/infinity_test.rb
@@ -30,7 +30,7 @@ class PostgresqlInfinityTest < ActiveRecord::PostgreSQLTestCase
record = PostgresqlInfinity.new(float: "-Infinity")
assert_equal(-Float::INFINITY, record.float)
record = PostgresqlInfinity.new(float: "NaN")
- assert_send [record.float, :nan?]
+ assert record.float.nan?, "Expected #{record.float} to be NaN"
end
test "update_all with infinity on a float column" do
diff --git a/activerecord/test/cases/adapters/postgresql/json_test.rb b/activerecord/test/cases/adapters/postgresql/json_test.rb
index 273b2c1c7b..4eeb563781 100644
--- a/activerecord/test/cases/adapters/postgresql/json_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/json_test.rb
@@ -1,14 +1,8 @@
require "cases/helper"
-require "support/schema_dumping_helper"
+require "cases/json_shared_test_cases"
module PostgresqlJSONSharedTestCases
- include SchemaDumpingHelper
-
- class JsonDataType < ActiveRecord::Base
- self.table_name = "json_data_type"
-
- store_accessor :settings, :resolution
- end
+ include JSONSharedTestCases
def setup
@connection = ActiveRecord::Base.connection
@@ -16,6 +10,7 @@ module PostgresqlJSONSharedTestCases
@connection.create_table("json_data_type") do |t|
t.public_send column_type, "payload", default: {} # t.json 'payload', default: {}
t.public_send column_type, "settings" # t.json 'settings'
+ t.public_send column_type, "objects", array: true # t.json 'objects', array: true
end
rescue ActiveRecord::StatementInvalid
skip "do not test on PostgreSQL without #{column_type} type."
@@ -27,186 +22,23 @@ module PostgresqlJSONSharedTestCases
JsonDataType.reset_column_information
end
- def test_column
- column = JsonDataType.columns_hash["payload"]
- assert_equal column_type, column.type
- assert_equal column_type.to_s, column.sql_type
- assert_not column.array?
-
- type = JsonDataType.type_for_attribute("payload")
- assert_not type.binary?
- end
-
def test_default
@connection.add_column "json_data_type", "permissions", column_type, default: { "users": "read", "posts": ["read", "write"] }
JsonDataType.reset_column_information
- assert_equal({ "users"=>"read", "posts"=>["read", "write"] }, JsonDataType.column_defaults["permissions"])
- assert_equal({ "users"=>"read", "posts"=>["read", "write"] }, JsonDataType.new.permissions)
- ensure
- JsonDataType.reset_column_information
- end
-
- def test_change_table_supports_json
- @connection.transaction do
- @connection.change_table("json_data_type") do |t|
- t.public_send column_type, "users", default: "{}" # t.json 'users', default: '{}'
- end
- JsonDataType.reset_column_information
- column = JsonDataType.columns_hash["users"]
- assert_equal column_type, column.type
-
- raise ActiveRecord::Rollback # reset the schema change
- end
+ assert_equal({ "users" => "read", "posts" => ["read", "write"] }, JsonDataType.column_defaults["permissions"])
+ assert_equal({ "users" => "read", "posts" => ["read", "write"] }, JsonDataType.new.permissions)
ensure
JsonDataType.reset_column_information
end
- def test_schema_dumping
- output = dump_table_schema("json_data_type")
- assert_match(/t\.#{column_type.to_s}\s+"payload",\s+default: {}/, output)
- end
-
- def test_cast_value_on_write
- x = JsonDataType.new payload: { "string" => "foo", :symbol => :bar }
- assert_equal({ "string" => "foo", :symbol => :bar }, x.payload_before_type_cast)
- assert_equal({ "string" => "foo", "symbol" => "bar" }, x.payload)
- x.save
- assert_equal({ "string" => "foo", "symbol" => "bar" }, x.reload.payload)
- end
-
- def test_type_cast_json
- type = JsonDataType.type_for_attribute("payload")
-
- data = "{\"a_key\":\"a_value\"}"
- hash = type.deserialize(data)
- assert_equal({ "a_key" => "a_value" }, hash)
- assert_equal({ "a_key" => "a_value" }, type.deserialize(data))
-
- assert_equal({}, type.deserialize("{}"))
- assert_equal({ "key"=>nil }, type.deserialize('{"key": null}'))
- assert_equal({ "c"=>"}",'"a"'=>'b "a b' }, type.deserialize(%q({"c":"}", "\"a\"":"b \"a b"})))
- end
-
- def test_rewrite
- @connection.execute "insert into json_data_type (payload) VALUES ('{\"k\":\"v\"}')"
- x = JsonDataType.first
- x.payload = { '"a\'' => "b" }
- assert x.save!
- end
-
- def test_select
- @connection.execute "insert into json_data_type (payload) VALUES ('{\"k\":\"v\"}')"
- x = JsonDataType.first
- assert_equal({ "k" => "v" }, x.payload)
- end
-
- def test_select_multikey
- @connection.execute %q|insert into json_data_type (payload) VALUES ('{"k1":"v1", "k2":"v2", "k3":[1,2,3]}')|
- x = JsonDataType.first
- assert_equal({ "k1" => "v1", "k2" => "v2", "k3" => [1,2,3] }, x.payload)
- end
-
- def test_null_json
- @connection.execute "insert into json_data_type (payload) VALUES(null)"
- x = JsonDataType.first
- assert_equal(nil, x.payload)
- end
-
- def test_select_nil_json_after_create
- json = JsonDataType.create(payload: nil)
- x = JsonDataType.where(payload:nil).first
- assert_equal(json, x)
- end
-
- def test_select_nil_json_after_update
- json = JsonDataType.create(payload: "foo")
- x = JsonDataType.where(payload:nil).first
- assert_equal(nil, x)
-
- json.update_attributes payload: nil
- x = JsonDataType.where(payload:nil).first
- assert_equal(json.reload, x)
- end
-
- def test_select_array_json_value
- @connection.execute %q|insert into json_data_type (payload) VALUES ('["v0",{"k1":"v1"}]')|
- x = JsonDataType.first
- assert_equal(["v0", { "k1" => "v1" }], x.payload)
- end
-
- def test_rewrite_array_json_value
- @connection.execute %q|insert into json_data_type (payload) VALUES ('["v0",{"k1":"v1"}]')|
- x = JsonDataType.first
- x.payload = ["v1", { "k2" => "v2" }, "v3"]
- assert x.save!
- end
-
- def test_with_store_accessors
- x = JsonDataType.new(resolution: "320×480")
- assert_equal "320×480", x.resolution
-
+ def test_deserialize_with_array
+ x = JsonDataType.new(objects: ["foo" => "bar"])
+ assert_equal ["foo" => "bar"], x.objects
x.save!
- x = JsonDataType.first
- assert_equal "320×480", x.resolution
-
- x.resolution = "640×1136"
- x.save!
-
- x = JsonDataType.first
- assert_equal "640×1136", x.resolution
- end
-
- def test_duplication_with_store_accessors
- x = JsonDataType.new(resolution: "320×480")
- assert_equal "320×480", x.resolution
-
- y = x.dup
- assert_equal "320×480", y.resolution
- end
-
- def test_yaml_round_trip_with_store_accessors
- x = JsonDataType.new(resolution: "320×480")
- assert_equal "320×480", x.resolution
-
- y = YAML.load(YAML.dump(x))
- assert_equal "320×480", y.resolution
- end
-
- def test_changes_in_place
- json = JsonDataType.new
- assert_not json.changed?
-
- json.payload = { "one" => "two" }
- assert json.changed?
- assert json.payload_changed?
-
- json.save!
- assert_not json.changed?
-
- json.payload["three"] = "four"
- assert json.payload_changed?
-
- json.save!
- json.reload
-
- assert_equal({ "one" => "two", "three" => "four" }, json.payload)
- assert_not json.changed?
- end
-
- def test_assigning_string_literal
- json = JsonDataType.create(payload: "foo")
- assert_equal "foo", json.payload
- end
-
- def test_assigning_number
- json = JsonDataType.create(payload: 1.234)
- assert_equal 1.234, json.payload
- end
-
- def test_assigning_boolean
- json = JsonDataType.create(payload: true)
- assert_equal true, json.payload
+ assert_equal ["foo" => "bar"], x.objects
+ x.reload
+ assert_equal ["foo" => "bar"], x.objects
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/numbers_test.rb b/activerecord/test/cases/adapters/postgresql/numbers_test.rb
index 834354dcc9..bfb2b7c27a 100644
--- a/activerecord/test/cases/adapters/postgresql/numbers_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/numbers_test.rb
@@ -31,7 +31,7 @@ class PostgresqlNumberTest < ActiveRecord::PostgreSQLTestCase
assert_equal 123456.789, first.double
assert_equal(-::Float::INFINITY, second.single)
assert_equal ::Float::INFINITY, second.double
- assert_send [third.double, :nan?]
+ assert third.double.nan?, "Expected #{third.double} to be NaN"
end
def test_update
diff --git a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
index e6af93a53e..bfc763e1ef 100644
--- a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
@@ -21,17 +21,6 @@ module ActiveRecord
end
end
- def test_valid_column
- with_example_table do
- column = @connection.columns("ex").find { |col| col.name == "id" }
- assert @connection.valid_type?(column.type)
- end
- end
-
- def test_invalid_column
- assert_not @connection.valid_type?(:foobar)
- end
-
def test_primary_key
with_example_table do
assert_equal "id", @connection.primary_key("ex")
@@ -54,12 +43,6 @@ module ActiveRecord
end
end
- def test_primary_key_raises_error_if_table_not_found
- assert_raises(ActiveRecord::StatementInvalid) do
- @connection.primary_key("unobtainium")
- end
- end
-
def test_exec_insert_with_returning_disabled
connection = connection_without_insert_returning
result = connection.exec_insert("insert into postgresql_partitioned_table_parent (number) VALUES (1)", nil, [], "id", "postgresql_partitioned_table_parent_id_seq")
@@ -219,8 +202,8 @@ module ActiveRecord
string = @connection.quote("foo")
@connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})")
- bind = Relation::QueryAttribute.new("id", 1, Type::Value.new)
- result = @connection.exec_query("SELECT id, data FROM ex WHERE id = $1", nil, [bind])
+ binds = [bind_attribute("id", 1)]
+ result = @connection.exec_query("SELECT id, data FROM ex WHERE id = $1", nil, binds)
assert_equal 1, result.rows.length
assert_equal 2, result.columns.length
@@ -234,8 +217,8 @@ module ActiveRecord
string = @connection.quote("foo")
@connection.exec_query("INSERT INTO ex (id, data) VALUES (1, #{string})")
- bind = Relation::QueryAttribute.new("id", "1-fuu", Type::Integer.new)
- result = @connection.exec_query("SELECT id, data FROM ex WHERE id = $1", nil, [bind])
+ binds = [bind_attribute("id", "1-fuu", Type::Integer.new)]
+ result = @connection.exec_query("SELECT id, data FROM ex WHERE id = $1", nil, binds)
assert_equal 1, result.rows.length
assert_equal 2, result.columns.length
@@ -263,9 +246,12 @@ module ActiveRecord
def test_index_with_opclass
with_example_table do
- @connection.add_index "ex", "data varchar_pattern_ops", name: "with_opclass"
- index = @connection.indexes("ex").find { |idx| idx.name == "with_opclass" }
+ @connection.add_index "ex", "data varchar_pattern_ops"
+ index = @connection.indexes("ex").find { |idx| idx.name == "index_ex_on_data_varchar_pattern_ops" }
assert_equal "data varchar_pattern_ops", index.columns
+
+ @connection.remove_index "ex", "data varchar_pattern_ops"
+ assert_not @connection.indexes("ex").find { |idx| idx.name == "index_ex_on_data_varchar_pattern_ops" }
end
end
@@ -360,7 +346,7 @@ module ActiveRecord
@connection.select_all "SELECT NULL::anyelement"
@connection.select_all "SELECT NULL::anyelement"
}
- assert_match(/\Aunknown OID \d+: failed to recognize type of 'anyelement'. It will be treated as String.\n\z/, warning)
+ assert_match(/\Aunknown OID \d+: failed to recognize type of 'anyelement'\. It will be treated as String\.\n\z/, warning)
ensure
reset_connection
end
diff --git a/activerecord/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb b/activerecord/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb
new file mode 100644
index 0000000000..8c62690866
--- /dev/null
+++ b/activerecord/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb
@@ -0,0 +1,25 @@
+require "cases/helper"
+require "models/computer"
+require "models/developer"
+
+class PreparedStatementsDisabledTest < ActiveRecord::PostgreSQLTestCase
+ fixtures :developers
+
+ def setup
+ @conn = ActiveRecord::Base.establish_connection :arunit_without_prepared_statements
+ end
+
+ def teardown
+ @conn.release_connection
+ ActiveRecord::Base.establish_connection :arunit
+ end
+
+ def test_select_query_works_even_when_prepared_statements_are_disabled
+ assert_not Developer.connection.prepared_statements
+
+ david = developers(:david)
+
+ assert_equal david, Developer.where(name: "David").last # With Binds
+ assert_operator Developer.count, :>, 0 # Without Binds
+ end
+end
diff --git a/activerecord/test/cases/adapters/postgresql/prepared_statements_test.rb b/activerecord/test/cases/adapters/postgresql/prepared_statements_test.rb
deleted file mode 100644
index b898929f8a..0000000000
--- a/activerecord/test/cases/adapters/postgresql/prepared_statements_test.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-require "cases/helper"
-require "models/developer"
-
-class PreparedStatementsTest < ActiveRecord::PostgreSQLTestCase
- fixtures :developers
-
- def setup
- @default_prepared_statements = Developer.connection_config[:prepared_statements]
- Developer.connection_config[:prepared_statements] = false
- end
-
- def teardown
- Developer.connection_config[:prepared_statements] = @default_prepared_statements
- end
-
- def nothing_raised_with_falsy_prepared_statements
- assert_nothing_raised do
- Developer.where(id: 1)
- end
- end
-end
diff --git a/activerecord/test/cases/adapters/postgresql/quoting_test.rb b/activerecord/test/cases/adapters/postgresql/quoting_test.rb
index 865a3a5098..a1e966b915 100644
--- a/activerecord/test/cases/adapters/postgresql/quoting_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/quoting_test.rb
@@ -1,5 +1,4 @@
require "cases/helper"
-require "ipaddr"
module ActiveRecord
module ConnectionAdapters
@@ -18,12 +17,12 @@ module ActiveRecord
end
def test_quote_float_nan
- nan = 0.0/0
+ nan = 0.0 / 0
assert_equal "'NaN'", @conn.quote(nan)
end
def test_quote_float_infinity
- infinity = 1.0/0
+ infinity = 1.0 / 0
assert_equal "'Infinity'", @conn.quote(infinity)
end
@@ -36,7 +35,7 @@ module ActiveRecord
def test_quote_bit_string
value = "'); SELECT * FROM users; /*\n01\n*/--"
type = OID::Bit.new
- assert_equal nil, @conn.quote(type.serialize(value))
+ assert_nil @conn.quote(type.serialize(value))
end
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb b/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb
index 7193f23880..f86a76e08a 100644
--- a/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/schema_authorization_test.rb
@@ -68,24 +68,13 @@ class SchemaAuthorizationTest < ActiveRecord::PostgreSQLTestCase
USERS.each do |u|
@connection.clear_cache!
set_session_auth u
- assert_equal u, @connection.select_value("SELECT name FROM #{TABLE_NAME} WHERE id = $1", "SQL", [bind_param(1)])
+ assert_equal u, @connection.select_value("SELECT name FROM #{TABLE_NAME} WHERE id = $1", "SQL", [bind_attribute("id", 1)])
set_session_auth
end
end
end
end
- def test_schema_uniqueness
- assert_nothing_raised do
- set_session_auth
- USERS.each do |u|
- set_session_auth u
- assert_equal u, @connection.select_value("SELECT name FROM #{TABLE_NAME} WHERE id = 1")
- set_session_auth
- end
- end
- end
-
def test_sequence_schema_caching
assert_nothing_raised do
USERS.each do |u|
@@ -110,10 +99,6 @@ class SchemaAuthorizationTest < ActiveRecord::PostgreSQLTestCase
private
def set_session_auth(auth = nil)
- @connection.session_auth = auth || "default"
- end
-
- def bind_param(value)
- ActiveRecord::Relation::QueryAttribute.new(nil, value, ActiveRecord::Type::Value.new)
+ @connection.session_auth = auth || "default"
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/schema_test.rb b/activerecord/test/cases/adapters/postgresql/schema_test.rb
index 51a2306c59..f6b957476b 100644
--- a/activerecord/test/cases/adapters/postgresql/schema_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/schema_test.rb
@@ -91,6 +91,7 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
@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
@@ -168,17 +169,17 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
def test_raise_wrapped_exception_on_bad_prepare
assert_raises(ActiveRecord::StatementInvalid) do
- @connection.exec_query "select * from developers where id = ?", "sql", [bind_param(1)]
+ @connection.exec_query "select * from developers where id = ?", "sql", [bind_attribute("id", 1)]
end
end
if ActiveRecord::Base.connection.prepared_statements
def test_schema_change_with_prepared_stmt
altered = false
- @connection.exec_query "select * from developers where id = $1", "sql", [bind_param(1)]
+ @connection.exec_query "select * from developers where id = $1", "sql", [bind_attribute("id", 1)]
@connection.exec_query "alter table developers add column zomg int", "sql", []
altered = true
- @connection.exec_query "select * from developers where id = $1", "sql", [bind_param(1)]
+ @connection.exec_query "select * from developers where id = $1", "sql", [bind_attribute("id", 1)]
ensure
# We are not using DROP COLUMN IF EXISTS because that syntax is only
# supported by pg 9.X
@@ -301,13 +302,13 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
def test_index_name_exists
with_schema_search_path(SCHEMA_NAME) do
- assert @connection.index_name_exists?(TABLE_NAME, INDEX_A_NAME, true)
- assert @connection.index_name_exists?(TABLE_NAME, INDEX_B_NAME, true)
- assert @connection.index_name_exists?(TABLE_NAME, INDEX_C_NAME, true)
- assert @connection.index_name_exists?(TABLE_NAME, INDEX_D_NAME, true)
- assert @connection.index_name_exists?(TABLE_NAME, INDEX_E_NAME, true)
- assert @connection.index_name_exists?(TABLE_NAME, INDEX_E_NAME, true)
- assert_not @connection.index_name_exists?(TABLE_NAME, "missing_index", true)
+ assert @connection.index_name_exists?(TABLE_NAME, INDEX_A_NAME)
+ assert @connection.index_name_exists?(TABLE_NAME, INDEX_B_NAME)
+ assert @connection.index_name_exists?(TABLE_NAME, INDEX_C_NAME)
+ assert @connection.index_name_exists?(TABLE_NAME, INDEX_D_NAME)
+ assert @connection.index_name_exists?(TABLE_NAME, INDEX_E_NAME)
+ assert @connection.index_name_exists?(TABLE_NAME, INDEX_E_NAME)
+ assert_not @connection.index_name_exists?(TABLE_NAME, "missing_index")
end
end
@@ -361,19 +362,11 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
end
def test_primary_key_assuming_schema_search_path
- with_schema_search_path(SCHEMA_NAME) do
+ with_schema_search_path("#{SCHEMA_NAME}, #{SCHEMA2_NAME}") do
assert_equal "id", @connection.primary_key(PK_TABLE_NAME), "primary key should be found"
end
end
- def test_primary_key_raises_error_if_table_not_found_on_schema_search_path
- with_schema_search_path(SCHEMA2_NAME) do
- assert_raises(ActiveRecord::StatementInvalid) do
- @connection.primary_key(PK_TABLE_NAME)
- end
- end
- end
-
def test_pk_and_sequence_for_with_schema_specified
pg_name = ActiveRecord::ConnectionAdapters::PostgreSQL::Name
[
@@ -383,7 +376,7 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
pk, seq = @connection.pk_and_sequence_for(given)
assert_equal "id", pk, "primary key should be found when table referenced as #{given}"
assert_equal pg_name.new(SCHEMA_NAME, "#{PK_TABLE_NAME}_id_seq"), seq, "sequence name should be found when table referenced as #{given}" if given == %("#{SCHEMA_NAME}"."#{PK_TABLE_NAME}")
- assert_equal pg_name.new(SCHEMA_NAME, UNMATCHED_SEQUENCE_NAME), seq, "sequence name should be found when table referenced as #{given}" if given == %("#{SCHEMA_NAME}"."#{UNMATCHED_PK_TABLE_NAME}")
+ assert_equal pg_name.new(SCHEMA_NAME, UNMATCHED_SEQUENCE_NAME), seq, "sequence name should be found when table referenced as #{given}" if given == %("#{SCHEMA_NAME}"."#{UNMATCHED_PK_TABLE_NAME}")
end
end
@@ -393,7 +386,7 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
SCHEMA_NAME => SCHEMA_NAME,
%(#{SCHEMA2_NAME},#{SCHEMA_NAME},public) => SCHEMA2_NAME,
%(public,#{SCHEMA2_NAME},#{SCHEMA_NAME}) => "public"
- }.each do |given,expect|
+ }.each do |given, expect|
with_schema_search_path(given) { assert_equal expect, @connection.current_schema }
end
end
@@ -418,7 +411,7 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
SCHEMA_NAME => true,
SCHEMA2_NAME => true,
"darkside" => false
- }.each do |given,expect|
+ }.each do |given, expect|
assert_equal expect, @connection.schema_exists?(given)
end
end
@@ -474,10 +467,6 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
assert_equal this_index_column, this_index.columns[0]
assert_equal this_index_name, this_index.name
end
-
- def bind_param(value)
- ActiveRecord::Relation::QueryAttribute.new(nil, value, ActiveRecord::Type::Value.new)
- end
end
class SchemaForeignKeyTest < ActiveRecord::PostgreSQLTestCase
diff --git a/activerecord/test/cases/adapters/postgresql/statement_pool_test.rb b/activerecord/test/cases/adapters/postgresql/statement_pool_test.rb
index eb9978a898..146b619a4b 100644
--- a/activerecord/test/cases/adapters/postgresql/statement_pool_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/statement_pool_test.rb
@@ -3,13 +3,13 @@ require "cases/helper"
module ActiveRecord
module ConnectionAdapters
class PostgreSQLAdapter < AbstractAdapter
- class InactivePGconn
+ class InactivePgConnection
def query(*args)
- raise PGError
+ raise PG::Error
end
def status
- PGconn::CONNECTION_BAD
+ PG::CONNECTION_BAD
end
end
@@ -31,7 +31,7 @@ module ActiveRecord
end
def test_dealloc_does_not_raise_on_inactive_connection
- cache = StatementPool.new InactivePGconn.new, 10
+ cache = StatementPool.new InactivePgConnection.new, 10
cache["foo"] = "bar"
assert_nothing_raised { cache.clear }
end
diff --git a/activerecord/test/cases/adapters/postgresql/timestamp_test.rb b/activerecord/test/cases/adapters/postgresql/timestamp_test.rb
index e7c1d97d16..962450aada 100644
--- a/activerecord/test/cases/adapters/postgresql/timestamp_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/timestamp_test.rb
@@ -21,7 +21,7 @@ class PostgresqlTimestampTest < ActiveRecord::PostgreSQLTestCase
@connection.reconnect!
timestamp = PostgresqlTimestampWithZone.find(1)
- assert_equal Time.utc(2010,1,1, 11,0,0), timestamp.time
+ assert_equal Time.utc(2010, 1, 1, 11, 0, 0), timestamp.time
assert_instance_of Time, timestamp.time
end
ensure
@@ -35,7 +35,7 @@ class PostgresqlTimestampTest < ActiveRecord::PostgreSQLTestCase
@connection.execute("SET time zone 'America/Jamaica'", "SCHEMA")
timestamp = PostgresqlTimestampWithZone.find(1)
- assert_equal Time.utc(2010,1,1, 11,0,0), timestamp.time
+ assert_equal Time.utc(2010, 1, 1, 11, 0, 0), timestamp.time
assert_instance_of Time, timestamp.time
end
ensure
diff --git a/activerecord/test/cases/adapters/postgresql/transaction_test.rb b/activerecord/test/cases/adapters/postgresql/transaction_test.rb
index d992e22305..9b42d0383d 100644
--- a/activerecord/test/cases/adapters/postgresql/transaction_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/transaction_test.rb
@@ -1,5 +1,6 @@
require "cases/helper"
require "support/connection_helper"
+require "concurrent/atomic/cyclic_barrier"
module ActiveRecord
class PostgresqlTransactionTest < ActiveRecord::PostgreSQLTestCase
@@ -10,6 +11,8 @@ module ActiveRecord
end
setup do
+ @abort, Thread.abort_on_exception = Thread.abort_on_exception, false
+
@connection = ActiveRecord::Base.connection
@connection.transaction do
@@ -24,35 +27,34 @@ module ActiveRecord
teardown do
@connection.drop_table "samples", if_exists: true
+
+ Thread.abort_on_exception = @abort
end
test "raises SerializationFailure when a serialization failure occurs" do
- with_warning_suppression do
- assert_raises(ActiveRecord::SerializationFailure) do
- thread = Thread.new do
- Sample.transaction isolation: :serializable do
- Sample.delete_all
+ assert_raises(ActiveRecord::SerializationFailure) do
+ before = Concurrent::CyclicBarrier.new(2)
+ after = Concurrent::CyclicBarrier.new(2)
- 10.times do |i|
- sleep 0.1
-
- Sample.create value: i
- end
+ thread = Thread.new do
+ with_warning_suppression do
+ Sample.transaction isolation: :serializable do
+ before.wait
+ Sample.create value: Sample.sum(:value)
+ after.wait
end
end
+ end
- sleep 0.1
-
- Sample.transaction isolation: :serializable do
- Sample.delete_all
-
- 10.times do |i|
- sleep 0.1
-
- Sample.create value: i
+ begin
+ with_warning_suppression do
+ Sample.transaction isolation: :serializable do
+ before.wait
+ Sample.create value: Sample.sum(:value)
+ after.wait
end
end
-
+ ensure
thread.join
end
end
@@ -61,37 +63,40 @@ module ActiveRecord
test "raises Deadlocked when a deadlock is encountered" do
with_warning_suppression do
assert_raises(ActiveRecord::Deadlocked) do
+ barrier = Concurrent::CyclicBarrier.new(2)
+
s1 = Sample.create value: 1
s2 = Sample.create value: 2
thread = Thread.new do
Sample.transaction do
s1.lock!
- sleep 1
+ barrier.wait
s2.update_attributes value: 1
end
end
- sleep 0.5
-
- Sample.transaction do
- s2.lock!
- sleep 1
- s1.update_attributes value: 2
+ begin
+ Sample.transaction do
+ s2.lock!
+ barrier.wait
+ s1.update_attributes value: 2
+ end
+ ensure
+ thread.join
end
-
- thread.join
end
end
end
- protected
+ private
def with_warning_suppression
- log_level = @connection.client_min_messages
- @connection.client_min_messages = "error"
+ log_level = ActiveRecord::Base.connection.client_min_messages
+ ActiveRecord::Base.connection.client_min_messages = "error"
yield
- @connection.client_min_messages = log_level
+ ensure
+ ActiveRecord::Base.connection.client_min_messages = log_level
end
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/type_lookup_test.rb b/activerecord/test/cases/adapters/postgresql/type_lookup_test.rb
index bd45a9daa0..784d77a8d1 100644
--- a/activerecord/test/cases/adapters/postgresql/type_lookup_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/type_lookup_test.rb
@@ -19,7 +19,7 @@ class PostgresqlTypeLookupTest < ActiveRecord::PostgreSQLTestCase
big_array = [123456789123456789]
assert_raises(ActiveModel::RangeError) { int_array.serialize(big_array) }
- assert_equal "{123456789123456789}", bigint_array.serialize(big_array)
+ assert_equal "{123456789123456789}", @connection.type_cast(bigint_array.serialize(big_array))
end
test "range types correctly respect registration of subtypes" do
diff --git a/activerecord/test/cases/adapters/postgresql/utils_test.rb b/activerecord/test/cases/adapters/postgresql/utils_test.rb
index 01c597beae..9f9e3bda2f 100644
--- a/activerecord/test/cases/adapters/postgresql/utils_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/utils_test.rb
@@ -7,13 +7,13 @@ class PostgreSQLUtilsTest < ActiveRecord::PostgreSQLTestCase
def test_extract_schema_qualified_name
{
- %(table_name) => [nil,"table_name"],
- %("table.name") => [nil,"table.name"],
+ %(table_name) => [nil, "table_name"],
+ %("table.name") => [nil, "table.name"],
%(schema.table_name) => %w{schema table_name},
%("schema".table_name) => %w{schema table_name},
%(schema."table_name") => %w{schema table_name},
%("schema"."table_name") => %w{schema table_name},
- %("even spaces".table) => ["even spaces","table"],
+ %("even spaces".table) => ["even spaces", "table"],
%(schema."table.name") => ["schema", "table.name"]
}.each do |given, expect|
assert_equal Name.new(*expect), extract_schema_qualified_name(given)
@@ -56,7 +56,7 @@ class PostgreSQLNameTest < ActiveRecord::PostgreSQLTestCase
test "can be used as hash key" do
hash = { Name.new("schema", "article_seq") => "success" }
assert_equal "success", hash[Name.new("schema", "article_seq")]
- assert_equal nil, hash[Name.new("schema", "articles")]
- assert_equal nil, hash[Name.new("public", "article_seq")]
+ assert_nil hash[Name.new("schema", "articles")]
+ assert_nil hash[Name.new("public", "article_seq")]
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/uuid_test.rb b/activerecord/test/cases/adapters/postgresql/uuid_test.rb
index 9a59691737..6ebe9d82a7 100644
--- a/activerecord/test/cases/adapters/postgresql/uuid_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/uuid_test.rb
@@ -9,6 +9,14 @@ module PostgresqlUUIDHelper
def drop_table(name)
connection.drop_table name, if_exists: true
end
+
+ def uuid_function
+ connection.supports_pgcrypto_uuid? ? "gen_random_uuid()" : "uuid_generate_v4()"
+ end
+
+ def uuid_default
+ connection.supports_pgcrypto_uuid? ? {} : { default: uuid_function }
+ end
end
class PostgresqlUUIDTest < ActiveRecord::PostgreSQLTestCase
@@ -21,6 +29,7 @@ class PostgresqlUUIDTest < ActiveRecord::PostgreSQLTestCase
setup do
enable_extension!("uuid-ossp", connection)
+ enable_extension!("pgcrypto", connection) if connection.supports_pgcrypto_uuid?
connection.create_table "uuid_data_type" do |t|
t.uuid "guid"
@@ -31,14 +40,22 @@ class PostgresqlUUIDTest < ActiveRecord::PostgreSQLTestCase
drop_table "uuid_data_type"
end
+ if ActiveRecord::Base.connection.supports_pgcrypto_uuid?
+ def test_uuid_column_default
+ connection.add_column :uuid_data_type, :thingy, :uuid, null: false, default: "gen_random_uuid()"
+ UUIDType.reset_column_information
+ column = UUIDType.columns_hash["thingy"]
+ assert_equal "gen_random_uuid()", column.default_function
+ end
+ end
+
def test_change_column_default
- @connection.add_column :uuid_data_type, :thingy, :uuid, null: false, default: "uuid_generate_v1()"
+ connection.add_column :uuid_data_type, :thingy, :uuid, null: false, default: "uuid_generate_v1()"
UUIDType.reset_column_information
column = UUIDType.columns_hash["thingy"]
assert_equal "uuid_generate_v1()", column.default_function
- @connection.change_column :uuid_data_type, :thingy, :uuid, null: false, default: "uuid_generate_v4()"
-
+ connection.change_column :uuid_data_type, :thingy, :uuid, null: false, default: "uuid_generate_v4()"
UUIDType.reset_column_information
column = UUIDType.columns_hash["thingy"]
assert_equal "uuid_generate_v4()", column.default_function
@@ -46,6 +63,16 @@ class PostgresqlUUIDTest < ActiveRecord::PostgreSQLTestCase
UUIDType.reset_column_information
end
+ def test_add_column_with_null_true_and_default_nil
+ assert_nothing_raised do
+ connection.add_column :uuid_data_type, :thingy, :uuid, null: true, default: nil
+ end
+ UUIDType.reset_column_information
+ column = UUIDType.columns_hash["thingy"]
+ assert column.null
+ assert_nil column.default
+ end
+
def test_data_type_of_uuid_types
column = UUIDType.columns_hash["guid"]
assert_equal :uuid, column.type
@@ -58,12 +85,12 @@ class PostgresqlUUIDTest < ActiveRecord::PostgreSQLTestCase
def test_treat_blank_uuid_as_nil
UUIDType.create! guid: ""
- assert_equal(nil, UUIDType.last.guid)
+ assert_nil(UUIDType.last.guid)
end
def test_treat_invalid_uuid_as_nil
uuid = UUIDType.create! guid: "foobar"
- assert_equal(nil, uuid.guid)
+ assert_nil(uuid.guid)
end
def test_invalid_uuid_dont_modify_before_type_cast
@@ -155,7 +182,7 @@ class PostgresqlUUIDGenerationTest < ActiveRecord::PostgreSQLTestCase
# to test dumping tables which columns have defaults with custom functions
connection.execute <<-SQL
CREATE OR REPLACE FUNCTION my_uuid_generator() RETURNS uuid
- AS $$ SELECT * FROM uuid_generate_v4() $$
+ AS $$ SELECT * FROM #{uuid_function} $$
LANGUAGE SQL VOLATILE;
SQL
@@ -164,11 +191,16 @@ class PostgresqlUUIDGenerationTest < ActiveRecord::PostgreSQLTestCase
t.string "name"
t.uuid "other_uuid_2", default: "my_uuid_generator()"
end
+
+ connection.create_table("pg_uuids_3", id: :uuid, **uuid_default) do |t|
+ t.string "name"
+ end
end
teardown do
drop_table "pg_uuids"
drop_table "pg_uuids_2"
+ drop_table "pg_uuids_3"
connection.execute "DROP FUNCTION IF EXISTS my_uuid_generator();"
end
@@ -192,7 +224,7 @@ class PostgresqlUUIDGenerationTest < ActiveRecord::PostgreSQLTestCase
def test_pk_and_sequence_for_uuid_primary_key
pk, seq = connection.pk_and_sequence_for("pg_uuids")
assert_equal "id", pk
- assert_equal nil, seq
+ assert_nil seq
end
def test_schema_dumper_for_uuid_primary_key
@@ -206,6 +238,34 @@ class PostgresqlUUIDGenerationTest < ActiveRecord::PostgreSQLTestCase
assert_match(/\bcreate_table "pg_uuids_2", id: :uuid, default: -> { "my_uuid_generator\(\)" }/, schema)
assert_match(/t\.uuid "other_uuid_2", default: -> { "my_uuid_generator\(\)" }/, schema)
end
+
+ def test_schema_dumper_for_uuid_primary_key_default
+ schema = dump_table_schema "pg_uuids_3"
+ if connection.supports_pgcrypto_uuid?
+ assert_match(/\bcreate_table "pg_uuids_3", id: :uuid, default: -> { "gen_random_uuid\(\)" }/, schema)
+ else
+ assert_match(/\bcreate_table "pg_uuids_3", id: :uuid, default: -> { "uuid_generate_v4\(\)" }/, schema)
+ end
+ end
+
+ def test_schema_dumper_for_uuid_primary_key_default_in_legacy_migration
+ @verbose_was = ActiveRecord::Migration.verbose
+ ActiveRecord::Migration.verbose = false
+
+ migration = Class.new(ActiveRecord::Migration[5.0]) do
+ def version; 101 end
+ def migrate(x)
+ create_table("pg_uuids_4", id: :uuid)
+ end
+ end.new
+ ActiveRecord::Migrator.new(:up, [migration]).migrate
+
+ schema = dump_table_schema "pg_uuids_4"
+ assert_match(/\bcreate_table "pg_uuids_4", id: :uuid, default: -> { "uuid_generate_v4\(\)" }/, schema)
+ ensure
+ drop_table "pg_uuids_4"
+ ActiveRecord::Migration.verbose = @verbose_was
+ end
end
end
@@ -237,6 +297,25 @@ class PostgresqlUUIDTestNilDefault < ActiveRecord::PostgreSQLTestCase
schema = dump_table_schema "pg_uuids"
assert_match(/\bcreate_table "pg_uuids", id: :uuid, default: nil/, schema)
end
+
+ def test_schema_dumper_for_uuid_primary_key_with_default_nil_in_legacy_migration
+ @verbose_was = ActiveRecord::Migration.verbose
+ ActiveRecord::Migration.verbose = false
+
+ migration = Class.new(ActiveRecord::Migration[5.0]) do
+ def version; 101 end
+ def migrate(x)
+ create_table("pg_uuids_4", id: :uuid, default: nil)
+ end
+ end.new
+ ActiveRecord::Migrator.new(:up, [migration]).migrate
+
+ schema = dump_table_schema "pg_uuids_4"
+ assert_match(/\bcreate_table "pg_uuids_4", id: :uuid, default: nil/, schema)
+ ensure
+ drop_table "pg_uuids_4"
+ ActiveRecord::Migration.verbose = @verbose_was
+ end
end
end
@@ -255,10 +334,10 @@ class PostgresqlUUIDTestInverseOf < ActiveRecord::PostgreSQLTestCase
setup do
connection.transaction do
- connection.create_table("pg_uuid_posts", id: :uuid) do |t|
+ connection.create_table("pg_uuid_posts", id: :uuid, **uuid_default) do |t|
t.string "title"
end
- connection.create_table("pg_uuid_comments", id: :uuid) do |t|
+ connection.create_table("pg_uuid_comments", id: :uuid, **uuid_default) do |t|
t.references :uuid_post, type: :uuid
t.string "content"
end
@@ -282,7 +361,6 @@ class PostgresqlUUIDTestInverseOf < ActiveRecord::PostgreSQLTestCase
assert_raise ActiveRecord::RecordNotFound do
UuidPost.find(123456)
end
-
end
def test_find_by_with_uuid