sequel 5.33.0 → 5.35.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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +42 -0
  3. data/doc/association_basics.rdoc +7 -2
  4. data/doc/dataset_filtering.rdoc +2 -2
  5. data/doc/release_notes/5.34.0.txt +40 -0
  6. data/doc/release_notes/5.35.0.txt +56 -0
  7. data/lib/sequel/adapters/oracle.rb +2 -1
  8. data/lib/sequel/adapters/shared/sqlite.rb +8 -2
  9. data/lib/sequel/adapters/tinytds.rb +1 -0
  10. data/lib/sequel/connection_pool/sharded_single.rb +4 -1
  11. data/lib/sequel/connection_pool/sharded_threaded.rb +10 -10
  12. data/lib/sequel/connection_pool/single.rb +1 -1
  13. data/lib/sequel/connection_pool/threaded.rb +1 -1
  14. data/lib/sequel/database/connecting.rb +1 -1
  15. data/lib/sequel/database/misc.rb +16 -10
  16. data/lib/sequel/database/query.rb +2 -0
  17. data/lib/sequel/database/schema_generator.rb +0 -1
  18. data/lib/sequel/database/schema_methods.rb +15 -16
  19. data/lib/sequel/database/transactions.rb +7 -4
  20. data/lib/sequel/dataset/placeholder_literalizer.rb +3 -7
  21. data/lib/sequel/dataset/query.rb +5 -4
  22. data/lib/sequel/deprecated.rb +3 -1
  23. data/lib/sequel/exceptions.rb +2 -0
  24. data/lib/sequel/extensions/_pretty_table.rb +1 -2
  25. data/lib/sequel/extensions/columns_introspection.rb +1 -2
  26. data/lib/sequel/extensions/core_refinements.rb +2 -0
  27. data/lib/sequel/extensions/duplicate_columns_handler.rb +2 -0
  28. data/lib/sequel/extensions/migration.rb +0 -1
  29. data/lib/sequel/extensions/pg_array_ops.rb +4 -0
  30. data/lib/sequel/extensions/pg_enum.rb +2 -0
  31. data/lib/sequel/extensions/pg_extended_date_support.rb +1 -1
  32. data/lib/sequel/extensions/pg_hstore_ops.rb +2 -0
  33. data/lib/sequel/extensions/pg_inet.rb +2 -0
  34. data/lib/sequel/extensions/pg_json_ops.rb +2 -0
  35. data/lib/sequel/extensions/pg_range.rb +3 -7
  36. data/lib/sequel/extensions/pg_range_ops.rb +2 -0
  37. data/lib/sequel/extensions/pg_row.rb +0 -1
  38. data/lib/sequel/extensions/run_transaction_hooks.rb +1 -1
  39. data/lib/sequel/extensions/s.rb +2 -0
  40. data/lib/sequel/extensions/symbol_aref_refinement.rb +2 -0
  41. data/lib/sequel/extensions/symbol_as_refinement.rb +2 -0
  42. data/lib/sequel/extensions/to_dot.rb +9 -3
  43. data/lib/sequel/model.rb +2 -0
  44. data/lib/sequel/model/associations.rb +36 -20
  45. data/lib/sequel/model/base.rb +11 -5
  46. data/lib/sequel/model/plugins.rb +2 -3
  47. data/lib/sequel/plugins/association_pks.rb +60 -18
  48. data/lib/sequel/plugins/blacklist_security.rb +1 -2
  49. data/lib/sequel/plugins/class_table_inheritance.rb +3 -3
  50. data/lib/sequel/plugins/csv_serializer.rb +2 -0
  51. data/lib/sequel/plugins/forbid_lazy_load.rb +2 -0
  52. data/lib/sequel/plugins/instance_specific_default.rb +113 -0
  53. data/lib/sequel/plugins/lazy_attributes.rb +1 -1
  54. data/lib/sequel/plugins/pg_array_associations.rb +2 -3
  55. data/lib/sequel/plugins/prepared_statements.rb +5 -11
  56. data/lib/sequel/plugins/prepared_statements_safe.rb +1 -3
  57. data/lib/sequel/plugins/rcte_tree.rb +10 -16
  58. data/lib/sequel/plugins/string_stripper.rb +1 -1
  59. data/lib/sequel/plugins/validation_class_methods.rb +5 -1
  60. data/lib/sequel/version.rb +1 -1
  61. metadata +7 -2
@@ -491,6 +491,11 @@ module Sequel
491
491
  # the module using a the camelized plugin name under Sequel::Plugins.
492
492
  def plugin(plugin, *args, &block)
493
493
  m = plugin.is_a?(Module) ? plugin : plugin_module(plugin)
494
+
495
+ if !m.respond_to?(:apply) && !m.respond_to?(:configure) && (!args.empty? || block)
496
+ Deprecation.deprecate("Plugin #{plugin} accepts no arguments or block, and passing arguments/block to it", "Remove arguments and block when loading the plugin")
497
+ end
498
+
494
499
  unless @plugins.include?(m)
495
500
  @plugins << m
496
501
  m.apply(self, *args, &block) if m.respond_to?(:apply)
@@ -500,6 +505,7 @@ module Sequel
500
505
  dataset_extend(m::DatasetMethods, :create_class_methods=>false)
501
506
  end
502
507
  end
508
+
503
509
  m.configure(self, *args, &block) if m.respond_to?(:configure)
504
510
  end
505
511
 
@@ -593,7 +599,7 @@ module Sequel
593
599
  @columns = superclass.instance_variable_get(:@columns)
594
600
  @db_schema = superclass.instance_variable_get(:@db_schema)
595
601
  else
596
- @dataset = @dataset.with_extend(*@dataset_method_modules.reverse) if @dataset_method_modules
602
+ @dataset = @dataset.with_extend(*@dataset_method_modules.reverse)
597
603
  @db_schema = get_db_schema
598
604
  end
599
605
 
@@ -632,8 +638,7 @@ module Sequel
632
638
 
633
639
  # Cache of setter methods to allow by default, in order to speed up mass assignment.
634
640
  def setter_methods
635
- return @setter_methods if @setter_methods
636
- @setter_methods = get_setter_methods
641
+ @setter_methods || (@setter_methods = get_setter_methods)
637
642
  end
638
643
 
639
644
  # Returns name of primary table for the dataset. If the table for the dataset
@@ -820,7 +825,6 @@ module Sequel
820
825
  super
821
826
  ivs = subclass.instance_variables
822
827
  inherited_instance_variables.each do |iv, dup|
823
- next if ivs.include?(iv)
824
828
  if (sup_class_value = instance_variable_get(iv)) && dup
825
829
  sup_class_value = case dup
826
830
  when :dup
@@ -1116,7 +1120,7 @@ module Sequel
1116
1120
  when nil
1117
1121
  return false
1118
1122
  when Array
1119
- return false if pk.any?(&:nil?)
1123
+ return false if pkv.any?(&:nil?)
1120
1124
  end
1121
1125
 
1122
1126
  (obj.class == model) && (obj.pk == pkv)
@@ -2232,7 +2236,9 @@ module Sequel
2232
2236
  plugin self
2233
2237
 
2234
2238
  singleton_class.send(:undef_method, :dup, :clone, :initialize_copy)
2239
+ # :nocov:
2235
2240
  if RUBY_VERSION >= '1.9.3'
2241
+ # :nocov:
2236
2242
  singleton_class.send(:undef_method, :initialize_clone, :initialize_dup)
2237
2243
  end
2238
2244
  end
@@ -149,9 +149,8 @@ module Sequel
149
149
  required_args = arity
150
150
  arity -= 1 if keyword == :required
151
151
 
152
- if callable.is_a?(Proc) && !callable.lambda?
153
- optional_args -= arity
154
- end
152
+ # callable currently is always a non-lambda Proc
153
+ optional_args -= arity
155
154
 
156
155
  [required_args, optional_args, rest, keyword]
157
156
  end
@@ -2,13 +2,17 @@
2
2
 
3
3
  module Sequel
4
4
  module Plugins
5
- # The association_pks plugin adds association_pks and association_pks=
6
- # instance methods to the model class for each association added. These
7
- # methods allow for easily returning the primary keys of the associated
8
- # objects, and easily modifying which objects are associated:
5
+ # The association_pks plugin adds association_pks, association_pks=, and
6
+ # association_pks_dataset instance methods to the model class for each
7
+ # one_to_many and many_to_many association added. These methods allow for
8
+ # easily returning the primary keys of the associated objects, and easily
9
+ # modifying which objects are associated:
9
10
  #
10
11
  # Artist.one_to_many :albums
11
12
  # artist = Artist[1]
13
+ # artist.album_pks_dataset
14
+ # # SELECT id FROM albums WHERE (albums.artist_id = 1)
15
+ #
12
16
  # artist.album_pks # [1, 2, 3]
13
17
  # artist.album_pks = [2, 4]
14
18
  # artist.album_pks # [2, 4]
@@ -22,11 +26,18 @@ module Sequel
22
26
  # This plugin makes modifications directly to the underlying tables,
23
27
  # it does not create or return any model objects, and therefore does
24
28
  # not call any callbacks. If you have any association callbacks,
25
- # you probably should not use the setter methods.
29
+ # you probably should not use the setter methods this plugin adds.
26
30
  #
27
31
  # By default, changes to the association will not happen until the object
28
- # is saved. However, using the delay_pks: false option, you can have the
29
- # changes made immediately when the association_pks setter method is called.
32
+ # is saved. However, using the delay_pks: false association option, you can have
33
+ # the changes made immediately when the association_pks setter method is called.
34
+ #
35
+ # By default, repeated calls to the association_pks getter method will not be
36
+ # cached, unless the setter method has been used and the delay_pks: false
37
+ # association option is not used. You can set caching of repeated calls to the
38
+ # association_pks getter method using the :cache_pks association option. You can
39
+ # pass the :refresh option when calling the getter method to ignore any existing
40
+ # cached values, similar to how the :refresh option works with associations.
30
41
  #
31
42
  # By default, if you pass a nil value to the setter, an exception will be raised.
32
43
  # You can change this behavior by using the :association_pks_nil association option.
@@ -60,9 +71,11 @@ module Sequel
60
71
 
61
72
  # Define a association_pks method using the block for the association reflection
62
73
  def def_association_pks_methods(opts)
74
+ association_module_def(opts[:pks_dataset_method], &opts[:pks_dataset])
75
+
63
76
  opts[:pks_getter_method] = :"#{singularize(opts[:name])}_pks_getter"
64
77
  association_module_def(opts[:pks_getter_method], &opts[:pks_getter])
65
- association_module_def(:"#{singularize(opts[:name])}_pks", opts){_association_pks_getter(opts)}
78
+ association_module_def(:"#{singularize(opts[:name])}_pks", opts){|dynamic_opts=OPTS| _association_pks_getter(opts, dynamic_opts)}
66
79
 
67
80
  if opts[:pks_setter]
68
81
  opts[:pks_setter_method] = :"#{singularize(opts[:name])}_pks_setter"
@@ -84,7 +97,9 @@ module Sequel
84
97
  clpk = lpk.is_a?(Array)
85
98
  crk = rk.is_a?(Array)
86
99
 
87
- opts[:pks_getter] = if join_associated_table = opts[:association_pks_use_associated_table]
100
+ dataset_method = opts[:pks_dataset_method] = :"#{singularize(opts[:name])}_pks_dataset"
101
+
102
+ opts[:pks_dataset] = if join_associated_table = opts[:association_pks_use_associated_table]
88
103
  tname = opts[:join_table]
89
104
  lambda do
90
105
  cond = if clpk
@@ -95,16 +110,26 @@ module Sequel
95
110
  rpk = opts.associated_class.primary_key
96
111
  opts.associated_dataset.
97
112
  naked.where(cond).
98
- select_map(Sequel.public_send(rpk.is_a?(Array) ? :deep_qualify : :qualify, opts.associated_class.table_name, rpk))
113
+ select(*Sequel.public_send(rpk.is_a?(Array) ? :deep_qualify : :qualify, opts.associated_class.table_name, rpk))
99
114
  end
100
115
  elsif clpk
101
116
  lambda do
102
117
  cond = lk.zip(lpk).map{|k, pk| [k, get_column_value(pk)]}
103
- _join_table_dataset(opts).where(cond).select_map(rk)
118
+ _join_table_dataset(opts).where(cond).select(*rk)
119
+ end
120
+ else
121
+ lambda do
122
+ _join_table_dataset(opts).where(lk=>get_column_value(lpk)).select(*rk)
123
+ end
124
+ end
125
+
126
+ opts[:pks_getter] = if join_associated_table = opts[:association_pks_use_associated_table]
127
+ lambda do
128
+ public_send(dataset_method).map(opts.associated_class.primary_key)
104
129
  end
105
130
  else
106
131
  lambda do
107
- _join_table_dataset(opts).where(lk=>get_column_value(lpk)).select_map(rk)
132
+ public_send(dataset_method).map(rk)
108
133
  end
109
134
  end
110
135
 
@@ -145,8 +170,14 @@ module Sequel
145
170
 
146
171
  key = opts[:key]
147
172
 
173
+ dataset_method = opts[:pks_dataset_method] = :"#{singularize(opts[:name])}_pks_dataset"
174
+
175
+ opts[:pks_dataset] = lambda do
176
+ public_send(opts[:dataset_method]).select(*opts.associated_class.primary_key)
177
+ end
178
+
148
179
  opts[:pks_getter] = lambda do
149
- public_send(opts[:dataset_method]).select_map(opts.associated_class.primary_key)
180
+ public_send(dataset_method).map(opts.associated_class.primary_key)
150
181
  end
151
182
 
152
183
  unless opts[:read_only]
@@ -207,12 +238,22 @@ module Sequel
207
238
  # Return the primary keys of the associated objects.
208
239
  # If the receiver is a new object, return any saved
209
240
  # pks, or an empty array if no pks have been saved.
210
- def _association_pks_getter(opts)
241
+ def _association_pks_getter(opts, dynamic_opts=OPTS)
242
+ do_cache = opts[:cache_pks]
211
243
  delay = opts.fetch(:delay_pks, true)
212
- if new? && delay
244
+ cache_or_delay = do_cache || delay
245
+
246
+ if dynamic_opts[:refresh] && @_association_pks
247
+ @_association_pks.delete(opts[:name])
248
+ end
249
+
250
+ if new? && cache_or_delay
213
251
  (@_association_pks ||= {})[opts[:name]] ||= []
214
- elsif delay && @_association_pks && (objs = @_association_pks[opts[:name]])
252
+ elsif cache_or_delay && @_association_pks && (objs = @_association_pks[opts[:name]])
215
253
  objs
254
+ elsif do_cache
255
+ # pks_getter_method is private
256
+ (@_association_pks ||= {})[opts[:name]] = send(opts[:pks_getter_method])
216
257
  else
217
258
  # pks_getter_method is private
218
259
  send(opts[:pks_getter_method])
@@ -254,9 +295,10 @@ module Sequel
254
295
 
255
296
  if primary_key.is_a?(Array)
256
297
  if (cols = sch.values_at(*klass.primary_key)).all? && (convs = cols.map{|c| c[:type] == :integer}).all?
298
+ db = model.db
257
299
  pks.map do |cpk|
258
- cpk.zip(convs).map do |pk, conv|
259
- conv ? model.db.typecast_value(:integer, pk) : pk
300
+ cpk.map do |pk|
301
+ db.typecast_value(:integer, pk)
260
302
  end
261
303
  end
262
304
  else
@@ -58,8 +58,7 @@ module Sequel
58
58
  # restricted_columns.
59
59
  def get_setter_methods
60
60
  meths = super
61
- #if !(respond_to?(:allowed_columns) && allowed_columns) && restricted_columns
62
- if (!defined?(::Sequel::Plugins::WhitelistSecurity) || !plugins.include?(::Sequel::Plugins::WhitelistSecurity) || !allowed_columns) && restricted_columns
61
+ if (!defined?(::Sequel::Plugins::WhitelistSecurity::ClassMethods) || !is_a?(::Sequel::Plugins::WhitelistSecurity::ClassMethods) || !allowed_columns) && restricted_columns
63
62
  meths -= restricted_columns.map{|x| "#{x}="}
64
63
  end
65
64
  meths
@@ -289,7 +289,7 @@ module Sequel
289
289
 
290
290
  # The name of the most recently joined table.
291
291
  def cti_table_name
292
- cti_tables ? cti_tables.last : dataset.first_source_alias
292
+ cti_tables.last
293
293
  end
294
294
 
295
295
  # The model class for the given key value.
@@ -310,7 +310,7 @@ module Sequel
310
310
  # Set table if this is a class table inheritance
311
311
  table = nil
312
312
  columns = nil
313
- if (n = subclass.name) && !n.empty?
313
+ if n = subclass.name
314
314
  if table = cti_table_map[n.to_sym]
315
315
  columns = db.schema(table).map(&:first)
316
316
  else
@@ -417,7 +417,7 @@ module Sequel
417
417
  @values[primary_key] ||= nid
418
418
  end
419
419
  end
420
- db.dataset.supports_insert_select? ? nil : @values[primary_key]
420
+ @values[primary_key]
421
421
  end
422
422
 
423
423
  # Update rows in all backing tables, using the columns in each table.
@@ -82,11 +82,13 @@ module Sequel
82
82
  end
83
83
  END
84
84
  else
85
+ # :nocov:
85
86
  # :nodoc:
86
87
  def self.csv_call(*args, opts, &block)
87
88
  CSV.send(*args, opts, &block)
88
89
  end
89
90
  # :nodoc:
91
+ # :nocov:
90
92
  end
91
93
 
92
94
  module ClassMethods
@@ -111,7 +111,9 @@ module Sequel
111
111
  # an association, allow lazy loading that association, since the
112
112
  # lazy association load will use a hash table lookup and not a query.
113
113
  def allow_lazy_load_for_static_cache_associations
114
+ # :nocov:
114
115
  if defined?(::Sequel::Plugins::StaticCache::ClassMethods)
116
+ # :nocov:
115
117
  @association_reflections.each_value do |ref|
116
118
  if ref.associated_class.is_a?(::Sequel::Plugins::StaticCache::ClassMethods)
117
119
  ref[:forbid_lazy_load] = false
@@ -0,0 +1,113 @@
1
+ # frozen-string-literal: true
2
+
3
+ module Sequel
4
+ module Plugins
5
+ # The instance_specific_default plugin exists to make it easier to use a
6
+ # global :instance_specific association option, or to warn or raise when Sequel
7
+ # has to guess which value to use :instance_specific option (Sequel defaults to
8
+ # guessing true as that is the conservative setting). It is helpful to
9
+ # use this plugin, particularly with the :warn or :raise settings, to determine
10
+ # which associations should have :instance_specific set. Setting the
11
+ # :instance_specific to false for associations that are not instance specific
12
+ # can improve performance.
13
+ #
14
+ # Associations are instance-specific if their block calls
15
+ # a model instance method, or where the value of the block varies
16
+ # based on runtime state, and the variance is outside of a delayed evaluation.
17
+ # For example, with the following three associations:
18
+ #
19
+ # Album.one_to_one :first_track, class: :Track do |ds|
20
+ # ds.where(number: 1)
21
+ # end
22
+ #
23
+ # Album.one_to_one :last_track, class: :Track do |ds|
24
+ # ds.where(number: num_tracks)
25
+ # end
26
+ #
27
+ # Album.one_to_many :recent_tracks, class: :Track do |ds|
28
+ # ds.where{date_updated > Date.today - 10}
29
+ # end
30
+ #
31
+ # +first_track+ is not instance specific, but +last_track+ and +recent_tracks+ are.
32
+ # +last_trac+ is because the +num_tracks+ call in the block is calling
33
+ # <tt>Album#num_tracks</tt>. +recent_tracks+ is because the value will change over
34
+ # time. This plugin allows you to find these cases, and set the :instance_specific
35
+ # option appropriately for them:
36
+ #
37
+ # Album.one_to_one :first_track, class: :Track, instance_specific: false do |ds|
38
+ # ds.where(number: 1)
39
+ # end
40
+ #
41
+ # Album.one_to_one :last_track, class: :Track, instance_specific: true do |ds|
42
+ # ds.where(number: num_tracks)
43
+ # end
44
+ #
45
+ # Album.one_to_many :recent_tracks, class: :Track, instance_specific: true do |ds|
46
+ # ds.where{date_updated > Date.today - 10}
47
+ # end
48
+ #
49
+ # For the +recent_tracks+ association, instead of marking it instance_specific, you
50
+ # could also use a delayed evaluation, since it doesn't actually contain
51
+ # instance-specific code:
52
+ #
53
+ # Album.one_to_many :recent_tracks, class: :Track, instance_specific: false do |ds|
54
+ # ds.where{date_updated > Sequel.delay{Date.today - 10}}
55
+ # end
56
+ #
57
+ # Possible arguments to provide when loading the plugin:
58
+ #
59
+ # true :: Set the :instance_specific option to true
60
+ # false :: Set the :instance_specific option to false
61
+ # :default :: Call super to set the :instance_specific option
62
+ # :warn :: Emit a warning before calling super to set the :instance_specific option
63
+ # :raise :: Raise a Sequel::Error if an :instance_specific option is not provided and
64
+ # an association could be instance-specific.
65
+ #
66
+ # Note that this plugin only affects associations which could be instance
67
+ # specific (those with blocks), where the :instance_specific option was not
68
+ # specified when the association was created.
69
+ #
70
+ # Usage:
71
+ #
72
+ # # Set how to handle associations that could be instance specific
73
+ # # but did not specify an :instance_specific option, for all subclasses
74
+ # # (set before creating subclasses).
75
+ # Sequel::Model.plugin :instance_specific_default, :warn
76
+ #
77
+ # # Set how to handle associations that could be instance specific
78
+ # # but did not specify an :instance_specific option, for the Album class
79
+ # Album.plugin :instance_specific_default, :warn
80
+ module InstanceSpecificDefault
81
+ # Set how to handle associations that could be instance specific but did
82
+ # not specify an :instance_specific value.
83
+ def self.configure(model, default)
84
+ model.instance_variable_set(:@instance_specific_default, default)
85
+ end
86
+
87
+ module ClassMethods
88
+ Plugins.inherited_instance_variables(self, :@instance_specific_default=>nil)
89
+
90
+ private
91
+
92
+ # Return the appropriate :instance_specific value, or warn or raise if
93
+ # configured.
94
+ def _association_instance_specific_default(name)
95
+ case @instance_specific_default
96
+ when true, false
97
+ return @instance_specific_default
98
+ when :default
99
+ # nothing
100
+ when :warn
101
+ warn("possibly instance-specific association without :instance_specific option (class: #{self}, association: #{name})", :uplevel => 3)
102
+ when :raise
103
+ raise Sequel::Error, "possibly instance-specific association without :instance_specific option (class: #{self}, association: #{name})"
104
+ else
105
+ raise Sequel::Error, "invalid value passed to instance_specific_default plugin: #{@instance_specific_default.inspect}"
106
+ end
107
+
108
+ super
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -98,7 +98,7 @@ module Sequel
98
98
  end
99
99
 
100
100
  if retrieved_with
101
- raise(Error, "Invalid primary key column for #{model}: #{pkc.inspect}") unless primary_key = model.primary_key
101
+ primary_key = model.primary_key
102
102
  composite_pk = true if primary_key.is_a?(Array)
103
103
  id_map = {}
104
104
  retrieved_with.each{|o| id_map[o.pk] = o unless o.values.has_key?(a) || o.frozen?}
@@ -341,10 +341,9 @@ module Sequel
341
341
  eo[:loader] = false
342
342
 
343
343
  eager_load_results(opts, eo) do |assoc_record|
344
- if pks ||= assoc_record.get_column_value(key)
344
+ if pks = assoc_record.get_column_value(key)
345
345
  pks.each do |pkv|
346
- next unless objects = id_map[pkv]
347
- objects.each do |object|
346
+ id_map[pkv].each do |object|
348
347
  object.associations[name].push(assoc_record)
349
348
  end
350
349
  end
@@ -41,11 +41,9 @@ module Sequel
41
41
  # Create a prepared statement, but modify the SQL used so that the model's columns are explicitly
42
42
  # selected instead of using *, assuming that the dataset selects from a single table.
43
43
  def prepare_explicit_statement(ds, type, vals=OPTS)
44
- f = ds.opts[:from]
45
- meth = type == :insert_select ? :returning : :select
46
- s = ds.opts[meth]
47
- if f && f.length == 1 && !ds.opts[:join] && (!s || s.empty?)
48
- ds = ds.public_send(meth, *columns.map{|c| Sequel.identifier(c)})
44
+ s = ds.opts[:returning]
45
+ if !s || s.empty?
46
+ ds = ds.returning(*columns.map{|c| Sequel.identifier(c)})
49
47
  end
50
48
 
51
49
  prepare_statement(ds, type, vals)
@@ -70,9 +68,7 @@ module Sequel
70
68
  # Return a prepared statement that can be used to insert a row using the given columns
71
69
  # and return that column values for the row created.
72
70
  def prepared_insert_select(cols)
73
- if dataset.supports_insert_select?
74
- cached_prepared_statement(:insert_select, prepared_columns(cols)){prepare_explicit_statement(naked.clone(:server=>dataset.opts.fetch(:server, :default)), :insert_select, prepared_statement_key_hash(cols))}
75
- end
71
+ cached_prepared_statement(:insert_select, prepared_columns(cols)){prepare_explicit_statement(naked.clone(:server=>dataset.opts.fetch(:server, :default)), :insert_select, prepared_statement_key_hash(cols))}
76
72
  end
77
73
 
78
74
  # Return an array of two element arrays with the column symbol as the first entry and the
@@ -138,9 +134,7 @@ module Sequel
138
134
  # and return the new column values.
139
135
  def _insert_select_raw(ds)
140
136
  if use_prepared_statements_for?(:insert_select)
141
- if ps = model.send(:prepared_insert_select, @values.keys)
142
- _set_prepared_statement_server(ps).call(@values)
143
- end
137
+ _set_prepared_statement_server(model.send(:prepared_insert_select, @values.keys)).call(@values)
144
138
  else
145
139
  super
146
140
  end