diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c8b5e367..47847fbb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## Unreleased +#### Fixed + +- [#1308](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1308) Fix retrieval of temporary table's column information. + #### Added - [#1301](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1301) Add support for INDEX INCLUDE. diff --git a/lib/active_record/connection_adapters/sqlserver/schema_statements.rb b/lib/active_record/connection_adapters/sqlserver/schema_statements.rb index 5f1e0f6dd..140cc89e1 100644 --- a/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +++ b/lib/active_record/connection_adapters/sqlserver/schema_statements.rb @@ -631,11 +631,21 @@ def column_type(ci:) end def column_definitions_sql(database, identifier) - object_name = prepared_statements ? "@0" : quote(identifier.object) - schema_name = if identifier.schema.blank? - "schema_name()" + schema_name = "schema_name()" + + if prepared_statements + object_name = "@0" + schema_name = "@1" if identifier.schema.present? else - prepared_statements ? "@1" : quote(identifier.schema) + object_name = quote(identifier.object) + schema_name = quote(identifier.schema) if identifier.schema.present? + end + + object_id_arg = identifier.schema.present? ? "CONCAT(#{schema_name},'.',#{object_name})" : object_name + + if identifier.temporary_table? + database = "TEMPDB" + object_id_arg = "CONCAT('#{database}','..',#{object_name})" end %{ @@ -691,7 +701,7 @@ def column_definitions_sql(database, identifier) AND k.unique_index_id = ic.index_id AND c.column_id = ic.column_id WHERE - o.name = #{object_name} + o.Object_ID = Object_ID(#{object_id_arg}) AND s.name = #{schema_name} ORDER BY c.column_id @@ -713,7 +723,7 @@ def remove_check_constraints(table_name, column_name) end def remove_default_constraint(table_name, column_name) - # If their are foreign keys in this table, we could still get back a 2D array, so flatten just in case. + # If there are foreign keys in this table, we could still get back a 2D array, so flatten just in case. execute_procedure(:sp_helpconstraint, table_name, "nomsg").flatten.select do |row| row["constraint_type"] == "DEFAULT on column #{column_name}" end.each do |row| diff --git a/lib/active_record/connection_adapters/sqlserver/utils.rb b/lib/active_record/connection_adapters/sqlserver/utils.rb index baf237495..77ec1d734 100644 --- a/lib/active_record/connection_adapters/sqlserver/utils.rb +++ b/lib/active_record/connection_adapters/sqlserver/utils.rb @@ -81,6 +81,10 @@ def hash parts.hash end + def temporary_table? + object.start_with?("#") + end + protected def parse_raw_name diff --git a/test/cases/temporary_table_test_sqlserver.rb b/test/cases/temporary_table_test_sqlserver.rb new file mode 100644 index 000000000..0ab808a70 --- /dev/null +++ b/test/cases/temporary_table_test_sqlserver.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require "cases/helper_sqlserver" + +class TemporaryTableSQLServer < ActiveRecord::TestCase + def test_insert_into_temporary_table + ActiveRecord::Base.with_connection do |conn| + conn.exec_query("CREATE TABLE #temp_users (id INT IDENTITY(1,1), name NVARCHAR(100))") + + result = conn.exec_query("SELECT * FROM #temp_users") + assert_equal 0, result.count + + conn.exec_query("INSERT INTO #temp_users (name) VALUES ('John'), ('Doe')") + + result = conn.exec_query("SELECT * FROM #temp_users") + assert_equal 2, result.count + end + end +end