sequel 5.33.0 → 5.35.0

Sign up to get free protection for your applications and to get access to all the features.
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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b83782f79b268011fa8a7dd3af1f6eefc03a92b58ac7f2cf4f3411ee3a0bc16e
4
- data.tar.gz: '00679a6acd9fef127e040be0ac93666fdf86f6cdf77d9220168e8b7acf13b069'
3
+ metadata.gz: 7ac0d24707f9029714f4e5258c484148d7dc10a733c0c33865d252141cd4cc2e
4
+ data.tar.gz: cdabb1bb51fdfe7b7a22df0a6a9102dd15366bbdd98100907b2e3d74db4e5878
5
5
  SHA512:
6
- metadata.gz: f3502c155f4bc2a38c799e4e633fdd9267add64b80e35ac9c77d01ade6666d294ccb60e5fe6e438e94bf0b94f16127c7c35da1c37a40272eafd9f025474ec17f
7
- data.tar.gz: fd8fde26b14389192787cd59d91def5a9efd4c1b5a8faa2a53c7da16fd479788516a233242548edf0c7901f9080038e9c1a4b967088e7eef4503c82cb153d628
6
+ metadata.gz: d87a7d026c51d8897c964cca01ad30384b853bdbbda42811ee7245ef669ac23c1093e572a0e414db5daeb84b8f417e63c14c3ac13aa0b12ac9eb8f801ea6e6c2
7
+ data.tar.gz: 3e788cabe74d01035b930ca699b5ebc763a6a34410c1b8a3a5075d5a276c5155355d9476303b6b606d1b0a74d6a535ca4fdca696cdc0b83e32658be45c8f946e
data/CHANGELOG CHANGED
@@ -1,3 +1,45 @@
1
+ === 5.35.0 (2020-08-01)
2
+
3
+ * Recognize another disconnect error in the oracle adapter (sterlzbd) (#1705)
4
+
5
+ * Consider all associations with :dataset options as instance-specific associations (jeremyevans)
6
+
7
+ * Make Model.finalize_associations not break with instance-specific associations (jeremyevans)
8
+
9
+ * Make association placeholder loader consider block if instance_specific: false association option is used (jeremyevans)
10
+
11
+ * Copy composite unique constraints when emulating alter table operations on SQLite (jeremyevans) (#1704)
12
+
13
+ * Add instance_specific_default plugin for setting default association :instance_specific value, or warning/raising for cases where it is not specified (jeremyevans)
14
+
15
+ * Make Model.plugin issue deprecation warning if loading plugin with arguments and block if plugin does not accept arguments/block (jeremyevans)
16
+
17
+ * Make validation_class_methods consider all :if, :allow_missing, :allow_nil, and :allow_blank settings, instead of just the first (jeremyevans)
18
+
19
+ * Include hash entries with nil keys in Dataset#to_dot output in to_dot extension (jeremyevans)
20
+
21
+ * Remove unneeded conditionals from plugins and extensions (jeremyevans)
22
+
23
+ * Fix exception class in run_transaction_hooks extension if calling run_after_{commit,rollback}_hooks outside of a transaction (jeremyevans)
24
+
25
+ === 5.34.0 (2020-07-01)
26
+
27
+ * Make eager_graph work correctly if called with no associations (jeremyevans)
28
+
29
+ * Make :ruby eager limit strategy handle cases where there is no limit or offset (jeremyevans)
30
+
31
+ * Do not keep a reference to a Sequel::Database instance that raises an exception during initialization (jeremyevans)
32
+
33
+ * Make Database#pool.all_connections not yield for a single connection pool in disconnected state (jeremyevans)
34
+
35
+ * Raise an exception if trying to disconnect a server that doesn't exist in the sharded connection pools (jeremyevans)
36
+
37
+ * Support :refresh option when calling *_pks getter method in the association_pks plugin (jeremyevans)
38
+
39
+ * Support caching of repeated calls to *_pks getter method in the association_pks plugin using :cache_pks association option (jeremyevans)
40
+
41
+ * Add *_pks_dataset methods for one_to_many and many_to_many associations when using the association_pks plugin (jeremyevans)
42
+
1
43
  === 5.33.0 (2020-06-01)
2
44
 
3
45
  * Support custom join types on a per-association basis when using eager_graph/association_join (jeremyevans)
@@ -1676,11 +1676,16 @@ instances.
1676
1676
  ==== :instance_specific
1677
1677
 
1678
1678
  This allows you to override the setting of whether the dataset contains instance
1679
- specific code. For example, if you are passing a block to the association,
1679
+ specific code. If you are passing a block to the association,
1680
1680
  Sequel sets this to true by default, which disables some optimizations that
1681
1681
  would be invalid if the association is instance specific. If you know that the
1682
1682
  block does not contain instance specific code, you can set this to false to
1683
- reenable the optimizations.
1683
+ reenable the optimizations. Instance specific code is mostly commonly calling
1684
+ model instance methods inside an association block, but also
1685
+ includes cases where the association block can return different values based
1686
+ on the runtime environment, such as calls to <tt>Time.now</tt> in the block.
1687
+ Associations that use the :dataset option are always considered instance specific,
1688
+ even if explicitly specified otherwise.
1684
1689
 
1685
1690
  ==== :cartesian_product_number
1686
1691
 
@@ -36,8 +36,8 @@ Ranges (both inclusive and exclusive) can also be used:
36
36
 
37
37
  If you need to select multiple items from a dataset, you can supply an array:
38
38
 
39
- items.where(id: [1, 38, 47, 99]).sql
40
- # "SELECT * FROM items WHERE (id IN (1, 38, 47, 99))"
39
+ items.where(id: [1, 38, 47, 99]).sql
40
+ # "SELECT * FROM items WHERE (id IN (1, 38, 47, 99))"
41
41
 
42
42
  == Filtering using expressions
43
43
 
@@ -0,0 +1,40 @@
1
+ = New Features
2
+
3
+ * The association_pks plugin now creates *_pks_dataset methods for
4
+ each association. These are similar to the existing *_pks getter
5
+ methods, but they return a dataset of the keys instead of the keys
6
+ themselves.
7
+
8
+ * The association_pks plugin now supports a :cache_pks association
9
+ option, which will cache calls to the *_pks getter method. The
10
+ default behavior remains that the *_pks getter method only returns
11
+ cached values if the *_pks= setter method has been used to set the
12
+ values.
13
+
14
+ * The *_pks getter methods supported by the association_pks plugin
15
+ now support a :refresh option to ignore any cached values, similar
16
+ to how the association getter methods work.
17
+
18
+ = Other Improvements
19
+
20
+ * If trying to disconnect a server that doesn't exist when using a
21
+ sharded connection pool, a Sequel::Error is now raised. Previously,
22
+ the sharded threaded pool raised a NoMethodError and the sharded
23
+ single connection pool did not raise an error.
24
+
25
+ * If using the :savepoint option when savepoints are not supported,
26
+ a Sequel::InvalidOperation exception is now raised, instead of a
27
+ NoMethodError.
28
+
29
+ * Calling Dataset#eager_graph with no arguments now returns the
30
+ dataset.
31
+
32
+ * If not connected to the database, the single connection pool will
33
+ not yield any connections to Database#pool.all_connections.
34
+
35
+ * Forcing a :ruby eager limit strategy for an association without a
36
+ limit or offset now works correctly.
37
+
38
+ * Multiple unnecessary conditionals have been removed.
39
+
40
+ * Sequel core and model code now have 100% branch coverage.
@@ -0,0 +1,56 @@
1
+ = New Features
2
+
3
+ * An instance_specific_default plugin has been added for setting the
4
+ default for the :instance_specific association option, or
5
+ warning/raises in cases where it is not specified. This allows
6
+ you to easily find associations that would be considering instance
7
+ specific by default, and mark them as not instance specific for
8
+ better performance.
9
+
10
+ = Other Improvements
11
+
12
+ * Setting the :instance_specific association option to false now
13
+ works correctly if the association uses a block. Associations
14
+ that set the :dataset option are now always considered instance
15
+ specific, even if the :instance_specific option is explicitly
16
+ passed.
17
+
18
+ * The validation_class_methods plugin now considers all :if,
19
+ :allow_missing, :allow_nil, and :allow_blank options. Previously,
20
+ it only considered the first of those options that was set.
21
+
22
+ * Model.finalize_associations no longer breaks if you have
23
+ instance-specific associations.
24
+
25
+ * Model.plugin now warns if you load the plugin with arguments or a
26
+ block if the plugin does not accept arguments or block. This is
27
+ because a future change to Sequel could break the call.
28
+
29
+ * When emulating unsupported alter table operations on SQLite, Sequel
30
+ now copies composite unique constraints unless the alter table
31
+ operation is the dropping of a unique constraint.
32
+
33
+ * Sequel now recognizes an additional disconnect error in the oracle
34
+ adapter.
35
+
36
+ * In the run_transaction_hooks extension, calling
37
+ run_after_{commit,rollback}_hooks now raises the correct exception
38
+ class.
39
+
40
+ * In the pg_range extension, conversion procs for the tsrange[] and
41
+ tstzrange[] types are not added unless the Database uses the
42
+ pg_array extension.
43
+
44
+ * Multiple unnecessary conditionals in plugins and extensions have
45
+ been removed.
46
+
47
+ * Sequel plugin and extension code now have 100% branch coverage.
48
+
49
+ * Sequel now avoids a statement not reached verbose warning in
50
+ Dataset#clone.
51
+
52
+ = Backwards Compatibility
53
+
54
+ * The output of Dataset#to_dot in the to_dot extension has changed
55
+ slightly, including hash entries with nil keys. These entries
56
+ were previously ignored.
@@ -14,7 +14,8 @@ module Sequel
14
14
  # ORA-02396: exceeded maximum idle time, please connect again
15
15
  # ORA-03113: end-of-file on communication channel
16
16
  # ORA-03114: not connected to ORACLE
17
- CONNECTION_ERROR_CODES = [ 28, 1012, 2396, 3113, 3114 ].freeze
17
+ # ORA-03135: connection lost contact
18
+ CONNECTION_ERROR_CODES = [ 28, 1012, 2396, 3113, 3114, 3135 ].freeze
18
19
 
19
20
  ORACLE_TYPES = {
20
21
  :blob=>lambda{|b| Sequel::SQL::Blob.new(b.read)},
@@ -269,6 +269,8 @@ module Sequel
269
269
  else
270
270
  duplicate_table(table, :no_foreign_keys=>true)
271
271
  end
272
+ when :unique
273
+ duplicate_table(table, :no_unique=>true)
272
274
  else
273
275
  duplicate_table(table)
274
276
  end
@@ -422,8 +424,12 @@ module Sequel
422
424
  skip_indexes = []
423
425
  indexes(table, :only_autocreated=>true).each do |name, h|
424
426
  skip_indexes << name
425
- if h[:columns].length == 1 && h[:unique]
426
- unique_columns.concat(h[:columns])
427
+ if h[:unique]
428
+ if h[:columns].length == 1
429
+ unique_columns.concat(h[:columns])
430
+ elsif h[:columns].map(&:to_s) != pks && !opts[:no_unique]
431
+ constraints << {:type=>:unique, :columns=>h[:columns]}
432
+ end
427
433
  end
428
434
  end
429
435
  unique_columns -= pks
@@ -16,6 +16,7 @@ module Sequel
16
16
  c = TinyTds::Client.new(opts)
17
17
  c.query_options.merge!(:cache_rows=>false)
18
18
 
19
+ # SEQUEL6: Default to ansi: true
19
20
  if opts[:ansi]
20
21
  sql = %w(
21
22
  ANSI_NULLS
@@ -41,7 +41,10 @@ class Sequel::ShardedSingleConnectionPool < Sequel::ConnectionPool
41
41
  # :server :: Should be a symbol specifing the server to disconnect from,
42
42
  # or an array of symbols to specify multiple servers.
43
43
  def disconnect(opts=OPTS)
44
- (opts[:server] ? Array(opts[:server]) : servers).each{|s| disconnect_server(s)}
44
+ (opts[:server] ? Array(opts[:server]) : servers).each do |s|
45
+ raise Sequel::Error, "invalid server: #{s}" unless @servers.has_key?(s)
46
+ disconnect_server(s)
47
+ end
45
48
  end
46
49
 
47
50
  def freeze
@@ -95,9 +95,7 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool
95
95
  # or an array of symbols to specify multiple servers.
96
96
  def disconnect(opts=OPTS)
97
97
  (opts[:server] ? Array(opts[:server]) : sync{@servers.keys}).each do |s|
98
- if conns = sync{disconnect_server_connections(s)}
99
- disconnect_connections(conns)
100
- end
98
+ disconnect_connections(sync{disconnect_server_connections(s)})
101
99
  end
102
100
  end
103
101
 
@@ -203,9 +201,9 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool
203
201
 
204
202
  until conn = assign_connection(thread, server)
205
203
  elapsed = Sequel.elapsed_seconds_since(timer)
204
+ # :nocov:
206
205
  raise_pool_timeout(elapsed, server) if elapsed > timeout
207
206
 
208
- # :nocov:
209
207
  # It's difficult to get to this point, it can only happen if there is a race condition
210
208
  # where a connection cannot be acquired even after the thread is signalled by the condition variable
211
209
  sync do
@@ -278,13 +276,15 @@ class Sequel::ShardedThreadedConnectionPool < Sequel::ThreadedConnectionPool
278
276
  # Mark any allocated connections to be removed when they are checked back in. The calling
279
277
  # code should already have the mutex before calling this.
280
278
  def disconnect_server_connections(server)
281
- @connections_to_remove.concat(allocated(server).values)
279
+ remove_conns = allocated(server)
280
+ dis_conns = available_connections(server)
281
+ raise Sequel::Error, "invalid server: #{server}" unless remove_conns && dis_conns
282
282
 
283
- if dis_conns = available_connections(server)
284
- conns = dis_conns.dup
285
- dis_conns.clear
286
- @waiters[server].signal
287
- end
283
+ @connections_to_remove.concat(remove_conns.values)
284
+
285
+ conns = dis_conns.dup
286
+ dis_conns.clear
287
+ @waiters[server].signal
288
288
  conns
289
289
  end
290
290
 
@@ -11,7 +11,7 @@ class Sequel::SingleConnectionPool < Sequel::ConnectionPool
11
11
 
12
12
  # Yield the connection if one has been made.
13
13
  def all_connections
14
- yield @conn.first if @conn
14
+ yield @conn.first unless @conn.empty?
15
15
  end
16
16
 
17
17
  # Disconnect the connection from the database.
@@ -152,9 +152,9 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
152
152
 
153
153
  until conn = assign_connection(thread)
154
154
  elapsed = Sequel.elapsed_seconds_since(timer)
155
+ # :nocov:
155
156
  raise_pool_timeout(elapsed) if elapsed > timeout
156
157
 
157
- # :nocov:
158
158
  # It's difficult to get to this point, it can only happen if there is a race condition
159
159
  # where a connection cannot be acquired even after the thread is signalled by the condition variable
160
160
  sync do
@@ -36,7 +36,7 @@ module Sequel
36
36
  c = adapter_class(scheme)
37
37
  uri_options = c.send(:uri_to_options, uri)
38
38
  uri.query.split('&').map{|s| s.split('=')}.each{|k,v| uri_options[k.to_sym] = v if k && !k.empty?} unless uri.query.to_s.strip.empty?
39
- uri_options.to_a.each{|k,v| uri_options[k] = (defined?(URI::DEFAULT_PARSER) ? URI::DEFAULT_PARSER : URI).unescape(v) if v.is_a?(String)}
39
+ uri_options.to_a.each{|k,v| uri_options[k] = URI::DEFAULT_PARSER.unescape(v) if v.is_a?(String)}
40
40
  opts = uri_options.merge(opts).merge!(:orig_opts=>opts.dup, :uri=>conn_string, :adapter=>scheme)
41
41
  end
42
42
  when Hash
@@ -153,19 +153,23 @@ module Sequel
153
153
  reset_default_dataset
154
154
  adapter_initialize
155
155
 
156
- unless typecast_value_boolean(@opts[:keep_reference]) == false
157
- Sequel.synchronize{::Sequel::DATABASES.push(self)}
158
- end
159
- Sequel::Database.run_after_initialize(self)
156
+ keep_reference = typecast_value_boolean(@opts[:keep_reference]) != false
157
+ begin
158
+ Sequel.synchronize{::Sequel::DATABASES.push(self)} if keep_reference
159
+ Sequel::Database.run_after_initialize(self)
160
160
 
161
- initialize_load_extensions(:preconnect_extensions)
161
+ initialize_load_extensions(:preconnect_extensions)
162
162
 
163
- if typecast_value_boolean(@opts[:preconnect]) && @pool.respond_to?(:preconnect, true)
164
- concurrent = typecast_value_string(@opts[:preconnect]) == "concurrently"
165
- @pool.send(:preconnect, concurrent)
166
- end
163
+ if typecast_value_boolean(@opts[:preconnect]) && @pool.respond_to?(:preconnect, true)
164
+ concurrent = typecast_value_string(@opts[:preconnect]) == "concurrently"
165
+ @pool.send(:preconnect, concurrent)
166
+ end
167
167
 
168
- initialize_load_extensions(:extensions)
168
+ initialize_load_extensions(:extensions)
169
+ rescue
170
+ Sequel.synchronize{::Sequel::DATABASES.delete(self)} if keep_reference
171
+ raise
172
+ end
169
173
  end
170
174
 
171
175
  # Freeze internal data structures for the Database instance.
@@ -185,7 +189,9 @@ module Sequel
185
189
 
186
190
  # Disallow dup/clone for Database instances
187
191
  undef_method :dup, :clone, :initialize_copy
192
+ # :nocov:
188
193
  if RUBY_VERSION >= '1.9.3'
194
+ # :nocov:
189
195
  undef_method :initialize_clone, :initialize_dup
190
196
  end
191
197
 
@@ -344,7 +344,9 @@ module Sequel
344
344
 
345
345
  # Post process the schema values.
346
346
  def schema_post_process(cols)
347
+ # :nocov:
347
348
  if RUBY_VERSION >= '2.5'
349
+ # :nocov:
348
350
  cols.each do |_, h|
349
351
  db_type = h[:db_type]
350
352
  if db_type.is_a?(String)
@@ -38,7 +38,6 @@ module Sequel
38
38
  @constraints = []
39
39
  @primary_key = nil
40
40
  instance_exec(&block) if block
41
- @columns.unshift(@primary_key) if @primary_key && !has_column?(primary_key_name)
42
41
  end
43
42
 
44
43
  # Use custom Bignum method to use :Bignum instead of Bignum class, to work
@@ -494,7 +494,9 @@ module Sequel
494
494
  when :drop_index
495
495
  drop_index_sql(table, op)
496
496
  else
497
- "ALTER TABLE #{quote_schema_table(table)} #{alter_table_op_sql(table, op)}"
497
+ if sql = alter_table_op_sql(table, op)
498
+ "ALTER TABLE #{quote_schema_table(table)} #{sql}"
499
+ end
498
500
  end
499
501
  end
500
502
 
@@ -811,23 +813,20 @@ module Sequel
811
813
  # Proxy the filter_expr call to the dataset, used for creating constraints.
812
814
  # Support passing Proc arguments as blocks, as well as treating plain strings
813
815
  # as literal strings, so that previous migrations that used this API do not break.
814
- def filter_expr(*args, &block)
815
- if args.length == 1
816
- arg = args.first
817
- if arg.is_a?(Proc) && !block
818
- block = args.first
819
- args = nil
820
- elsif arg.is_a?(String)
821
- args = [Sequel.lit(*args)]
822
- elsif arg.is_a?(Array)
823
- if arg.first.is_a?(String)
824
- args = [Sequel.lit(*arg)]
825
- elsif arg.length > 1
826
- args = [Sequel.&(*arg)]
827
- end
816
+ def filter_expr(arg=nil, &block)
817
+ if arg.is_a?(Proc) && !block
818
+ block = arg
819
+ arg = nil
820
+ elsif arg.is_a?(String)
821
+ arg = Sequel.lit(arg)
822
+ elsif arg.is_a?(Array)
823
+ if arg.first.is_a?(String)
824
+ arg = Sequel.lit(*arg)
825
+ elsif arg.length > 1
826
+ arg = Sequel.&(*arg)
828
827
  end
829
828
  end
830
- schema_utility_dataset.literal(schema_utility_dataset.send(:filter_expr, *args, &block))
829
+ schema_utility_dataset.literal(schema_utility_dataset.send(:filter_expr, arg, &block))
831
830
  end
832
831
 
833
832
  # SQL statement for creating an index for the table with the given name
@@ -205,6 +205,10 @@ module Sequel
205
205
  end
206
206
  end
207
207
 
208
+ if opts[:savepoint] && !supports_savepoints?
209
+ raise Sequel::InvalidOperation, "savepoints not supported on #{database_type}"
210
+ end
211
+
208
212
  if already_in_transaction?(conn, opts)
209
213
  if opts[:rollback] == :always && !opts.has_key?(:savepoint)
210
214
  if supports_savepoints?
@@ -418,11 +422,10 @@ module Sequel
418
422
  end
419
423
 
420
424
  # Retrieve the savepoint hooks that should be run for the given
421
- # connection and commit status.
425
+ # connection and commit status. This expacts that you are
426
+ # already inside a savepoint when calling.
422
427
  def savepoint_hooks(conn, committed)
423
- if in_savepoint?(conn)
424
- _trans(conn)[:savepoints].last[committed ? :after_commit : :after_rollback]
425
- end
428
+ _trans(conn)[:savepoints].last[committed ? :after_commit : :after_rollback]
426
429
  end
427
430
 
428
431
  # Retrieve the transaction hooks that should be run for the given