sequel 5.56.0 → 5.59.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +32 -0
- data/README.rdoc +25 -0
- data/doc/cheat_sheet.rdoc +8 -0
- data/doc/opening_databases.rdoc +10 -6
- data/doc/release_notes/5.57.0.txt +23 -0
- data/doc/release_notes/5.58.0.txt +31 -0
- data/doc/release_notes/5.59.0.txt +73 -0
- data/doc/testing.rdoc +1 -1
- data/lib/sequel/adapters/jdbc/derby.rb +5 -0
- data/lib/sequel/adapters/jdbc/h2.rb +5 -0
- data/lib/sequel/adapters/jdbc/hsqldb.rb +6 -0
- data/lib/sequel/adapters/postgres.rb +12 -6
- data/lib/sequel/adapters/shared/db2.rb +28 -0
- data/lib/sequel/adapters/shared/mssql.rb +34 -0
- data/lib/sequel/adapters/shared/mysql.rb +12 -0
- data/lib/sequel/adapters/shared/oracle.rb +69 -0
- data/lib/sequel/adapters/shared/postgres.rb +70 -4
- data/lib/sequel/database/schema_generator.rb +4 -0
- data/lib/sequel/database/schema_methods.rb +3 -0
- data/lib/sequel/dataset/actions.rb +49 -0
- data/lib/sequel/dataset/features.rb +5 -0
- data/lib/sequel/dataset/query.rb +62 -0
- data/lib/sequel/dataset/sql.rb +112 -25
- data/lib/sequel/extensions/is_distinct_from.rb +139 -0
- data/lib/sequel/extensions/pg_hstore.rb +1 -1
- data/lib/sequel/extensions/pg_json_ops.rb +52 -0
- data/lib/sequel/model/associations.rb +12 -0
- data/lib/sequel/model/base.rb +14 -4
- data/lib/sequel/plugins/insert_conflict.rb +4 -0
- data/lib/sequel/plugins/list.rb +3 -1
- data/lib/sequel/plugins/require_valid_schema.rb +67 -0
- data/lib/sequel/plugins/tactical_eager_loading.rb +7 -0
- data/lib/sequel/version.rb +1 -1
- metadata +10 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47d7144911d61be13cc600fc3153c8e30eb384476ea7fb94ce61bd0f2f627c36
|
4
|
+
data.tar.gz: fa763e2f24d5b6b26feecb405b5a43d8bbf30d2b727590e8fd98031640dfef2a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3855f6fbb47f26bfd0e9570ed8b7e908815bc7de3752751b92708c3e88948719f62dafe26cc1ea83b598c73e1ee84e4dbf12f01437dd1b087eed68ca4281b33d
|
7
|
+
data.tar.gz: 932fa5c97bc8dcf077a50961b2da7ecd59ae0c077409c2b0c3111d875fe468d5fbb4030f155faf17d3ba3ed0392e264d8e5ebaa11ad04db3ab98c209e2199440
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,35 @@
|
|
1
|
+
=== 5.59.0 (2022-08-01)
|
2
|
+
|
3
|
+
* Set :allow_eager association option to false for instance specific associations without eager loaders (jeremyevans)
|
4
|
+
|
5
|
+
* Add require_valid_schema plugin for checking that model classes have schema parsed as expected (jeremyevans)
|
6
|
+
|
7
|
+
* Model classes created from aliased expressions and literal strings no longer use the simple table optimization (jeremyevans)
|
8
|
+
|
9
|
+
* Model code that does not swallow connection errors will now also not swallow disconnect errors (jeremyevans) (#1892)
|
10
|
+
|
11
|
+
* Add is_json and is_not_json methods to the pg_json_ops extension, for the PostgreSQL 15+ IS [NOT] JSON operator (jeremyevans)
|
12
|
+
|
13
|
+
* Support :security_invoker view option on PostgreSQL 15+, for views where access uses permissions of user instead of owner (jeremyevans)
|
14
|
+
|
15
|
+
* Support :nulls_distinct index option on PostgreSQL 15+, for NULLS [NOT] DISTINCT (jeremyevans)
|
16
|
+
|
17
|
+
* Support sequel-postgres-pr driver in the postgres adapter (jeremyevans)
|
18
|
+
|
19
|
+
=== 5.58.0 (2022-07-01)
|
20
|
+
|
21
|
+
* Support :disable_split_materialized Database option on MySQL to work around optimizer bug in MariaDB 10.5+ affecting association tests (jeremyevans)
|
22
|
+
|
23
|
+
* Add Dataset#merge* methods to support MERGE statement on PostgreSQL 15+, MSSQL, Oracle, DB2, H2, HSQLDB, and Derby (jeremyevans)
|
24
|
+
|
25
|
+
=== 5.57.0 (2022-06-01)
|
26
|
+
|
27
|
+
* Make Database#create_function on PostgreSQL accept :parallel option (bananarne) (#1870)
|
28
|
+
|
29
|
+
* Add support for :on_update_current_timestamp column option on MySQL (jeremyevans)
|
30
|
+
|
31
|
+
* Add is_distinct_from extension with support for the IS DISTINCT FROM operator (jeremyevans)
|
32
|
+
|
1
33
|
=== 5.56.0 (2022-05-01)
|
2
34
|
|
3
35
|
* Make alter_table add_column/add_foreign_key methods support :index option to create an index on the column (jeremyevans)
|
data/README.rdoc
CHANGED
@@ -414,6 +414,31 @@ As with +delete+, +update+ affects all rows in the dataset, so +where+ first,
|
|
414
414
|
# NOT THIS:
|
415
415
|
posts.update(:state => 'archived').where(Sequel[:stamp] < Date.today - 7)
|
416
416
|
|
417
|
+
=== Merging records
|
418
|
+
|
419
|
+
Merging records using the SQL MERGE statment is done using <tt>merge*</tt> methods.
|
420
|
+
You use +merge_using+ to specify the merge source and join conditions.
|
421
|
+
You can use +merge_insert+, +merge_delete+, and/or +merge_update+ to set the
|
422
|
+
INSERT, DELETE, and UPDATE clauses for the merge. +merge_insert+ takes the same
|
423
|
+
arguments as +insert+, and +merge_update+ takes the same arguments as +update+.
|
424
|
+
+merge_insert+, +merge_delete+, and +merge_update+ can all be called with blocks,
|
425
|
+
to set the conditions for the related INSERT, DELETE, or UPDATE.
|
426
|
+
|
427
|
+
Finally, after calling all of the other <tt>merge_*</tt> methods, you call +merge+
|
428
|
+
to run the MERGE statement on the database.
|
429
|
+
|
430
|
+
ds = DB[:m1]
|
431
|
+
merge_using(:m2, i1: :i2).
|
432
|
+
merge_insert(i1: :i2, a: Sequel[:b]+11).
|
433
|
+
merge_delete{a > 30}.
|
434
|
+
merge_update(i1: Sequel[:i1]+:i2+10, a: Sequel[:a]+:b+20)
|
435
|
+
|
436
|
+
ds.merge
|
437
|
+
# MERGE INTO m1 USING m2 ON (i1 = i2)
|
438
|
+
# WHEN NOT MATCHED THEN INSERT (i1, a) VALUES (i2, (b + 11))
|
439
|
+
# WHEN MATCHED AND (a > 30) THEN DELETE
|
440
|
+
# WHEN MATCHED THEN UPDATE SET i1 = (i1 + i2 + 10), a = (a + b + 20)
|
441
|
+
|
417
442
|
=== Transactions
|
418
443
|
|
419
444
|
You can wrap a block of code in a database transaction using the <tt>Database#transaction</tt> method:
|
data/doc/cheat_sheet.rdoc
CHANGED
@@ -57,6 +57,14 @@ Without a filename argument, the sqlite adapter will setup a new sqlite database
|
|
57
57
|
dataset.where{price < 100}.update(:active => true)
|
58
58
|
dataset.where(:active).update(:price => Sequel[:price] * 0.90)
|
59
59
|
|
60
|
+
= Merge rows
|
61
|
+
|
62
|
+
dataset.
|
63
|
+
merge_using(:table, col1: :col2).
|
64
|
+
merge_insert(col3: :col4).
|
65
|
+
merge_delete{col5 > 30}.
|
66
|
+
merge_update(col3: Sequel[:col3] + :col4)
|
67
|
+
|
60
68
|
== Datasets are Enumerable
|
61
69
|
|
62
70
|
dataset.map{|r| r[:name]}
|
data/doc/opening_databases.rdoc
CHANGED
@@ -102,6 +102,7 @@ The following options can be specified and are passed to the database's internal
|
|
102
102
|
:after_connect :: A callable object called after each new connection is made, with the
|
103
103
|
connection object (and server argument if the callable accepts 2 arguments),
|
104
104
|
useful for customizations that you want to apply to all connections (nil by default).
|
105
|
+
:connect_sqls :: An array of sql strings to execute on each new connection, after :after_connect runs.
|
105
106
|
:max_connections :: The maximum size of the connection pool (4 connections by default on most databases)
|
106
107
|
:pool_timeout :: The number of seconds to wait if a connection cannot be acquired before raising an error (5 seconds by default)
|
107
108
|
:single_threaded :: Whether to use a single-threaded (non-thread safe) connection pool
|
@@ -258,6 +259,8 @@ The following additional options are supported:
|
|
258
259
|
:compress :: Whether to compress data sent/received via the socket connection.
|
259
260
|
:config_default_group :: The default group to read from the in the MySQL config file, defaults to "client")
|
260
261
|
:config_local_infile :: If provided, sets the Mysql::OPT_LOCAL_INFILE option on the connection with the given value.
|
262
|
+
:disable_split_materialized :: Set split_materialized=off in the optimizer settings. Necessary to pass the associations
|
263
|
+
integration tests in MariaDB 10.5+, due to a unfixed bug in the optimizer.
|
261
264
|
:encoding :: Specify the encoding/character set to use for the connection.
|
262
265
|
:fractional_seconds :: On MySQL 5.6.5+, this option is recognized and will include fractional seconds in
|
263
266
|
time/timestamp values, as well as have the schema method create columns that can contain
|
@@ -278,7 +281,9 @@ if either the :sslca or :sslkey option is given.
|
|
278
281
|
|
279
282
|
This is a newer MySQL adapter that does typecasting in C, so it is often faster than the
|
280
283
|
mysql adapter. The options given are passed to Mysql2::Client.new, see the mysql2 documentation
|
281
|
-
for details on what options are supported.
|
284
|
+
for details on what options are supported. The :timeout, :auto_is_null, :sql_mode, and :disable_split_materialized
|
285
|
+
options supported by the mysql adapter are also supported for mysql2 adapter (and any other adapters connecting to
|
286
|
+
mysql, such as the jdbc/mysql adapter).
|
282
287
|
|
283
288
|
=== odbc
|
284
289
|
|
@@ -307,15 +312,14 @@ The following additional options are supported:
|
|
307
312
|
|
308
313
|
=== postgres
|
309
314
|
|
310
|
-
Requires: pg (or postgres-pr/postgres-compat if pg is not available)
|
315
|
+
Requires: pg (or sequel/postgres-pr or postgres-pr/postgres-compat if pg is not available)
|
311
316
|
|
312
|
-
The Sequel postgres adapter works with the pg and postgres-pr ruby libraries.
|
317
|
+
The Sequel postgres adapter works with the pg, sequel-postgres-pr, jeremyevans-postgres-pr, and postgres-pr ruby libraries.
|
313
318
|
The pg library is the best supported, as it supports real bound variables and prepared statements.
|
314
319
|
If the pg library is being used, Sequel will also attempt to load the sequel_pg library, which is
|
315
320
|
a C extension that optimizes performance when Sequel is used with pg. All users of Sequel who
|
316
|
-
use pg are encouraged to install sequel_pg. For users who want to use postgres-pr
|
317
|
-
with C extensions, it is recommended to use
|
318
|
-
the upstream postgres-pr gem, and is regularly tested with Sequel.
|
321
|
+
use pg are encouraged to install sequel_pg. For users who want to use one of the postgres-pr
|
322
|
+
libraries to avoid issues with C extensions, it is recommended to use sequel-postgres-pr.
|
319
323
|
|
320
324
|
The following additional options are supported:
|
321
325
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* An is_distinct_from extension has been added with support for the
|
4
|
+
SQL IS DISTINCT FROM operator. This operator is similar to the
|
5
|
+
not equals operator, except in terms of NULL handling. It returns
|
6
|
+
true if only one side is NULL, and false if both sides are NULL.
|
7
|
+
You can call is_distinct_from on Sequel itself or on Sequel objects:
|
8
|
+
|
9
|
+
Sequel.is_distinct_from(:column_a, :column_b)
|
10
|
+
Sequel[:column_a].is_distinct_from(:column_b)
|
11
|
+
# (column_a IS DISTINCT FROM column_b)
|
12
|
+
|
13
|
+
On databases not supporting IS DISTINCT FROM, support is emulated
|
14
|
+
using a CASE statement.
|
15
|
+
|
16
|
+
* Column definitions on MySQL can use the :on_update_current_timestamp
|
17
|
+
option for ON UPDATE CURRENT_TIMESTAMP, which creates a column that
|
18
|
+
will automatically have its value set to CURRENT_TIMESTAMP on every
|
19
|
+
update.
|
20
|
+
|
21
|
+
* Database#create_function on PostgreSQL now supports a :parallel
|
22
|
+
option to set the thread safety of the funciton. The value should
|
23
|
+
be :safe, :unsafe, or :restricted.
|
@@ -0,0 +1,31 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* Dataset#merge and related #merge_* methods have been added for the
|
4
|
+
MERGE statement. MERGE is supported on PostgreSQL 15+, Oracle,
|
5
|
+
Microsoft SQL Server, DB2, H2, HSQLDB, and Derby. You can use MERGE
|
6
|
+
to insert, update, and/or delete in a single query. You call
|
7
|
+
the #merge_* methods to setup the MERGE statement, and #merge to
|
8
|
+
execute it on the database:
|
9
|
+
|
10
|
+
ds = DB[:m1]
|
11
|
+
merge_using(:m2, i1: :i2).
|
12
|
+
merge_insert(i1: :i2, a: Sequel[:b]+11).
|
13
|
+
merge_delete{a > 30}.
|
14
|
+
merge_update(i1: Sequel[:i1]+:i2+10, a: Sequel[:a]+:b+20)
|
15
|
+
|
16
|
+
ds.merge
|
17
|
+
# MERGE INTO m1 USING m2 ON (i1 = i2)
|
18
|
+
# WHEN NOT MATCHED THEN INSERT (i1, a) VALUES (i2, (b + 11))
|
19
|
+
# WHEN MATCHED AND (a > 30) THEN DELETE
|
20
|
+
# WHEN MATCHED THEN UPDATE SET i1 = (i1 + i2 + 10), a = (a + b + 20)
|
21
|
+
|
22
|
+
On PostgreSQL, the following additional MERGE related methods are
|
23
|
+
available:
|
24
|
+
|
25
|
+
* #merge_do_nothing_when_matched
|
26
|
+
* #merge_do_nothing_when_not_matched
|
27
|
+
|
28
|
+
* A :disable_split_materialized Database option is now supported on
|
29
|
+
MySQL. This disables split_materialized support in the optimizer,
|
30
|
+
working around a bug in MariaDB 10.5+ that causes failures in
|
31
|
+
Sequel's association tests.
|
@@ -0,0 +1,73 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* A require_valid_schema plugin has been added, for checking that
|
4
|
+
model classes have schema parsed as expected. By default, model
|
5
|
+
classes are not required to have valid schema, because it is
|
6
|
+
allowed to have model classes based on arbitrary datasets (such
|
7
|
+
as those using joins or set-returning functions), and it is not
|
8
|
+
possible to determine the schema for arbitary datasets.
|
9
|
+
|
10
|
+
Sequel swallows non-connection errors when trying to parse schema
|
11
|
+
for a model's dataset, but if schema parsing fails when you would
|
12
|
+
expect it to succeed, it results in a model where typecasting does
|
13
|
+
not work as expected.
|
14
|
+
|
15
|
+
The require_valid_schema plugin will raise an error when setting
|
16
|
+
the dataset for a model if schema parsing fails and the dataset
|
17
|
+
uses a simple table where you would expect schema parsing to
|
18
|
+
succeed. You can also provide an argument of :warn when loading
|
19
|
+
the plugin, to warn instead of raising an error.
|
20
|
+
|
21
|
+
This plugin may not work correctly in all cases for all adapters,
|
22
|
+
especially external adapters. Adapters are not required to support
|
23
|
+
schema parsing. Even if supported, adapters may not support
|
24
|
+
parsing schema for qualified tables, or parsing schema for views.
|
25
|
+
You should consider this plugin as a possible safety net. Users
|
26
|
+
are encouraged to try using it and report any unexpected breakage,
|
27
|
+
as that may help improve schema parsing in adapters that Sequel
|
28
|
+
ships.
|
29
|
+
|
30
|
+
* is_json and is_not_json methods have been added to the pg_json_ops
|
31
|
+
extension, for the IS [NOT] JSON operator supported in PostgreSQL
|
32
|
+
15+.
|
33
|
+
|
34
|
+
* Index creation methods on PostgreSQL 15+ now support a
|
35
|
+
:nulls_distinct option, for NULLS [NOT] DISTINCT. This allows you
|
36
|
+
to create unique indexes where NULL values are not considered
|
37
|
+
distinct.
|
38
|
+
|
39
|
+
* View creation methods on PostgreSQL 15+ now support a
|
40
|
+
:security_invoker option to create a view where access is
|
41
|
+
determined by the permissions of the role that is accessing the
|
42
|
+
view, instead of the role that created the view.
|
43
|
+
|
44
|
+
= Other Improvements
|
45
|
+
|
46
|
+
* The :allow_eager association option is now set to false by default
|
47
|
+
for associations explicitly marked as :instance_specific, if the
|
48
|
+
:eager_loader association is not given.
|
49
|
+
|
50
|
+
* The postgres adapter now supports the sequel-postgres-pr driver.
|
51
|
+
The sequel-postgres-pr driver is a slimmed down fork of the
|
52
|
+
postgres-pr driver designed specifically for use by Sequel.
|
53
|
+
|
54
|
+
* Model code that explicitly does not swallow connection errors
|
55
|
+
will also now not swallow disconnect errors. This can fix issues
|
56
|
+
where model classes are being loaded at runtime, and the query to
|
57
|
+
get the columns/schema for the model uses a connection that has
|
58
|
+
been disconnected.
|
59
|
+
|
60
|
+
* Model classes created from aliased expressions and literal
|
61
|
+
strings no longer use the simple_table optimization, as there
|
62
|
+
are cases where doing so is not safe.
|
63
|
+
|
64
|
+
= Backwards Compatibility
|
65
|
+
|
66
|
+
* The change to not swallow disconnect errors when not swallowing
|
67
|
+
connection errors can result in exceptions being raised which
|
68
|
+
weren't raised previously. In most cases, this will alert you
|
69
|
+
to issues in your application that should be fixed, but it
|
70
|
+
potentially it can result in regressions if you were OK with
|
71
|
+
the errors being swallowed. If this does result in regressions
|
72
|
+
in your application, please file an issue and we can probably
|
73
|
+
add a setting controlling this feature.
|
data/doc/testing.rdoc
CHANGED
@@ -113,7 +113,7 @@ The order in which you delete/truncate the tables is important if you are using
|
|
113
113
|
|
114
114
|
= Testing Sequel Itself
|
115
115
|
|
116
|
-
Sequel has multiple separate test suites. All test suites use minitest/spec, with the minitest-hooks
|
116
|
+
Sequel has multiple separate test suites. All test suites use minitest/spec, with the minitest-hooks and minitest-global_expectations extensions. To install the dependencies necessary to test Sequel, run <tt>gem install --development sequel</tt>.
|
117
117
|
|
118
118
|
== rake
|
119
119
|
|
@@ -179,6 +179,12 @@ module Sequel
|
|
179
179
|
true
|
180
180
|
end
|
181
181
|
|
182
|
+
# HSQLDB 2.3.4+ supports MERGE. Older versions also support MERGE, but not all
|
183
|
+
# features that are in Sequel's tests.
|
184
|
+
def supports_merge?
|
185
|
+
db.db_version >= 20304
|
186
|
+
end
|
187
|
+
|
182
188
|
private
|
183
189
|
|
184
190
|
def empty_from_sql
|
@@ -23,16 +23,20 @@ begin
|
|
23
23
|
end
|
24
24
|
rescue LoadError => e
|
25
25
|
begin
|
26
|
-
require 'postgres-pr
|
27
|
-
Sequel::Postgres::USES_PG = false
|
26
|
+
require 'sequel/postgres-pr'
|
28
27
|
rescue LoadError
|
29
|
-
|
28
|
+
begin
|
29
|
+
require 'postgres-pr/postgres-compat'
|
30
|
+
rescue LoadError
|
31
|
+
raise e
|
32
|
+
end
|
30
33
|
end
|
34
|
+
Sequel::Postgres::USES_PG = false
|
31
35
|
end
|
32
36
|
|
33
37
|
module Sequel
|
34
38
|
module Postgres
|
35
|
-
if
|
39
|
+
if USES_PG
|
36
40
|
# Whether the given sequel_pg version integer is supported.
|
37
41
|
def self.sequel_pg_version_supported?(version)
|
38
42
|
version >= 10617
|
@@ -74,8 +78,10 @@ module Sequel
|
|
74
78
|
unless public_method_defined?(:async_exec_params)
|
75
79
|
alias async_exec_params async_exec
|
76
80
|
end
|
77
|
-
|
78
|
-
#
|
81
|
+
elsif !const_defined?(:CONNECTION_OK)
|
82
|
+
# Handle old postgres-pr
|
83
|
+
# sequel-postgres-pr already implements this API
|
84
|
+
|
79
85
|
CONNECTION_OK = -1
|
80
86
|
|
81
87
|
# Escape bytea values. Uses historical format instead of hex
|
@@ -338,6 +338,11 @@ module Sequel
|
|
338
338
|
true
|
339
339
|
end
|
340
340
|
|
341
|
+
# DB2 supports MERGE
|
342
|
+
def supports_merge?
|
343
|
+
true
|
344
|
+
end
|
345
|
+
|
341
346
|
# DB2 does not support multiple columns in IN.
|
342
347
|
def supports_multiple_column_in?
|
343
348
|
false
|
@@ -360,6 +365,29 @@ module Sequel
|
|
360
365
|
|
361
366
|
private
|
362
367
|
|
368
|
+
# Normalize conditions for MERGE WHEN.
|
369
|
+
def _merge_when_conditions_sql(sql, data)
|
370
|
+
if data.has_key?(:conditions)
|
371
|
+
sql << " AND "
|
372
|
+
literal_append(sql, _normalize_merge_when_conditions(data[:conditions]))
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
# Handle nil, false, and true MERGE WHEN conditions to avoid non-boolean
|
377
|
+
# type error.
|
378
|
+
def _normalize_merge_when_conditions(conditions)
|
379
|
+
case conditions
|
380
|
+
when nil, false
|
381
|
+
{1=>0}
|
382
|
+
when true
|
383
|
+
{1=>1}
|
384
|
+
when Sequel::SQL::DelayedEvaluation
|
385
|
+
Sequel.delay{_normalize_merge_when_conditions(conditions.call(self))}
|
386
|
+
else
|
387
|
+
conditions
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
363
391
|
def empty_from_sql
|
364
392
|
' FROM "SYSIBM"."SYSDUMMY1"'
|
365
393
|
end
|
@@ -734,6 +734,11 @@ module Sequel
|
|
734
734
|
false
|
735
735
|
end
|
736
736
|
|
737
|
+
# MSSQL 2008+ supports MERGE
|
738
|
+
def supports_merge?
|
739
|
+
is_2008_or_later?
|
740
|
+
end
|
741
|
+
|
737
742
|
# MSSQL 2005+ supports modifying joined datasets
|
738
743
|
def supports_modifying_joins?
|
739
744
|
is_2005_or_later?
|
@@ -824,6 +829,35 @@ module Sequel
|
|
824
829
|
|
825
830
|
private
|
826
831
|
|
832
|
+
# Normalize conditions for MERGE WHEN.
|
833
|
+
def _merge_when_conditions_sql(sql, data)
|
834
|
+
if data.has_key?(:conditions)
|
835
|
+
sql << " AND "
|
836
|
+
literal_append(sql, _normalize_merge_when_conditions(data[:conditions]))
|
837
|
+
end
|
838
|
+
end
|
839
|
+
|
840
|
+
# Handle nil, false, and true MERGE WHEN conditions to avoid non-boolean
|
841
|
+
# type error.
|
842
|
+
def _normalize_merge_when_conditions(conditions)
|
843
|
+
case conditions
|
844
|
+
when nil, false
|
845
|
+
{1=>0}
|
846
|
+
when true
|
847
|
+
{1=>1}
|
848
|
+
when Sequel::SQL::DelayedEvaluation
|
849
|
+
Sequel.delay{_normalize_merge_when_conditions(conditions.call(self))}
|
850
|
+
else
|
851
|
+
conditions
|
852
|
+
end
|
853
|
+
end
|
854
|
+
|
855
|
+
# MSSQL requires a semicolon at the end of MERGE.
|
856
|
+
def _merge_when_sql(sql)
|
857
|
+
super
|
858
|
+
sql << ';'
|
859
|
+
end
|
860
|
+
|
827
861
|
# MSSQL does not allow ordering in sub-clauses unless TOP (limit) is specified
|
828
862
|
def aggregate_dataset
|
829
863
|
(options_overlap(Sequel::Dataset::COUNT_FROM_SELF_OPTS) && !options_overlap([:limit])) ? unordered.from_self : super
|
@@ -333,6 +333,12 @@ module Sequel
|
|
333
333
|
sqls << "SET sql_mode = '#{sql_mode}'"
|
334
334
|
end
|
335
335
|
|
336
|
+
# Disable the use of split_materialized in the optimizer. This is
|
337
|
+
# needed to pass association tests on MariaDB 10.5+.
|
338
|
+
if opts[:disable_split_materialized] && typecast_value_boolean(opts[:disable_split_materialized])
|
339
|
+
sqls << "SET SESSION optimizer_switch='split_materialized=off'"
|
340
|
+
end
|
341
|
+
|
336
342
|
sqls
|
337
343
|
end
|
338
344
|
|
@@ -356,6 +362,12 @@ module Sequel
|
|
356
362
|
end
|
357
363
|
end
|
358
364
|
|
365
|
+
# Support :on_update_current_timestamp option.
|
366
|
+
def column_definition_default_sql(sql, column)
|
367
|
+
super
|
368
|
+
sql << " ON UPDATE CURRENT_TIMESTAMP" if column[:on_update_current_timestamp]
|
369
|
+
end
|
370
|
+
|
359
371
|
# Add generation clause SQL fragment to column creation SQL.
|
360
372
|
def column_definition_generated_sql(sql, column)
|
361
373
|
if (generated_expression = column[:generated_always_as])
|
@@ -478,6 +478,11 @@ module Sequel
|
|
478
478
|
false
|
479
479
|
end
|
480
480
|
|
481
|
+
# Oracle supports MERGE
|
482
|
+
def supports_merge?
|
483
|
+
true
|
484
|
+
end
|
485
|
+
|
481
486
|
# Oracle supports NOWAIT.
|
482
487
|
def supports_nowait?
|
483
488
|
true
|
@@ -525,6 +530,70 @@ module Sequel
|
|
525
530
|
|
526
531
|
private
|
527
532
|
|
533
|
+
# Handle nil, false, and true MERGE WHEN conditions to avoid non-boolean
|
534
|
+
# type error.
|
535
|
+
def _normalize_merge_when_conditions(conditions)
|
536
|
+
case conditions
|
537
|
+
when nil, false
|
538
|
+
{1=>0}
|
539
|
+
when true
|
540
|
+
{1=>1}
|
541
|
+
when Sequel::SQL::DelayedEvaluation
|
542
|
+
Sequel.delay{_normalize_merge_when_conditions(conditions.call(self))}
|
543
|
+
else
|
544
|
+
conditions
|
545
|
+
end
|
546
|
+
end
|
547
|
+
|
548
|
+
# Handle Oracle's non standard MERGE syntax
|
549
|
+
def _merge_when_sql(sql)
|
550
|
+
raise Error, "no WHEN [NOT] MATCHED clauses provided for MERGE" unless merge_when = @opts[:merge_when]
|
551
|
+
insert = update = delete = nil
|
552
|
+
types = merge_when.map{|d| d[:type]}
|
553
|
+
raise Error, "Oracle does not support multiple INSERT, UPDATE, or DELETE clauses in MERGE" if types != types.uniq
|
554
|
+
|
555
|
+
merge_when.each do |data|
|
556
|
+
case data[:type]
|
557
|
+
when :insert
|
558
|
+
insert = data
|
559
|
+
when :update
|
560
|
+
update = data
|
561
|
+
else # when :delete
|
562
|
+
delete = data
|
563
|
+
end
|
564
|
+
end
|
565
|
+
|
566
|
+
if delete
|
567
|
+
raise Error, "Oracle does not support DELETE without UPDATE clause in MERGE" unless update
|
568
|
+
raise Error, "Oracle does not support DELETE without conditions clause in MERGE" unless delete.has_key?(:conditions)
|
569
|
+
end
|
570
|
+
|
571
|
+
if update
|
572
|
+
sql << " WHEN MATCHED"
|
573
|
+
_merge_update_sql(sql, update)
|
574
|
+
_merge_when_conditions_sql(sql, update)
|
575
|
+
|
576
|
+
if delete
|
577
|
+
sql << " DELETE"
|
578
|
+
_merge_when_conditions_sql(sql, delete)
|
579
|
+
end
|
580
|
+
end
|
581
|
+
|
582
|
+
if insert
|
583
|
+
sql << " WHEN NOT MATCHED"
|
584
|
+
_merge_insert_sql(sql, insert)
|
585
|
+
_merge_when_conditions_sql(sql, insert)
|
586
|
+
end
|
587
|
+
end
|
588
|
+
|
589
|
+
# Handle Oracle's non-standard MERGE WHEN condition syntax.
|
590
|
+
def _merge_when_conditions_sql(sql, data)
|
591
|
+
if data.has_key?(:conditions)
|
592
|
+
sql << " WHERE "
|
593
|
+
literal_append(sql, _normalize_merge_when_conditions(data[:conditions]))
|
594
|
+
end
|
595
|
+
end
|
596
|
+
|
528
597
|
# Allow preparing prepared statements, since determining the prepared sql to use for
|
529
598
|
# a prepared statement requires calling prepare on that statement.
|
530
599
|
def allow_preparing_prepared_statements?
|