activerecord-sqlserver-adapter 7.2.0 → 7.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b6356803690516019929168fed2c356f3250eb5ec8a9894b8117fc35db84b8c1
4
- data.tar.gz: dbedbedb583e766c526d959459166edd195516700fb6f0b1be2769ea1d947233
3
+ metadata.gz: dba9ea79e6287b945d1c8fba8894559510999b58272b968f69953630d94eb484
4
+ data.tar.gz: 9abcab548b00c1c906e26ebbb5f1d18982529c605452d447fba3b0a081f5046d
5
5
  SHA512:
6
- metadata.gz: 5079fd8e88a8e67b91f11de2f9ec158d686afe121461f2b2050ebdd1072f1ac0fc86356dd81da507e99b72b8f9266aa5a59031d886dcb8d119715cab4cbef1c8
7
- data.tar.gz: d1a8f37563ba09c443242e83f75098b2cc74bd269c9b11b9c6834a5e2fa23c7791f93083c7884ec1d22acdeca3bdf75f752153bde565fa0d92c3988a6653565c
6
+ metadata.gz: cba19ac223013b55bc0d67fade1dc8b8d0a80dc05175bebcc5ba209e28a3980d271f8d9240a92ec8d2cebba2ae33049581d21c0a30c5f9e188ca9150909d5bb3
7
+ data.tar.gz: e4feae1a11d2f000c1f75b81e6e5600a5abb0c08ea3220b26bf8d681aa881e34ebafb212ad0ae8a85280ae3d72401f27855e2af0e79f42521e6cdb5b56334907
@@ -1,17 +1,11 @@
1
1
  name: CI
2
2
 
3
- on:
4
- push:
5
- branches: [ main ]
6
- pull_request:
7
- branches: [ main ]
8
- schedule:
9
- - cron: '0 18 * * *'
3
+ on: [push, pull_request]
10
4
 
11
5
  jobs:
12
6
  test:
13
7
  name: Run test suite
14
- runs-on: ubuntu-latest
8
+ runs-on: ubuntu-20.04 # TODO: Change back to 'ubuntu-latest' when https://github.com/microsoft/mssql-docker/issues/899 resolved.
15
9
 
16
10
  env:
17
11
  COMPOSE_FILE: docker-compose.ci.yml
data/CHANGELOG.md CHANGED
@@ -1,4 +1,19 @@
1
- ## Unreleased
1
+ ## v7.2.2
2
+
3
+ #### Fixed
4
+
5
+ - [#1244](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1244) Allow INSERT statements with SELECT notation
6
+ - [#1247](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1247) Fix queries with date and date-time placeholder conditions
7
+ - [#1249](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1249) Binary basic columns should be limitable
8
+ - [#1255](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1255) Fixed the ordering of optimizer hints in the generated SQL
9
+
10
+ ## v7.2.1
11
+
12
+ #### Fixed
13
+
14
+ - [#1231](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1231) Enable identity insert on view's base table
15
+
16
+ ## v7.2.0
2
17
 
3
18
  #### Added
4
19
 
@@ -9,4 +24,5 @@
9
24
  - [#1153](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1153) Only support Ruby v3.1+
10
25
  - [#1196](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1196) Use default inspect for database adapter
11
26
 
27
+
12
28
  Please check [7-1-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/7-1-stable/CHANGELOG.md) for previous changes.
data/Dockerfile.ci CHANGED
@@ -9,6 +9,6 @@ WORKDIR $WORKDIR
9
9
 
10
10
  COPY . $WORKDIR
11
11
 
12
- RUN bundle install --jobs `expr $(cat /proc/cpuinfo | grep -c "cpu cores") - 1` --retry 3
12
+ RUN RAILS_BRANCH=7-2-stable bundle install --jobs `expr $(cat /proc/cpuinfo | grep -c "cpu cores") - 1` --retry 3
13
13
 
14
14
  CMD ["sh"]
data/README.md CHANGED
@@ -18,8 +18,8 @@ their stable branches.
18
18
  |-----------------|---------------|----------------|-------------------------------------------------------------------------------------------------|
19
19
  | `7.2.x` | `7.2.x` | Active | [main](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/main) |
20
20
  | `7.1.x` | `7.1.x` | Active | [7-1-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/7-1-stable) |
21
- | `7.0.x` | `7.0.x` | Active | [7-0-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/7-0-stable) |
22
- | `6.1.x` | `6.1.x` | Active | [6-1-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/6-1-stable) |
21
+ | `7.0.x` | `7.0.x` | Ended | [7-0-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/7-0-stable) |
22
+ | `6.1.x` | `6.1.x` | Ended | [6-1-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/6-1-stable) |
23
23
  | `6.0.x` | `6.0.x` | Ended | [6-0-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/6-0-stable) |
24
24
  | `5.2.x` | `5.2.x` | Ended | [5-2-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/5-2-stable) |
25
25
  | `5.1.x` | `5.1.x` | Ended | [5-1-stable](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/5-1-stable) |
data/VERSION CHANGED
@@ -1 +1 @@
1
- 7.2.0
1
+ 7.2.2
@@ -5,6 +5,7 @@ services:
5
5
  ci:
6
6
  environment:
7
7
  - ACTIVERECORD_UNITTEST_HOST=sqlserver
8
+ - RAILS_BRANCH=7-2-stable
8
9
  build:
9
10
  context: .
10
11
  dockerfile: Dockerfile.ci
@@ -42,6 +42,9 @@ module ActiveRecord
42
42
  log(sql, name, binds, async: async) do |notification_payload|
43
43
  with_raw_connection do |conn|
44
44
  result = if id_insert_table_name = query_requires_identity_insert?(sql)
45
+ # If the table name is a view, we need to get the base table name for enabling identity insert.
46
+ id_insert_table_name = view_table_name(id_insert_table_name) if view_exists?(id_insert_table_name)
47
+
45
48
  with_identity_insert_enabled(id_insert_table_name, conn) do
46
49
  internal_exec_sql_query(sql, conn)
47
50
  end
@@ -336,7 +339,7 @@ module ActiveRecord
336
339
  end
337
340
  end
338
341
 
339
- value = basic_attribute_type?(attr) ? attr : attr.value_for_database
342
+ value = active_model_attribute?(attr) ? attr.value_for_database : attr
340
343
 
341
344
  if value.is_a?(Numeric)
342
345
  value > 2_147_483_647 ? "bigint".freeze : "int".freeze
@@ -346,7 +349,7 @@ module ActiveRecord
346
349
  end
347
350
 
348
351
  def sp_executesql_sql_param(attr)
349
- return quote(attr) if basic_attribute_type?(attr)
352
+ return quote(attr) unless active_model_attribute?(attr)
350
353
 
351
354
  case value = attr.value_for_database
352
355
  when Type::Binary::Data, ActiveRecord::Type::SQLServer::Data
@@ -356,14 +359,8 @@ module ActiveRecord
356
359
  end
357
360
  end
358
361
 
359
- def basic_attribute_type?(type)
360
- type.is_a?(Symbol) ||
361
- type.is_a?(String) ||
362
- type.is_a?(Numeric) ||
363
- type.is_a?(Time) ||
364
- type.is_a?(TrueClass) ||
365
- type.is_a?(FalseClass) ||
366
- type.is_a?(NilClass)
362
+ def active_model_attribute?(type)
363
+ type.is_a?(::ActiveModel::Attribute)
367
364
  end
368
365
 
369
366
  def sp_executesql_sql(sql, types, params, name)
@@ -291,7 +291,7 @@ module ActiveRecord
291
291
  end
292
292
 
293
293
  def type_to_sql(type, limit: nil, precision: nil, scale: nil, **)
294
- type_limitable = %w(string integer float char nchar varchar nvarchar).include?(type.to_s)
294
+ type_limitable = %w(string integer float char nchar varchar nvarchar binary_basic).include?(type.to_s)
295
295
  limit = nil unless type_limitable
296
296
 
297
297
  case type.to_s
@@ -681,6 +681,7 @@ module ActiveRecord
681
681
  s.split(/INSERT INTO/i)[1]
682
682
  .split(/OUTPUT INSERTED/i)[0]
683
683
  .split(/(DEFAULT)?\s+VALUES/i)[0]
684
+ .split(/\bSELECT\b(?![^\[]*\])/i)[0]
684
685
  .match(/\s*([^(]*)/i)[0]
685
686
  elsif s.match?(/^\s*UPDATE\s+.*/i)
686
687
  s.match(/UPDATE\s+([^\(\s]+)\s*/i)[1]
@@ -134,26 +134,24 @@ module Arel
134
134
 
135
135
  def visit_Arel_Nodes_SelectStatement(o, collector)
136
136
  @select_statement = o
137
+ optimizer_hints = nil
137
138
  distinct_One_As_One_Is_So_Not_Fetch o
138
139
  if o.with
139
140
  collector = visit o.with, collector
140
141
  collector << " "
141
142
  end
142
- collector = o.cores.inject(collector) { |c, x|
143
- visit_Arel_Nodes_SelectCore(x, c)
144
- }
143
+ collector = o.cores.inject(collector) do |collect, core|
144
+ optimizer_hints = core.optimizer_hints if core.optimizer_hints
145
+ visit_Arel_Nodes_SelectCore(core, collect)
146
+ end
145
147
  collector = visit_Orders_And_Let_Fetch_Happen o, collector
146
148
  collector = visit_Make_Fetch_Happen o, collector
149
+ collector = maybe_visit optimizer_hints, collector
147
150
  collector
148
151
  ensure
149
152
  @select_statement = nil
150
153
  end
151
154
 
152
- def visit_Arel_Nodes_SelectCore(o, collector)
153
- collector = super
154
- maybe_visit o.optimizer_hints, collector
155
- end
156
-
157
155
  def visit_Arel_Nodes_OptimizerHints(o, collector)
158
156
  hints = o.expr.map { |v| sanitize_as_option_clause(v) }.join(", ")
159
157
  collector << "OPTION (#{hints})"
@@ -580,4 +580,18 @@ class AdapterTestSQLServer < ActiveRecord::TestCase
580
580
  end
581
581
  end
582
582
  end
583
+
584
+ describe "placeholder conditions" do
585
+ it 'using time placeholder' do
586
+ assert_equal Task.where("starting < ?", Time.now).count, 1
587
+ end
588
+
589
+ it 'using date placeholder' do
590
+ assert_equal Task.where("starting < ?", Date.today).count, 1
591
+ end
592
+
593
+ it 'using date-time placeholder' do
594
+ assert_equal Task.where("starting < ?", DateTime.current).count, 1
595
+ end
596
+ end
583
597
  end
@@ -36,6 +36,15 @@ class OptimizerHitsTestSQLServer < ActiveRecord::TestCase
36
36
  end
37
37
  end
38
38
 
39
+
40
+ it "support order" do
41
+ assert_queries_match(%r{\ASELECT .+ FROM .+ ORDER .+ OPTION .+\z}) do
42
+ companies = Company.optimizer_hints("LABEL='FindCompanies'")
43
+ companies = companies.order(:id)
44
+ companies.to_a
45
+ end
46
+ end
47
+
39
48
  it "sanitize values" do
40
49
  assert_queries_match(%r{\ASELECT .+ FROM .+ OPTION \(HASH GROUP\)\z}) do
41
50
  companies = Company.optimizer_hints("OPTION (HASH GROUP)")
@@ -93,39 +93,41 @@ class SchemaDumperTestSQLServer < ActiveRecord::TestCase
93
93
  assert_line :binary_col, type: "binary"
94
94
 
95
95
  # Our type methods.
96
- _(columns["real_col"].sql_type).must_equal "real"
97
- _(columns["money_col"].sql_type).must_equal "money"
98
- _(columns["smalldatetime_col"].sql_type).must_equal "smalldatetime"
99
- _(columns["datetime2_col"].sql_type).must_equal "datetime2(7)"
100
- _(columns["datetimeoffset"].sql_type).must_equal "datetimeoffset(7)"
101
- _(columns["smallmoney_col"].sql_type).must_equal "smallmoney"
102
- _(columns["char_col"].sql_type).must_equal "char(1)"
103
- _(columns["varchar_col"].sql_type).must_equal "varchar(8000)"
104
- _(columns["text_basic_col"].sql_type).must_equal "text"
105
- _(columns["nchar_col"].sql_type).must_equal "nchar(1)"
106
- _(columns["ntext_col"].sql_type).must_equal "ntext"
107
- _(columns["binary_basic_col"].sql_type).must_equal "binary(1)"
108
- _(columns["varbinary_col"].sql_type).must_equal "varbinary(8000)"
109
- _(columns["uuid_col"].sql_type).must_equal "uniqueidentifier"
110
- _(columns["sstimestamp_col"].sql_type).must_equal "timestamp"
111
- _(columns["json_col"].sql_type).must_equal "nvarchar(max)"
112
-
113
- assert_line :real_col, type: "real"
114
- assert_line :money_col, type: "money", precision: 19, scale: 4
115
- assert_line :smalldatetime_col, type: "smalldatetime"
116
- assert_line :datetime2_col, type: "datetime", precision: 7
117
- assert_line :datetimeoffset, type: "datetimeoffset", precision: 7
118
- assert_line :smallmoney_col, type: "smallmoney", precision: 10, scale: 4
119
- assert_line :char_col, type: "char", limit: 1
120
- assert_line :varchar_col, type: "varchar"
121
- assert_line :text_basic_col, type: "text_basic"
122
- assert_line :nchar_col, type: "nchar", limit: 1
123
- assert_line :ntext_col, type: "ntext"
124
- assert_line :binary_basic_col, type: "binary_basic", limit: 1
125
- assert_line :varbinary_col, type: "varbinary"
126
- assert_line :uuid_col, type: "uuid"
127
- assert_line :sstimestamp_col, type: "ss_timestamp", null: false
128
- assert_line :json_col, type: "text"
96
+ _(columns["real_col"].sql_type).must_equal "real"
97
+ _(columns["money_col"].sql_type).must_equal "money"
98
+ _(columns["smalldatetime_col"].sql_type).must_equal "smalldatetime"
99
+ _(columns["datetime2_col"].sql_type).must_equal "datetime2(7)"
100
+ _(columns["datetimeoffset"].sql_type).must_equal "datetimeoffset(7)"
101
+ _(columns["smallmoney_col"].sql_type).must_equal "smallmoney"
102
+ _(columns["char_col"].sql_type).must_equal "char(1)"
103
+ _(columns["varchar_col"].sql_type).must_equal "varchar(8000)"
104
+ _(columns["text_basic_col"].sql_type).must_equal "text"
105
+ _(columns["nchar_col"].sql_type).must_equal "nchar(1)"
106
+ _(columns["ntext_col"].sql_type).must_equal "ntext"
107
+ _(columns["binary_basic_col"].sql_type).must_equal "binary(1)"
108
+ _(columns["binary_basic_16_col"].sql_type).must_equal "binary(16)"
109
+ _(columns["varbinary_col"].sql_type).must_equal "varbinary(8000)"
110
+ _(columns["uuid_col"].sql_type).must_equal "uniqueidentifier"
111
+ _(columns["sstimestamp_col"].sql_type).must_equal "timestamp"
112
+ _(columns["json_col"].sql_type).must_equal "nvarchar(max)"
113
+
114
+ assert_line :real_col, type: "real"
115
+ assert_line :money_col, type: "money", precision: 19, scale: 4
116
+ assert_line :smalldatetime_col, type: "smalldatetime"
117
+ assert_line :datetime2_col, type: "datetime", precision: 7
118
+ assert_line :datetimeoffset, type: "datetimeoffset", precision: 7
119
+ assert_line :smallmoney_col, type: "smallmoney", precision: 10, scale: 4
120
+ assert_line :char_col, type: "char", limit: 1
121
+ assert_line :varchar_col, type: "varchar"
122
+ assert_line :text_basic_col, type: "text_basic"
123
+ assert_line :nchar_col, type: "nchar", limit: 1
124
+ assert_line :ntext_col, type: "ntext"
125
+ assert_line :binary_basic_col, type: "binary_basic", limit: 1
126
+ assert_line :binary_basic_16_col, type: "binary_basic", limit: 16
127
+ assert_line :varbinary_col, type: "varbinary"
128
+ assert_line :uuid_col, type: "uuid"
129
+ assert_line :sstimestamp_col, type: "ss_timestamp", null: false
130
+ assert_line :json_col, type: "text"
129
131
  end
130
132
 
131
133
  it "dump column collation" do
@@ -96,6 +96,10 @@ class SchemaTestSQLServer < ActiveRecord::TestCase
96
96
  it do
97
97
  assert_equal "[test].[aliens]", connection.send(:get_raw_table_name, "EXEC sp_executesql N'INSERT INTO [test].[aliens] ([name]) OUTPUT INSERTED.[id] VALUES (@0)', N'@0 varchar(255)', @0 = 'Trisolarans'")
98
98
  end
99
+
100
+ it do
101
+ assert_equal "[with].[select notation]", connection.send(:get_raw_table_name, "INSERT INTO [with].[select notation] SELECT * FROM [table_name]")
102
+ end
99
103
  end
100
104
  end
101
105
  end
@@ -47,4 +47,12 @@ class ViewTestSQLServer < ActiveRecord::TestCase
47
47
  assert_equal 1, klass.count
48
48
  end
49
49
  end
50
+
51
+ describe 'identity insert' do
52
+ it "identity insert works with views" do
53
+ assert_difference("SSTestCustomersView.count", 1) do
54
+ SSTestCustomersView.create!(id: 5, name: "Bob")
55
+ end
56
+ end
57
+ end
50
58
  end
@@ -33,6 +33,7 @@ ActiveRecord::Schema.define do
33
33
  t.nchar :nchar_col
34
34
  t.ntext :ntext_col
35
35
  t.binary_basic :binary_basic_col
36
+ t.binary_basic :binary_basic_16_col, limit: 16
36
37
  t.varbinary :varbinary_col
37
38
  t.uuid :uuid_col
38
39
  t.ss_timestamp :sstimestamp_col
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-sqlserver-adapter
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.2.0
4
+ version: 7.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ken Collins
@@ -15,7 +15,7 @@ authors:
15
15
  autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
- date: 2024-08-12 00:00:00.000000000 Z
18
+ date: 2024-11-10 00:00:00.000000000 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: activerecord
@@ -239,8 +239,8 @@ licenses:
239
239
  - MIT
240
240
  metadata:
241
241
  bug_tracker_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/issues
242
- changelog_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/v7.2.0/CHANGELOG.md
243
- source_code_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/v7.2.0
242
+ changelog_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/v7.2.2/CHANGELOG.md
243
+ source_code_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/v7.2.2
244
244
  post_install_message:
245
245
  rdoc_options: []
246
246
  require_paths:
@@ -256,7 +256,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
256
256
  - !ruby/object:Gem::Version
257
257
  version: '0'
258
258
  requirements: []
259
- rubygems_version: 3.5.17
259
+ rubygems_version: 3.5.21
260
260
  signing_key:
261
261
  specification_version: 4
262
262
  summary: ActiveRecord SQL Server Adapter.