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.rb12
-rw-r--r--activerecord/test/cases/adapters/postgresql/explain_test.rb7
-rw-r--r--activerecord/test/cases/adapters/postgresql/hstore_test.rb90
-rw-r--r--activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb42
-rw-r--r--activerecord/test/cases/adapters/postgresql/schema_test.rb53
5 files changed, 188 insertions, 16 deletions
diff --git a/activerecord/test/cases/adapters/postgresql/active_schema_test.rb b/activerecord/test/cases/adapters/postgresql/active_schema_test.rb
index e4746d4aa3..447d729e52 100644
--- a/activerecord/test/cases/adapters/postgresql/active_schema_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/active_schema_test.rb
@@ -21,6 +21,18 @@ class PostgresqlActiveSchemaTest < ActiveRecord::TestCase
assert_equal %(CREATE DATABASE "aimonetti" ENCODING = 'latin1'), create_database(:aimonetti, :encoding => :latin1)
end
+ def test_add_index
+ # add_index calls index_name_exists? which can't work since execute is stubbed
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send(:define_method, :index_name_exists?) do |*|
+ false
+ end
+
+ expected = %(CREATE UNIQUE INDEX "index_people_on_last_name" ON "people" ("last_name") WHERE state = 'active')
+ assert_equal expected, add_index(:people, :last_name, :unique => true, :where => "state = 'active'")
+
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send(:remove_method, :index_name_exists?)
+ end
+
private
def method_missing(method_symbol, *arguments)
ActiveRecord::Base.connection.send(method_symbol, *arguments)
diff --git a/activerecord/test/cases/adapters/postgresql/explain_test.rb b/activerecord/test/cases/adapters/postgresql/explain_test.rb
index 0b61f61572..619d581d5f 100644
--- a/activerecord/test/cases/adapters/postgresql/explain_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/explain_test.rb
@@ -22,6 +22,13 @@ module ActiveRecord
assert_match %(EXPLAIN for: SELECT "audit_logs".* FROM "audit_logs" WHERE "audit_logs"."developer_id" IN (1)), explain
assert_match %(Seq Scan on audit_logs), explain
end
+
+ def test_dont_explain_for_set_search_path
+ queries = Thread.current[:available_queries_for_explain] = []
+ ActiveRecord::Base.connection.schema_search_path = "public"
+ assert queries.empty?
+ end
+
end
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/hstore_test.rb b/activerecord/test/cases/adapters/postgresql/hstore_test.rb
index 33bf4478cc..23bafde17b 100644
--- a/activerecord/test/cases/adapters/postgresql/hstore_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/hstore_test.rb
@@ -1,4 +1,8 @@
+# encoding: utf-8
+
require "cases/helper"
+require 'active_record/base'
+require 'active_record/connection_adapters/postgresql_adapter'
class PostgresqlHstoreTest < ActiveRecord::TestCase
class Hstore < ActiveRecord::Base
@@ -10,12 +14,13 @@ class PostgresqlHstoreTest < ActiveRecord::TestCase
begin
@connection.transaction do
@connection.create_table('hstores') do |t|
- t.hstore 'tags'
+ t.hstore 'tags', :default => ''
end
end
rescue ActiveRecord::StatementInvalid
return skip "do not test on PG without hstore"
end
+ @column = Hstore.columns.find { |c| c.name == 'tags' }
end
def teardown
@@ -23,30 +28,83 @@ class PostgresqlHstoreTest < ActiveRecord::TestCase
end
def test_column
- column = Hstore.columns.find { |c| c.name == 'tags' }
- assert column
- assert_equal :hstore, column.type
+ assert_equal :hstore, @column.type
end
def test_type_cast_hstore
- column = Hstore.columns.find { |c| c.name == 'tags' }
- assert column
+ assert @column
data = "\"1\"=>\"2\""
- hash = column.class.cast_hstore data
+ hash = @column.class.string_to_hstore data
assert_equal({'1' => '2'}, hash)
- assert_equal({'1' => '2'}, column.type_cast(data))
+ assert_equal({'1' => '2'}, @column.type_cast(data))
+
+ assert_equal({}, @column.type_cast(""))
+ assert_equal({'key'=>nil}, @column.type_cast('key => NULL'))
+ assert_equal({'c'=>'}','"a"'=>'b "a b'}, @column.type_cast(%q(c=>"}", "\"a\""=>"b \"a b")))
+ end
+
+ def test_gen1
+ assert_equal(%q(" "=>""), @column.class.hstore_to_string({' '=>''}))
+ end
+
+ def test_gen2
+ assert_equal(%q(","=>""), @column.class.hstore_to_string({','=>''}))
+ end
+
+ def test_gen3
+ assert_equal(%q("="=>""), @column.class.hstore_to_string({'='=>''}))
+ end
+
+ def test_gen4
+ assert_equal(%q(">"=>""), @column.class.hstore_to_string({'>'=>''}))
+ end
+
+ def test_parse1
+ assert_equal({'a'=>nil,'b'=>nil,'c'=>'NuLl','null'=>'c'}, @column.type_cast('a=>null,b=>NuLl,c=>"NuLl",null=>c'))
+ end
+
+ def test_parse2
+ assert_equal({" " => " "}, @column.type_cast("\\ =>\\ "))
+ end
+
+ def test_parse3
+ assert_equal({"=" => ">"}, @column.type_cast("==>>"))
end
+ def test_parse4
+ assert_equal({"=a"=>"q=w"}, @column.type_cast('\=a=>q=w'))
+ end
+
+ def test_parse5
+ assert_equal({"=a"=>"q=w"}, @column.type_cast('"=a"=>q\=w'))
+ end
+
+ def test_parse6
+ assert_equal({"\"a"=>"q>w"}, @column.type_cast('"\"a"=>q>w'))
+ end
+
+ def test_parse7
+ assert_equal({"\"a"=>"q\"w"}, @column.type_cast('\"a=>q"w'))
+ end
+
+ def test_rewrite
+ @connection.execute "insert into hstores (tags) VALUES ('1=>2')"
+ x = Hstore.first
+ x.tags = { '"a\'' => 'b' }
+ assert x.save!
+ end
+
+
def test_select
@connection.execute "insert into hstores (tags) VALUES ('1=>2')"
- x = Hstore.find :first
+ x = Hstore.first
assert_equal({'1' => '2'}, x.tags)
end
def test_select_multikey
@connection.execute "insert into hstores (tags) VALUES ('1=>2,2=>3')"
- x = Hstore.find :first
+ x = Hstore.first
assert_equal({'1' => '2', '2' => '3'}, x.tags)
end
@@ -54,6 +112,10 @@ class PostgresqlHstoreTest < ActiveRecord::TestCase
assert_cycle('a' => 'b', '1' => '2')
end
+ def test_nil
+ assert_cycle('a' => nil)
+ end
+
def test_quotes
assert_cycle('a' => 'b"ar', '1"foo' => '2')
end
@@ -74,13 +136,19 @@ class PostgresqlHstoreTest < ActiveRecord::TestCase
assert_cycle('a=>b' => 'bar', '1"foo' => '2')
end
+ def test_quoting_special_characters
+ assert_cycle('ca' => 'cà', 'ac' => 'àc')
+ end
+
private
def assert_cycle hash
+ # test creation
x = Hstore.create!(:tags => hash)
x.reload
assert_equal(hash, x.tags)
- # make sure updates work
+ # test updating
+ x = Hstore.create!(:tags => {})
x.tags = hash
x.save!
x.reload
diff --git a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
index d57794daf8..92e31a3e44 100644
--- a/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/postgresql_adapter_test.rb
@@ -49,6 +49,33 @@ module ActiveRecord
assert_equal expect, id
end
+ def test_insert_sql_with_returning_disabled
+ connection = connection_without_insert_returning
+ id = connection.insert_sql("insert into postgresql_partitioned_table_parent (number) VALUES (1)")
+ expect = connection.query('select max(id) from postgresql_partitioned_table_parent').first.first
+ assert_equal expect, id
+ 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')
+ expect = connection.query('select max(id) from postgresql_partitioned_table_parent').first.first
+ assert_equal expect, result.rows.first.first
+ end
+
+ def test_exec_insert_with_returning_disabled_and_no_sequence_name_given
+ connection = connection_without_insert_returning
+ result = connection.exec_insert("insert into postgresql_partitioned_table_parent (number) VALUES (1)", nil, [], 'id')
+ expect = connection.query('select max(id) from postgresql_partitioned_table_parent').first.first
+ assert_equal expect, result.rows.first.first
+ end
+
+ def test_sql_for_insert_with_returning_disabled
+ connection = connection_without_insert_returning
+ result = connection.sql_for_insert('sql', nil, nil, nil, 'binds')
+ assert_equal ['sql', 'binds'], result
+ end
+
def test_serial_sequence
assert_equal 'public.accounts_id_seq',
@connection.serial_sequence('accounts', 'id')
@@ -179,6 +206,17 @@ module ActiveRecord
assert_equal Arel.sql('$2'), bind
end
+ def test_partial_index
+ @connection.add_index 'ex', %w{ id number }, :name => 'partial', :where => "number > 100"
+ index = @connection.indexes('ex').find { |idx| idx.name == 'partial' }
+ assert_equal "(number > 100)", index.where
+ end
+
+ def test_distinct_with_nulls
+ assert_equal "DISTINCT posts.title, posts.updater_id AS alias_0", @connection.distinct("posts.title", ["posts.updater_id desc nulls first"])
+ assert_equal "DISTINCT posts.title, posts.updater_id AS alias_0", @connection.distinct("posts.title", ["posts.updater_id desc nulls last"])
+ end
+
private
def insert(ctx, data)
binds = data.map { |name, value|
@@ -193,6 +231,10 @@ module ActiveRecord
ctx.exec_insert(sql, 'SQL', binds)
end
+
+ def connection_without_insert_returning
+ ActiveRecord::Base.postgresql_connection(ActiveRecord::Base.configurations['arunit'].merge(:insert_returning => false))
+ end
end
end
end
diff --git a/activerecord/test/cases/adapters/postgresql/schema_test.rb b/activerecord/test/cases/adapters/postgresql/schema_test.rb
index 18670b4177..9208f53997 100644
--- a/activerecord/test/cases/adapters/postgresql/schema_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/schema_test.rb
@@ -24,6 +24,8 @@ class SchemaTest < ActiveRecord::TestCase
'moment timestamp without time zone default now()'
]
PK_TABLE_NAME = 'table_with_pk'
+ UNMATCHED_SEQUENCE_NAME = 'unmatched_primary_key_default_value_seq'
+ UNMATCHED_PK_TABLE_NAME = 'table_with_unmatched_sequence_for_pk'
class Thing1 < ActiveRecord::Base
self.table_name = "test_schema.things"
@@ -60,6 +62,8 @@ class SchemaTest < ActiveRecord::TestCase
@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 TABLE #{SCHEMA_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
def teardown
@@ -67,6 +71,45 @@ class SchemaTest < ActiveRecord::TestCase
@connection.execute "DROP SCHEMA #{SCHEMA_NAME} CASCADE"
end
+ def test_schema_names
+ assert_equal ["public", "test_schema", "test_schema2"], @connection.schema_names
+ end
+
+ def test_create_schema
+ begin
+ @connection.create_schema "test_schema3"
+ assert @connection.schema_names.include? "test_schema3"
+ ensure
+ @connection.drop_schema "test_schema3"
+ end
+ end
+
+ def test_raise_create_schema_with_existing_schema
+ begin
+ @connection.create_schema "test_schema3"
+ assert_raises(ActiveRecord::StatementInvalid) do
+ @connection.create_schema "test_schema3"
+ end
+ ensure
+ @connection.drop_schema "test_schema3"
+ end
+ end
+
+ def test_drop_schema
+ begin
+ @connection.create_schema "test_schema3"
+ ensure
+ @connection.drop_schema "test_schema3"
+ end
+ assert !@connection.schema_names.include?("test_schema3")
+ end
+
+ def test_raise_drop_schema_with_nonexisting_schema
+ assert_raises(ActiveRecord::StatementInvalid) do
+ @connection.drop_schema "test_schema3"
+ end
+ end
+
def test_schema_change_with_prepared_stmt
altered = false
@connection.exec_query "select * from developers where id = $1", 'sql', [[nil, 1]]
@@ -179,13 +222,13 @@ class SchemaTest < ActiveRecord::TestCase
end
def test_raise_on_unquoted_schema_name
- assert_raise(ActiveRecord::StatementInvalid) do
+ assert_raises(ActiveRecord::StatementInvalid) do
with_schema_search_path '$user,public'
end
end
def test_without_schema_search_path
- assert_raise(ActiveRecord::StatementInvalid) { columns(TABLE_NAME) }
+ assert_raises(ActiveRecord::StatementInvalid) { columns(TABLE_NAME) }
end
def test_ignore_nil_schema_search_path
@@ -241,12 +284,12 @@ class SchemaTest < ActiveRecord::TestCase
def test_pk_and_sequence_for_with_schema_specified
[
%("#{SCHEMA_NAME}"."#{PK_TABLE_NAME}"),
- %(#{SCHEMA_NAME}."#{PK_TABLE_NAME}"),
- %(#{SCHEMA_NAME}.#{PK_TABLE_NAME})
+ %("#{SCHEMA_NAME}"."#{UNMATCHED_PK_TABLE_NAME}")
].each do |given|
pk, seq = @connection.pk_and_sequence_for(given)
assert_equal 'id', pk, "primary key should be found when table referenced as #{given}"
- assert_equal "#{SCHEMA_NAME}.#{PK_TABLE_NAME}_id_seq", seq, "sequence name should be found when table referenced as #{given}"
+ assert_equal "#{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 "#{UNMATCHED_SEQUENCE_NAME}", seq, "sequence name should be found when table referenced as #{given}" if given == %("#{SCHEMA_NAME}"."#{UNMATCHED_PK_TABLE_NAME}")
end
end