activerecord-sqlserver-adapter 7.2.0 → 7.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +2 -8
- data/CHANGELOG.md +17 -1
- data/Dockerfile.ci +1 -1
- data/README.md +2 -2
- data/VERSION +1 -1
- data/docker-compose.ci.yml +1 -0
- data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +7 -10
- data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +2 -1
- data/lib/arel/visitors/sqlserver.rb +6 -8
- data/test/cases/adapter_test_sqlserver.rb +14 -0
- data/test/cases/optimizer_hints_test_sqlserver.rb +9 -0
- data/test/cases/schema_dumper_test_sqlserver.rb +35 -33
- data/test/cases/schema_test_sqlserver.rb +4 -0
- data/test/cases/view_test_sqlserver.rb +8 -0
- data/test/schema/sqlserver_specific_schema.rb +1 -0
- metadata +5 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dba9ea79e6287b945d1c8fba8894559510999b58272b968f69953630d94eb484
|
|
4
|
+
data.tar.gz: 9abcab548b00c1c906e26ebbb5f1d18982529c605452d447fba3b0a081f5046d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cba19ac223013b55bc0d67fade1dc8b8d0a80dc05175bebcc5ba209e28a3980d271f8d9240a92ec8d2cebba2ae33049581d21c0a30c5f9e188ca9150909d5bb3
|
|
7
|
+
data.tar.gz: e4feae1a11d2f000c1f75b81e6e5600a5abb0c08ea3220b26bf8d681aa881e34ebafb212ad0ae8a85280ae3d72401f27855e2af0e79f42521e6cdb5b56334907
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -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
|
-
##
|
|
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` |
|
|
22
|
-
| `6.1.x` | `6.1.x` |
|
|
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.
|
|
1
|
+
7.2.2
|
data/docker-compose.ci.yml
CHANGED
|
@@ -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 =
|
|
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)
|
|
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
|
|
360
|
-
type.is_a?(
|
|
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)
|
|
143
|
-
|
|
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
|
|
97
|
-
_(columns["money_col"].sql_type).must_equal
|
|
98
|
-
_(columns["smalldatetime_col"].sql_type).must_equal
|
|
99
|
-
_(columns["datetime2_col"].sql_type).must_equal
|
|
100
|
-
_(columns["datetimeoffset"].sql_type).must_equal
|
|
101
|
-
_(columns["smallmoney_col"].sql_type).must_equal
|
|
102
|
-
_(columns["char_col"].sql_type).must_equal
|
|
103
|
-
_(columns["varchar_col"].sql_type).must_equal
|
|
104
|
-
_(columns["text_basic_col"].sql_type).must_equal
|
|
105
|
-
_(columns["nchar_col"].sql_type).must_equal
|
|
106
|
-
_(columns["ntext_col"].sql_type).must_equal
|
|
107
|
-
_(columns["binary_basic_col"].sql_type).must_equal
|
|
108
|
-
_(columns["
|
|
109
|
-
_(columns["
|
|
110
|
-
_(columns["
|
|
111
|
-
_(columns["
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
assert_line :
|
|
115
|
-
assert_line :
|
|
116
|
-
assert_line :
|
|
117
|
-
assert_line :
|
|
118
|
-
assert_line :
|
|
119
|
-
assert_line :
|
|
120
|
-
assert_line :
|
|
121
|
-
assert_line :
|
|
122
|
-
assert_line :
|
|
123
|
-
assert_line :
|
|
124
|
-
assert_line :
|
|
125
|
-
assert_line :
|
|
126
|
-
assert_line :
|
|
127
|
-
assert_line :
|
|
128
|
-
assert_line :
|
|
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
|
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.
|
|
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-
|
|
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.
|
|
243
|
-
source_code_uri: https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/tree/v7.2.
|
|
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.
|
|
259
|
+
rubygems_version: 3.5.21
|
|
260
260
|
signing_key:
|
|
261
261
|
specification_version: 4
|
|
262
262
|
summary: ActiveRecord SQL Server Adapter.
|