mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Do not consider PG array columns as number or text columns
The code uses these checks in several places to know what to do with a particular column, for instance AR attribute query methods has a branch like this: if column.number? !value.zero? end This should never be true for array columns, since it would be the same as running [].zero?, which results in a NoMethodError exception. Fixing this by ensuring that array columns in PostgreSQL never return true for number?/text? checks. Since most of the array support was based on the postgres_ext lib, it's worth noting it does the same thing for numeric array columns too: https://github.com/dockyard/postgres_ext/blob/v1.0.0/lib/postgres_ext/active_record/connection_adapters/postgres_adapter.rb#L72 This extended the same logic for text columns to ensure consistency.
This commit is contained in:
parent
618d5317d3
commit
56510091fb
3 changed files with 33 additions and 3 deletions
|
@ -1,3 +1,21 @@
|
||||||
|
* Do not consider PostgreSQL array columns as number or text columns.
|
||||||
|
|
||||||
|
The code uses these checks in several places to know what to do with a
|
||||||
|
particular column, for instance AR attribute query methods has a branch
|
||||||
|
like this:
|
||||||
|
|
||||||
|
if column.number?
|
||||||
|
!value.zero?
|
||||||
|
end
|
||||||
|
|
||||||
|
This should never be true for array columns, since it would be the same
|
||||||
|
as running [].zero?, which results in a NoMethodError exception.
|
||||||
|
|
||||||
|
Fixing this by ensuring that array columns in PostgreSQL never return
|
||||||
|
true for number?/text? checks.
|
||||||
|
|
||||||
|
*Carlos Antonio da Silva*
|
||||||
|
|
||||||
* When connecting to a non-existant postgresql database, the error:
|
* When connecting to a non-existant postgresql database, the error:
|
||||||
`ActiveRecord::NoDatabaseError` will now be raised. When being used with Rails
|
`ActiveRecord::NoDatabaseError` will now be raised. When being used with Rails
|
||||||
the error message will include information on how to create a database:
|
the error message will include information on how to create a database:
|
||||||
|
|
|
@ -46,7 +46,7 @@ module ActiveRecord
|
||||||
# PostgreSQL-specific extensions to column definitions in a table.
|
# PostgreSQL-specific extensions to column definitions in a table.
|
||||||
class PostgreSQLColumn < Column #:nodoc:
|
class PostgreSQLColumn < Column #:nodoc:
|
||||||
attr_accessor :array
|
attr_accessor :array
|
||||||
# Instantiates a new PostgreSQL column definition in a table.
|
|
||||||
def initialize(name, default, oid_type, sql_type = nil, null = true)
|
def initialize(name, default, oid_type, sql_type = nil, null = true)
|
||||||
@oid_type = oid_type
|
@oid_type = oid_type
|
||||||
default_value = self.class.extract_value_from_default(default)
|
default_value = self.class.extract_value_from_default(default)
|
||||||
|
@ -62,6 +62,14 @@ module ActiveRecord
|
||||||
@default_function = default if has_default_function?(default_value, default)
|
@default_function = default if has_default_function?(default_value, default)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def number?
|
||||||
|
!array && super
|
||||||
|
end
|
||||||
|
|
||||||
|
def text?
|
||||||
|
!array && super
|
||||||
|
end
|
||||||
|
|
||||||
# :stopdoc:
|
# :stopdoc:
|
||||||
class << self
|
class << self
|
||||||
include ConnectionAdapters::PostgreSQLColumn::Cast
|
include ConnectionAdapters::PostgreSQLColumn::Cast
|
||||||
|
|
|
@ -26,6 +26,12 @@ class PostgresqlArrayTest < ActiveRecord::TestCase
|
||||||
def test_column
|
def test_column
|
||||||
assert_equal :string, @column.type
|
assert_equal :string, @column.type
|
||||||
assert @column.array
|
assert @column.array
|
||||||
|
assert_not @column.text?
|
||||||
|
|
||||||
|
ratings_column = PgArray.columns_hash['ratings']
|
||||||
|
assert_equal :integer, ratings_column.type
|
||||||
|
assert ratings_column.array
|
||||||
|
assert_not ratings_column.number?
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_change_column_with_array
|
def test_change_column_with_array
|
||||||
|
@ -50,8 +56,6 @@ class PostgresqlArrayTest < ActiveRecord::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_type_cast_array
|
def test_type_cast_array
|
||||||
assert @column
|
|
||||||
|
|
||||||
data = '{1,2,3}'
|
data = '{1,2,3}'
|
||||||
oid_type = @column.instance_variable_get('@oid_type').subtype
|
oid_type = @column.instance_variable_get('@oid_type').subtype
|
||||||
# we are getting the instance variable in this test, but in the
|
# we are getting the instance variable in this test, but in the
|
||||||
|
|
Loading…
Reference in a new issue