sequel 5.33.0 → 5.58.0
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/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?
|