diff --git a/CHANGELOG.md b/CHANGELOG.md index 49ebdde93..0d37bbaec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## Unreleased + +#### Fixed + +- [#1133](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1133) Fix matching view's real column name + ## v7.0.5.0 #### Fixed diff --git a/lib/active_record/connection_adapters/sqlserver/schema_statements.rb b/lib/active_record/connection_adapters/sqlserver/schema_statements.rb index da296f0c7..542caba93 100644 --- a/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +++ b/lib/active_record/connection_adapters/sqlserver/schema_statements.rb @@ -601,17 +601,19 @@ def view_information(table_name) identifier = SQLServer::Utils.extract_identifiers(table_name) information_query_table = identifier.database.present? ? "[#{identifier.database}].[INFORMATION_SCHEMA].[VIEWS]" : "[INFORMATION_SCHEMA].[VIEWS]" view_info = select_one "SELECT * FROM #{information_query_table} WITH (NOLOCK) WHERE TABLE_NAME = #{quote(identifier.object)}", "SCHEMA" + if view_info view_info = view_info.with_indifferent_access if view_info[:VIEW_DEFINITION].blank? || view_info[:VIEW_DEFINITION].length == 4000 view_info[:VIEW_DEFINITION] = begin - select_values("EXEC sp_helptext #{identifier.object_quoted}", "SCHEMA").join + select_values("EXEC sp_helptext #{identifier.object_quoted}", "SCHEMA").join rescue warn "No view definition found, possible permissions problem.\nPlease run GRANT VIEW DEFINITION TO your_user;" nil - end + end end end + view_info end end @@ -620,7 +622,8 @@ def views_real_column_name(table_name, column_name) view_definition = view_information(table_name)[:VIEW_DEFINITION] return column_name unless view_definition - match_data = view_definition.match(/CREATE\s+VIEW.*AS\s+SELECT.*\W([\w-]*)\s+AS\s+#{column_name}/im) + # Remove "CREATE VIEW ... AS SELECT ..." and then match the column name. + match_data = view_definition.sub(/CREATE\s+VIEW.*AS\s+SELECT\s/, '').match(/([\w-]*)\s+AS\s+#{column_name}\W/im) match_data ? match_data[1] : column_name end diff --git a/test/cases/view_test_sqlserver.rb b/test/cases/view_test_sqlserver.rb index 5fd5c973c..b371bd0b1 100644 --- a/test/cases/view_test_sqlserver.rb +++ b/test/cases/view_test_sqlserver.rb @@ -9,18 +9,20 @@ class ViewTestSQLServer < ActiveRecord::TestCase before do connection.drop_table :view_casing_table rescue nil connection.create_table :view_casing_table, force: true do |t| - t.boolean :Default_Falsey, null: false, default: false - t.boolean :Default_Truthy, null: false, default: true - t.string :default_string, null: false, default: "abc" + t.boolean :Default_Falsey, null: false, default: false + t.boolean :Default_Truthy, null: false, default: true + t.string :default_string_null, null: true, default: nil + t.string :default_string, null: false, default: "abc" end connection.execute("DROP VIEW IF EXISTS view_casing_table_view;") connection.execute <<-SQL CREATE VIEW view_casing_table_view AS SELECT id AS id, - default_falsey AS falsey, - default_truthy AS truthy, - default_string AS s + default_falsey AS falsey, + default_truthy AS truthy, + default_string_null AS s_null, + default_string AS s FROM view_casing_table SQL end @@ -34,12 +36,14 @@ class ViewTestSQLServer < ActiveRecord::TestCase assert_equal false, obj.falsey assert_equal true, obj.truthy assert_equal "abc", obj.s + assert_nil obj.s_null assert_equal 0, klass.count obj.save! assert_equal false, obj.falsey assert_equal true, obj.truthy assert_equal "abc", obj.s + assert_nil obj.s_null assert_equal 1, klass.count end end