sequel 5.33.0 → 5.58.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +318 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +40 -9
- data/doc/association_basics.rdoc +77 -13
- data/doc/cheat_sheet.rdoc +13 -5
- data/doc/code_order.rdoc +0 -12
- data/doc/dataset_filtering.rdoc +2 -2
- data/doc/fork_safety.rdoc +84 -0
- data/doc/migration.rdoc +12 -6
- data/doc/model_plugins.rdoc +1 -1
- data/doc/opening_databases.rdoc +15 -3
- data/doc/postgresql.rdoc +9 -1
- data/doc/querying.rdoc +7 -5
- data/doc/release_notes/5.34.0.txt +40 -0
- data/doc/release_notes/5.35.0.txt +56 -0
- data/doc/release_notes/5.36.0.txt +60 -0
- data/doc/release_notes/5.37.0.txt +30 -0
- data/doc/release_notes/5.38.0.txt +28 -0
- data/doc/release_notes/5.39.0.txt +19 -0
- data/doc/release_notes/5.40.0.txt +40 -0
- data/doc/release_notes/5.41.0.txt +25 -0
- data/doc/release_notes/5.42.0.txt +136 -0
- data/doc/release_notes/5.43.0.txt +98 -0
- data/doc/release_notes/5.44.0.txt +32 -0
- data/doc/release_notes/5.45.0.txt +34 -0
- data/doc/release_notes/5.46.0.txt +87 -0
- data/doc/release_notes/5.47.0.txt +59 -0
- data/doc/release_notes/5.48.0.txt +14 -0
- data/doc/release_notes/5.49.0.txt +59 -0
- data/doc/release_notes/5.50.0.txt +78 -0
- data/doc/release_notes/5.51.0.txt +47 -0
- data/doc/release_notes/5.52.0.txt +87 -0
- data/doc/release_notes/5.53.0.txt +23 -0
- data/doc/release_notes/5.54.0.txt +27 -0
- data/doc/release_notes/5.55.0.txt +21 -0
- data/doc/release_notes/5.56.0.txt +51 -0
- data/doc/release_notes/5.57.0.txt +23 -0
- data/doc/release_notes/5.58.0.txt +31 -0
- data/doc/sql.rdoc +14 -2
- data/doc/testing.rdoc +10 -1
- data/doc/transactions.rdoc +0 -8
- data/doc/validations.rdoc +1 -1
- data/doc/virtual_rows.rdoc +1 -1
- data/lib/sequel/adapters/ado/access.rb +1 -1
- data/lib/sequel/adapters/ado.rb +17 -17
- data/lib/sequel/adapters/amalgalite.rb +3 -5
- data/lib/sequel/adapters/ibmdb.rb +2 -2
- data/lib/sequel/adapters/jdbc/derby.rb +8 -0
- data/lib/sequel/adapters/jdbc/h2.rb +60 -10
- data/lib/sequel/adapters/jdbc/hsqldb.rb +6 -0
- data/lib/sequel/adapters/jdbc/mysql.rb +4 -4
- data/lib/sequel/adapters/jdbc/postgresql.rb +4 -4
- data/lib/sequel/adapters/jdbc.rb +29 -19
- data/lib/sequel/adapters/mysql.rb +80 -67
- data/lib/sequel/adapters/mysql2.rb +54 -49
- data/lib/sequel/adapters/odbc.rb +8 -6
- data/lib/sequel/adapters/oracle.rb +5 -4
- data/lib/sequel/adapters/postgres.rb +27 -29
- data/lib/sequel/adapters/shared/access.rb +2 -0
- data/lib/sequel/adapters/shared/db2.rb +30 -0
- data/lib/sequel/adapters/shared/mssql.rb +84 -7
- data/lib/sequel/adapters/shared/mysql.rb +33 -2
- data/lib/sequel/adapters/shared/oracle.rb +82 -7
- data/lib/sequel/adapters/shared/postgres.rb +158 -20
- data/lib/sequel/adapters/shared/sqlanywhere.rb +3 -0
- data/lib/sequel/adapters/shared/sqlite.rb +102 -10
- data/lib/sequel/adapters/sqlanywhere.rb +1 -1
- data/lib/sequel/adapters/sqlite.rb +60 -18
- data/lib/sequel/adapters/tinytds.rb +2 -1
- data/lib/sequel/adapters/utils/columns_limit_1.rb +22 -0
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +2 -1
- data/lib/sequel/ast_transformer.rb +6 -0
- data/lib/sequel/connection_pool/sharded_single.rb +9 -8
- data/lib/sequel/connection_pool/sharded_threaded.rb +10 -10
- data/lib/sequel/connection_pool/single.rb +7 -9
- data/lib/sequel/connection_pool/threaded.rb +1 -1
- data/lib/sequel/core.rb +33 -24
- data/lib/sequel/database/connecting.rb +3 -4
- data/lib/sequel/database/misc.rb +37 -12
- data/lib/sequel/database/query.rb +3 -1
- data/lib/sequel/database/schema_generator.rb +50 -53
- data/lib/sequel/database/schema_methods.rb +45 -23
- data/lib/sequel/database/transactions.rb +9 -6
- data/lib/sequel/dataset/actions.rb +61 -8
- data/lib/sequel/dataset/features.rb +15 -0
- data/lib/sequel/dataset/placeholder_literalizer.rb +3 -7
- data/lib/sequel/dataset/prepared_statements.rb +2 -0
- data/lib/sequel/dataset/query.rb +114 -11
- data/lib/sequel/dataset/sql.rb +172 -46
- data/lib/sequel/deprecated.rb +3 -1
- data/lib/sequel/exceptions.rb +2 -0
- data/lib/sequel/extensions/_pretty_table.rb +1 -2
- data/lib/sequel/extensions/any_not_empty.rb +1 -1
- data/lib/sequel/extensions/async_thread_pool.rb +438 -0
- data/lib/sequel/extensions/blank.rb +8 -0
- data/lib/sequel/extensions/columns_introspection.rb +1 -2
- data/lib/sequel/extensions/core_refinements.rb +38 -11
- data/lib/sequel/extensions/date_arithmetic.rb +36 -24
- data/lib/sequel/extensions/date_parse_input_handler.rb +67 -0
- data/lib/sequel/extensions/datetime_parse_to_time.rb +5 -1
- data/lib/sequel/extensions/duplicate_columns_handler.rb +3 -1
- data/lib/sequel/extensions/eval_inspect.rb +2 -0
- data/lib/sequel/extensions/inflector.rb +9 -1
- data/lib/sequel/extensions/is_distinct_from.rb +139 -0
- data/lib/sequel/extensions/migration.rb +13 -2
- data/lib/sequel/extensions/named_timezones.rb +5 -1
- data/lib/sequel/extensions/pagination.rb +1 -1
- data/lib/sequel/extensions/pg_array.rb +1 -0
- data/lib/sequel/extensions/pg_array_ops.rb +6 -2
- data/lib/sequel/extensions/pg_enum.rb +3 -1
- data/lib/sequel/extensions/pg_extended_date_support.rb +2 -2
- data/lib/sequel/extensions/pg_hstore.rb +1 -1
- data/lib/sequel/extensions/pg_hstore_ops.rb +55 -3
- data/lib/sequel/extensions/pg_inet.rb +2 -0
- data/lib/sequel/extensions/pg_inet_ops.rb +1 -1
- data/lib/sequel/extensions/pg_interval.rb +35 -8
- data/lib/sequel/extensions/pg_json.rb +3 -5
- data/lib/sequel/extensions/pg_json_ops.rb +119 -4
- data/lib/sequel/extensions/pg_loose_count.rb +3 -1
- data/lib/sequel/extensions/pg_multirange.rb +372 -0
- data/lib/sequel/extensions/pg_range.rb +7 -19
- data/lib/sequel/extensions/pg_range_ops.rb +39 -9
- data/lib/sequel/extensions/pg_row.rb +1 -1
- data/lib/sequel/extensions/pg_row_ops.rb +25 -1
- data/lib/sequel/extensions/query.rb +3 -0
- data/lib/sequel/extensions/run_transaction_hooks.rb +1 -1
- data/lib/sequel/extensions/s.rb +4 -1
- data/lib/sequel/extensions/schema_dumper.rb +16 -5
- data/lib/sequel/extensions/server_block.rb +8 -12
- data/lib/sequel/extensions/sql_comments.rb +110 -3
- data/lib/sequel/extensions/sql_log_normalizer.rb +108 -0
- data/lib/sequel/extensions/sqlite_json_ops.rb +255 -0
- data/lib/sequel/extensions/string_agg.rb +1 -1
- data/lib/sequel/extensions/string_date_time.rb +19 -23
- data/lib/sequel/extensions/symbol_aref_refinement.rb +2 -0
- data/lib/sequel/extensions/symbol_as_refinement.rb +2 -0
- data/lib/sequel/extensions/to_dot.rb +9 -3
- data/lib/sequel/model/associations.rb +342 -114
- data/lib/sequel/model/base.rb +45 -24
- data/lib/sequel/model/errors.rb +10 -1
- data/lib/sequel/model/inflections.rb +1 -1
- data/lib/sequel/model/plugins.rb +8 -3
- data/lib/sequel/model.rb +3 -1
- data/lib/sequel/plugins/association_pks.rb +60 -18
- data/lib/sequel/plugins/association_proxies.rb +3 -0
- data/lib/sequel/plugins/async_thread_pool.rb +39 -0
- data/lib/sequel/plugins/auto_restrict_eager_graph.rb +62 -0
- data/lib/sequel/plugins/auto_validations.rb +39 -5
- data/lib/sequel/plugins/auto_validations_constraint_validations_presence_message.rb +68 -0
- data/lib/sequel/plugins/blacklist_security.rb +1 -2
- data/lib/sequel/plugins/class_table_inheritance.rb +3 -8
- data/lib/sequel/plugins/column_encryption.rb +728 -0
- data/lib/sequel/plugins/composition.rb +8 -2
- data/lib/sequel/plugins/concurrent_eager_loading.rb +174 -0
- data/lib/sequel/plugins/constraint_validations.rb +2 -1
- data/lib/sequel/plugins/csv_serializer.rb +2 -0
- data/lib/sequel/plugins/dataset_associations.rb +4 -1
- data/lib/sequel/plugins/dirty.rb +44 -0
- data/lib/sequel/plugins/enum.rb +124 -0
- data/lib/sequel/plugins/forbid_lazy_load.rb +2 -0
- data/lib/sequel/plugins/insert_conflict.rb +4 -0
- data/lib/sequel/plugins/instance_specific_default.rb +113 -0
- data/lib/sequel/plugins/json_serializer.rb +39 -24
- data/lib/sequel/plugins/lazy_attributes.rb +4 -1
- data/lib/sequel/plugins/many_through_many.rb +108 -9
- data/lib/sequel/plugins/nested_attributes.rb +8 -3
- data/lib/sequel/plugins/pg_array_associations.rb +58 -41
- data/lib/sequel/plugins/pg_auto_constraint_validations.rb +2 -0
- data/lib/sequel/plugins/prepared_statements.rb +15 -12
- data/lib/sequel/plugins/prepared_statements_safe.rb +1 -3
- data/lib/sequel/plugins/rcte_tree.rb +37 -35
- data/lib/sequel/plugins/serialization.rb +9 -3
- data/lib/sequel/plugins/serialization_modification_detection.rb +2 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +7 -0
- data/lib/sequel/plugins/sql_comments.rb +189 -0
- data/lib/sequel/plugins/static_cache.rb +1 -1
- data/lib/sequel/plugins/string_stripper.rb +1 -1
- data/lib/sequel/plugins/subclasses.rb +28 -11
- data/lib/sequel/plugins/tactical_eager_loading.rb +8 -2
- data/lib/sequel/plugins/timestamps.rb +1 -1
- data/lib/sequel/plugins/tree.rb +9 -4
- data/lib/sequel/plugins/unused_associations.rb +521 -0
- data/lib/sequel/plugins/update_or_create.rb +1 -1
- data/lib/sequel/plugins/validation_class_methods.rb +5 -1
- data/lib/sequel/plugins/validation_helpers.rb +18 -11
- data/lib/sequel/plugins/xml_serializer.rb +1 -1
- data/lib/sequel/sql.rb +1 -1
- data/lib/sequel/timezones.rb +20 -17
- data/lib/sequel/version.rb +1 -1
- metadata +93 -39
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen-string-literal: true
|
2
2
|
|
3
3
|
require_relative '../utils/emulate_offset_with_row_number'
|
4
|
+
require_relative '../utils/columns_limit_1'
|
4
5
|
|
5
6
|
module Sequel
|
6
7
|
module DB2
|
@@ -273,6 +274,7 @@ module Sequel
|
|
273
274
|
|
274
275
|
module DatasetMethods
|
275
276
|
include EmulateOffsetWithRowNumber
|
277
|
+
include ::Sequel::Dataset::ColumnsLimit1
|
276
278
|
|
277
279
|
BITWISE_METHOD_MAP = {:& =>:BITAND, :| => :BITOR, :^ => :BITXOR, :'B~'=>:BITNOT}.freeze
|
278
280
|
|
@@ -336,6 +338,11 @@ module Sequel
|
|
336
338
|
true
|
337
339
|
end
|
338
340
|
|
341
|
+
# DB2 supports MERGE
|
342
|
+
def supports_merge?
|
343
|
+
true
|
344
|
+
end
|
345
|
+
|
339
346
|
# DB2 does not support multiple columns in IN.
|
340
347
|
def supports_multiple_column_in?
|
341
348
|
false
|
@@ -358,6 +365,29 @@ module Sequel
|
|
358
365
|
|
359
366
|
private
|
360
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
|
+
|
361
391
|
def empty_from_sql
|
362
392
|
' FROM "SYSIBM"."SYSDUMMY1"'
|
363
393
|
end
|
@@ -24,6 +24,10 @@ module Sequel
|
|
24
24
|
# Database object.
|
25
25
|
attr_accessor :mssql_unicode_strings
|
26
26
|
|
27
|
+
# Whether to use LIKE without COLLATE Latin1_General_CS_AS. Skipping the COLLATE
|
28
|
+
# can significantly increase performance in some cases.
|
29
|
+
attr_accessor :like_without_collate
|
30
|
+
|
27
31
|
# Execute the given stored procedure with the given name.
|
28
32
|
#
|
29
33
|
# Options:
|
@@ -244,6 +248,16 @@ module Sequel
|
|
244
248
|
|
245
249
|
private
|
246
250
|
|
251
|
+
# Add CLUSTERED or NONCLUSTERED as needed
|
252
|
+
def add_clustered_sql_fragment(sql, opts)
|
253
|
+
clustered = opts[:clustered]
|
254
|
+
unless clustered.nil?
|
255
|
+
sql += " #{'NON' unless clustered}CLUSTERED"
|
256
|
+
end
|
257
|
+
|
258
|
+
sql
|
259
|
+
end
|
260
|
+
|
247
261
|
# Add dropping of the default constraint to the list of SQL queries.
|
248
262
|
# This is necessary before dropping the column or changing its type.
|
249
263
|
def add_drop_default_constraint_sql(sqls, table, column)
|
@@ -284,7 +298,7 @@ module Sequel
|
|
284
298
|
when :set_column_null
|
285
299
|
sch = schema(table).find{|k,v| k.to_s == op[:name].to_s}.last
|
286
300
|
type = sch[:db_type]
|
287
|
-
if [:string, :decimal].include?(sch[:type]) && !["text", "ntext"].include?(type) && (size = (sch[:max_chars] || sch[:column_size]))
|
301
|
+
if [:string, :decimal, :blob].include?(sch[:type]) && !["text", "ntext"].include?(type) && (size = (sch[:max_chars] || sch[:column_size]))
|
288
302
|
size = "MAX" if size == -1
|
289
303
|
type += "(#{size}#{", #{sch[:scale]}" if sch[:scale] && sch[:scale].to_i > 0})"
|
290
304
|
end
|
@@ -396,6 +410,11 @@ module Sequel
|
|
396
410
|
super.with_quote_identifiers(true)
|
397
411
|
end
|
398
412
|
|
413
|
+
# Handle clustered and nonclustered primary keys
|
414
|
+
def primary_key_constraint_sql_fragment(opts)
|
415
|
+
add_clustered_sql_fragment(super, opts)
|
416
|
+
end
|
417
|
+
|
399
418
|
# Use sp_rename to rename the table
|
400
419
|
def rename_table_sql(name, new_name)
|
401
420
|
"sp_rename #{literal(quote_schema_table(name))}, #{quote_identifier(schema_and_table(new_name).pop)}"
|
@@ -492,6 +511,11 @@ module Sequel
|
|
492
511
|
:'varbinary(max)'
|
493
512
|
end
|
494
513
|
|
514
|
+
# Handle clustered and nonclustered unique constraints
|
515
|
+
def unique_constraint_sql_fragment(opts)
|
516
|
+
add_clustered_sql_fragment(super, opts)
|
517
|
+
end
|
518
|
+
|
495
519
|
# MSSQL supports views with check option, but not local.
|
496
520
|
def view_with_check_option_support
|
497
521
|
true
|
@@ -528,9 +552,9 @@ module Sequel
|
|
528
552
|
when :'||'
|
529
553
|
super(sql, :+, args)
|
530
554
|
when :LIKE, :"NOT LIKE"
|
531
|
-
super(sql, op, args
|
555
|
+
super(sql, op, complex_expression_sql_like_args(args, " COLLATE Latin1_General_CS_AS)"))
|
532
556
|
when :ILIKE, :"NOT ILIKE"
|
533
|
-
super(sql, (op == :ILIKE ? :LIKE : :"NOT LIKE"), args
|
557
|
+
super(sql, (op == :ILIKE ? :LIKE : :"NOT LIKE"), complex_expression_sql_like_args(args, " COLLATE Latin1_General_CI_AS)"))
|
534
558
|
when :<<, :>>
|
535
559
|
complex_expression_emulate_append(sql, op, args)
|
536
560
|
when :extract
|
@@ -659,11 +683,11 @@ module Sequel
|
|
659
683
|
# case by default, and that also adds a default order, so it's better to just
|
660
684
|
# avoid the subquery.
|
661
685
|
def select_sql
|
662
|
-
if @opts[:offset]
|
663
|
-
|
664
|
-
|
665
|
-
super
|
686
|
+
if @opts[:offset]
|
687
|
+
raise(Error, "Using with_ties is not supported with an offset on Microsoft SQL Server") if @opts[:limit_with_ties]
|
688
|
+
return order(1).select_sql if is_2012_or_later? && !@opts[:order]
|
666
689
|
end
|
690
|
+
super
|
667
691
|
end
|
668
692
|
|
669
693
|
# The version of the database server.
|
@@ -710,6 +734,11 @@ module Sequel
|
|
710
734
|
false
|
711
735
|
end
|
712
736
|
|
737
|
+
# MSSQL 2008+ supports MERGE
|
738
|
+
def supports_merge?
|
739
|
+
is_2008_or_later?
|
740
|
+
end
|
741
|
+
|
713
742
|
# MSSQL 2005+ supports modifying joined datasets
|
714
743
|
def supports_modifying_joins?
|
715
744
|
is_2005_or_later?
|
@@ -755,6 +784,12 @@ module Sequel
|
|
755
784
|
false
|
756
785
|
end
|
757
786
|
|
787
|
+
# Use WITH TIES when limiting the result set to also include additional
|
788
|
+
# rows matching the last row.
|
789
|
+
def with_ties
|
790
|
+
clone(:limit_with_ties=>true)
|
791
|
+
end
|
792
|
+
|
758
793
|
protected
|
759
794
|
|
760
795
|
# If returned primary keys are requested, use OUTPUT unless already set on the
|
@@ -794,6 +829,35 @@ module Sequel
|
|
794
829
|
|
795
830
|
private
|
796
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
|
+
|
797
861
|
# MSSQL does not allow ordering in sub-clauses unless TOP (limit) is specified
|
798
862
|
def aggregate_dataset
|
799
863
|
(options_overlap(Sequel::Dataset::COUNT_FROM_SELF_OPTS) && !options_overlap([:limit])) ? unordered.from_self : super
|
@@ -821,6 +885,15 @@ module Sequel
|
|
821
885
|
server_version >= 11000000
|
822
886
|
end
|
823
887
|
|
888
|
+
# Determine whether to add the COLLATE for LIKE arguments, based on the Database setting.
|
889
|
+
def complex_expression_sql_like_args(args, collation)
|
890
|
+
if db.like_without_collate
|
891
|
+
args
|
892
|
+
else
|
893
|
+
args.map{|a| Sequel.lit(["(", collation], a)}
|
894
|
+
end
|
895
|
+
end
|
896
|
+
|
824
897
|
# Use strict ISO-8601 format with T between date and time,
|
825
898
|
# since that is the format that is multilanguage and not
|
826
899
|
# DATEFORMAT dependent.
|
@@ -959,6 +1032,10 @@ module Sequel
|
|
959
1032
|
sql << " TOP "
|
960
1033
|
literal_append(sql, l)
|
961
1034
|
end
|
1035
|
+
|
1036
|
+
if @opts[:limit_with_ties]
|
1037
|
+
sql << " WITH TIES"
|
1038
|
+
end
|
962
1039
|
end
|
963
1040
|
|
964
1041
|
def update_limit_sql(sql)
|
@@ -187,6 +187,15 @@ module Sequel
|
|
187
187
|
def views(opts=OPTS)
|
188
188
|
full_tables('VIEW', opts)
|
189
189
|
end
|
190
|
+
|
191
|
+
# Renames multiple tables in a single call.
|
192
|
+
#
|
193
|
+
# DB.rename_tables [:items, :old_items], [:other_items, :old_other_items]
|
194
|
+
# # RENAME TABLE items TO old_items, other_items TO old_other_items
|
195
|
+
def rename_tables(*renames)
|
196
|
+
execute_ddl(rename_tables_sql(renames))
|
197
|
+
renames.each{|from,| remove_cached_schema(from)}
|
198
|
+
end
|
190
199
|
|
191
200
|
private
|
192
201
|
|
@@ -324,6 +333,12 @@ module Sequel
|
|
324
333
|
sqls << "SET sql_mode = '#{sql_mode}'"
|
325
334
|
end
|
326
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
|
+
|
327
342
|
sqls
|
328
343
|
end
|
329
344
|
|
@@ -347,6 +362,12 @@ module Sequel
|
|
347
362
|
end
|
348
363
|
end
|
349
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
|
+
|
350
371
|
# Add generation clause SQL fragment to column creation SQL.
|
351
372
|
def column_definition_generated_sql(sql, column)
|
352
373
|
if (generated_expression = column[:generated_always_as])
|
@@ -473,6 +494,14 @@ module Sequel
|
|
473
494
|
schema(table).select{|a| a[1][:primary_key]}.map{|a| a[0]}
|
474
495
|
end
|
475
496
|
|
497
|
+
# SQL statement for renaming multiple tables.
|
498
|
+
def rename_tables_sql(renames)
|
499
|
+
rename_tos = renames.map do |from, to|
|
500
|
+
"#{quote_schema_table(from)} TO #{quote_schema_table(to)}"
|
501
|
+
end.join(', ')
|
502
|
+
"RENAME TABLE #{rename_tos}"
|
503
|
+
end
|
504
|
+
|
476
505
|
# Rollback the currently open XA transaction
|
477
506
|
def rollback_transaction(conn, opts=OPTS)
|
478
507
|
if (s = opts[:prepare]) && savepoint_level(conn) <= 1
|
@@ -516,6 +545,7 @@ module Sequel
|
|
516
545
|
row[:default] = row.delete(:Default)
|
517
546
|
row[:db_type] = row.delete(:Type)
|
518
547
|
row[:type] = schema_column_type(row[:db_type])
|
548
|
+
row[:extra] = extra
|
519
549
|
[m.call(row.delete(:Field)), row]
|
520
550
|
end
|
521
551
|
end
|
@@ -526,9 +556,10 @@ module Sequel
|
|
526
556
|
server_version >= 50600 && (op[:op] == :drop_index || (op[:op] == :drop_constraint && op[:type] == :unique))
|
527
557
|
end
|
528
558
|
|
529
|
-
#
|
559
|
+
# CHECK constraints only supported on MariaDB 10.2+ and MySQL 8.0.19+
|
560
|
+
# (at least MySQL documents DROP CONSTRAINT was supported in 8.0.19+).
|
530
561
|
def supports_check_constraints?
|
531
|
-
mariadb?
|
562
|
+
server_version >= (mariadb? ? 100200 : 80019)
|
532
563
|
end
|
533
564
|
|
534
565
|
# MySQL can combine multiple alter table ops into a single query.
|
@@ -103,12 +103,18 @@ module Sequel
|
|
103
103
|
map{|r| m.call(r[:view_name])}
|
104
104
|
end
|
105
105
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
106
|
+
# Whether a view with a given name exists. By default, looks in all schemas other than system
|
107
|
+
# schemas. If the :current_schema option is given, looks in the schema for the current user.
|
108
|
+
def view_exists?(name, opts=OPTS)
|
109
|
+
ds = metadata_dataset.from(:all_views).where(:view_name=>input_identifier_meth.call(name))
|
110
|
+
|
111
|
+
if opts[:current_schema]
|
112
|
+
ds = ds.where(:owner=>Sequel.function(:SYS_CONTEXT, 'userenv', 'current_schema'))
|
113
|
+
else
|
114
|
+
ds = ds.exclude(:owner=>IGNORE_OWNERS)
|
115
|
+
end
|
116
|
+
|
117
|
+
ds.count > 0
|
112
118
|
end
|
113
119
|
|
114
120
|
# The version of the Oracle server, used for determining capability.
|
@@ -178,7 +184,7 @@ module Sequel
|
|
178
184
|
|
179
185
|
def create_table_from_generator(name, generator, options)
|
180
186
|
drop_statement, create_statements = create_table_sql_list(name, generator, options)
|
181
|
-
|
187
|
+
swallow_database_error{execute_ddl(drop_statement)} if drop_statement
|
182
188
|
create_statements.each{|sql| execute_ddl(sql)}
|
183
189
|
end
|
184
190
|
|
@@ -472,6 +478,11 @@ module Sequel
|
|
472
478
|
false
|
473
479
|
end
|
474
480
|
|
481
|
+
# Oracle supports MERGE
|
482
|
+
def supports_merge?
|
483
|
+
true
|
484
|
+
end
|
485
|
+
|
475
486
|
# Oracle supports NOWAIT.
|
476
487
|
def supports_nowait?
|
477
488
|
true
|
@@ -519,6 +530,70 @@ module Sequel
|
|
519
530
|
|
520
531
|
private
|
521
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
|
+
|
522
597
|
# Allow preparing prepared statements, since determining the prepared sql to use for
|
523
598
|
# a prepared statement requires calling prepare on that statement.
|
524
599
|
def allow_preparing_prepared_statements?
|