Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
- [#1381](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1381) Fix `change_column` to preserve old column attributes.
- [#1393](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1393) Treat TinyTDS `failed dbsqlsend() function` errors as `ConnectionNotEstablished` so they're retried instead of surfaced as `StatementInvalid`.
- [#1397](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1397) Treat "DBPROCESS is dead or not enabled" as ConnectionNotEstablished.
- [#1406](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1406) Stop deserializing column defaults.

Please check [8-1-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/8-1-stable/CHANGELOG.md) for previous changes.
Original file line number Diff line number Diff line change
Expand Up @@ -573,13 +573,16 @@ def default_value_and_function(default:, name:, type:, original_type:, view_exis
[string_literal, nil]
when /CREATE DEFAULT/mi
[nil, nil]
when /\A\(NULL\)\Z/i
[nil, nil]
else
type = case type
when /smallint|int|bigint/ then original_type
else type
end
value = default.match(/\A\((.*)\)\Z/m)[1]
value = select_value("SELECT CAST(#{value} AS #{type}) AS value", "SCHEMA")
if value.start_with?("(") && value.end_with?(")")
value = value[1..-2]
end
if value.start_with?("'") && value.end_with?("'")
value = value[1..-2]
end
[value, nil]
end
end
Expand Down
64 changes: 0 additions & 64 deletions test/cases/coerced_tests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -524,31 +524,6 @@ def test_distinct_count_all_with_custom_select_and_order_coerced
module ActiveRecord
class Migration
class ChangeSchemaTest < ActiveRecord::TestCase
# Integer.default is a number and not a string
coerce_tests! :test_create_table_with_defaults
def test_create_table_with_defaults_coerce
connection.create_table :testings do |t|
t.column :one, :string, default: "hello"
t.column :two, :boolean, default: true
t.column :three, :boolean, default: false
t.column :four, :integer, default: 1
t.column :five, :text, default: "hello"
end

columns = connection.columns(:testings)
one = columns.detect { |c| c.name == "one" }
two = columns.detect { |c| c.name == "two" }
three = columns.detect { |c| c.name == "three" }
four = columns.detect { |c| c.name == "four" }
five = columns.detect { |c| c.name == "five" }

assert_equal "hello", one.default
assert_equal true, two.cast_type.deserialize(two.default)
assert_equal false, three.cast_type.deserialize(three.default)
assert_equal 1, four.default
assert_equal "hello", five.default
end

# Use precision 6 by default for datetime/timestamp columns. SQL Server uses `datetime2` for date-times with precision.
coerce_tests! :test_add_column_with_postgresql_datetime_type
def test_add_column_with_postgresql_datetime_type_coerced
Expand Down Expand Up @@ -610,19 +585,6 @@ def test_add_column_without_limit_coerced
module ActiveRecord
class Migration
class ColumnsTest < ActiveRecord::TestCase
# Our defaults are real 70000 integers vs '70000' strings.
coerce_tests! :test_rename_column_preserves_default_value_not_null
def test_rename_column_preserves_default_value_not_null_coerced
add_column "test_models", "salary", :integer, default: 70000
default_before = connection.columns("test_models").find { |c| c.name == "salary" }.default
assert_equal 70000, default_before
rename_column "test_models", "salary", "annual_salary"
TestModel.reset_column_information
assert TestModel.column_names.include?("annual_salary")
default_after = connection.columns("test_models").find { |c| c.name == "annual_salary" }.default
assert_equal 70000, default_after
end

# Dropping the column removes the single index.
coerce_tests! :test_remove_column_with_multi_column_index
def test_remove_column_with_multi_column_index_coerced
Expand Down Expand Up @@ -1958,32 +1920,6 @@ def test_time_precision_is_truncated_on_assignment_coerced
coerce_tests! :test_invalid_time_precision_raises_error
end

class DefaultNumbersTest < ActiveRecord::TestCase
# We do better with native types and do not return strings for everything.
coerce_tests! :test_default_positive_integer
def test_default_positive_integer_coerced
record = DefaultNumber.new
assert_equal 7, record.positive_integer
assert_equal 7, record.positive_integer_before_type_cast
end

# We do better with native types and do not return strings for everything.
coerce_tests! :test_default_negative_integer
def test_default_negative_integer_coerced
record = DefaultNumber.new
assert_equal(-5, record.negative_integer)
assert_equal(-5, record.negative_integer_before_type_cast)
end

# We do better with native types and do not return strings for everything.
coerce_tests! :test_default_decimal_number
def test_default_decimal_number_coerced
record = DefaultNumber.new
assert_equal BigDecimal("2.78"), record.decimal_number
assert_equal 2.78, record.decimal_number_before_type_cast
end
end

module ActiveRecord
class CollectionCacheKeyTest < ActiveRecord::TestCase
# Will trust rails has this sorted since you cant offset without a limit.
Expand Down
40 changes: 20 additions & 20 deletions test/cases/column_test_sqlserver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def assert_obj_set_and_save(attribute, value)
_(col.sql_type).must_equal "bigint(8)"
_(col.type).must_equal :integer
_(col.null).must_equal true
_(col.default).must_equal 42
_(col.default).must_equal "42"
_(obj.bigint).must_equal 42
_(col.default_function).must_be_nil
type = col.cast_type
Expand All @@ -56,7 +56,7 @@ def assert_obj_set_and_save(attribute, value)
_(col.sql_type).must_equal "int(4)"
_(col.type).must_equal :integer
_(col.null).must_equal true
_(col.default).must_equal 42
_(col.default).must_equal "42"
_(obj.int).must_equal 42
_(col.default_function).must_be_nil
type = col.cast_type
Expand All @@ -71,7 +71,7 @@ def assert_obj_set_and_save(attribute, value)
_(col.sql_type).must_equal "smallint(2)"
_(col.type).must_equal :integer
_(col.null).must_equal true
_(col.default).must_equal 42
_(col.default).must_equal "42"
_(obj.smallint).must_equal 42
_(col.default_function).must_be_nil
type = col.cast_type
Expand All @@ -86,7 +86,7 @@ def assert_obj_set_and_save(attribute, value)
_(col.sql_type).must_equal "tinyint(1)"
_(col.type).must_equal :integer
_(col.null).must_equal true
_(col.default).must_equal 42
_(col.default).must_equal "42"
_(obj.tinyint).must_equal 42
_(col.default_function).must_be_nil
type = col.cast_type
Expand All @@ -101,7 +101,7 @@ def assert_obj_set_and_save(attribute, value)
_(col.sql_type).must_equal "bit"
_(col.type).must_equal :boolean
_(col.null).must_equal true
_(col.default).must_equal true
_(col.default).must_equal "1"
_(obj.bit).must_equal true
_(col.default_function).must_be_nil
type = col.cast_type
Expand All @@ -122,7 +122,7 @@ def assert_obj_set_and_save(attribute, value)
_(col.sql_type).must_equal "decimal(9,2)"
_(col.type).must_equal :decimal
_(col.null).must_equal true
_(col.default).must_equal BigDecimal("12345.01")
_(col.default).must_equal "12345.01"
_(obj.decimal_9_2).must_equal BigDecimal("12345.01")
_(col.default_function).must_be_nil
type = col.cast_type
Expand All @@ -139,7 +139,7 @@ def assert_obj_set_and_save(attribute, value)
it "decimal(16,4)" do
col = column("decimal_16_4")
_(col.sql_type).must_equal "decimal(16,4)"
_(col.default).must_equal BigDecimal("1234567.89")
_(col.default).must_equal "1234567.89"
_(obj.decimal_16_4).must_equal BigDecimal("1234567.89")
_(col.default_function).must_be_nil
type = col.cast_type
Expand All @@ -156,7 +156,7 @@ def assert_obj_set_and_save(attribute, value)
_(col.sql_type).must_equal "numeric(18,0)"
_(col.type).must_equal :decimal
_(col.null).must_equal true
_(col.default).must_equal BigDecimal(191)
_(col.default).must_equal "191"
_(obj.numeric_18_0).must_equal BigDecimal(191)
_(col.default_function).must_be_nil

Expand All @@ -178,7 +178,7 @@ def assert_obj_set_and_save(attribute, value)
_(col.sql_type).must_equal "numeric(36,2)"
_(col.type).must_equal :decimal
_(col.null).must_equal true
_(col.default).must_equal BigDecimal("12345678901234567890.01")
_(col.default).must_equal "12345678901234567890.01"
_(obj.numeric_36_2).must_equal BigDecimal("12345678901234567890.01")
_(col.default_function).must_be_nil
type = col.cast_type
Expand All @@ -197,7 +197,7 @@ def assert_obj_set_and_save(attribute, value)
_(col.sql_type).must_equal "money"
_(col.type).must_equal :money
_(col.null).must_equal true
_(col.default).must_equal BigDecimal("4.20")
_(col.default).must_equal "4.20"
_(obj.money).must_equal BigDecimal("4.20")
_(col.default_function).must_be_nil
type = col.cast_type
Expand All @@ -216,7 +216,7 @@ def assert_obj_set_and_save(attribute, value)
_(col.sql_type).must_equal "smallmoney"
_(col.type).must_equal :smallmoney
_(col.null).must_equal true
_(col.default).must_equal BigDecimal("4.20")
_(col.default).must_equal "4.20"
_(obj.smallmoney).must_equal BigDecimal("4.20")
_(col.default_function).must_be_nil
type = col.cast_type
Expand All @@ -239,7 +239,7 @@ def assert_obj_set_and_save(attribute, value)
_(col.sql_type).must_equal "float"
_(col.type).must_equal :float
_(col.null).must_equal true
_(col.default).must_equal 123.00000001
_(col.default).must_equal "123.00000001"
_(obj.float).must_equal 123.00000001
_(col.default_function).must_be_nil
type = col.cast_type
Expand All @@ -258,7 +258,7 @@ def assert_obj_set_and_save(attribute, value)
_(col.sql_type).must_equal "real"
_(col.type).must_equal :real
_(col.null).must_equal true
_(col.default).must_be_close_to 123.45, 0.01
_(col.default).must_equal "123.45"
_(obj.real).must_be_close_to 123.45, 0.01
_(col.default_function).must_be_nil
type = col.cast_type
Expand All @@ -279,7 +279,7 @@ def assert_obj_set_and_save(attribute, value)
_(col.sql_type).must_equal "date"
_(col.type).must_equal :date
_(col.null).must_equal true
_(col.default).must_equal Date.civil(1, 1, 1)
_(col.default).must_equal "0001-01-01"
_(obj.date).must_equal Date.civil(1, 1, 1)
_(col.default_function).must_be_nil
type = col.cast_type
Expand Down Expand Up @@ -317,8 +317,8 @@ def assert_obj_set_and_save(attribute, value)
_(col.sql_type).must_equal "datetime"
_(col.type).must_equal :datetime
_(col.null).must_equal true
_(col.default).must_equal "1753-01-01T00:00:00.123"
time = Time.utc 1753, 1, 1, 0, 0, 0, 123000
_(col.default).must_equal time, "Microseconds were <#{col.default.usec}> vs <123000>"
_(obj.datetime).must_equal time, "Microseconds were <#{obj.datetime.usec}> vs <123000>"
_(col.default_function).must_be_nil
type = col.cast_type
Expand Down Expand Up @@ -363,8 +363,8 @@ def assert_obj_set_and_save(attribute, value)
_(col.sql_type).must_equal "datetime2(7)"
_(col.type).must_equal :datetime
_(col.null).must_equal true
_(col.default).must_equal "9999-12-31 23:59:59.9999999"
time = Time.utc 9999, 12, 31, 23, 59, 59, Rational(999999900, 1000)
_(col.default).must_equal time, "Nanoseconds were <#{col.default.nsec}> vs <999999900>"
_(obj.datetime2_7).must_equal time, "Nanoseconds were <#{obj.datetime2_7.nsec}> vs <999999900>"
_(col.default_function).must_be_nil
type = col.cast_type
Expand Down Expand Up @@ -430,7 +430,7 @@ def assert_obj_set_and_save(attribute, value)
_(col.sql_type).must_equal "datetimeoffset(7)"
_(col.type).must_equal :datetimeoffset
_(col.null).must_equal true
_(col.default).must_equal Time.new(1984, 1, 24, 4, 20, 0, -28800).change(nsec: 123456700), "Nanoseconds <#{col.default.nsec}> vs <123456700>"
_(col.default).must_equal "1984-01-24 04:20:00.1234567 -08:00"
_(obj.datetimeoffset_7).must_equal Time.new(1984, 1, 24, 4, 20, 0, -28800).change(nsec: 123456700), "Nanoseconds were <#{obj.datetimeoffset_7.nsec}> vs <999999900>"
_(col.default_function).must_be_nil
type = col.cast_type
Expand Down Expand Up @@ -476,7 +476,7 @@ def assert_obj_set_and_save(attribute, value)
_(col.sql_type).must_equal "smalldatetime"
_(col.type).must_equal :smalldatetime
_(col.null).must_equal true
_(col.default).must_equal Time.utc(1901, 1, 1, 15, 45, 0, 0)
_(col.default).must_equal "1901-01-01T15:45:00.000Z"
_(obj.smalldatetime).must_equal Time.utc(1901, 1, 1, 15, 45, 0, 0)
_(col.default_function).must_be_nil
type = col.cast_type
Expand All @@ -498,7 +498,7 @@ def assert_obj_set_and_save(attribute, value)
_(col.sql_type).must_equal "time(7)"
_(col.type).must_equal :time
_(col.null).must_equal true
_(col.default).must_equal Time.utc(1900, 1, 1, 4, 20, 0, Rational(288321500, 1000)), "Nanoseconds were <#{col.default.nsec}> vs <288321500>"
_(col.default).must_equal "04:20:00.2883215"
_(col.default_function).must_be_nil
type = col.cast_type
_(type).must_be_instance_of ActiveRecord::ConnectionAdapters::SQLServer::Type::Time
Expand Down Expand Up @@ -564,7 +564,7 @@ def assert_obj_set_and_save(attribute, value)
_(col.sql_type).must_equal "time(7)"
_(col.type).must_equal :time
_(col.null).must_equal true
_(col.default).must_equal Time.utc(1900, 1, 1, 15, 3, 42, Rational(62197800, 1000)), "Nanoseconds were <#{col.default.nsec}> vs <62197800>"
_(col.default).must_equal "15:03:42.0621978"
_(col.default_function).must_be_nil
type = col.cast_type
_(type).must_be_instance_of ActiveRecord::ConnectionAdapters::SQLServer::Type::Time
Expand Down
2 changes: 1 addition & 1 deletion test/cases/migration_test_sqlserver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class MigrationTestSQLServer < ActiveRecord::TestCase
lock_version_column = Person.columns_hash["lock_version"]
assert_equal :integer, lock_version_column.type
assert lock_version_column.default.present?
assert_equal 0, lock_version_column.default
assert_equal "0", lock_version_column.default
assert_nothing_raised { connection.change_column "people", "lock_version", :string }
Person.reset_column_information
lock_version_column = Person.columns_hash["lock_version"]
Expand Down
Loading