sequel 5.64.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: 1971882f6efac487f21b4b5fb74695b757f2e129c14d82ffdca062cd5bc9d58f
4
- data.tar.gz: ca4d9df4e18bd2806ad0a288856cb87f270f702a73f8de0ebea3934776d4304c
3
+ metadata.gz: 24bfe7c123337539140b0385dd9a828fe0fec4d6ad4e39e5fd8f150258ae7a03
4
+ data.tar.gz: d820be46e60ba7b08b1129f0a6b67a24a550a27d5b682a84730172bc256f4118
5
5
  SHA512:
6
- metadata.gz: abdd0fbcb5da74256493a8cfb7ff32f9247d8b021096344d3d072d2d5981fec557ed222df11da3db12abae7318c43c09b9bb2c63795816244aea76425f4106ba
7
- data.tar.gz: 7b37c7c8cdc9172baf273ee80b328fa79bd6694a070ef81220e31bbaa20bcb0dc90a137b5cccd4c0326a7b99f17dd57591deab375dbaf61881bac3536b4eeb12
6
+ metadata.gz: bd5c7dacdf48f8ada7c34c88210ac804faa1b47741f946ca16cd6f645c1f86055eb85ac6b601e9cef2ab4aa8a5cba3dc444e3005d6ed61d324c1158f2e03a70e
7
+ data.tar.gz: d17eb580a3f50f4b0c33561aed320c2ea3089044b905f4dc845ea8682afe1cdbf2798c6cd202f1233b1d168d06c9686a94728d41e0f47264245a33da5a99b251
data/CHANGELOG CHANGED
@@ -1,3 +1,11 @@
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
+
1
9
  === 5.64.0 (2023-01-01)
2
10
 
3
11
  * Make :db_type column schema entries on SQLAnywhere include precision/scale information (jeremyevans)
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.
@@ -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
 
@@ -557,6 +557,13 @@ module Sequel
557
557
  super if supports_check_constraints?
558
558
  end
559
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)
564
+ super if supports_check_constraints?
565
+ end
566
+
560
567
  # Split DROP INDEX ops on MySQL 5.6+, as dropping them in the same
561
568
  # statement as dropping a related foreign key causes an error.
562
569
  def split_alter_table_op?(op)
@@ -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}}.
@@ -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))
@@ -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
 
@@ -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 = 64
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.64.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: 2023-01-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
@@ -196,6 +196,7 @@ extra_rdoc_files:
196
196
  - doc/release_notes/5.62.0.txt
197
197
  - doc/release_notes/5.63.0.txt
198
198
  - doc/release_notes/5.64.0.txt
199
+ - doc/release_notes/5.65.0.txt
199
200
  - doc/release_notes/5.7.0.txt
200
201
  - doc/release_notes/5.8.0.txt
201
202
  - doc/release_notes/5.9.0.txt
@@ -288,6 +289,7 @@ files:
288
289
  - doc/release_notes/5.62.0.txt
289
290
  - doc/release_notes/5.63.0.txt
290
291
  - doc/release_notes/5.64.0.txt
292
+ - doc/release_notes/5.65.0.txt
291
293
  - doc/release_notes/5.7.0.txt
292
294
  - doc/release_notes/5.8.0.txt
293
295
  - doc/release_notes/5.9.0.txt