sequel 5.64.0 → 5.65.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 +8 -0
- data/MIT-LICENSE +1 -1
- data/doc/association_basics.rdoc +2 -2
- data/doc/release_notes/5.65.0.txt +21 -0
- data/doc/sql.rdoc +1 -1
- data/lib/sequel/adapters/shared/mysql.rb +7 -0
- data/lib/sequel/adapters/shared/postgres.rb +1 -1
- data/lib/sequel/dataset/misc.rb +11 -1
- data/lib/sequel/dataset/placeholder_literalizer.rb +20 -9
- data/lib/sequel/extensions/pg_auto_parameterize.rb +35 -4
- data/lib/sequel/model/associations.rb +15 -5
- data/lib/sequel/plugins/finder.rb +1 -1
- data/lib/sequel/version.rb +1 -1
- metadata +4 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 24bfe7c123337539140b0385dd9a828fe0fec4d6ad4e39e5fd8f150258ae7a03
         | 
| 4 | 
            +
              data.tar.gz: d820be46e60ba7b08b1129f0a6b67a24a550a27d5b682a84730172bc256f4118
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 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- | 
| 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
         | 
    
        data/doc/association_basics.rdoc
    CHANGED
    
    | @@ -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  | 
| 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  | 
| 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+  | 
| 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] | 
| 922 | 
            +
                          indc[:relkind]=>%w'i I',
         | 
| 923 923 | 
             
                          ind[:indisprimary]=>false,
         | 
| 924 924 | 
             
                          :indexprs=>nil,
         | 
| 925 925 | 
             
                          :indisvalid=>true}}.
         | 
    
        data/lib/sequel/dataset/misc.rb
    CHANGED
    
    | @@ -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 =  | 
| 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 | 
            -
                       | 
| 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 =  | 
| 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 | | 
| 205 | 
            -
                       | 
| 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( | 
| 217 | 
            +
                      ds.literal_append(sql, v)
         | 
| 213 218 | 
             
                    end
         | 
| 214 | 
            -
                     | 
| 215 | 
            -
                     | 
| 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 | 
            -
                       | 
| 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 | 
            -
                    #  | 
| 286 | 
            -
                    def  | 
| 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 | 
            -
                           | 
| 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 | 
            -
                           | 
| 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 | 
            -
                         | 
| 752 | 
            -
                          apply_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 | 
            -
                         | 
| 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))
         | 
    
        data/lib/sequel/version.rb
    CHANGED
    
    | @@ -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 =  | 
| 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. | 
| 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- | 
| 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
         |