sequel 5.63.0 → 5.65.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: abbe367cded9066a40aee5dd911a9b915f580264d00e6b668fad956bb94e38ef
4
- data.tar.gz: 40ab8f35b0129177b550469f5ce9b6b6fccbcc97bdcfb3b06a2d8528bca37432
3
+ metadata.gz: 24bfe7c123337539140b0385dd9a828fe0fec4d6ad4e39e5fd8f150258ae7a03
4
+ data.tar.gz: d820be46e60ba7b08b1129f0a6b67a24a550a27d5b682a84730172bc256f4118
5
5
  SHA512:
6
- metadata.gz: 87a17fc09f790b81df75fb7d170f851c9607a0f45abf6fc50c21f50243e418362fe7c804521bfe06a12e32656e234c7e79469d40d365436edad0a2e9c176a335
7
- data.tar.gz: ee366f061a808d7983c2996dd969f834b74815e2a1ed77410f0bdc32f822dad72dee3c48a9ad22b6f77d791d8dc43de8bc0b4619929ac5870976495774959a7b
6
+ metadata.gz: bd5c7dacdf48f8ada7c34c88210ac804faa1b47741f946ca16cd6f645c1f86055eb85ac6b601e9cef2ab4aa8a5cba3dc444e3005d6ed61d324c1158f2e03a70e
7
+ data.tar.gz: d17eb580a3f50f4b0c33561aed320c2ea3089044b905f4dc845ea8682afe1cdbf2798c6cd202f1233b1d168d06c9686a94728d41e0f47264245a33da5a99b251
data/CHANGELOG CHANGED
@@ -1,3 +1,21 @@
1
+ === 5.65.0 (2023-02-01)
2
+
3
+ * Allow pg_auto_parameterize extension to use placeholder loaders (jeremyevans)
4
+
5
+ * Do not include :min_value and :max_value schema entries for decimal/numeric columns on MySQL versions not supporting check constraints (jeremyevans)
6
+
7
+ * Make Database#indexes return indexes for partitioned tables on PostgreSQL 11+ (jeremyevans)
8
+
9
+ === 5.64.0 (2023-01-01)
10
+
11
+ * Make :db_type column schema entries on SQLAnywhere include precision/scale information (jeremyevans)
12
+
13
+ * Include :min_value and :max_value schema entries for decimal/numeric columns on most databases (rolftimmermans, jeremyevans) (#1975)
14
+
15
+ * Support :graph_use_association_block association option to make eager_graph use the association block (jeremyevans)
16
+
17
+ * Make many_through_many and many_through_one associations support eager_graph callbacks (jeremyevans)
18
+
1
19
  === 5.63.0 (2022-12-01)
2
20
 
3
21
  * Make validates_associated plugin avoid database type errors for non-integer association keys (jeremyevans) (#1968)
data/MIT-LICENSE CHANGED
@@ -1,5 +1,5 @@
1
1
  Copyright (c) 2007-2008 Sharon Rosner
2
- Copyright (c) 2008-2022 Jeremy Evans
2
+ Copyright (c) 2008-2023 Jeremy Evans
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  of this software and associated documentation files (the "Software"), to
@@ -864,14 +864,14 @@ You can set this to +nil+ to not create a remove_all_<i>association</i> method.
864
864
 
865
865
  === :no_dataset_method
866
866
 
867
- Setting this to true will not result in the <i>association</i>_dataset method
867
+ Setting this to true will result in the <i>association</i>_dataset method
868
868
  not being defined. This can save memory if you only use the <i>association</i>
869
869
  method and do not call the <i>association</i>_dataset method directly or
870
870
  indirectly.
871
871
 
872
872
  === :no_association_method
873
873
 
874
- Setting this to true will not result in the <i>association</i> method
874
+ Setting this to true will result in the <i>association</i> method
875
875
  not being defined. This can save memory if you only use the
876
876
  <i>association</i>_dataset method and do not call the <i>association</i> method
877
877
  directly or indirectly.
@@ -1498,6 +1498,36 @@ as the qualifiers may not match the aliases automatically used by eager_graph.
1498
1498
  This should contain unqualified identifiers, and eager_graph will automatically
1499
1499
  qualify them with the appropriate alias.
1500
1500
 
1501
+ ==== :graph_use_association_block
1502
+
1503
+ Setting this to true makes eager_graph apply the association block to the
1504
+ associated dataset before graphing the associated dataset into the receiver.
1505
+ In most cases when this option is used and the association has a block, the
1506
+ dataset returned by eager_graph will contain a JOIN to a subquery.
1507
+
1508
+ By default (when this option is not used), the association block will be ignored
1509
+ when using eager_graph:
1510
+
1511
+ Artist.one_to_many :tracks do |ds|
1512
+ ds.where(foo: 3)
1513
+ end
1514
+ Artist.eager_graph(:tracks)
1515
+ # SELECT albums.id, tracks.id AS tracks_id, tracks.album_id
1516
+ # FROM albums
1517
+ # LEFT OUTER JOIN tracks
1518
+ # ON (tracks.album_id = albums.id)
1519
+
1520
+ When this option is used, the block will be respected:
1521
+
1522
+ Artist.one_to_many :tracks, graph_use_association_block: true do |ds|
1523
+ ds.where(foo: 3)
1524
+ end
1525
+ Artist.eager_graph(:tracks)
1526
+ # SELECT albums.id, tracks.id AS tracks_id, tracks.album_id
1527
+ # FROM albums
1528
+ # LEFT OUTER JOIN (SELECT * FROM tracks WHERE (foo = 3)) AS tracks
1529
+ # ON (tracks.album_id = albums.id)
1530
+
1501
1531
  ==== :graph_join_table_conditions [+many_to_many+, +one_through_one+]
1502
1532
 
1503
1533
  The additional conditions to use on the SQL join for the join table when
@@ -0,0 +1,50 @@
1
+ = New Features
2
+
3
+ * A :graph_use_association_block association option has been added,
4
+ which makes eager_graph use the association block (as eager does),
5
+ generally resulting in a JOIN to a subquery:
6
+
7
+ Artist.one_to_many :tracks, graph_use_association_block: true do |ds|
8
+ ds.where(foo: 3)
9
+ end
10
+ Artist.eager_graph(:tracks)
11
+ # SELECT albums.id, tracks.id AS tracks_id, tracks.album_id
12
+ # FROM albums
13
+ # LEFT OUTER JOIN (SELECT * FROM tracks WHERE (foo = 3)) AS tracks
14
+ # ON (tracks.album_id = albums.id)
15
+
16
+ Assuming that the database can optimize the query correctly, using
17
+ the :graph_use_association_block option is probably simpler than
18
+ than using other :graph_* options to duplicate the conditions added
19
+ by the association block.
20
+
21
+ * Numeric/Decimal column schema entries now include :min_value and
22
+ :max_value entries on most databases, indicating the minimum and
23
+ maximum values supported for the column. Similar to the support
24
+ for integer columns added in 5.62.0, this allows the
25
+ auto_validations plugin to automatically validate the values of
26
+ the columns are in the allowed range.
27
+
28
+ = Other Improvements
29
+
30
+ * many_through_{one,many} associations now support eager_graph
31
+ callbacks.
32
+
33
+ * The :db_type column schema entries on SQLAnywhere now include
34
+ precision/scale information, to work with the numeric/decimal
35
+ column min_value/max_value support.
36
+
37
+ * The oracle adapter now includes a :column_size column schema
38
+ entry containing the precision of the columns, to work with the
39
+ numeric/decimal column min_value/max_value support.
40
+
41
+ = Backwards Compatibility
42
+
43
+ * The private Database#column_schema_integer_min_max_values method
44
+ added in 5.62.0 now takes a column schema hash instead of a
45
+ database type string.
46
+
47
+ * Code that previously looked at the :db_type column schema entry on
48
+ SQLAnywhere should be updated to look at the :domain_name entry, and
49
+ code that looked at the :domain_name_with_size entry should be
50
+ updated to look at the :db_type entry.
@@ -0,0 +1,21 @@
1
+ = Improvements
2
+
3
+ * The pg_auto_parameterize extension now uses a modified placeholder
4
+ literalizer for speeding up the generation of SQL queries in the same
5
+ cases where a standard dataset would use a placeholder literalizer.
6
+ This can provide a 4% speedup for simple queries, with greater
7
+ speedups for more complex queries.
8
+
9
+ * Database#indexes now returns indexes for partitioned tables on
10
+ PostgreSQL 11+.
11
+
12
+ * MySQL versions not supporting CHECK constraints no longer include
13
+ :min_value/:max_value schema entries for decimal/numeric columns.
14
+
15
+ = Backwards Compatibility
16
+
17
+ * The Dataset::PlaceholderLiterlizer::Record.loader API has changed,
18
+ it now accepts the Dataset::PlaceholderLiterlizer class to use as
19
+ the first argument. This makes it easier to create
20
+ Dataset::PlaceholderLiterlizer subclasses, such as the one now used
21
+ by the pg_auto_parameterize extension.
data/doc/sql.rdoc CHANGED
@@ -59,7 +59,7 @@ Then, you call the +insert+, +update+, or +delete+ method on the returned datase
59
59
  update_ds.update
60
60
  delete_ds.delete
61
61
 
62
- +update+ and +delete+ should return the number of rows affected, and +insert+ should return the autogenerated primary key integer for the row inserted (if any).
62
+ +update+ and +delete+ generally return the number of rows affected, and +insert+ generally returns the autogenerated primary key integer for the row inserted (if any), but not all adapters/databases support this behavior for datasets using custom SQL (notably it is not supported for +insert+ on PostgreSQL).
63
63
 
64
64
  === Other Queries
65
65
 
@@ -312,6 +312,7 @@ module Sequel
312
312
  :char_used => column.char_used?,
313
313
  :char_size => column.char_size,
314
314
  :data_size => column.data_size,
315
+ :column_size => column.precision,
315
316
  :precision => column.precision,
316
317
  :scale => column.scale,
317
318
  :fsprecision => column.fsprecision,
@@ -60,8 +60,8 @@ module Sequel
60
60
  # Access's Byte type will accept much larger values,
61
61
  # even though it only stores 0-255. Do not set min/max
62
62
  # values for the Byte type.
63
- def column_schema_integer_min_max_values(db_type)
64
- return if /byte/i =~ db_type
63
+ def column_schema_integer_min_max_values(column)
64
+ return if /byte/i =~ column[:db_type]
65
65
  super
66
66
  end
67
67
 
@@ -553,7 +553,14 @@ module Sequel
553
553
  # Return nil if CHECK constraints are not supported, because
554
554
  # versions that don't support check constraints don't raise
555
555
  # errors for values outside of range.
556
- def column_schema_integer_min_max_values(db_type)
556
+ def column_schema_integer_min_max_values(column)
557
+ super if supports_check_constraints?
558
+ end
559
+
560
+ # Return nil if CHECK constraints are not supported, because
561
+ # versions that don't support check constraints don't raise
562
+ # errors for values outside of range.
563
+ def column_schema_decimal_min_max_values(column)
557
564
  super if supports_check_constraints?
558
565
  end
559
566
 
@@ -178,11 +178,11 @@ module Sequel
178
178
  ''
179
179
  end
180
180
 
181
- # Do not support min/max integer values on Oracle, since
182
- # Oracle uses a number type, and integer just adds a
183
- # constaint on the number type.
184
- def column_schema_integer_min_max_values(db_type)
185
- nil
181
+ # Support min/max integer values on Oracle only if
182
+ # they use a NUMBER column with a fixed precision
183
+ # and no scale.
184
+ def column_schema_integer_min_max_values(column)
185
+ super if column[:db_type] =~ /NUMBER\(\d+\)/i || (column[:db_type] == 'NUMBER' && column[:column_size].is_a?(Integer) && column[:scale] == 0)
186
186
  end
187
187
 
188
188
  def create_sequence_sql(name, opts=OPTS)
@@ -919,7 +919,7 @@ module Sequel
919
919
  join(Sequel[:pg_attribute].as(:att), :attrelid=>Sequel[:tab][:oid], :attnum=>attnums).
920
920
  left_join(Sequel[:pg_constraint].as(:con), :conname=>Sequel[:indc][:relname]).
921
921
  where{{
922
- indc[:relkind]=>'i',
922
+ indc[:relkind]=>%w'i I',
923
923
  ind[:indisprimary]=>false,
924
924
  :indexprs=>nil,
925
925
  :indisvalid=>true}}.
@@ -37,7 +37,7 @@ module Sequel
37
37
  row[:auto_increment] = auto_increment == 1 || auto_increment == true
38
38
  row[:primary_key] = row.delete(:pkey) == 'Y'
39
39
  row[:allow_null] = row[:nulls_allowed].is_a?(Integer) ? row.delete(:nulls_allowed) == 1 : row.delete(:nulls_allowed)
40
- row[:db_type] = row.delete(:domain_name)
40
+ row[:db_type] = row.delete(:domain_name_with_size)
41
41
  row[:type] = if row[:db_type] =~ /numeric/i and (row[:scale].is_a?(Integer) ? row[:scale] == 0 : !row[:scale])
42
42
  :integer
43
43
  else
@@ -320,10 +320,11 @@ module Sequel
320
320
  end
321
321
  end
322
322
 
323
- # SQLite does not restrict the integer type to a specific range.
324
- def column_schema_integer_min_max_values(db_type)
323
+ # SQLite does not restrict the integer or decimal type to a specific range.
324
+ def column_schema_integer_min_max_values(column)
325
325
  nil
326
326
  end
327
+ alias column_schema_decimal_min_max_values column_schema_integer_min_max_values
327
328
 
328
329
  # Array of PRAGMA SQL statements based on the Database options that should be applied to
329
330
  # new connections.
@@ -175,8 +175,14 @@ module Sequel
175
175
  if !c[:max_length] && c[:type] == :string && (max_length = column_schema_max_length(c[:db_type]))
176
176
  c[:max_length] = max_length
177
177
  end
178
- if !c[:max_value] && !c[:min_value] && c[:type] == :integer && (min_max = column_schema_integer_min_max_values(c[:db_type]))
179
- c[:min_value], c[:max_value] = min_max
178
+ if !c[:max_value] && !c[:min_value]
179
+ min_max = case c[:type]
180
+ when :integer
181
+ column_schema_integer_min_max_values(c)
182
+ when :decimal
183
+ column_schema_decimal_min_max_values(c)
184
+ end
185
+ c[:min_value], c[:max_value] = min_max if min_max
180
186
  end
181
187
  end
182
188
  schema_post_process(cols)
@@ -288,7 +294,15 @@ module Sequel
288
294
 
289
295
  # Look at the db_type and guess the minimum and maximum integer values for
290
296
  # the column.
291
- def column_schema_integer_min_max_values(db_type)
297
+ def column_schema_integer_min_max_values(column)
298
+ db_type = column[:db_type]
299
+ if /decimal|numeric|number/i =~ db_type
300
+ if min_max = column_schema_decimal_min_max_values(column)
301
+ min_max.map!(&:to_i)
302
+ end
303
+ return min_max
304
+ end
305
+
292
306
  unsigned = /unsigned/i =~ db_type
293
307
  case db_type
294
308
  when /big|int8/i
@@ -304,6 +318,26 @@ module Sequel
304
318
  end
305
319
  end
306
320
 
321
+ # Look at the db_type and guess the minimum and maximum decimal values for
322
+ # the column.
323
+ def column_schema_decimal_min_max_values(column)
324
+ if column[:column_size] && column[:scale]
325
+ precision = column[:column_size]
326
+ scale = column[:scale]
327
+ elsif /\((\d+)(?:,\s*(-?\d+))?\)/ =~ column[:db_type]
328
+ precision = $1.to_i
329
+ scale = $2.to_i if $2
330
+ end
331
+
332
+ if precision
333
+ limit = BigDecimal("9" * precision)
334
+ if scale
335
+ limit /= 10**(scale)
336
+ end
337
+ [-limit, limit]
338
+ end
339
+ end
340
+
307
341
  # Whether the tinyint type (if supported by the database) is unsigned by default.
308
342
  def column_schema_tinyint_type_is_unsigned?
309
343
  false
@@ -370,7 +404,7 @@ module Sequel
370
404
  :boolean
371
405
  when /\A(real|float( unsigned)?|double( precision)?|double\(\d+,\d+\)( unsigned)?)\z/io
372
406
  :float
373
- when /\A(?:(?:(?:num(?:ber|eric)?|decimal)(?:\(\d+,\s*(\d+|false|true)\))?))\z/io
407
+ when /\A(?:(?:(?:num(?:ber|eric)?|decimal)(?:\(\d+,\s*(-?\d+|false|true)\))?))\z/io
374
408
  $1 && ['0', 'false'].include?($1) ? :integer : :decimal
375
409
  when /bytea|blob|image|(var)?binary/io
376
410
  :blob
@@ -158,6 +158,16 @@ module Sequel
158
158
  !!((opts[:from].is_a?(Array) && opts[:from].size > 1) || opts[:join])
159
159
  end
160
160
 
161
+ # The class to use for placeholder literalizers for the current dataset.
162
+ def placeholder_literalizer_class
163
+ ::Sequel::Dataset::PlaceholderLiteralizer
164
+ end
165
+
166
+ # A placeholder literalizer loader for the current dataset.
167
+ def placeholder_literalizer_loader(&block)
168
+ placeholder_literalizer_class.loader(self, &block)
169
+ end
170
+
161
171
  # The alias to use for the row_number column, used when emulating OFFSET
162
172
  # support and for eager limit strategies
163
173
  def row_number_column
@@ -296,7 +306,7 @@ module Sequel
296
306
  loader += 1
297
307
 
298
308
  if loader >= 3
299
- loader = Sequel::Dataset::PlaceholderLiteralizer.loader(self){|pl, _| yield pl}
309
+ loader = placeholder_literalizer_loader{|pl, _| yield pl}
300
310
  cache_set(key, loader)
301
311
  else
302
312
  cache_set(key, loader + 1)
@@ -77,8 +77,8 @@ module Sequel
77
77
  # Yields the receiver and the dataset to the block, which should
78
78
  # call #arg on the receiver for each placeholder argument, and
79
79
  # return the dataset that you want to load.
80
- def loader(dataset, &block)
81
- PlaceholderLiteralizer.new(*process(dataset, &block))
80
+ def loader(pl, dataset, &block)
81
+ pl.new(*process(dataset, &block))
82
82
  end
83
83
 
84
84
  # Return an Argument with the specified position, or the next position. In
@@ -145,7 +145,7 @@ module Sequel
145
145
  # given block, recording the offsets at which the recorders arguments
146
146
  # are used in the query.
147
147
  def self.loader(dataset, &block)
148
- Recorder.new.loader(dataset, &block)
148
+ Recorder.new.loader(self, dataset, &block)
149
149
  end
150
150
 
151
151
  # Save the dataset, array of SQL fragments, and ending SQL string.
@@ -199,20 +199,31 @@ module Sequel
199
199
  # Return the SQL query to use for the given arguments.
200
200
  def sql(*args)
201
201
  raise Error, "wrong number of arguments (#{args.length} for #{@arity})" unless args.length == @arity
202
- s = String.new
202
+ s = sql_origin
203
+ append_sql(s, *args)
204
+ end
205
+
206
+ # Append the SQL query to use for the given arguments to the given SQL string.
207
+ def append_sql(sql, *args)
203
208
  ds = @dataset
204
- @fragments.each do |sql, i, transformer|
205
- s << sql
209
+ @fragments.each do |s, i, transformer|
210
+ sql << s
206
211
  if i.is_a?(Integer)
207
212
  v = args.fetch(i)
208
213
  v = transformer.call(v) if transformer
209
214
  else
210
215
  v = i.call
211
216
  end
212
- ds.literal_append(s, v)
217
+ ds.literal_append(sql, v)
213
218
  end
214
- s << @final_sql
215
- s
219
+ sql << @final_sql
220
+ sql
221
+ end
222
+
223
+ private
224
+
225
+ def sql_origin
226
+ String.new
216
227
  end
217
228
  end
218
229
  end
@@ -148,7 +148,10 @@ module Sequel
148
148
 
149
149
  # Freeze the stored arguments when freezing the query string.
150
150
  def freeze
151
- @args.freeze if @args
151
+ if @args
152
+ @args.freeze
153
+ @arg_map.freeze
154
+ end
152
155
  super
153
156
  end
154
157
 
@@ -156,6 +159,14 @@ module Sequel
156
159
  def inspect
157
160
  @args ? "#{self}; #{@args.inspect}".inspect : super
158
161
  end
162
+
163
+ def initialize_copy(other)
164
+ super
165
+ if args = other.instance_variable_get(:@args)
166
+ @args = args.dup
167
+ @arg_map = other.instance_variable_get(:@arg_map).dup
168
+ end
169
+ end
159
170
  end
160
171
 
161
172
  # Wrapper class that skips auto parameterization for the wrapped object.
@@ -169,6 +180,22 @@ module Sequel
169
180
  end
170
181
  end
171
182
 
183
+ # PlacholderLiteralizer subclass with support for stored auto parameters.
184
+ class PlaceholderLiteralizer < ::Sequel::Dataset::PlaceholderLiteralizer
185
+ def initialize(dataset, fragments, final_sql, arity)
186
+ s = dataset.sql.dup
187
+ s.clear
188
+ @sql_origin = s.freeze
189
+ super
190
+ end
191
+
192
+ private
193
+
194
+ def sql_origin
195
+ @sql_origin.dup
196
+ end
197
+ end
198
+
172
199
  module DatabaseMethods
173
200
  def self.extended(db)
174
201
  unless (db.adapter_scheme == :postgres && USES_PG) || (db.adapter_scheme == :mock && db.database_type == :postgres)
@@ -282,9 +309,13 @@ module Sequel
282
309
  end
283
310
  end
284
311
 
285
- # Placeholder literalizers are not supported supported when using automatic parameterization.
286
- def supports_placeholder_literalizer?
287
- @opts[:no_auto_parameterize]
312
+ # The class to use for placeholder literalizers.
313
+ def placeholder_literalizer_class
314
+ if @opts[:no_auto_parameterize]
315
+ super
316
+ else
317
+ PlaceholderLiteralizer
318
+ end
288
319
  end
289
320
 
290
321
  # Disable automatic parameterization when using a cursor.
@@ -310,7 +310,17 @@ module Sequel
310
310
  loader = union_eager_loader
311
311
  joiner = " UNION ALL "
312
312
  ids.each_slice(subqueries_per_union).each do |slice|
313
- objects.concat(ds.with_sql(slice.map{|k| loader.sql(*k)}.join(joiner)).to_a)
313
+ sql = loader.send(:sql_origin)
314
+ join = false
315
+ slice.each do |k|
316
+ if join
317
+ sql << joiner
318
+ else
319
+ join = true
320
+ end
321
+ loader.append_sql(sql, *k)
322
+ end
323
+ objects.concat(ds.with_sql(sql).to_a)
314
324
  end
315
325
  ds = ds.eager(cascade) if cascade
316
326
  ds.send(:post_load, objects)
@@ -446,7 +456,7 @@ module Sequel
446
456
  def placeholder_loader
447
457
  if use_placeholder_loader?
448
458
  cached_fetch(:placeholder_loader) do
449
- Sequel::Dataset::PlaceholderLiteralizer.loader(associated_dataset) do |pl, ds|
459
+ associated_dataset.placeholder_literalizer_loader do |pl, ds|
450
460
  ds = ds.where(Sequel.&(*predicate_keys.map{|k| SQL::BooleanExpression.new(:'=', k, pl.arg)}))
451
461
  if self[:block]
452
462
  ds = self[:block].call(ds)
@@ -748,8 +758,8 @@ module Sequel
748
758
  # A placeholder literalizer used to speed up eager loading.
749
759
  def placeholder_eager_loader
750
760
  cached_fetch(:placeholder_eager_loader) do
751
- Sequel::Dataset::PlaceholderLiteralizer.loader(associated_dataset) do |pl, ds|
752
- apply_eager_limit_strategy(eager_loading_dataset.where(predicate_key=>pl.arg), eager_limit_strategy)
761
+ eager_loading_dataset.placeholder_literalizer_loader do |pl, ds|
762
+ apply_eager_limit_strategy(ds.where(predicate_key=>pl.arg), eager_limit_strategy)
753
763
  end
754
764
  end
755
765
  end
@@ -808,7 +818,7 @@ module Sequel
808
818
  # loading a limited association.
809
819
  def union_eager_loader
810
820
  cached_fetch(:union_eager_loader) do
811
- Sequel::Dataset::PlaceholderLiteralizer.loader(associated_dataset) do |pl, ds|
821
+ associated_dataset.placeholder_literalizer_loader do |pl, ds|
812
822
  ds = self[:eager_block].call(ds) if self[:eager_block]
813
823
  keys = predicate_keys
814
824
  ds = ds.where(keys.map{pl.arg}.zip(keys))
@@ -1722,6 +1732,8 @@ module Sequel
1722
1732
  # :graph_select :: A column or array of columns to select from the associated table
1723
1733
  # when eagerly loading the association via +eager_graph+. Defaults to all
1724
1734
  # columns in the associated table.
1735
+ # :graph_use_association_block :: Makes eager_graph consider the association block. Without this, eager_graph
1736
+ # ignores the bock and only use the :graph_* options.
1725
1737
  # :instance_specific :: Marks the association as instance specific. Should be used if the association block
1726
1738
  # uses instance specific state, or transient state (accessing current date/time, etc.).
1727
1739
  # :limit :: Limit the number of records to the provided value. Use
@@ -2461,6 +2473,9 @@ module Sequel
2461
2473
  # Return dataset to graph into given the association reflection, applying the :callback option if set.
2462
2474
  def eager_graph_dataset(opts, eager_options)
2463
2475
  ds = opts.associated_class.dataset
2476
+ if opts[:graph_use_association_block] && (b = opts[:block])
2477
+ ds = b.call(ds)
2478
+ end
2464
2479
  if cb = eager_options[:callback]
2465
2480
  ds = cb.call(ds)
2466
2481
  end
@@ -151,7 +151,7 @@ module Sequel
151
151
  ds
152
152
  end
153
153
 
154
- Sequel::Dataset::PlaceholderLiteralizer.loader(model, &block)
154
+ model.dataset.placeholder_literalizer_class.loader(model, &block)
155
155
  end
156
156
  end
157
157
 
@@ -385,7 +385,7 @@ module Sequel
385
385
  iq = nil
386
386
  end
387
387
  fe = opts.final_edge
388
- ds.graph(opts.associated_class.dataset, use_only_conditions ? only_conditions : (Array(opts.right_primary_key).zip(Array(fe[:left])) + conditions), :select=>select, :table_alias=>eo[:table_alias], :qualify=>:deep, :join_type=>eo[:join_type]||join_type, :join_only=>eo[:join_only], &graph_block)
388
+ ds.graph(eager_graph_dataset(opts, eo), use_only_conditions ? only_conditions : (Array(opts.right_primary_key).zip(Array(fe[:left])) + conditions), :select=>select, :table_alias=>eo[:table_alias], :qualify=>:deep, :join_type=>eo[:join_type]||join_type, :join_only=>eo[:join_only], &graph_block)
389
389
  end
390
390
  end
391
391
  end
@@ -6,7 +6,7 @@ module Sequel
6
6
 
7
7
  # The minor version of Sequel. Bumped for every non-patch level
8
8
  # release, generally around once a month.
9
- MINOR = 63
9
+ MINOR = 65
10
10
 
11
11
  # The tiny version of Sequel. Usually 0, only bumped for bugfix
12
12
  # releases that fix regressions from previous versions.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.63.0
4
+ version: 5.65.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-01 00:00:00.000000000 Z
11
+ date: 2023-02-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -195,6 +195,8 @@ extra_rdoc_files:
195
195
  - doc/release_notes/5.61.0.txt
196
196
  - doc/release_notes/5.62.0.txt
197
197
  - doc/release_notes/5.63.0.txt
198
+ - doc/release_notes/5.64.0.txt
199
+ - doc/release_notes/5.65.0.txt
198
200
  - doc/release_notes/5.7.0.txt
199
201
  - doc/release_notes/5.8.0.txt
200
202
  - doc/release_notes/5.9.0.txt
@@ -286,6 +288,8 @@ files:
286
288
  - doc/release_notes/5.61.0.txt
287
289
  - doc/release_notes/5.62.0.txt
288
290
  - doc/release_notes/5.63.0.txt
291
+ - doc/release_notes/5.64.0.txt
292
+ - doc/release_notes/5.65.0.txt
289
293
  - doc/release_notes/5.7.0.txt
290
294
  - doc/release_notes/5.8.0.txt
291
295
  - doc/release_notes/5.9.0.txt
@@ -609,7 +613,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
609
613
  - !ruby/object:Gem::Version
610
614
  version: '0'
611
615
  requirements: []
612
- rubygems_version: 3.3.26
616
+ rubygems_version: 3.4.1
613
617
  signing_key:
614
618
  specification_version: 4
615
619
  summary: The Database Toolkit for Ruby