sequel 5.45.0 → 5.77.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 +434 -0
 - data/MIT-LICENSE +1 -1
 - data/README.rdoc +59 -27
 - data/bin/sequel +11 -3
 - data/doc/advanced_associations.rdoc +16 -14
 - data/doc/association_basics.rdoc +119 -24
 - data/doc/cheat_sheet.rdoc +11 -3
 - data/doc/mass_assignment.rdoc +1 -1
 - data/doc/migration.rdoc +27 -6
 - data/doc/model_hooks.rdoc +1 -1
 - data/doc/object_model.rdoc +8 -8
 - data/doc/opening_databases.rdoc +28 -12
 - data/doc/postgresql.rdoc +16 -8
 - data/doc/querying.rdoc +5 -3
 - data/doc/release_notes/5.46.0.txt +87 -0
 - data/doc/release_notes/5.47.0.txt +59 -0
 - data/doc/release_notes/5.48.0.txt +14 -0
 - data/doc/release_notes/5.49.0.txt +59 -0
 - data/doc/release_notes/5.50.0.txt +78 -0
 - data/doc/release_notes/5.51.0.txt +47 -0
 - data/doc/release_notes/5.52.0.txt +87 -0
 - data/doc/release_notes/5.53.0.txt +23 -0
 - data/doc/release_notes/5.54.0.txt +27 -0
 - data/doc/release_notes/5.55.0.txt +21 -0
 - data/doc/release_notes/5.56.0.txt +51 -0
 - data/doc/release_notes/5.57.0.txt +23 -0
 - data/doc/release_notes/5.58.0.txt +31 -0
 - data/doc/release_notes/5.59.0.txt +73 -0
 - data/doc/release_notes/5.60.0.txt +22 -0
 - data/doc/release_notes/5.61.0.txt +43 -0
 - data/doc/release_notes/5.62.0.txt +132 -0
 - data/doc/release_notes/5.63.0.txt +33 -0
 - data/doc/release_notes/5.64.0.txt +50 -0
 - data/doc/release_notes/5.65.0.txt +21 -0
 - data/doc/release_notes/5.66.0.txt +24 -0
 - data/doc/release_notes/5.67.0.txt +32 -0
 - data/doc/release_notes/5.68.0.txt +61 -0
 - data/doc/release_notes/5.69.0.txt +26 -0
 - data/doc/release_notes/5.70.0.txt +35 -0
 - data/doc/release_notes/5.71.0.txt +21 -0
 - data/doc/release_notes/5.72.0.txt +33 -0
 - data/doc/release_notes/5.73.0.txt +66 -0
 - data/doc/release_notes/5.74.0.txt +45 -0
 - data/doc/release_notes/5.75.0.txt +35 -0
 - data/doc/release_notes/5.76.0.txt +86 -0
 - data/doc/release_notes/5.77.0.txt +63 -0
 - data/doc/schema_modification.rdoc +1 -1
 - data/doc/security.rdoc +9 -9
 - data/doc/sharding.rdoc +3 -1
 - data/doc/sql.rdoc +27 -15
 - data/doc/testing.rdoc +23 -13
 - data/doc/transactions.rdoc +6 -6
 - data/doc/virtual_rows.rdoc +1 -1
 - data/lib/sequel/adapters/ado/access.rb +1 -1
 - data/lib/sequel/adapters/ado.rb +1 -1
 - data/lib/sequel/adapters/amalgalite.rb +3 -5
 - data/lib/sequel/adapters/ibmdb.rb +3 -3
 - data/lib/sequel/adapters/jdbc/derby.rb +8 -0
 - data/lib/sequel/adapters/jdbc/h2.rb +63 -10
 - data/lib/sequel/adapters/jdbc/hsqldb.rb +8 -0
 - data/lib/sequel/adapters/jdbc/postgresql.rb +7 -4
 - data/lib/sequel/adapters/jdbc/sqlanywhere.rb +15 -0
 - data/lib/sequel/adapters/jdbc/sqlserver.rb +4 -0
 - data/lib/sequel/adapters/jdbc.rb +24 -22
 - data/lib/sequel/adapters/mysql.rb +92 -67
 - data/lib/sequel/adapters/mysql2.rb +56 -51
 - data/lib/sequel/adapters/odbc/mssql.rb +1 -1
 - data/lib/sequel/adapters/odbc.rb +1 -1
 - data/lib/sequel/adapters/oracle.rb +4 -3
 - data/lib/sequel/adapters/postgres.rb +89 -45
 - data/lib/sequel/adapters/shared/access.rb +11 -1
 - data/lib/sequel/adapters/shared/db2.rb +42 -0
 - data/lib/sequel/adapters/shared/mssql.rb +91 -10
 - data/lib/sequel/adapters/shared/mysql.rb +78 -3
 - data/lib/sequel/adapters/shared/oracle.rb +86 -7
 - data/lib/sequel/adapters/shared/postgres.rb +576 -171
 - data/lib/sequel/adapters/shared/sqlanywhere.rb +21 -5
 - data/lib/sequel/adapters/shared/sqlite.rb +92 -8
 - data/lib/sequel/adapters/sqlanywhere.rb +1 -1
 - data/lib/sequel/adapters/sqlite.rb +99 -18
 - data/lib/sequel/adapters/tinytds.rb +1 -1
 - data/lib/sequel/adapters/trilogy.rb +117 -0
 - data/lib/sequel/adapters/utils/columns_limit_1.rb +22 -0
 - data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -1
 - data/lib/sequel/ast_transformer.rb +6 -0
 - data/lib/sequel/connection_pool/sharded_single.rb +5 -7
 - data/lib/sequel/connection_pool/sharded_threaded.rb +16 -11
 - data/lib/sequel/connection_pool/sharded_timed_queue.rb +374 -0
 - data/lib/sequel/connection_pool/single.rb +6 -8
 - data/lib/sequel/connection_pool/threaded.rb +14 -8
 - data/lib/sequel/connection_pool/timed_queue.rb +270 -0
 - data/lib/sequel/connection_pool.rb +57 -31
 - data/lib/sequel/core.rb +17 -18
 - data/lib/sequel/database/connecting.rb +27 -3
 - data/lib/sequel/database/dataset.rb +16 -6
 - data/lib/sequel/database/misc.rb +70 -14
 - data/lib/sequel/database/query.rb +73 -2
 - data/lib/sequel/database/schema_generator.rb +11 -6
 - data/lib/sequel/database/schema_methods.rb +23 -4
 - data/lib/sequel/database/transactions.rb +6 -0
 - data/lib/sequel/dataset/actions.rb +111 -15
 - data/lib/sequel/dataset/deprecated_singleton_class_methods.rb +42 -0
 - data/lib/sequel/dataset/features.rb +20 -1
 - data/lib/sequel/dataset/misc.rb +12 -2
 - data/lib/sequel/dataset/placeholder_literalizer.rb +20 -9
 - data/lib/sequel/dataset/query.rb +170 -41
 - data/lib/sequel/dataset/sql.rb +190 -71
 - data/lib/sequel/dataset.rb +4 -0
 - data/lib/sequel/extensions/_model_pg_row.rb +0 -12
 - data/lib/sequel/extensions/_pretty_table.rb +1 -1
 - data/lib/sequel/extensions/any_not_empty.rb +2 -2
 - data/lib/sequel/extensions/async_thread_pool.rb +14 -13
 - data/lib/sequel/extensions/auto_cast_date_and_time.rb +94 -0
 - data/lib/sequel/extensions/auto_literal_strings.rb +1 -1
 - data/lib/sequel/extensions/connection_expiration.rb +15 -9
 - data/lib/sequel/extensions/connection_validator.rb +16 -11
 - data/lib/sequel/extensions/constraint_validations.rb +1 -1
 - data/lib/sequel/extensions/core_refinements.rb +36 -11
 - data/lib/sequel/extensions/date_arithmetic.rb +36 -8
 - data/lib/sequel/extensions/date_parse_input_handler.rb +67 -0
 - data/lib/sequel/extensions/datetime_parse_to_time.rb +5 -1
 - data/lib/sequel/extensions/duplicate_columns_handler.rb +11 -10
 - data/lib/sequel/extensions/index_caching.rb +5 -1
 - data/lib/sequel/extensions/inflector.rb +1 -1
 - data/lib/sequel/extensions/is_distinct_from.rb +141 -0
 - data/lib/sequel/extensions/looser_typecasting.rb +3 -0
 - data/lib/sequel/extensions/migration.rb +57 -15
 - data/lib/sequel/extensions/named_timezones.rb +22 -6
 - data/lib/sequel/extensions/pagination.rb +1 -1
 - data/lib/sequel/extensions/pg_array.rb +33 -4
 - data/lib/sequel/extensions/pg_array_ops.rb +2 -2
 - data/lib/sequel/extensions/pg_auto_parameterize.rb +509 -0
 - data/lib/sequel/extensions/pg_auto_parameterize_in_array.rb +110 -0
 - data/lib/sequel/extensions/pg_enum.rb +1 -2
 - data/lib/sequel/extensions/pg_extended_date_support.rb +39 -28
 - data/lib/sequel/extensions/pg_extended_integer_support.rb +116 -0
 - data/lib/sequel/extensions/pg_hstore.rb +6 -1
 - data/lib/sequel/extensions/pg_hstore_ops.rb +53 -3
 - data/lib/sequel/extensions/pg_inet.rb +10 -11
 - data/lib/sequel/extensions/pg_inet_ops.rb +1 -1
 - data/lib/sequel/extensions/pg_interval.rb +11 -11
 - data/lib/sequel/extensions/pg_json.rb +13 -15
 - data/lib/sequel/extensions/pg_json_ops.rb +125 -2
 - data/lib/sequel/extensions/pg_multirange.rb +367 -0
 - data/lib/sequel/extensions/pg_range.rb +13 -26
 - data/lib/sequel/extensions/pg_range_ops.rb +37 -9
 - data/lib/sequel/extensions/pg_row.rb +20 -19
 - data/lib/sequel/extensions/pg_row_ops.rb +1 -1
 - data/lib/sequel/extensions/pg_timestamptz.rb +27 -3
 - data/lib/sequel/extensions/round_timestamps.rb +1 -1
 - data/lib/sequel/extensions/s.rb +2 -1
 - data/lib/sequel/extensions/schema_caching.rb +1 -1
 - data/lib/sequel/extensions/schema_dumper.rb +45 -11
 - data/lib/sequel/extensions/server_block.rb +10 -13
 - data/lib/sequel/extensions/set_literalizer.rb +58 -0
 - data/lib/sequel/extensions/sql_comments.rb +110 -3
 - data/lib/sequel/extensions/sql_log_normalizer.rb +108 -0
 - data/lib/sequel/extensions/sqlite_json_ops.rb +255 -0
 - data/lib/sequel/extensions/string_agg.rb +1 -1
 - data/lib/sequel/extensions/string_date_time.rb +19 -23
 - data/lib/sequel/extensions/symbol_aref.rb +2 -0
 - data/lib/sequel/extensions/transaction_connection_validator.rb +78 -0
 - data/lib/sequel/model/associations.rb +286 -92
 - data/lib/sequel/model/base.rb +53 -33
 - data/lib/sequel/model/dataset_module.rb +3 -0
 - data/lib/sequel/model/errors.rb +10 -1
 - data/lib/sequel/model/exceptions.rb +15 -3
 - data/lib/sequel/model/inflections.rb +1 -1
 - data/lib/sequel/plugins/auto_restrict_eager_graph.rb +62 -0
 - data/lib/sequel/plugins/auto_validations.rb +74 -16
 - data/lib/sequel/plugins/class_table_inheritance.rb +2 -2
 - data/lib/sequel/plugins/column_encryption.rb +29 -8
 - data/lib/sequel/plugins/composition.rb +3 -2
 - data/lib/sequel/plugins/concurrent_eager_loading.rb +4 -4
 - data/lib/sequel/plugins/constraint_validations.rb +8 -5
 - data/lib/sequel/plugins/defaults_setter.rb +16 -0
 - data/lib/sequel/plugins/dirty.rb +1 -1
 - data/lib/sequel/plugins/enum.rb +124 -0
 - data/lib/sequel/plugins/finder.rb +4 -2
 - data/lib/sequel/plugins/insert_conflict.rb +4 -0
 - data/lib/sequel/plugins/instance_specific_default.rb +1 -1
 - data/lib/sequel/plugins/json_serializer.rb +2 -2
 - data/lib/sequel/plugins/lazy_attributes.rb +3 -0
 - data/lib/sequel/plugins/list.rb +8 -3
 - data/lib/sequel/plugins/many_through_many.rb +109 -10
 - data/lib/sequel/plugins/mssql_optimistic_locking.rb +8 -38
 - data/lib/sequel/plugins/nested_attributes.rb +4 -4
 - data/lib/sequel/plugins/optimistic_locking.rb +9 -42
 - data/lib/sequel/plugins/optimistic_locking_base.rb +55 -0
 - data/lib/sequel/plugins/paged_operations.rb +181 -0
 - data/lib/sequel/plugins/pg_array_associations.rb +46 -34
 - data/lib/sequel/plugins/pg_auto_constraint_validations.rb +9 -3
 - data/lib/sequel/plugins/pg_xmin_optimistic_locking.rb +109 -0
 - data/lib/sequel/plugins/prepared_statements.rb +12 -2
 - data/lib/sequel/plugins/prepared_statements_safe.rb +2 -1
 - data/lib/sequel/plugins/primary_key_lookup_check_values.rb +154 -0
 - data/lib/sequel/plugins/rcte_tree.rb +7 -4
 - data/lib/sequel/plugins/require_valid_schema.rb +67 -0
 - data/lib/sequel/plugins/serialization.rb +1 -0
 - data/lib/sequel/plugins/serialization_modification_detection.rb +1 -0
 - data/lib/sequel/plugins/single_table_inheritance.rb +8 -0
 - data/lib/sequel/plugins/sql_comments.rb +189 -0
 - data/lib/sequel/plugins/static_cache.rb +39 -1
 - data/lib/sequel/plugins/static_cache_cache.rb +5 -1
 - data/lib/sequel/plugins/subclasses.rb +28 -11
 - data/lib/sequel/plugins/tactical_eager_loading.rb +23 -10
 - data/lib/sequel/plugins/timestamps.rb +1 -1
 - data/lib/sequel/plugins/unused_associations.rb +521 -0
 - data/lib/sequel/plugins/update_or_create.rb +1 -1
 - data/lib/sequel/plugins/validate_associated.rb +22 -12
 - data/lib/sequel/plugins/validation_helpers.rb +41 -11
 - data/lib/sequel/plugins/validation_helpers_generic_type_messages.rb +73 -0
 - data/lib/sequel/plugins/xml_serializer.rb +1 -1
 - data/lib/sequel/sql.rb +1 -1
 - data/lib/sequel/timezones.rb +12 -14
 - data/lib/sequel/version.rb +1 -1
 - metadata +109 -19
 
| 
         @@ -19,6 +19,9 @@ module Sequel 
     | 
|
| 
       19 
19 
     | 
    
         
             
              module Postgres
         
     | 
| 
       20 
20 
     | 
    
         
             
                Sequel::Database.set_shared_adapter_scheme(:postgres, self)
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
      
 22 
     | 
    
         
            +
                # Exception class ranged when literalizing integers outside the bigint/int8 range.
         
     | 
| 
      
 23 
     | 
    
         
            +
                class IntegerOutsideBigintRange < InvalidValue; end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
       22 
25 
     | 
    
         
             
                NAN             = 0.0/0.0
         
     | 
| 
       23 
26 
     | 
    
         
             
                PLUS_INFINITY   = 1.0/0.0
         
     | 
| 
       24 
27 
     | 
    
         
             
                MINUS_INFINITY  = -1.0/0.0
         
     | 
| 
         @@ -83,11 +86,22 @@ module Sequel 
     | 
|
| 
       83 
86 
     | 
    
         
             
                  def primary_key(table)
         
     | 
| 
       84 
87 
     | 
    
         
             
                    :id
         
     | 
| 
       85 
88 
     | 
    
         
             
                  end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                  private
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                  # Handle NoMethodErrors when parsing schema due to output_identifier
         
     | 
| 
      
 93 
     | 
    
         
            +
                  # being called with nil when the Database fetch results are not set
         
     | 
| 
      
 94 
     | 
    
         
            +
                  # to what schema parsing expects.
         
     | 
| 
      
 95 
     | 
    
         
            +
                  def schema_parse_table(table, opts=OPTS)
         
     | 
| 
      
 96 
     | 
    
         
            +
                    super
         
     | 
| 
      
 97 
     | 
    
         
            +
                  rescue NoMethodError
         
     | 
| 
      
 98 
     | 
    
         
            +
                    []
         
     | 
| 
      
 99 
     | 
    
         
            +
                  end
         
     | 
| 
       86 
100 
     | 
    
         
             
                end
         
     | 
| 
       87 
101 
     | 
    
         | 
| 
       88 
102 
     | 
    
         
             
                def self.mock_adapter_setup(db)
         
     | 
| 
       89 
103 
     | 
    
         
             
                  db.instance_exec do
         
     | 
| 
       90 
     | 
    
         
            -
                    @server_version =  
     | 
| 
      
 104 
     | 
    
         
            +
                    @server_version = 150000
         
     | 
| 
       91 
105 
     | 
    
         
             
                    initialize_postgres_adapter
         
     | 
| 
       92 
106 
     | 
    
         
             
                    extend(MockAdapterDatabaseMethods)
         
     | 
| 
       93 
107 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -230,7 +244,6 @@ module Sequel 
     | 
|
| 
       230 
244 
     | 
    
         
             
                module DatabaseMethods
         
     | 
| 
       231 
245 
     | 
    
         
             
                  include UnmodifiedIdentifiers::DatabaseMethods
         
     | 
| 
       232 
246 
     | 
    
         | 
| 
       233 
     | 
    
         
            -
                  PREPARED_ARG_PLACEHOLDER = LiteralString.new('$').freeze
         
     | 
| 
       234 
247 
     | 
    
         
             
                  FOREIGN_KEY_LIST_ON_DELETE_MAP = {'a'=>:no_action, 'r'=>:restrict, 'c'=>:cascade, 'n'=>:set_null, 'd'=>:set_default}.freeze
         
     | 
| 
       235 
248 
     | 
    
         
             
                  ON_COMMIT = {:drop => 'DROP', :delete_rows => 'DELETE ROWS', :preserve_rows => 'PRESERVE ROWS'}.freeze
         
     | 
| 
       236 
249 
     | 
    
         
             
                  ON_COMMIT.each_value(&:freeze)
         
     | 
| 
         @@ -254,7 +267,7 @@ module Sequel 
     | 
|
| 
       254 
267 
     | 
    
         
             
                    WHERE cons.contype = 'p'
         
     | 
| 
       255 
268 
     | 
    
         
             
                      AND pg_get_expr(def.adbin, attr.attrelid) ~* 'nextval'
         
     | 
| 
       256 
269 
     | 
    
         
             
                  end_sql
         
     | 
| 
       257 
     | 
    
         
            -
                  ).strip.gsub(/\s+/, ' ').freeze
         
     | 
| 
      
 270 
     | 
    
         
            +
                  ).strip.gsub(/\s+/, ' ').freeze # SEQUEL6: Remove
         
     | 
| 
       258 
271 
     | 
    
         | 
| 
       259 
272 
     | 
    
         
             
                  # SQL fragment for determining primary key column for the given table.  Only
         
     | 
| 
       260 
273 
     | 
    
         
             
                  # returns the first primary key if the table has a composite primary key.
         
     | 
| 
         @@ -267,7 +280,7 @@ module Sequel 
     | 
|
| 
       267 
280 
     | 
    
         
             
                      AND pg_index.indkey[0] = pg_attribute.attnum
         
     | 
| 
       268 
281 
     | 
    
         
             
                      AND pg_index.indisprimary = 't'
         
     | 
| 
       269 
282 
     | 
    
         
             
                  end_sql
         
     | 
| 
       270 
     | 
    
         
            -
                  ).strip.gsub(/\s+/, ' ').freeze
         
     | 
| 
      
 283 
     | 
    
         
            +
                  ).strip.gsub(/\s+/, ' ').freeze # SEQUEL6: Remove
         
     | 
| 
       271 
284 
     | 
    
         | 
| 
       272 
285 
     | 
    
         
             
                  # SQL fragment for getting sequence associated with table's
         
     | 
| 
       273 
286 
     | 
    
         
             
                  # primary key, assuming it was a serial primary key column.
         
     | 
| 
         @@ -285,7 +298,7 @@ module Sequel 
     | 
|
| 
       285 
298 
     | 
    
         
             
                      AND attr.attrelid = t.oid
         
     | 
| 
       286 
299 
     | 
    
         
             
                      AND cons.contype = 'p'
         
     | 
| 
       287 
300 
     | 
    
         
             
                  end_sql
         
     | 
| 
       288 
     | 
    
         
            -
                  ).strip.gsub(/\s+/, ' ').freeze
         
     | 
| 
      
 301 
     | 
    
         
            +
                  ).strip.gsub(/\s+/, ' ').freeze # SEQUEL6: Remove
         
     | 
| 
       289 
302 
     | 
    
         | 
| 
       290 
303 
     | 
    
         
             
                  # A hash of conversion procs, keyed by type integer (oid) and
         
     | 
| 
       291 
304 
     | 
    
         
             
                  # having callable values for the conversion proc for that type.
         
     | 
| 
         @@ -319,14 +332,8 @@ module Sequel 
     | 
|
| 
       319 
332 
     | 
    
         
             
                  def check_constraints(table)
         
     | 
| 
       320 
333 
     | 
    
         
             
                    m = output_identifier_meth
         
     | 
| 
       321 
334 
     | 
    
         | 
| 
       322 
     | 
    
         
            -
                    rows = metadata_dataset.
         
     | 
| 
       323 
     | 
    
         
            -
                      from{pg_constraint.as(:co)}.
         
     | 
| 
       324 
     | 
    
         
            -
                      left_join(Sequel[:pg_attribute].as(:att), :attrelid=>:conrelid, :attnum=>SQL::Function.new(:ANY, Sequel[:co][:conkey])).
         
     | 
| 
       325 
     | 
    
         
            -
                      where(:conrelid=>regclass_oid(table), :contype=>'c').
         
     | 
| 
       326 
     | 
    
         
            -
                      select{[co[:conname].as(:constraint), att[:attname].as(:column), pg_get_constraintdef(co[:oid]).as(:definition)]}
         
     | 
| 
       327 
     | 
    
         
            -
             
     | 
| 
       328 
335 
     | 
    
         
             
                    hash = {}
         
     | 
| 
       329 
     | 
    
         
            -
                     
     | 
| 
      
 336 
     | 
    
         
            +
                    _check_constraints_ds.where_each(:conrelid=>regclass_oid(table)) do |row|
         
     | 
| 
       330 
337 
     | 
    
         
             
                      constraint = m.call(row[:constraint])
         
     | 
| 
       331 
338 
     | 
    
         
             
                      entry = hash[constraint] ||= {:definition=>row[:definition], :columns=>[]}
         
     | 
| 
       332 
339 
     | 
    
         
             
                      entry[:columns] << m.call(row[:column]) if row[:column]
         
     | 
| 
         @@ -365,9 +372,10 @@ module Sequel 
     | 
|
| 
       365 
372 
     | 
    
         | 
| 
       366 
373 
     | 
    
         
             
                    table_oid = regclass_oid(table)
         
     | 
| 
       367 
374 
     | 
    
         
             
                    im = input_identifier_meth
         
     | 
| 
       368 
     | 
    
         
            -
                    unless column =  
     | 
| 
      
 375 
     | 
    
         
            +
                    unless column = (opts[:column] || ((sch = schema(table).find{|_, sc| sc[:primary_key] && sc[:auto_increment]}) && sch[0]))
         
     | 
| 
       369 
376 
     | 
    
         
             
                      raise Error, "could not determine column to convert from serial to identity automatically"
         
     | 
| 
       370 
377 
     | 
    
         
             
                    end
         
     | 
| 
      
 378 
     | 
    
         
            +
                    column = im.call(column)
         
     | 
| 
       371 
379 
     | 
    
         | 
| 
       372 
380 
     | 
    
         
             
                    column_num = ds.from(:pg_attribute).
         
     | 
| 
       373 
381 
     | 
    
         
             
                      where(:attrelid=>table_oid, :attname=>column).
         
     | 
| 
         @@ -414,6 +422,7 @@ module Sequel 
     | 
|
| 
       414 
422 
     | 
    
         
             
                  #                  2 :: argument name
         
     | 
| 
       415 
423 
     | 
    
         
             
                  #                  3 :: argument mode (e.g. in, out, inout)
         
     | 
| 
       416 
424 
     | 
    
         
             
                  #         :behavior :: Should be IMMUTABLE, STABLE, or VOLATILE.  PostgreSQL assumes VOLATILE by default.
         
     | 
| 
      
 425 
     | 
    
         
            +
                  #         :parallel :: The thread safety attribute of the function. Should be SAFE, UNSAFE, RESTRICTED. PostgreSQL assumes UNSAFE by default.
         
     | 
| 
       417 
426 
     | 
    
         
             
                  #         :cost :: The estimated cost of the function, used by the query planner.
         
     | 
| 
       418 
427 
     | 
    
         
             
                  #         :language :: The language the function uses.  SQL is the default.
         
     | 
| 
       419 
428 
     | 
    
         
             
                  #         :link_symbol :: For a dynamically loaded see function, the function's link symbol if different from the definition argument.
         
     | 
| 
         @@ -479,6 +488,7 @@ module Sequel 
     | 
|
| 
       479 
488 
     | 
    
         
             
                  #         :each_row :: Calls the trigger for each row instead of for each statement.
         
     | 
| 
       480 
489 
     | 
    
         
             
                  #         :events :: Can be :insert, :update, :delete, or an array of any of those. Calls the trigger whenever that type of statement is used.  By default,
         
     | 
| 
       481 
490 
     | 
    
         
             
                  #                    the trigger is called for insert, update, or delete.
         
     | 
| 
      
 491 
     | 
    
         
            +
                  #         :replace :: Replace the trigger with the same name if it already exists (PostgreSQL 14+).
         
     | 
| 
       482 
492 
     | 
    
         
             
                  #         :when :: A filter to use for the trigger
         
     | 
| 
       483 
493 
     | 
    
         
             
                  def create_trigger(table, name, function, opts=OPTS)
         
     | 
| 
       484 
494 
     | 
    
         
             
                    self << create_trigger_sql(table, name, function, opts)
         
     | 
| 
         @@ -488,6 +498,25 @@ module Sequel 
     | 
|
| 
       488 
498 
     | 
    
         
             
                    :postgres
         
     | 
| 
       489 
499 
     | 
    
         
             
                  end
         
     | 
| 
       490 
500 
     | 
    
         | 
| 
      
 501 
     | 
    
         
            +
                  # For constraints that are deferrable, defer constraints until 
         
     | 
| 
      
 502 
     | 
    
         
            +
                  # transaction commit. Options:
         
     | 
| 
      
 503 
     | 
    
         
            +
                  #
         
     | 
| 
      
 504 
     | 
    
         
            +
                  # :constraints :: An identifier of the constraint, or an array of
         
     | 
| 
      
 505 
     | 
    
         
            +
                  #                 identifiers for constraints, to apply this
         
     | 
| 
      
 506 
     | 
    
         
            +
                  #                 change to specific constraints.
         
     | 
| 
      
 507 
     | 
    
         
            +
                  # :server :: The server/shard on which to run the query.
         
     | 
| 
      
 508 
     | 
    
         
            +
                  #
         
     | 
| 
      
 509 
     | 
    
         
            +
                  # Examples:
         
     | 
| 
      
 510 
     | 
    
         
            +
                  #
         
     | 
| 
      
 511 
     | 
    
         
            +
                  #   DB.defer_constraints
         
     | 
| 
      
 512 
     | 
    
         
            +
                  #   # SET CONSTRAINTS ALL DEFERRED
         
     | 
| 
      
 513 
     | 
    
         
            +
                  #
         
     | 
| 
      
 514 
     | 
    
         
            +
                  #   DB.defer_constraints(constraints: [:c1, Sequel[:sc][:c2]])
         
     | 
| 
      
 515 
     | 
    
         
            +
                  #   # SET CONSTRAINTS "c1", "sc"."s2" DEFERRED
         
     | 
| 
      
 516 
     | 
    
         
            +
                  def defer_constraints(opts=OPTS)
         
     | 
| 
      
 517 
     | 
    
         
            +
                    _set_constraints(' DEFERRED', opts)
         
     | 
| 
      
 518 
     | 
    
         
            +
                  end
         
     | 
| 
      
 519 
     | 
    
         
            +
             
     | 
| 
       491 
520 
     | 
    
         
             
                  # Use PostgreSQL's DO syntax to execute an anonymous code block.  The code should
         
     | 
| 
       492 
521 
     | 
    
         
             
                  # be the literal code string to use in the underlying procedural language.  Options:
         
     | 
| 
       493 
522 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -549,63 +578,12 @@ module Sequel 
     | 
|
| 
       549 
578 
     | 
    
         
             
                  def foreign_key_list(table, opts=OPTS)
         
     | 
| 
       550 
579 
     | 
    
         
             
                    m = output_identifier_meth
         
     | 
| 
       551 
580 
     | 
    
         
             
                    schema, _ = opts.fetch(:schema, schema_and_table(table))
         
     | 
| 
       552 
     | 
    
         
            -
                    oid = regclass_oid(table)
         
     | 
| 
       553 
     | 
    
         
            -
                    reverse = opts[:reverse]
         
     | 
| 
       554 
     | 
    
         
            -
             
     | 
| 
       555 
     | 
    
         
            -
                    if reverse
         
     | 
| 
       556 
     | 
    
         
            -
                      ctable = Sequel[:att2]
         
     | 
| 
       557 
     | 
    
         
            -
                      cclass = Sequel[:cl2]
         
     | 
| 
       558 
     | 
    
         
            -
                      rtable = Sequel[:att]
         
     | 
| 
       559 
     | 
    
         
            -
                      rclass = Sequel[:cl]
         
     | 
| 
       560 
     | 
    
         
            -
                    else
         
     | 
| 
       561 
     | 
    
         
            -
                      ctable = Sequel[:att]
         
     | 
| 
       562 
     | 
    
         
            -
                      cclass = Sequel[:cl]
         
     | 
| 
       563 
     | 
    
         
            -
                      rtable = Sequel[:att2]
         
     | 
| 
       564 
     | 
    
         
            -
                      rclass = Sequel[:cl2]
         
     | 
| 
       565 
     | 
    
         
            -
                    end
         
     | 
| 
       566 
     | 
    
         
            -
             
     | 
| 
       567 
     | 
    
         
            -
                    if server_version >= 90500
         
     | 
| 
       568 
     | 
    
         
            -
                      cpos = Sequel.expr{array_position(co[:conkey], ctable[:attnum])}
         
     | 
| 
       569 
     | 
    
         
            -
                      rpos = Sequel.expr{array_position(co[:confkey], rtable[:attnum])}
         
     | 
| 
       570 
     | 
    
         
            -
                    else
         
     | 
| 
       571 
     | 
    
         
            -
                      range = 0...32
         
     | 
| 
       572 
     | 
    
         
            -
                      cpos = Sequel.expr{SQL::CaseExpression.new(range.map{|x| [SQL::Subscript.new(co[:conkey], [x]), x]}, 32, ctable[:attnum])}
         
     | 
| 
       573 
     | 
    
         
            -
                      rpos = Sequel.expr{SQL::CaseExpression.new(range.map{|x| [SQL::Subscript.new(co[:confkey], [x]), x]}, 32, rtable[:attnum])}
         
     | 
| 
       574 
     | 
    
         
            -
                    end
         
     | 
| 
       575 
     | 
    
         
            -
             
     | 
| 
       576 
     | 
    
         
            -
                    ds = metadata_dataset.
         
     | 
| 
       577 
     | 
    
         
            -
                      from{pg_constraint.as(:co)}.
         
     | 
| 
       578 
     | 
    
         
            -
                      join(Sequel[:pg_class].as(cclass), :oid=>:conrelid).
         
     | 
| 
       579 
     | 
    
         
            -
                      join(Sequel[:pg_attribute].as(ctable), :attrelid=>:oid, :attnum=>SQL::Function.new(:ANY, Sequel[:co][:conkey])).
         
     | 
| 
       580 
     | 
    
         
            -
                      join(Sequel[:pg_class].as(rclass), :oid=>Sequel[:co][:confrelid]).
         
     | 
| 
       581 
     | 
    
         
            -
                      join(Sequel[:pg_attribute].as(rtable), :attrelid=>:oid, :attnum=>SQL::Function.new(:ANY, Sequel[:co][:confkey])).
         
     | 
| 
       582 
     | 
    
         
            -
                      join(Sequel[:pg_namespace].as(:nsp), :oid=>Sequel[:cl2][:relnamespace]).
         
     | 
| 
       583 
     | 
    
         
            -
                      order{[co[:conname], cpos]}.
         
     | 
| 
       584 
     | 
    
         
            -
                      where{{
         
     | 
| 
       585 
     | 
    
         
            -
                        cl[:relkind]=>'r',
         
     | 
| 
       586 
     | 
    
         
            -
                        co[:contype]=>'f',
         
     | 
| 
       587 
     | 
    
         
            -
                        cl[:oid]=>oid,
         
     | 
| 
       588 
     | 
    
         
            -
                        cpos=>rpos
         
     | 
| 
       589 
     | 
    
         
            -
                      }}.
         
     | 
| 
       590 
     | 
    
         
            -
                      select{[
         
     | 
| 
       591 
     | 
    
         
            -
                        co[:conname].as(:name),
         
     | 
| 
       592 
     | 
    
         
            -
                        ctable[:attname].as(:column),
         
     | 
| 
       593 
     | 
    
         
            -
                        co[:confupdtype].as(:on_update),
         
     | 
| 
       594 
     | 
    
         
            -
                        co[:confdeltype].as(:on_delete),
         
     | 
| 
       595 
     | 
    
         
            -
                        cl2[:relname].as(:table),
         
     | 
| 
       596 
     | 
    
         
            -
                        rtable[:attname].as(:refcolumn),
         
     | 
| 
       597 
     | 
    
         
            -
                        SQL::BooleanExpression.new(:AND, co[:condeferrable], co[:condeferred]).as(:deferrable),
         
     | 
| 
       598 
     | 
    
         
            -
                        nsp[:nspname].as(:schema)
         
     | 
| 
       599 
     | 
    
         
            -
                      ]}
         
     | 
| 
       600 
     | 
    
         
            -
             
     | 
| 
       601 
     | 
    
         
            -
                    if reverse
         
     | 
| 
       602 
     | 
    
         
            -
                      ds = ds.order_append(Sequel[:nsp][:nspname], Sequel[:cl2][:relname])
         
     | 
| 
       603 
     | 
    
         
            -
                    end
         
     | 
| 
       604 
581 
     | 
    
         | 
| 
       605 
582 
     | 
    
         
             
                    h = {}
         
     | 
| 
       606 
583 
     | 
    
         
             
                    fklod_map = FOREIGN_KEY_LIST_ON_DELETE_MAP 
         
     | 
| 
      
 584 
     | 
    
         
            +
                    reverse = opts[:reverse]
         
     | 
| 
       607 
585 
     | 
    
         | 
| 
       608 
     | 
    
         
            -
                     
     | 
| 
      
 586 
     | 
    
         
            +
                    (reverse ? _reverse_foreign_key_list_ds : _foreign_key_list_ds).where_each(Sequel[:cl][:oid]=>regclass_oid(table)) do |row|
         
     | 
| 
       609 
587 
     | 
    
         
             
                      if reverse
         
     | 
| 
       610 
588 
     | 
    
         
             
                        key = [row[:schema], row[:table], row[:name]]
         
     | 
| 
       611 
589 
     | 
    
         
             
                      else
         
     | 
| 
         @@ -640,45 +618,44 @@ module Sequel 
     | 
|
| 
       640 
618 
     | 
    
         
             
                  def freeze
         
     | 
| 
       641 
619 
     | 
    
         
             
                    server_version
         
     | 
| 
       642 
620 
     | 
    
         
             
                    supports_prepared_transactions?
         
     | 
| 
      
 621 
     | 
    
         
            +
                    _schema_ds
         
     | 
| 
      
 622 
     | 
    
         
            +
                    _select_serial_sequence_ds
         
     | 
| 
      
 623 
     | 
    
         
            +
                    _select_custom_sequence_ds
         
     | 
| 
      
 624 
     | 
    
         
            +
                    _select_pk_ds
         
     | 
| 
      
 625 
     | 
    
         
            +
                    _indexes_ds
         
     | 
| 
      
 626 
     | 
    
         
            +
                    _check_constraints_ds
         
     | 
| 
      
 627 
     | 
    
         
            +
                    _foreign_key_list_ds
         
     | 
| 
      
 628 
     | 
    
         
            +
                    _reverse_foreign_key_list_ds
         
     | 
| 
       643 
629 
     | 
    
         
             
                    @conversion_procs.freeze
         
     | 
| 
       644 
630 
     | 
    
         
             
                    super
         
     | 
| 
       645 
631 
     | 
    
         
             
                  end
         
     | 
| 
       646 
632 
     | 
    
         | 
| 
      
 633 
     | 
    
         
            +
                  # Immediately apply deferrable constraints.
         
     | 
| 
      
 634 
     | 
    
         
            +
                  #
         
     | 
| 
      
 635 
     | 
    
         
            +
                  # :constraints :: An identifier of the constraint, or an array of
         
     | 
| 
      
 636 
     | 
    
         
            +
                  #                 identifiers for constraints, to apply this
         
     | 
| 
      
 637 
     | 
    
         
            +
                  #                 change to specific constraints.
         
     | 
| 
      
 638 
     | 
    
         
            +
                  # :server :: The server/shard on which to run the query.
         
     | 
| 
      
 639 
     | 
    
         
            +
                  #
         
     | 
| 
      
 640 
     | 
    
         
            +
                  # Examples:
         
     | 
| 
      
 641 
     | 
    
         
            +
                  #
         
     | 
| 
      
 642 
     | 
    
         
            +
                  #   DB.immediate_constraints
         
     | 
| 
      
 643 
     | 
    
         
            +
                  #   # SET CONSTRAINTS ALL IMMEDIATE
         
     | 
| 
      
 644 
     | 
    
         
            +
                  #
         
     | 
| 
      
 645 
     | 
    
         
            +
                  #   DB.immediate_constraints(constraints: [:c1, Sequel[:sc][:c2]])
         
     | 
| 
      
 646 
     | 
    
         
            +
                  #   # SET CONSTRAINTS "c1", "sc"."s2" IMMEDIATE
         
     | 
| 
      
 647 
     | 
    
         
            +
                  def immediate_constraints(opts=OPTS)
         
     | 
| 
      
 648 
     | 
    
         
            +
                    _set_constraints(' IMMEDIATE', opts)
         
     | 
| 
      
 649 
     | 
    
         
            +
                  end
         
     | 
| 
      
 650 
     | 
    
         
            +
             
     | 
| 
       647 
651 
     | 
    
         
             
                  # Use the pg_* system tables to determine indexes on a table
         
     | 
| 
       648 
652 
     | 
    
         
             
                  def indexes(table, opts=OPTS)
         
     | 
| 
       649 
653 
     | 
    
         
             
                    m = output_identifier_meth
         
     | 
| 
       650 
     | 
    
         
            -
                     
     | 
| 
       651 
     | 
    
         
            -
             
     | 
| 
       652 
     | 
    
         
            -
                    if server_version >= 90500
         
     | 
| 
       653 
     | 
    
         
            -
                      order = [Sequel[:indc][:relname], Sequel.function(:array_position, Sequel[:ind][:indkey], Sequel[:att][:attnum])]
         
     | 
| 
       654 
     | 
    
         
            -
                    else
         
     | 
| 
       655 
     | 
    
         
            -
                      range = 0...32
         
     | 
| 
       656 
     | 
    
         
            -
                      order = [Sequel[:indc][:relname], SQL::CaseExpression.new(range.map{|x| [SQL::Subscript.new(Sequel[:ind][:indkey], [x]), x]}, 32, Sequel[:att][:attnum])]
         
     | 
| 
       657 
     | 
    
         
            -
                    end
         
     | 
| 
       658 
     | 
    
         
            -
             
     | 
| 
       659 
     | 
    
         
            -
                    attnums = SQL::Function.new(:ANY, Sequel[:ind][:indkey])
         
     | 
| 
       660 
     | 
    
         
            -
             
     | 
| 
       661 
     | 
    
         
            -
                    ds = metadata_dataset.
         
     | 
| 
       662 
     | 
    
         
            -
                      from{pg_class.as(:tab)}.
         
     | 
| 
       663 
     | 
    
         
            -
                      join(Sequel[:pg_index].as(:ind), :indrelid=>:oid).
         
     | 
| 
       664 
     | 
    
         
            -
                      join(Sequel[:pg_class].as(:indc), :oid=>:indexrelid).
         
     | 
| 
       665 
     | 
    
         
            -
                      join(Sequel[:pg_attribute].as(:att), :attrelid=>Sequel[:tab][:oid], :attnum=>attnums).
         
     | 
| 
       666 
     | 
    
         
            -
                      left_join(Sequel[:pg_constraint].as(:con), :conname=>Sequel[:indc][:relname]).
         
     | 
| 
       667 
     | 
    
         
            -
                      where{{
         
     | 
| 
       668 
     | 
    
         
            -
                        indc[:relkind]=>'i',
         
     | 
| 
       669 
     | 
    
         
            -
                        ind[:indisprimary]=>false,
         
     | 
| 
       670 
     | 
    
         
            -
                        :indexprs=>nil,
         
     | 
| 
       671 
     | 
    
         
            -
                        :indisvalid=>true,
         
     | 
| 
       672 
     | 
    
         
            -
                        tab[:oid]=>oid}}.
         
     | 
| 
       673 
     | 
    
         
            -
                      order(*order).
         
     | 
| 
       674 
     | 
    
         
            -
                      select{[indc[:relname].as(:name), ind[:indisunique].as(:unique), att[:attname].as(:column), con[:condeferrable].as(:deferrable)]}
         
     | 
| 
       675 
     | 
    
         
            -
             
     | 
| 
       676 
     | 
    
         
            -
                    ds = ds.where(:indpred=>nil) unless opts[:include_partial]
         
     | 
| 
       677 
     | 
    
         
            -
                    ds = ds.where(:indisready=>true) if server_version >= 80300
         
     | 
| 
       678 
     | 
    
         
            -
                    ds = ds.where(:indislive=>true) if server_version >= 90300
         
     | 
| 
      
 654 
     | 
    
         
            +
                    cond = {Sequel[:tab][:oid]=>regclass_oid(table, opts)}
         
     | 
| 
      
 655 
     | 
    
         
            +
                    cond[:indpred] = nil unless opts[:include_partial]
         
     | 
| 
       679 
656 
     | 
    
         | 
| 
       680 
657 
     | 
    
         
             
                    indexes = {}
         
     | 
| 
       681 
     | 
    
         
            -
                     
     | 
| 
      
 658 
     | 
    
         
            +
                    _indexes_ds.where_each(cond) do |r|
         
     | 
| 
       682 
659 
     | 
    
         
             
                      i = indexes[m.call(r[:name])] ||= {:columns=>[], :unique=>r[:unique], :deferrable=>r[:deferrable]}
         
     | 
| 
       683 
660 
     | 
    
         
             
                      i[:columns] << m.call(r[:column])
         
     | 
| 
       684 
661 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -711,8 +688,7 @@ module Sequel 
     | 
|
| 
       711 
688 
     | 
    
         
             
                  def primary_key(table, opts=OPTS)
         
     | 
| 
       712 
689 
     | 
    
         
             
                    quoted_table = quote_schema_table(table)
         
     | 
| 
       713 
690 
     | 
    
         
             
                    Sequel.synchronize{return @primary_keys[quoted_table] if @primary_keys.has_key?(quoted_table)}
         
     | 
| 
       714 
     | 
    
         
            -
                     
     | 
| 
       715 
     | 
    
         
            -
                    value = fetch(sql).single_value
         
     | 
| 
      
 691 
     | 
    
         
            +
                    value = _select_pk_ds.where_single_value(Sequel[:pg_class][:oid] => regclass_oid(table, opts))
         
     | 
| 
       716 
692 
     | 
    
         
             
                    Sequel.synchronize{@primary_keys[quoted_table] = value}
         
     | 
| 
       717 
693 
     | 
    
         
             
                  end
         
     | 
| 
       718 
694 
     | 
    
         | 
| 
         @@ -720,24 +696,21 @@ module Sequel 
     | 
|
| 
       720 
696 
     | 
    
         
             
                  def primary_key_sequence(table, opts=OPTS)
         
     | 
| 
       721 
697 
     | 
    
         
             
                    quoted_table = quote_schema_table(table)
         
     | 
| 
       722 
698 
     | 
    
         
             
                    Sequel.synchronize{return @primary_key_sequences[quoted_table] if @primary_key_sequences.has_key?(quoted_table)}
         
     | 
| 
       723 
     | 
    
         
            -
                     
     | 
| 
       724 
     | 
    
         
            -
                    if pks =  
     | 
| 
       725 
     | 
    
         
            -
                       
     | 
| 
       726 
     | 
    
         
            -
             
     | 
| 
       727 
     | 
    
         
            -
             
     | 
| 
       728 
     | 
    
         
            -
                      sql = "#{SELECT_CUSTOM_SEQUENCE_SQL} AND t.oid = #{literal(regclass_oid(table, opts))}"
         
     | 
| 
       729 
     | 
    
         
            -
                      if pks = fetch(sql).single_record
         
     | 
| 
       730 
     | 
    
         
            -
                        value = literal(SQL::QualifiedIdentifier.new(pks[:schema], LiteralString.new(pks[:sequence])))
         
     | 
| 
       731 
     | 
    
         
            -
                        Sequel.synchronize{@primary_key_sequences[quoted_table] = value}
         
     | 
| 
       732 
     | 
    
         
            -
                      end
         
     | 
| 
      
 699 
     | 
    
         
            +
                    cond = {Sequel[:t][:oid] => regclass_oid(table, opts)}
         
     | 
| 
      
 700 
     | 
    
         
            +
                    value = if pks = _select_serial_sequence_ds.first(cond)
         
     | 
| 
      
 701 
     | 
    
         
            +
                      literal(SQL::QualifiedIdentifier.new(pks[:schema], pks[:sequence]))
         
     | 
| 
      
 702 
     | 
    
         
            +
                    elsif pks = _select_custom_sequence_ds.first(cond)
         
     | 
| 
      
 703 
     | 
    
         
            +
                      literal(SQL::QualifiedIdentifier.new(pks[:schema], LiteralString.new(pks[:sequence])))
         
     | 
| 
       733 
704 
     | 
    
         
             
                    end
         
     | 
| 
      
 705 
     | 
    
         
            +
             
     | 
| 
      
 706 
     | 
    
         
            +
                    Sequel.synchronize{@primary_key_sequences[quoted_table] = value} if value
         
     | 
| 
       734 
707 
     | 
    
         
             
                  end
         
     | 
| 
       735 
708 
     | 
    
         | 
| 
       736 
709 
     | 
    
         
             
                  # Refresh the materialized view with the given name.
         
     | 
| 
       737 
710 
     | 
    
         
             
                  # 
         
     | 
| 
       738 
711 
     | 
    
         
             
                  #   DB.refresh_view(:items_view)
         
     | 
| 
       739 
712 
     | 
    
         
             
                  #   # REFRESH MATERIALIZED VIEW items_view
         
     | 
| 
       740 
     | 
    
         
            -
                  #   DB.refresh_view(:items_view, : 
     | 
| 
      
 713 
     | 
    
         
            +
                  #   DB.refresh_view(:items_view, concurrently: true)
         
     | 
| 
       741 
714 
     | 
    
         
             
                  #   # REFRESH MATERIALIZED VIEW CONCURRENTLY items_view
         
     | 
| 
       742 
715 
     | 
    
         
             
                  def refresh_view(name, opts=OPTS)
         
     | 
| 
       743 
716 
     | 
    
         
             
                    run "REFRESH MATERIALIZED VIEW#{' CONCURRENTLY' if opts[:concurrently]} #{quote_schema_table(name)}"
         
     | 
| 
         @@ -756,10 +729,12 @@ module Sequel 
     | 
|
| 
       756 
729 
     | 
    
         
             
                      seq_ds = metadata_dataset.from(:pg_sequence).where(:seqrelid=>regclass_oid(LiteralString.new(seq)))
         
     | 
| 
       757 
730 
     | 
    
         
             
                      increment_by = :seqincrement
         
     | 
| 
       758 
731 
     | 
    
         
             
                      min_value = :seqmin
         
     | 
| 
      
 732 
     | 
    
         
            +
                    # :nocov:
         
     | 
| 
       759 
733 
     | 
    
         
             
                    else
         
     | 
| 
       760 
734 
     | 
    
         
             
                      seq_ds = metadata_dataset.from(LiteralString.new(seq))
         
     | 
| 
       761 
735 
     | 
    
         
             
                      increment_by = :increment_by
         
     | 
| 
       762 
736 
     | 
    
         
             
                      min_value = :min_value
         
     | 
| 
      
 737 
     | 
    
         
            +
                    # :nocov:
         
     | 
| 
       763 
738 
     | 
    
         
             
                    end
         
     | 
| 
       764 
739 
     | 
    
         | 
| 
       765 
740 
     | 
    
         
             
                    get{setval(seq, db[table].select(coalesce(max(pk)+seq_ds.select(increment_by), seq_ds.select(min_value))), false)}
         
     | 
| 
         @@ -772,7 +747,9 @@ module Sequel 
     | 
|
| 
       772 
747 
     | 
    
         
             
                  # PostgreSQL uses SERIAL psuedo-type instead of AUTOINCREMENT for
         
     | 
| 
       773 
748 
     | 
    
         
             
                  # managing incrementing primary keys.
         
     | 
| 
       774 
749 
     | 
    
         
             
                  def serial_primary_key_options
         
     | 
| 
      
 750 
     | 
    
         
            +
                    # :nocov:
         
     | 
| 
       775 
751 
     | 
    
         
             
                    auto_increment_key = server_version >= 100002 ? :identity : :serial
         
     | 
| 
      
 752 
     | 
    
         
            +
                    # :nocov:
         
     | 
| 
       776 
753 
     | 
    
         
             
                    {:primary_key => true, auto_increment_key => true, :type=>Integer}
         
     | 
| 
       777 
754 
     | 
    
         
             
                  end
         
     | 
| 
       778 
755 
     | 
    
         | 
| 
         @@ -865,6 +842,7 @@ module Sequel 
     | 
|
| 
       865 
842 
     | 
    
         
             
                  #   DB.values([[1, 2], [3, 4]]).order(:column2).limit(1, 1)
         
     | 
| 
       866 
843 
     | 
    
         
             
                  #   # VALUES ((1, 2), (3, 4)) ORDER BY column2 LIMIT 1 OFFSET 1
         
     | 
| 
       867 
844 
     | 
    
         
             
                  def values(v)
         
     | 
| 
      
 845 
     | 
    
         
            +
                    raise Error, "Cannot provide an empty array for values" if v.empty?
         
     | 
| 
       868 
846 
     | 
    
         
             
                    @default_dataset.clone(:values=>v)
         
     | 
| 
       869 
847 
     | 
    
         
             
                  end
         
     | 
| 
       870 
848 
     | 
    
         | 
| 
         @@ -883,6 +861,245 @@ module Sequel 
     | 
|
| 
       883 
861 
     | 
    
         | 
| 
       884 
862 
     | 
    
         
             
                  private
         
     | 
| 
       885 
863 
     | 
    
         | 
| 
      
 864 
     | 
    
         
            +
                  # Dataset used to retrieve CHECK constraint information
         
     | 
| 
      
 865 
     | 
    
         
            +
                  def _check_constraints_ds
         
     | 
| 
      
 866 
     | 
    
         
            +
                    @_check_constraints_ds ||= metadata_dataset.
         
     | 
| 
      
 867 
     | 
    
         
            +
                      from{pg_constraint.as(:co)}.
         
     | 
| 
      
 868 
     | 
    
         
            +
                      left_join(Sequel[:pg_attribute].as(:att), :attrelid=>:conrelid, :attnum=>SQL::Function.new(:ANY, Sequel[:co][:conkey])).
         
     | 
| 
      
 869 
     | 
    
         
            +
                      where(:contype=>'c').
         
     | 
| 
      
 870 
     | 
    
         
            +
                      select{[co[:conname].as(:constraint), att[:attname].as(:column), pg_get_constraintdef(co[:oid]).as(:definition)]}
         
     | 
| 
      
 871 
     | 
    
         
            +
                  end
         
     | 
| 
      
 872 
     | 
    
         
            +
             
     | 
| 
      
 873 
     | 
    
         
            +
                  # Dataset used to retrieve foreign keys referenced by a table
         
     | 
| 
      
 874 
     | 
    
         
            +
                  def _foreign_key_list_ds
         
     | 
| 
      
 875 
     | 
    
         
            +
                    @_foreign_key_list_ds ||= __foreign_key_list_ds(false)
         
     | 
| 
      
 876 
     | 
    
         
            +
                  end
         
     | 
| 
      
 877 
     | 
    
         
            +
             
     | 
| 
      
 878 
     | 
    
         
            +
                  # Dataset used to retrieve foreign keys referencing a table
         
     | 
| 
      
 879 
     | 
    
         
            +
                  def _reverse_foreign_key_list_ds
         
     | 
| 
      
 880 
     | 
    
         
            +
                    @_reverse_foreign_key_list_ds ||= __foreign_key_list_ds(true)
         
     | 
| 
      
 881 
     | 
    
         
            +
                  end
         
     | 
| 
      
 882 
     | 
    
         
            +
             
     | 
| 
      
 883 
     | 
    
         
            +
                  # Build dataset used for foreign key list methods.
         
     | 
| 
      
 884 
     | 
    
         
            +
                  def __foreign_key_list_ds(reverse)
         
     | 
| 
      
 885 
     | 
    
         
            +
                    if reverse
         
     | 
| 
      
 886 
     | 
    
         
            +
                      ctable = Sequel[:att2]
         
     | 
| 
      
 887 
     | 
    
         
            +
                      cclass = Sequel[:cl2]
         
     | 
| 
      
 888 
     | 
    
         
            +
                      rtable = Sequel[:att]
         
     | 
| 
      
 889 
     | 
    
         
            +
                      rclass = Sequel[:cl]
         
     | 
| 
      
 890 
     | 
    
         
            +
                    else
         
     | 
| 
      
 891 
     | 
    
         
            +
                      ctable = Sequel[:att]
         
     | 
| 
      
 892 
     | 
    
         
            +
                      cclass = Sequel[:cl]
         
     | 
| 
      
 893 
     | 
    
         
            +
                      rtable = Sequel[:att2]
         
     | 
| 
      
 894 
     | 
    
         
            +
                      rclass = Sequel[:cl2]
         
     | 
| 
      
 895 
     | 
    
         
            +
                    end
         
     | 
| 
      
 896 
     | 
    
         
            +
             
     | 
| 
      
 897 
     | 
    
         
            +
                    if server_version >= 90500
         
     | 
| 
      
 898 
     | 
    
         
            +
                      cpos = Sequel.expr{array_position(co[:conkey], ctable[:attnum])}
         
     | 
| 
      
 899 
     | 
    
         
            +
                      rpos = Sequel.expr{array_position(co[:confkey], rtable[:attnum])}
         
     | 
| 
      
 900 
     | 
    
         
            +
                    # :nocov:
         
     | 
| 
      
 901 
     | 
    
         
            +
                    else
         
     | 
| 
      
 902 
     | 
    
         
            +
                      range = 0...32
         
     | 
| 
      
 903 
     | 
    
         
            +
                      cpos = Sequel.expr{SQL::CaseExpression.new(range.map{|x| [SQL::Subscript.new(co[:conkey], [x]), x]}, 32, ctable[:attnum])}
         
     | 
| 
      
 904 
     | 
    
         
            +
                      rpos = Sequel.expr{SQL::CaseExpression.new(range.map{|x| [SQL::Subscript.new(co[:confkey], [x]), x]}, 32, rtable[:attnum])}
         
     | 
| 
      
 905 
     | 
    
         
            +
                    # :nocov:
         
     | 
| 
      
 906 
     | 
    
         
            +
                    end
         
     | 
| 
      
 907 
     | 
    
         
            +
             
     | 
| 
      
 908 
     | 
    
         
            +
                    ds = metadata_dataset.
         
     | 
| 
      
 909 
     | 
    
         
            +
                      from{pg_constraint.as(:co)}.
         
     | 
| 
      
 910 
     | 
    
         
            +
                      join(Sequel[:pg_class].as(cclass), :oid=>:conrelid).
         
     | 
| 
      
 911 
     | 
    
         
            +
                      join(Sequel[:pg_attribute].as(ctable), :attrelid=>:oid, :attnum=>SQL::Function.new(:ANY, Sequel[:co][:conkey])).
         
     | 
| 
      
 912 
     | 
    
         
            +
                      join(Sequel[:pg_class].as(rclass), :oid=>Sequel[:co][:confrelid]).
         
     | 
| 
      
 913 
     | 
    
         
            +
                      join(Sequel[:pg_attribute].as(rtable), :attrelid=>:oid, :attnum=>SQL::Function.new(:ANY, Sequel[:co][:confkey])).
         
     | 
| 
      
 914 
     | 
    
         
            +
                      join(Sequel[:pg_namespace].as(:nsp), :oid=>Sequel[:cl2][:relnamespace]).
         
     | 
| 
      
 915 
     | 
    
         
            +
                      order{[co[:conname], cpos]}.
         
     | 
| 
      
 916 
     | 
    
         
            +
                      where{{
         
     | 
| 
      
 917 
     | 
    
         
            +
                        cl[:relkind]=>%w'r p',
         
     | 
| 
      
 918 
     | 
    
         
            +
                        co[:contype]=>'f',
         
     | 
| 
      
 919 
     | 
    
         
            +
                        cpos=>rpos
         
     | 
| 
      
 920 
     | 
    
         
            +
                      }}.
         
     | 
| 
      
 921 
     | 
    
         
            +
                      select{[
         
     | 
| 
      
 922 
     | 
    
         
            +
                        co[:conname].as(:name),
         
     | 
| 
      
 923 
     | 
    
         
            +
                        ctable[:attname].as(:column),
         
     | 
| 
      
 924 
     | 
    
         
            +
                        co[:confupdtype].as(:on_update),
         
     | 
| 
      
 925 
     | 
    
         
            +
                        co[:confdeltype].as(:on_delete),
         
     | 
| 
      
 926 
     | 
    
         
            +
                        cl2[:relname].as(:table),
         
     | 
| 
      
 927 
     | 
    
         
            +
                        rtable[:attname].as(:refcolumn),
         
     | 
| 
      
 928 
     | 
    
         
            +
                        SQL::BooleanExpression.new(:AND, co[:condeferrable], co[:condeferred]).as(:deferrable),
         
     | 
| 
      
 929 
     | 
    
         
            +
                        nsp[:nspname].as(:schema)
         
     | 
| 
      
 930 
     | 
    
         
            +
                      ]}
         
     | 
| 
      
 931 
     | 
    
         
            +
             
     | 
| 
      
 932 
     | 
    
         
            +
                    if reverse
         
     | 
| 
      
 933 
     | 
    
         
            +
                      ds = ds.order_append(Sequel[:nsp][:nspname], Sequel[:cl2][:relname])
         
     | 
| 
      
 934 
     | 
    
         
            +
                    end
         
     | 
| 
      
 935 
     | 
    
         
            +
             
     | 
| 
      
 936 
     | 
    
         
            +
                    ds
         
     | 
| 
      
 937 
     | 
    
         
            +
                  end
         
     | 
| 
      
 938 
     | 
    
         
            +
             
     | 
| 
      
 939 
     | 
    
         
            +
                  # Dataset used to retrieve index information
         
     | 
| 
      
 940 
     | 
    
         
            +
                  def _indexes_ds
         
     | 
| 
      
 941 
     | 
    
         
            +
                    @_indexes_ds ||= begin
         
     | 
| 
      
 942 
     | 
    
         
            +
                      if server_version >= 90500
         
     | 
| 
      
 943 
     | 
    
         
            +
                        order = [Sequel[:indc][:relname], Sequel.function(:array_position, Sequel[:ind][:indkey], Sequel[:att][:attnum])]
         
     | 
| 
      
 944 
     | 
    
         
            +
                      # :nocov:
         
     | 
| 
      
 945 
     | 
    
         
            +
                      else
         
     | 
| 
      
 946 
     | 
    
         
            +
                        range = 0...32
         
     | 
| 
      
 947 
     | 
    
         
            +
                        order = [Sequel[:indc][:relname], SQL::CaseExpression.new(range.map{|x| [SQL::Subscript.new(Sequel[:ind][:indkey], [x]), x]}, 32, Sequel[:att][:attnum])]
         
     | 
| 
      
 948 
     | 
    
         
            +
                      # :nocov:
         
     | 
| 
      
 949 
     | 
    
         
            +
                      end
         
     | 
| 
      
 950 
     | 
    
         
            +
             
     | 
| 
      
 951 
     | 
    
         
            +
                      attnums = SQL::Function.new(:ANY, Sequel[:ind][:indkey])
         
     | 
| 
      
 952 
     | 
    
         
            +
             
     | 
| 
      
 953 
     | 
    
         
            +
                      ds = metadata_dataset.
         
     | 
| 
      
 954 
     | 
    
         
            +
                        from{pg_class.as(:tab)}.
         
     | 
| 
      
 955 
     | 
    
         
            +
                        join(Sequel[:pg_index].as(:ind), :indrelid=>:oid).
         
     | 
| 
      
 956 
     | 
    
         
            +
                        join(Sequel[:pg_class].as(:indc), :oid=>:indexrelid).
         
     | 
| 
      
 957 
     | 
    
         
            +
                        join(Sequel[:pg_attribute].as(:att), :attrelid=>Sequel[:tab][:oid], :attnum=>attnums).
         
     | 
| 
      
 958 
     | 
    
         
            +
                        left_join(Sequel[:pg_constraint].as(:con), :conname=>Sequel[:indc][:relname]).
         
     | 
| 
      
 959 
     | 
    
         
            +
                        where{{
         
     | 
| 
      
 960 
     | 
    
         
            +
                          indc[:relkind]=>%w'i I',
         
     | 
| 
      
 961 
     | 
    
         
            +
                          ind[:indisprimary]=>false,
         
     | 
| 
      
 962 
     | 
    
         
            +
                          :indexprs=>nil,
         
     | 
| 
      
 963 
     | 
    
         
            +
                          :indisvalid=>true}}.
         
     | 
| 
      
 964 
     | 
    
         
            +
                        order(*order).
         
     | 
| 
      
 965 
     | 
    
         
            +
                        select{[indc[:relname].as(:name), ind[:indisunique].as(:unique), att[:attname].as(:column), con[:condeferrable].as(:deferrable)]}
         
     | 
| 
      
 966 
     | 
    
         
            +
             
     | 
| 
      
 967 
     | 
    
         
            +
                      # :nocov:
         
     | 
| 
      
 968 
     | 
    
         
            +
                      ds = ds.where(:indisready=>true) if server_version >= 80300
         
     | 
| 
      
 969 
     | 
    
         
            +
                      ds = ds.where(:indislive=>true) if server_version >= 90300
         
     | 
| 
      
 970 
     | 
    
         
            +
                      # :nocov:
         
     | 
| 
      
 971 
     | 
    
         
            +
             
     | 
| 
      
 972 
     | 
    
         
            +
                      ds
         
     | 
| 
      
 973 
     | 
    
         
            +
                    end
         
     | 
| 
      
 974 
     | 
    
         
            +
                  end
         
     | 
| 
      
 975 
     | 
    
         
            +
             
     | 
| 
      
 976 
     | 
    
         
            +
                  # Dataset used to determine custom serial sequences for tables
         
     | 
| 
      
 977 
     | 
    
         
            +
                  def _select_custom_sequence_ds
         
     | 
| 
      
 978 
     | 
    
         
            +
                    @_select_custom_sequence_ds ||= metadata_dataset.
         
     | 
| 
      
 979 
     | 
    
         
            +
                      from{pg_class.as(:t)}.
         
     | 
| 
      
 980 
     | 
    
         
            +
                      join(:pg_namespace, {:oid => :relnamespace}, :table_alias=>:name).
         
     | 
| 
      
 981 
     | 
    
         
            +
                      join(:pg_attribute, {:attrelid => Sequel[:t][:oid]}, :table_alias=>:attr).
         
     | 
| 
      
 982 
     | 
    
         
            +
                      join(:pg_attrdef, {:adrelid => :attrelid, :adnum => :attnum}, :table_alias=>:def).
         
     | 
| 
      
 983 
     | 
    
         
            +
                      join(:pg_constraint, {:conrelid => :adrelid, Sequel[:cons][:conkey].sql_subscript(1) => :adnum}, :table_alias=>:cons).
         
     | 
| 
      
 984 
     | 
    
         
            +
                      where{{cons[:contype] => 'p', pg_get_expr(self.def[:adbin], attr[:attrelid]) => /nextval/i}}.
         
     | 
| 
      
 985 
     | 
    
         
            +
                      select{
         
     | 
| 
      
 986 
     | 
    
         
            +
                        expr = split_part(pg_get_expr(self.def[:adbin], attr[:attrelid]), "'", 2)
         
     | 
| 
      
 987 
     | 
    
         
            +
                        [
         
     | 
| 
      
 988 
     | 
    
         
            +
                          name[:nspname].as(:schema),
         
     | 
| 
      
 989 
     | 
    
         
            +
                          Sequel.case({{expr => /./} => substr(expr, strpos(expr, '.')+1)}, expr).as(:sequence)
         
     | 
| 
      
 990 
     | 
    
         
            +
                        ]
         
     | 
| 
      
 991 
     | 
    
         
            +
                      }
         
     | 
| 
      
 992 
     | 
    
         
            +
                  end
         
     | 
| 
      
 993 
     | 
    
         
            +
             
     | 
| 
      
 994 
     | 
    
         
            +
                  # Dataset used to determine normal serial sequences for tables
         
     | 
| 
      
 995 
     | 
    
         
            +
                  def _select_serial_sequence_ds
         
     | 
| 
      
 996 
     | 
    
         
            +
                    @_serial_sequence_ds ||= metadata_dataset.
         
     | 
| 
      
 997 
     | 
    
         
            +
                      from{[
         
     | 
| 
      
 998 
     | 
    
         
            +
                        pg_class.as(:seq),
         
     | 
| 
      
 999 
     | 
    
         
            +
                        pg_attribute.as(:attr),
         
     | 
| 
      
 1000 
     | 
    
         
            +
                        pg_depend.as(:dep),
         
     | 
| 
      
 1001 
     | 
    
         
            +
                        pg_namespace.as(:name),
         
     | 
| 
      
 1002 
     | 
    
         
            +
                        pg_constraint.as(:cons),
         
     | 
| 
      
 1003 
     | 
    
         
            +
                        pg_class.as(:t)
         
     | 
| 
      
 1004 
     | 
    
         
            +
                      ]}.
         
     | 
| 
      
 1005 
     | 
    
         
            +
                      where{[
         
     | 
| 
      
 1006 
     | 
    
         
            +
                        [seq[:oid], dep[:objid]],
         
     | 
| 
      
 1007 
     | 
    
         
            +
                        [seq[:relnamespace], name[:oid]],
         
     | 
| 
      
 1008 
     | 
    
         
            +
                        [seq[:relkind], 'S'],
         
     | 
| 
      
 1009 
     | 
    
         
            +
                        [attr[:attrelid], dep[:refobjid]],
         
     | 
| 
      
 1010 
     | 
    
         
            +
                        [attr[:attnum], dep[:refobjsubid]],
         
     | 
| 
      
 1011 
     | 
    
         
            +
                        [attr[:attrelid], cons[:conrelid]],
         
     | 
| 
      
 1012 
     | 
    
         
            +
                        [attr[:attnum], cons[:conkey].sql_subscript(1)],
         
     | 
| 
      
 1013 
     | 
    
         
            +
                        [attr[:attrelid], t[:oid]],
         
     | 
| 
      
 1014 
     | 
    
         
            +
                        [cons[:contype], 'p']
         
     | 
| 
      
 1015 
     | 
    
         
            +
                      ]}.
         
     | 
| 
      
 1016 
     | 
    
         
            +
                      select{[
         
     | 
| 
      
 1017 
     | 
    
         
            +
                        name[:nspname].as(:schema),
         
     | 
| 
      
 1018 
     | 
    
         
            +
                        seq[:relname].as(:sequence)
         
     | 
| 
      
 1019 
     | 
    
         
            +
                      ]}
         
     | 
| 
      
 1020 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1021 
     | 
    
         
            +
             
     | 
| 
      
 1022 
     | 
    
         
            +
                  # Dataset used to determine primary keys for tables
         
     | 
| 
      
 1023 
     | 
    
         
            +
                  def _select_pk_ds
         
     | 
| 
      
 1024 
     | 
    
         
            +
                    @_select_pk_ds ||= metadata_dataset.
         
     | 
| 
      
 1025 
     | 
    
         
            +
                      from(:pg_class, :pg_attribute, :pg_index, :pg_namespace).
         
     | 
| 
      
 1026 
     | 
    
         
            +
                      where{[
         
     | 
| 
      
 1027 
     | 
    
         
            +
                        [pg_class[:oid], pg_attribute[:attrelid]],
         
     | 
| 
      
 1028 
     | 
    
         
            +
                        [pg_class[:relnamespace], pg_namespace[:oid]],
         
     | 
| 
      
 1029 
     | 
    
         
            +
                        [pg_class[:oid], pg_index[:indrelid]],
         
     | 
| 
      
 1030 
     | 
    
         
            +
                        [pg_index[:indkey].sql_subscript(0), pg_attribute[:attnum]],
         
     | 
| 
      
 1031 
     | 
    
         
            +
                        [pg_index[:indisprimary], 't']
         
     | 
| 
      
 1032 
     | 
    
         
            +
                      ]}.
         
     | 
| 
      
 1033 
     | 
    
         
            +
                      select{pg_attribute[:attname].as(:pk)}
         
     | 
| 
      
 1034 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1035 
     | 
    
         
            +
             
     | 
| 
      
 1036 
     | 
    
         
            +
                  # Dataset used to get schema for tables
         
     | 
| 
      
 1037 
     | 
    
         
            +
                  def _schema_ds
         
     | 
| 
      
 1038 
     | 
    
         
            +
                    @_schema_ds ||= begin
         
     | 
| 
      
 1039 
     | 
    
         
            +
                      ds = metadata_dataset.select{[
         
     | 
| 
      
 1040 
     | 
    
         
            +
                          pg_attribute[:attname].as(:name),
         
     | 
| 
      
 1041 
     | 
    
         
            +
                          SQL::Cast.new(pg_attribute[:atttypid], :integer).as(:oid),
         
     | 
| 
      
 1042 
     | 
    
         
            +
                          SQL::Cast.new(basetype[:oid], :integer).as(:base_oid),
         
     | 
| 
      
 1043 
     | 
    
         
            +
                          SQL::Function.new(:format_type, basetype[:oid], pg_type[:typtypmod]).as(:db_base_type),
         
     | 
| 
      
 1044 
     | 
    
         
            +
                          SQL::Function.new(:format_type, pg_type[:oid], pg_attribute[:atttypmod]).as(:db_type),
         
     | 
| 
      
 1045 
     | 
    
         
            +
                          SQL::Function.new(:pg_get_expr, pg_attrdef[:adbin], pg_class[:oid]).as(:default),
         
     | 
| 
      
 1046 
     | 
    
         
            +
                          SQL::BooleanExpression.new(:NOT, pg_attribute[:attnotnull]).as(:allow_null),
         
     | 
| 
      
 1047 
     | 
    
         
            +
                          SQL::Function.new(:COALESCE, SQL::BooleanExpression.from_value_pairs(pg_attribute[:attnum] => SQL::Function.new(:ANY, pg_index[:indkey])), false).as(:primary_key),
         
     | 
| 
      
 1048 
     | 
    
         
            +
                          Sequel[:pg_type][:typtype],
         
     | 
| 
      
 1049 
     | 
    
         
            +
                          (~Sequel[Sequel[:elementtype][:oid]=>nil]).as(:is_array),
         
     | 
| 
      
 1050 
     | 
    
         
            +
                        ]}.
         
     | 
| 
      
 1051 
     | 
    
         
            +
                        from(:pg_class).
         
     | 
| 
      
 1052 
     | 
    
         
            +
                        join(:pg_attribute, :attrelid=>:oid).
         
     | 
| 
      
 1053 
     | 
    
         
            +
                        join(:pg_type, :oid=>:atttypid).
         
     | 
| 
      
 1054 
     | 
    
         
            +
                        left_outer_join(Sequel[:pg_type].as(:basetype), :oid=>:typbasetype).
         
     | 
| 
      
 1055 
     | 
    
         
            +
                        left_outer_join(Sequel[:pg_type].as(:elementtype), :typarray=>Sequel[:pg_type][:oid]).
         
     | 
| 
      
 1056 
     | 
    
         
            +
                        left_outer_join(:pg_attrdef, :adrelid=>Sequel[:pg_class][:oid], :adnum=>Sequel[:pg_attribute][:attnum]).
         
     | 
| 
      
 1057 
     | 
    
         
            +
                        left_outer_join(:pg_index, :indrelid=>Sequel[:pg_class][:oid], :indisprimary=>true).
         
     | 
| 
      
 1058 
     | 
    
         
            +
                        where{{pg_attribute[:attisdropped]=>false}}.
         
     | 
| 
      
 1059 
     | 
    
         
            +
                        where{pg_attribute[:attnum] > 0}.
         
     | 
| 
      
 1060 
     | 
    
         
            +
                        order{pg_attribute[:attnum]}
         
     | 
| 
      
 1061 
     | 
    
         
            +
             
     | 
| 
      
 1062 
     | 
    
         
            +
                      # :nocov:
         
     | 
| 
      
 1063 
     | 
    
         
            +
                      if server_version > 100000
         
     | 
| 
      
 1064 
     | 
    
         
            +
                      # :nocov:
         
     | 
| 
      
 1065 
     | 
    
         
            +
                        ds = ds.select_append{pg_attribute[:attidentity]}
         
     | 
| 
      
 1066 
     | 
    
         
            +
             
     | 
| 
      
 1067 
     | 
    
         
            +
                        # :nocov:
         
     | 
| 
      
 1068 
     | 
    
         
            +
                        if server_version > 120000
         
     | 
| 
      
 1069 
     | 
    
         
            +
                        # :nocov:
         
     | 
| 
      
 1070 
     | 
    
         
            +
                          ds = ds.select_append{Sequel.~(pg_attribute[:attgenerated]=>'').as(:generated)}
         
     | 
| 
      
 1071 
     | 
    
         
            +
                        end
         
     | 
| 
      
 1072 
     | 
    
         
            +
                      end
         
     | 
| 
      
 1073 
     | 
    
         
            +
             
     | 
| 
      
 1074 
     | 
    
         
            +
                      ds
         
     | 
| 
      
 1075 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1076 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1077 
     | 
    
         
            +
             
     | 
| 
      
 1078 
     | 
    
         
            +
                  # Internals of defer_constraints/immediate_constraints
         
     | 
| 
      
 1079 
     | 
    
         
            +
                  def _set_constraints(type, opts)
         
     | 
| 
      
 1080 
     | 
    
         
            +
                    execute_ddl(_set_constraints_sql(type, opts), opts)
         
     | 
| 
      
 1081 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1082 
     | 
    
         
            +
             
     | 
| 
      
 1083 
     | 
    
         
            +
                  # SQL to use for SET CONSTRAINTS
         
     | 
| 
      
 1084 
     | 
    
         
            +
                  def _set_constraints_sql(type, opts)
         
     | 
| 
      
 1085 
     | 
    
         
            +
                    sql = String.new
         
     | 
| 
      
 1086 
     | 
    
         
            +
                    sql << "SET CONSTRAINTS "
         
     | 
| 
      
 1087 
     | 
    
         
            +
                    if constraints = opts[:constraints]
         
     | 
| 
      
 1088 
     | 
    
         
            +
                      dataset.send(:source_list_append, sql, Array(constraints))
         
     | 
| 
      
 1089 
     | 
    
         
            +
                    else
         
     | 
| 
      
 1090 
     | 
    
         
            +
                      sql << "ALL"
         
     | 
| 
      
 1091 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1092 
     | 
    
         
            +
                    sql << type
         
     | 
| 
      
 1093 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1094 
     | 
    
         
            +
             
     | 
| 
      
 1095 
     | 
    
         
            +
                  # Consider lock or statement timeout errors as evidence that the table exists
         
     | 
| 
      
 1096 
     | 
    
         
            +
                  # but is locked.
         
     | 
| 
      
 1097 
     | 
    
         
            +
                  def _table_exists?(ds)
         
     | 
| 
      
 1098 
     | 
    
         
            +
                    super
         
     | 
| 
      
 1099 
     | 
    
         
            +
                  rescue DatabaseError => e    
         
     | 
| 
      
 1100 
     | 
    
         
            +
                    raise e unless /canceling statement due to (?:statement|lock) timeout/ =~ e.message 
         
     | 
| 
      
 1101 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1102 
     | 
    
         
            +
                
         
     | 
| 
       886 
1103 
     | 
    
         
             
                  def alter_table_add_column_sql(table, op)
         
     | 
| 
       887 
1104 
     | 
    
         
             
                    "ADD COLUMN#{' IF NOT EXISTS' if op[:if_not_exists]} #{column_definition_sql(op)}"
         
     | 
| 
       888 
1105 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -1116,6 +1333,7 @@ module Sequel 
     | 
|
| 
       1116 
1333 
     | 
    
         
             
                    #{opts[:behavior].to_s.upcase if opts[:behavior]}
         
     | 
| 
       1117 
1334 
     | 
    
         
             
                    #{'STRICT' if opts[:strict]}
         
     | 
| 
       1118 
1335 
     | 
    
         
             
                    #{'SECURITY DEFINER' if opts[:security_definer]}
         
     | 
| 
      
 1336 
     | 
    
         
            +
                    #{"PARALLEL #{opts[:parallel].to_s.upcase}" if opts[:parallel]}
         
     | 
| 
       1119 
1337 
     | 
    
         
             
                    #{"COST #{opts[:cost]}" if opts[:cost]}
         
     | 
| 
       1120 
1338 
     | 
    
         
             
                    #{"ROWS #{opts[:rows]}" if opts[:rows]}
         
     | 
| 
       1121 
1339 
     | 
    
         
             
                    #{opts[:set].map{|k,v| " SET #{k} = #{v}"}.join("\n") if opts[:set]}
         
     | 
| 
         @@ -1149,7 +1367,7 @@ module Sequel 
     | 
|
| 
       1149 
1367 
     | 
    
         
             
                    when :hash
         
     | 
| 
       1150 
1368 
     | 
    
         
             
                      mod, remainder = generator.hash_values
         
     | 
| 
       1151 
1369 
     | 
    
         
             
                      sql << " FOR VALUES WITH (MODULUS #{literal(mod)}, REMAINDER #{literal(remainder)})"
         
     | 
| 
       1152 
     | 
    
         
            -
                    when :default
         
     | 
| 
      
 1370 
     | 
    
         
            +
                    else # when :default
         
     | 
| 
       1153 
1371 
     | 
    
         
             
                      sql << " DEFAULT"
         
     | 
| 
       1154 
1372 
     | 
    
         
             
                    end
         
     | 
| 
       1155 
1373 
     | 
    
         | 
| 
         @@ -1237,13 +1455,17 @@ module Sequel 
     | 
|
| 
       1237 
1455 
     | 
    
         
             
                      raise Error, "Trigger conditions are not supported for this database" unless supports_trigger_conditions?
         
     | 
| 
       1238 
1456 
     | 
    
         
             
                      filter = " WHEN #{filter_expr(filter)}"
         
     | 
| 
       1239 
1457 
     | 
    
         
             
                    end
         
     | 
| 
       1240 
     | 
    
         
            -
                    "CREATE TRIGGER #{name} #{whence} #{events.map{|e| e.to_s.upcase}.join(' OR ')} ON #{quote_schema_table(table)}#{' FOR EACH ROW' if opts[:each_row]}#{filter} EXECUTE PROCEDURE #{function}(#{Array(opts[:args]).map{|a| literal(a)}.join(', ')})"
         
     | 
| 
      
 1458 
     | 
    
         
            +
                    "CREATE #{'OR REPLACE ' if opts[:replace]}TRIGGER #{name} #{whence} #{events.map{|e| e.to_s.upcase}.join(' OR ')} ON #{quote_schema_table(table)}#{' FOR EACH ROW' if opts[:each_row]}#{filter} EXECUTE PROCEDURE #{function}(#{Array(opts[:args]).map{|a| literal(a)}.join(', ')})"
         
     | 
| 
       1241 
1459 
     | 
    
         
             
                  end
         
     | 
| 
       1242 
1460 
     | 
    
         | 
| 
       1243 
1461 
     | 
    
         
             
                  # DDL fragment for initial part of CREATE VIEW statement
         
     | 
| 
       1244 
1462 
     | 
    
         
             
                  def create_view_prefix_sql(name, options)
         
     | 
| 
       1245 
1463 
     | 
    
         
             
                    sql = create_view_sql_append_columns("CREATE #{'OR REPLACE 'if options[:replace]}#{'TEMPORARY 'if options[:temp]}#{'RECURSIVE ' if options[:recursive]}#{'MATERIALIZED ' if options[:materialized]}VIEW #{quote_schema_table(name)}", options[:columns] || options[:recursive])
         
     | 
| 
       1246 
1464 
     | 
    
         | 
| 
      
 1465 
     | 
    
         
            +
                    if options[:security_invoker]
         
     | 
| 
      
 1466 
     | 
    
         
            +
                      sql += " WITH (security_invoker)"
         
     | 
| 
      
 1467 
     | 
    
         
            +
                    end
         
     | 
| 
      
 1468 
     | 
    
         
            +
             
     | 
| 
       1247 
1469 
     | 
    
         
             
                    if tablespace = options[:tablespace]
         
     | 
| 
       1248 
1470 
     | 
    
         
             
                      sql += " TABLESPACE #{quote_identifier(tablespace)}"
         
     | 
| 
       1249 
1471 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -1291,7 +1513,11 @@ module Sequel 
     | 
|
| 
       1291 
1513 
     | 
    
         
             
                  # currently visible schemas.
         
     | 
| 
       1292 
1514 
     | 
    
         
             
                  def filter_schema(ds, opts)
         
     | 
| 
       1293 
1515 
     | 
    
         
             
                    expr = if schema = opts[:schema]
         
     | 
| 
       1294 
     | 
    
         
            -
                      schema. 
     | 
| 
      
 1516 
     | 
    
         
            +
                      if schema.is_a?(SQL::Identifier)
         
     | 
| 
      
 1517 
     | 
    
         
            +
                        schema.value.to_s
         
     | 
| 
      
 1518 
     | 
    
         
            +
                      else
         
     | 
| 
      
 1519 
     | 
    
         
            +
                        schema.to_s
         
     | 
| 
      
 1520 
     | 
    
         
            +
                      end
         
     | 
| 
       1295 
1521 
     | 
    
         
             
                    else
         
     | 
| 
       1296 
1522 
     | 
    
         
             
                      Sequel.function(:any, Sequel.function(:current_schemas, false))
         
     | 
| 
       1297 
1523 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -1301,16 +1527,20 @@ module Sequel 
     | 
|
| 
       1301 
1527 
     | 
    
         
             
                  def index_definition_sql(table_name, index)
         
     | 
| 
       1302 
1528 
     | 
    
         
             
                    cols = index[:columns]
         
     | 
| 
       1303 
1529 
     | 
    
         
             
                    index_name = index[:name] || default_index_name(table_name, cols)
         
     | 
| 
      
 1530 
     | 
    
         
            +
             
     | 
| 
       1304 
1531 
     | 
    
         
             
                    expr = if o = index[:opclass]
         
     | 
| 
       1305 
1532 
     | 
    
         
             
                      "(#{Array(cols).map{|c| "#{literal(c)} #{o}"}.join(', ')})"
         
     | 
| 
       1306 
1533 
     | 
    
         
             
                    else
         
     | 
| 
       1307 
1534 
     | 
    
         
             
                      literal(Array(cols))
         
     | 
| 
       1308 
1535 
     | 
    
         
             
                    end
         
     | 
| 
      
 1536 
     | 
    
         
            +
             
     | 
| 
       1309 
1537 
     | 
    
         
             
                    if_not_exists = " IF NOT EXISTS" if index[:if_not_exists]
         
     | 
| 
       1310 
1538 
     | 
    
         
             
                    unique = "UNIQUE " if index[:unique]
         
     | 
| 
       1311 
1539 
     | 
    
         
             
                    index_type = index[:type]
         
     | 
| 
       1312 
1540 
     | 
    
         
             
                    filter = index[:where] || index[:filter]
         
     | 
| 
       1313 
1541 
     | 
    
         
             
                    filter = " WHERE #{filter_expr(filter)}" if filter
         
     | 
| 
      
 1542 
     | 
    
         
            +
                    nulls_distinct = " NULLS#{' NOT' if index[:nulls_distinct] == false} DISTINCT" unless index[:nulls_distinct].nil?
         
     | 
| 
      
 1543 
     | 
    
         
            +
             
     | 
| 
       1314 
1544 
     | 
    
         
             
                    case index_type
         
     | 
| 
       1315 
1545 
     | 
    
         
             
                    when :full_text
         
     | 
| 
       1316 
1546 
     | 
    
         
             
                      expr = "(to_tsvector(#{literal(index[:language] || 'simple')}::regconfig, #{literal(dataset.send(:full_text_string_join, cols))}))"
         
     | 
| 
         @@ -1318,7 +1548,8 @@ module Sequel 
     | 
|
| 
       1318 
1548 
     | 
    
         
             
                    when :spatial
         
     | 
| 
       1319 
1549 
     | 
    
         
             
                      index_type = :gist
         
     | 
| 
       1320 
1550 
     | 
    
         
             
                    end
         
     | 
| 
       1321 
     | 
    
         
            -
             
     | 
| 
      
 1551 
     | 
    
         
            +
             
     | 
| 
      
 1552 
     | 
    
         
            +
                    "CREATE #{unique}INDEX#{' CONCURRENTLY' if index[:concurrently]}#{if_not_exists} #{quote_identifier(index_name)} ON #{quote_schema_table(table_name)} #{"USING #{index_type} " if index_type}#{expr}#{" INCLUDE #{literal(Array(index[:include]))}" if index[:include]}#{nulls_distinct}#{" TABLESPACE #{quote_identifier(index[:tablespace])}" if index[:tablespace]}#{filter}"
         
     | 
| 
       1322 
1553 
     | 
    
         
             
                  end
         
     | 
| 
       1323 
1554 
     | 
    
         | 
| 
       1324 
1555 
     | 
    
         
             
                  # Setup datastructures shared by all postgres adapters.
         
     | 
| 
         @@ -1335,7 +1566,7 @@ module Sequel 
     | 
|
| 
       1335 
1566 
     | 
    
         
             
                    ds = metadata_dataset.from(:pg_class).where(:relkind=>type).select(:relname).server(opts[:server]).join(:pg_namespace, :oid=>:relnamespace)
         
     | 
| 
       1336 
1567 
     | 
    
         
             
                    ds = filter_schema(ds, opts)
         
     | 
| 
       1337 
1568 
     | 
    
         
             
                    m = output_identifier_meth
         
     | 
| 
       1338 
     | 
    
         
            -
                    if  
     | 
| 
      
 1569 
     | 
    
         
            +
                    if defined?(yield)
         
     | 
| 
       1339 
1570 
     | 
    
         
             
                      yield(ds)
         
     | 
| 
       1340 
1571 
     | 
    
         
             
                    elsif opts[:qualify]
         
     | 
| 
       1341 
1572 
     | 
    
         
             
                      ds.select_append{pg_namespace[:nspname]}.map{|r| Sequel.qualify(m.call(r[:nspname]).to_s, m.call(r[:relname]).to_s)}
         
     | 
| 
         @@ -1344,11 +1575,6 @@ module Sequel 
     | 
|
| 
       1344 
1575 
     | 
    
         
             
                    end
         
     | 
| 
       1345 
1576 
     | 
    
         
             
                  end
         
     | 
| 
       1346 
1577 
     | 
    
         | 
| 
       1347 
     | 
    
         
            -
                  # Use a dollar sign instead of question mark for the argument placeholder.
         
     | 
| 
       1348 
     | 
    
         
            -
                  def prepared_arg_placeholder
         
     | 
| 
       1349 
     | 
    
         
            -
                    PREPARED_ARG_PLACEHOLDER
         
     | 
| 
       1350 
     | 
    
         
            -
                  end
         
     | 
| 
       1351 
     | 
    
         
            -
             
     | 
| 
       1352 
1578 
     | 
    
         
             
                  # Return an expression the oid for the table expr.  Used by the metadata parsing
         
     | 
| 
       1353 
1579 
     | 
    
         
             
                  # code to disambiguate unqualified tables.
         
     | 
| 
       1354 
1580 
     | 
    
         
             
                  def regclass_oid(expr, opts=OPTS)
         
     | 
| 
         @@ -1382,11 +1608,12 @@ module Sequel 
     | 
|
| 
       1382 
1608 
     | 
    
         
             
                  end
         
     | 
| 
       1383 
1609 
     | 
    
         | 
| 
       1384 
1610 
     | 
    
         
             
                  # SQL DDL statement for renaming a table. PostgreSQL doesn't allow you to change a table's schema in
         
     | 
| 
       1385 
     | 
    
         
            -
                  # a rename table operation, so  
     | 
| 
      
 1611 
     | 
    
         
            +
                  # a rename table operation, so specifying a new schema in new_name will not have an effect.
         
     | 
| 
       1386 
1612 
     | 
    
         
             
                  def rename_table_sql(name, new_name)
         
     | 
| 
       1387 
1613 
     | 
    
         
             
                    "ALTER TABLE #{quote_schema_table(name)} RENAME TO #{quote_identifier(schema_and_table(new_name).last)}"
         
     | 
| 
       1388 
1614 
     | 
    
         
             
                  end
         
     | 
| 
       1389 
1615 
     | 
    
         | 
| 
      
 1616 
     | 
    
         
            +
                  # Handle interval and citext types.
         
     | 
| 
       1390 
1617 
     | 
    
         
             
                  def schema_column_type(db_type)
         
     | 
| 
       1391 
1618 
     | 
    
         
             
                    case db_type
         
     | 
| 
       1392 
1619 
     | 
    
         
             
                    when /\Ainterval\z/io
         
     | 
| 
         @@ -1398,39 +1625,48 @@ module Sequel 
     | 
|
| 
       1398 
1625 
     | 
    
         
             
                    end
         
     | 
| 
       1399 
1626 
     | 
    
         
             
                  end
         
     | 
| 
       1400 
1627 
     | 
    
         | 
| 
      
 1628 
     | 
    
         
            +
                  # The schema :type entry to use for array types.
         
     | 
| 
      
 1629 
     | 
    
         
            +
                  def schema_array_type(db_type)
         
     | 
| 
      
 1630 
     | 
    
         
            +
                    :array
         
     | 
| 
      
 1631 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1632 
     | 
    
         
            +
             
     | 
| 
      
 1633 
     | 
    
         
            +
                  # The schema :type entry to use for row/composite types.
         
     | 
| 
      
 1634 
     | 
    
         
            +
                  def schema_composite_type(db_type)
         
     | 
| 
      
 1635 
     | 
    
         
            +
                    :composite
         
     | 
| 
      
 1636 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1637 
     | 
    
         
            +
             
     | 
| 
      
 1638 
     | 
    
         
            +
                  # The schema :type entry to use for enum types.
         
     | 
| 
      
 1639 
     | 
    
         
            +
                  def schema_enum_type(db_type)
         
     | 
| 
      
 1640 
     | 
    
         
            +
                    :enum
         
     | 
| 
      
 1641 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1642 
     | 
    
         
            +
             
     | 
| 
      
 1643 
     | 
    
         
            +
                  # The schema :type entry to use for range types.
         
     | 
| 
      
 1644 
     | 
    
         
            +
                  def schema_range_type(db_type)
         
     | 
| 
      
 1645 
     | 
    
         
            +
                    :range
         
     | 
| 
      
 1646 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1647 
     | 
    
         
            +
             
     | 
| 
      
 1648 
     | 
    
         
            +
                  # The schema :type entry to use for multirange types.
         
     | 
| 
      
 1649 
     | 
    
         
            +
                  def schema_multirange_type(db_type)
         
     | 
| 
      
 1650 
     | 
    
         
            +
                    :multirange
         
     | 
| 
      
 1651 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1652 
     | 
    
         
            +
             
     | 
| 
      
 1653 
     | 
    
         
            +
                  MIN_DATE = Date.new(-4713, 11, 24)
         
     | 
| 
      
 1654 
     | 
    
         
            +
                  MAX_DATE = Date.new(5874897, 12, 31)
         
     | 
| 
      
 1655 
     | 
    
         
            +
                  MIN_TIMESTAMP = Time.utc(-4713, 11, 24).freeze
         
     | 
| 
      
 1656 
     | 
    
         
            +
                  MAX_TIMESTAMP = (Time.utc(294277) - Rational(1, 1000000)).freeze
         
     | 
| 
      
 1657 
     | 
    
         
            +
                  TYPTYPE_METHOD_MAP = {
         
     | 
| 
      
 1658 
     | 
    
         
            +
                    'c' => :schema_composite_type,
         
     | 
| 
      
 1659 
     | 
    
         
            +
                    'e' => :schema_enum_type,
         
     | 
| 
      
 1660 
     | 
    
         
            +
                    'r' => :schema_range_type,
         
     | 
| 
      
 1661 
     | 
    
         
            +
                    'm' => :schema_multirange_type,
         
     | 
| 
      
 1662 
     | 
    
         
            +
                  }
         
     | 
| 
      
 1663 
     | 
    
         
            +
                  TYPTYPE_METHOD_MAP.default = :schema_column_type
         
     | 
| 
      
 1664 
     | 
    
         
            +
                  TYPTYPE_METHOD_MAP.freeze
         
     | 
| 
       1401 
1665 
     | 
    
         
             
                  # The dataset used for parsing table schemas, using the pg_* system catalogs.
         
     | 
| 
       1402 
1666 
     | 
    
         
             
                  def schema_parse_table(table_name, opts)
         
     | 
| 
       1403 
1667 
     | 
    
         
             
                    m = output_identifier_meth(opts[:dataset])
         
     | 
| 
       1404 
     | 
    
         
            -
                    oid = regclass_oid(table_name, opts)
         
     | 
| 
       1405 
     | 
    
         
            -
                    ds = metadata_dataset.select{[
         
     | 
| 
       1406 
     | 
    
         
            -
                        pg_attribute[:attname].as(:name),
         
     | 
| 
       1407 
     | 
    
         
            -
                        SQL::Cast.new(pg_attribute[:atttypid], :integer).as(:oid),
         
     | 
| 
       1408 
     | 
    
         
            -
                        SQL::Cast.new(basetype[:oid], :integer).as(:base_oid),
         
     | 
| 
       1409 
     | 
    
         
            -
                        SQL::Function.new(:format_type, basetype[:oid], pg_type[:typtypmod]).as(:db_base_type),
         
     | 
| 
       1410 
     | 
    
         
            -
                        SQL::Function.new(:format_type, pg_type[:oid], pg_attribute[:atttypmod]).as(:db_type),
         
     | 
| 
       1411 
     | 
    
         
            -
                        SQL::Function.new(:pg_get_expr, pg_attrdef[:adbin], pg_class[:oid]).as(:default),
         
     | 
| 
       1412 
     | 
    
         
            -
                        SQL::BooleanExpression.new(:NOT, pg_attribute[:attnotnull]).as(:allow_null),
         
     | 
| 
       1413 
     | 
    
         
            -
                        SQL::Function.new(:COALESCE, SQL::BooleanExpression.from_value_pairs(pg_attribute[:attnum] => SQL::Function.new(:ANY, pg_index[:indkey])), false).as(:primary_key)]}.
         
     | 
| 
       1414 
     | 
    
         
            -
                      from(:pg_class).
         
     | 
| 
       1415 
     | 
    
         
            -
                      join(:pg_attribute, :attrelid=>:oid).
         
     | 
| 
       1416 
     | 
    
         
            -
                      join(:pg_type, :oid=>:atttypid).
         
     | 
| 
       1417 
     | 
    
         
            -
                      left_outer_join(Sequel[:pg_type].as(:basetype), :oid=>:typbasetype).
         
     | 
| 
       1418 
     | 
    
         
            -
                      left_outer_join(:pg_attrdef, :adrelid=>Sequel[:pg_class][:oid], :adnum=>Sequel[:pg_attribute][:attnum]).
         
     | 
| 
       1419 
     | 
    
         
            -
                      left_outer_join(:pg_index, :indrelid=>Sequel[:pg_class][:oid], :indisprimary=>true).
         
     | 
| 
       1420 
     | 
    
         
            -
                      where{{pg_attribute[:attisdropped]=>false}}.
         
     | 
| 
       1421 
     | 
    
         
            -
                      where{pg_attribute[:attnum] > 0}.
         
     | 
| 
       1422 
     | 
    
         
            -
                      where{{pg_class[:oid]=>oid}}.
         
     | 
| 
       1423 
     | 
    
         
            -
                      order{pg_attribute[:attnum]}
         
     | 
| 
       1424 
     | 
    
         
            -
             
     | 
| 
       1425 
     | 
    
         
            -
                    if server_version > 100000
         
     | 
| 
       1426 
     | 
    
         
            -
                      ds = ds.select_append{pg_attribute[:attidentity]}
         
     | 
| 
       1427 
     | 
    
         
            -
             
     | 
| 
       1428 
     | 
    
         
            -
                      if server_version > 120000
         
     | 
| 
       1429 
     | 
    
         
            -
                        ds = ds.select_append{Sequel.~(pg_attribute[:attgenerated]=>'').as(:generated)}
         
     | 
| 
       1430 
     | 
    
         
            -
                      end
         
     | 
| 
       1431 
     | 
    
         
            -
                    end
         
     | 
| 
       1432 
1668 
     | 
    
         | 
| 
       1433 
     | 
    
         
            -
                     
     | 
| 
      
 1669 
     | 
    
         
            +
                    _schema_ds.where_all(Sequel[:pg_class][:oid]=>regclass_oid(table_name, opts)).map do |row|
         
     | 
| 
       1434 
1670 
     | 
    
         
             
                      row[:default] = nil if blank_object?(row[:default])
         
     | 
| 
       1435 
1671 
     | 
    
         
             
                      if row[:base_oid]
         
     | 
| 
       1436 
1672 
     | 
    
         
             
                        row[:domain_oid] = row[:oid]
         
     | 
| 
         @@ -1441,11 +1677,33 @@ module Sequel 
     | 
|
| 
       1441 
1677 
     | 
    
         
             
                        row.delete(:base_oid)
         
     | 
| 
       1442 
1678 
     | 
    
         
             
                        row.delete(:db_base_type)
         
     | 
| 
       1443 
1679 
     | 
    
         
             
                      end
         
     | 
| 
       1444 
     | 
    
         
            -
             
     | 
| 
      
 1680 
     | 
    
         
            +
             
     | 
| 
      
 1681 
     | 
    
         
            +
                      db_type = row[:db_type]
         
     | 
| 
      
 1682 
     | 
    
         
            +
                      row[:type] = if row.delete(:is_array)
         
     | 
| 
      
 1683 
     | 
    
         
            +
                        schema_array_type(db_type)
         
     | 
| 
      
 1684 
     | 
    
         
            +
                      else
         
     | 
| 
      
 1685 
     | 
    
         
            +
                        send(TYPTYPE_METHOD_MAP[row.delete(:typtype)], db_type)
         
     | 
| 
      
 1686 
     | 
    
         
            +
                      end
         
     | 
| 
       1445 
1687 
     | 
    
         
             
                      identity = row.delete(:attidentity)
         
     | 
| 
       1446 
1688 
     | 
    
         
             
                      if row[:primary_key]
         
     | 
| 
       1447 
1689 
     | 
    
         
             
                        row[:auto_increment] = !!(row[:default] =~ /\A(?:nextval)/i) || identity == 'a' || identity == 'd'
         
     | 
| 
       1448 
1690 
     | 
    
         
             
                      end
         
     | 
| 
      
 1691 
     | 
    
         
            +
             
     | 
| 
      
 1692 
     | 
    
         
            +
                      # :nocov:
         
     | 
| 
      
 1693 
     | 
    
         
            +
                      if server_version >= 90600
         
     | 
| 
      
 1694 
     | 
    
         
            +
                      # :nocov:
         
     | 
| 
      
 1695 
     | 
    
         
            +
                        case row[:oid]
         
     | 
| 
      
 1696 
     | 
    
         
            +
                        when 1082
         
     | 
| 
      
 1697 
     | 
    
         
            +
                          row[:min_value] = MIN_DATE
         
     | 
| 
      
 1698 
     | 
    
         
            +
                          row[:max_value] = MAX_DATE
         
     | 
| 
      
 1699 
     | 
    
         
            +
                        when 1184, 1114
         
     | 
| 
      
 1700 
     | 
    
         
            +
                          if Sequel.datetime_class == Time
         
     | 
| 
      
 1701 
     | 
    
         
            +
                            row[:min_value] = MIN_TIMESTAMP
         
     | 
| 
      
 1702 
     | 
    
         
            +
                            row[:max_value] = MAX_TIMESTAMP
         
     | 
| 
      
 1703 
     | 
    
         
            +
                          end
         
     | 
| 
      
 1704 
     | 
    
         
            +
                        end
         
     | 
| 
      
 1705 
     | 
    
         
            +
                      end
         
     | 
| 
      
 1706 
     | 
    
         
            +
             
     | 
| 
       1449 
1707 
     | 
    
         
             
                      [m.call(row.delete(:name)), row]
         
     | 
| 
       1450 
1708 
     | 
    
         
             
                    end
         
     | 
| 
       1451 
1709 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -1503,9 +1761,9 @@ module Sequel 
     | 
|
| 
       1503 
1761 
     | 
    
         
             
                    if column[:text]
         
     | 
| 
       1504 
1762 
     | 
    
         
             
                      :text
         
     | 
| 
       1505 
1763 
     | 
    
         
             
                    elsif column[:fixed]
         
     | 
| 
       1506 
     | 
    
         
            -
                      "char(#{column[:size]|| 
     | 
| 
      
 1764 
     | 
    
         
            +
                      "char(#{column[:size]||default_string_column_size})"
         
     | 
| 
       1507 
1765 
     | 
    
         
             
                    elsif column[:text] == false || column[:size]
         
     | 
| 
       1508 
     | 
    
         
            -
                      "varchar(#{column[:size]|| 
     | 
| 
      
 1766 
     | 
    
         
            +
                      "varchar(#{column[:size]||default_string_column_size})"
         
     | 
| 
       1509 
1767 
     | 
    
         
             
                    else
         
     | 
| 
       1510 
1768 
     | 
    
         
             
                      :text
         
     | 
| 
       1511 
1769 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -1513,7 +1771,9 @@ module Sequel 
     | 
|
| 
       1513 
1771 
     | 
    
         | 
| 
       1514 
1772 
     | 
    
         
             
                  # PostgreSQL 9.4+ supports views with check option.
         
     | 
| 
       1515 
1773 
     | 
    
         
             
                  def view_with_check_option_support
         
     | 
| 
      
 1774 
     | 
    
         
            +
                    # :nocov:
         
     | 
| 
       1516 
1775 
     | 
    
         
             
                    :local if server_version >= 90400
         
     | 
| 
      
 1776 
     | 
    
         
            +
                    # :nocov:
         
     | 
| 
       1517 
1777 
     | 
    
         
             
                  end
         
     | 
| 
       1518 
1778 
     | 
    
         
             
                end
         
     | 
| 
       1519 
1779 
     | 
    
         | 
| 
         @@ -1524,7 +1784,7 @@ module Sequel 
     | 
|
| 
       1524 
1784 
     | 
    
         
             
                  LOCK_MODES = ['ACCESS SHARE', 'ROW SHARE', 'ROW EXCLUSIVE', 'SHARE UPDATE EXCLUSIVE', 'SHARE', 'SHARE ROW EXCLUSIVE', 'EXCLUSIVE', 'ACCESS EXCLUSIVE'].each(&:freeze).freeze
         
     | 
| 
       1525 
1785 
     | 
    
         | 
| 
       1526 
1786 
     | 
    
         
             
                  Dataset.def_sql_method(self, :delete, [['if server_version >= 90100', %w'with delete from using where returning'], ['else', %w'delete from using where returning']])
         
     | 
| 
       1527 
     | 
    
         
            -
                  Dataset.def_sql_method(self, :insert, [['if server_version >= 90500', %w'with insert into columns values conflict returning'], ['elsif server_version >= 90100', %w'with insert into columns values returning'], ['else', %w'insert into columns values returning']])
         
     | 
| 
      
 1787 
     | 
    
         
            +
                  Dataset.def_sql_method(self, :insert, [['if server_version >= 90500', %w'with insert into columns override values conflict returning'], ['elsif server_version >= 90100', %w'with insert into columns values returning'], ['else', %w'insert into columns values returning']])
         
     | 
| 
       1528 
1788 
     | 
    
         
             
                  Dataset.def_sql_method(self, :select, [['if opts[:values]', %w'values order limit'], ['elsif server_version >= 80400', %w'with select distinct columns from join where group having window compounds order limit lock'], ['else', %w'select distinct columns from join where group having compounds order limit lock']])
         
     | 
| 
       1529 
1789 
     | 
    
         
             
                  Dataset.def_sql_method(self, :update, [['if server_version >= 90100', %w'with update table set from where returning'], ['else', %w'update table set from where returning']])
         
     | 
| 
       1530 
1790 
     | 
    
         | 
| 
         @@ -1551,8 +1811,6 @@ module Sequel 
     | 
|
| 
       1551 
1811 
     | 
    
         
             
                      literal_append(sql, args[0])
         
     | 
| 
       1552 
1812 
     | 
    
         
             
                      sql << ' ' << op.to_s << ' '
         
     | 
| 
       1553 
1813 
     | 
    
         
             
                      literal_append(sql, args[1])
         
     | 
| 
       1554 
     | 
    
         
            -
                      sql << " ESCAPE "
         
     | 
| 
       1555 
     | 
    
         
            -
                      literal_append(sql, "\\")
         
     | 
| 
       1556 
1814 
     | 
    
         
             
                      sql << ')'
         
     | 
| 
       1557 
1815 
     | 
    
         
             
                    else
         
     | 
| 
       1558 
1816 
     | 
    
         
             
                      super
         
     | 
| 
         @@ -1577,6 +1835,12 @@ module Sequel 
     | 
|
| 
       1577 
1835 
     | 
    
         
             
                    clone(:disable_insert_returning=>true)
         
     | 
| 
       1578 
1836 
     | 
    
         
             
                  end
         
     | 
| 
       1579 
1837 
     | 
    
         | 
| 
      
 1838 
     | 
    
         
            +
                  # Always return false when using VALUES
         
     | 
| 
      
 1839 
     | 
    
         
            +
                  def empty?
         
     | 
| 
      
 1840 
     | 
    
         
            +
                    return false if @opts[:values]
         
     | 
| 
      
 1841 
     | 
    
         
            +
                    super
         
     | 
| 
      
 1842 
     | 
    
         
            +
                  end
         
     | 
| 
      
 1843 
     | 
    
         
            +
             
     | 
| 
       1580 
1844 
     | 
    
         
             
                  # Return the results of an EXPLAIN query as a string
         
     | 
| 
       1581 
1845 
     | 
    
         
             
                  def explain(opts=OPTS)
         
     | 
| 
       1582 
1846 
     | 
    
         
             
                    with_sql((opts[:analyze] ? 'EXPLAIN ANALYZE ' : 'EXPLAIN ') + select_sql).map(:'QUERY PLAN').join("\r\n")
         
     | 
| 
         @@ -1600,7 +1864,7 @@ module Sequel 
     | 
|
| 
       1600 
1864 
     | 
    
         
             
                  # :phrase :: Similar to :plain, but also adding an ILIKE filter to ensure that
         
     | 
| 
       1601 
1865 
     | 
    
         
             
                  #            returned rows also include the exact phrase used.
         
     | 
| 
       1602 
1866 
     | 
    
         
             
                  # :rank :: Set to true to order by the rank, so that closer matches are returned first.
         
     | 
| 
       1603 
     | 
    
         
            -
                  # :to_tsquery :: Can be set to :plain or : 
     | 
| 
      
 1867 
     | 
    
         
            +
                  # :to_tsquery :: Can be set to :plain, :phrase, or :websearch to specify the function to use to
         
     | 
| 
       1604 
1868 
     | 
    
         
             
                  #                convert the terms to a ts_query.
         
     | 
| 
       1605 
1869 
     | 
    
         
             
                  # :tsquery :: Specifies the terms argument is already a valid SQL expression returning a
         
     | 
| 
       1606 
1870 
     | 
    
         
             
                  #             tsquery, and can be used directly in the query.
         
     | 
| 
         @@ -1620,6 +1884,8 @@ module Sequel 
     | 
|
| 
       1620 
1884 
     | 
    
         
             
                      query_func = case to_tsquery = opts[:to_tsquery]
         
     | 
| 
       1621 
1885 
     | 
    
         
             
                      when :phrase, :plain
         
     | 
| 
       1622 
1886 
     | 
    
         
             
                        :"#{to_tsquery}to_tsquery"
         
     | 
| 
      
 1887 
     | 
    
         
            +
                      when :websearch
         
     | 
| 
      
 1888 
     | 
    
         
            +
                        :"websearch_to_tsquery"
         
     | 
| 
       1623 
1889 
     | 
    
         
             
                      else
         
     | 
| 
       1624 
1890 
     | 
    
         
             
                        (opts[:phrase] || opts[:plain]) ? :plainto_tsquery : :to_tsquery
         
     | 
| 
       1625 
1891 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -1727,13 +1993,22 @@ module Sequel 
     | 
|
| 
       1727 
1993 
     | 
    
         
             
                    ds.insert_sql(*values)
         
     | 
| 
       1728 
1994 
     | 
    
         
             
                  end
         
     | 
| 
       1729 
1995 
     | 
    
         | 
| 
      
 1996 
     | 
    
         
            +
                  # Support SQL::AliasedExpression as expr to setup a USING join with a table alias for the
         
     | 
| 
      
 1997 
     | 
    
         
            +
                  # USING columns.
         
     | 
| 
      
 1998 
     | 
    
         
            +
                  def join_table(type, table, expr=nil, options=OPTS, &block)
         
     | 
| 
      
 1999 
     | 
    
         
            +
                    if expr.is_a?(SQL::AliasedExpression) && expr.expression.is_a?(Array) && !expr.expression.empty? && expr.expression.all?
         
     | 
| 
      
 2000 
     | 
    
         
            +
                      options = options.merge(:join_using=>true)
         
     | 
| 
      
 2001 
     | 
    
         
            +
                    end
         
     | 
| 
      
 2002 
     | 
    
         
            +
                    super
         
     | 
| 
      
 2003 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2004 
     | 
    
         
            +
             
     | 
| 
       1730 
2005 
     | 
    
         
             
                  # Locks all tables in the dataset's FROM clause (but not in JOINs) with
         
     | 
| 
       1731 
2006 
     | 
    
         
             
                  # the specified mode (e.g. 'EXCLUSIVE').  If a block is given, starts
         
     | 
| 
       1732 
2007 
     | 
    
         
             
                  # a new transaction, locks the table, and yields.  If a block is not given,
         
     | 
| 
       1733 
2008 
     | 
    
         
             
                  # just locks the tables.  Note that PostgreSQL will probably raise an error
         
     | 
| 
       1734 
2009 
     | 
    
         
             
                  # if you lock the table outside of an existing transaction.  Returns nil.
         
     | 
| 
       1735 
2010 
     | 
    
         
             
                  def lock(mode, opts=OPTS)
         
     | 
| 
       1736 
     | 
    
         
            -
                    if  
     | 
| 
      
 2011 
     | 
    
         
            +
                    if defined?(yield) # perform locking inside a transaction and yield to block
         
     | 
| 
       1737 
2012 
     | 
    
         
             
                      @db.transaction(opts){lock(mode, opts); yield}
         
     | 
| 
       1738 
2013 
     | 
    
         
             
                    else
         
     | 
| 
       1739 
2014 
     | 
    
         
             
                      sql = 'LOCK TABLE '.dup
         
     | 
| 
         @@ -1748,6 +2023,41 @@ module Sequel 
     | 
|
| 
       1748 
2023 
     | 
    
         
             
                    nil
         
     | 
| 
       1749 
2024 
     | 
    
         
             
                  end
         
     | 
| 
       1750 
2025 
     | 
    
         | 
| 
      
 2026 
     | 
    
         
            +
                  # Return a dataset with a WHEN MATCHED THEN DO NOTHING clause added to the
         
     | 
| 
      
 2027 
     | 
    
         
            +
                  # MERGE statement.  If a block is passed, treat it as a virtual row and
         
     | 
| 
      
 2028 
     | 
    
         
            +
                  # use it as additional conditions for the match.
         
     | 
| 
      
 2029 
     | 
    
         
            +
                  #
         
     | 
| 
      
 2030 
     | 
    
         
            +
                  #   merge_do_nothing_when_matched
         
     | 
| 
      
 2031 
     | 
    
         
            +
                  #   # WHEN MATCHED THEN DO NOTHING
         
     | 
| 
      
 2032 
     | 
    
         
            +
                  #
         
     | 
| 
      
 2033 
     | 
    
         
            +
                  #   merge_do_nothing_when_matched{a > 30}
         
     | 
| 
      
 2034 
     | 
    
         
            +
                  #   # WHEN MATCHED AND (a > 30) THEN DO NOTHING
         
     | 
| 
      
 2035 
     | 
    
         
            +
                  def merge_do_nothing_when_matched(&block)
         
     | 
| 
      
 2036 
     | 
    
         
            +
                    _merge_when(:type=>:matched, &block)
         
     | 
| 
      
 2037 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2038 
     | 
    
         
            +
             
     | 
| 
      
 2039 
     | 
    
         
            +
                  # Return a dataset with a WHEN NOT MATCHED THEN DO NOTHING clause added to the
         
     | 
| 
      
 2040 
     | 
    
         
            +
                  # MERGE statement.  If a block is passed, treat it as a virtual row and
         
     | 
| 
      
 2041 
     | 
    
         
            +
                  # use it as additional conditions for the match.
         
     | 
| 
      
 2042 
     | 
    
         
            +
                  #
         
     | 
| 
      
 2043 
     | 
    
         
            +
                  #   merge_do_nothing_when_not_matched
         
     | 
| 
      
 2044 
     | 
    
         
            +
                  #   # WHEN NOT MATCHED THEN DO NOTHING
         
     | 
| 
      
 2045 
     | 
    
         
            +
                  #
         
     | 
| 
      
 2046 
     | 
    
         
            +
                  #   merge_do_nothing_when_not_matched{a > 30}
         
     | 
| 
      
 2047 
     | 
    
         
            +
                  #   # WHEN NOT MATCHED AND (a > 30) THEN DO NOTHING
         
     | 
| 
      
 2048 
     | 
    
         
            +
                  def merge_do_nothing_when_not_matched(&block)
         
     | 
| 
      
 2049 
     | 
    
         
            +
                    _merge_when(:type=>:not_matched, &block)
         
     | 
| 
      
 2050 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2051 
     | 
    
         
            +
             
     | 
| 
      
 2052 
     | 
    
         
            +
                  # Support OVERRIDING USER|SYSTEM VALUE for MERGE INSERT.
         
     | 
| 
      
 2053 
     | 
    
         
            +
                  def merge_insert(*values, &block)
         
     | 
| 
      
 2054 
     | 
    
         
            +
                    h = {:type=>:insert, :values=>values}
         
     | 
| 
      
 2055 
     | 
    
         
            +
                    if override = @opts[:override]
         
     | 
| 
      
 2056 
     | 
    
         
            +
                      h[:override] = insert_override_sql(String.new)
         
     | 
| 
      
 2057 
     | 
    
         
            +
                    end
         
     | 
| 
      
 2058 
     | 
    
         
            +
                    _merge_when(h, &block)
         
     | 
| 
      
 2059 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2060 
     | 
    
         
            +
                
         
     | 
| 
       1751 
2061 
     | 
    
         
             
                  # Use OVERRIDING USER VALUE for INSERT statements, so that identity columns
         
     | 
| 
       1752 
2062 
     | 
    
         
             
                  # always use the user supplied value, and an error is not raised for identity
         
     | 
| 
       1753 
2063 
     | 
    
         
             
                  # columns that are GENERATED ALWAYS.
         
     | 
| 
         @@ -1815,6 +2125,11 @@ module Sequel 
     | 
|
| 
       1815 
2125 
     | 
    
         
             
                    true
         
     | 
| 
       1816 
2126 
     | 
    
         
             
                  end
         
     | 
| 
       1817 
2127 
     | 
    
         | 
| 
      
 2128 
     | 
    
         
            +
                  # PostgreSQL 15+ supports MERGE.
         
     | 
| 
      
 2129 
     | 
    
         
            +
                  def supports_merge?
         
     | 
| 
      
 2130 
     | 
    
         
            +
                    server_version >= 150000
         
     | 
| 
      
 2131 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2132 
     | 
    
         
            +
             
     | 
| 
       1818 
2133 
     | 
    
         
             
                  # PostgreSQL supports NOWAIT.
         
     | 
| 
       1819 
2134 
     | 
    
         
             
                  def supports_nowait?
         
     | 
| 
       1820 
2135 
     | 
    
         
             
                    true
         
     | 
| 
         @@ -1835,10 +2150,14 @@ module Sequel 
     | 
|
| 
       1835 
2150 
     | 
    
         
             
                    server_version >= 90500
         
     | 
| 
       1836 
2151 
     | 
    
         
             
                  end
         
     | 
| 
       1837 
2152 
     | 
    
         | 
| 
      
 2153 
     | 
    
         
            +
                  # :nocov:
         
     | 
| 
      
 2154 
     | 
    
         
            +
             
     | 
| 
       1838 
2155 
     | 
    
         
             
                  # PostgreSQL supports timezones in literal timestamps
         
     | 
| 
       1839 
2156 
     | 
    
         
             
                  def supports_timestamp_timezones?
         
     | 
| 
      
 2157 
     | 
    
         
            +
                    # SEQUEL6: Remove
         
     | 
| 
       1840 
2158 
     | 
    
         
             
                    true
         
     | 
| 
       1841 
2159 
     | 
    
         
             
                  end
         
     | 
| 
      
 2160 
     | 
    
         
            +
                  # :nocov:
         
     | 
| 
       1842 
2161 
     | 
    
         | 
| 
       1843 
2162 
     | 
    
         
             
                  # PostgreSQL 8.4+ supports WINDOW clause.
         
     | 
| 
       1844 
2163 
     | 
    
         
             
                  def supports_window_clause?
         
     | 
| 
         @@ -1860,6 +2179,8 @@ module Sequel 
     | 
|
| 
       1860 
2179 
     | 
    
         
             
                      server_version >= 90000
         
     | 
| 
       1861 
2180 
     | 
    
         
             
                    when :groups, :exclude
         
     | 
| 
       1862 
2181 
     | 
    
         
             
                      server_version >= 110000
         
     | 
| 
      
 2182 
     | 
    
         
            +
                    else
         
     | 
| 
      
 2183 
     | 
    
         
            +
                      false
         
     | 
| 
       1863 
2184 
     | 
    
         
             
                    end
         
     | 
| 
       1864 
2185 
     | 
    
         
             
                  end
         
     | 
| 
       1865 
2186 
     | 
    
         | 
| 
         @@ -1902,12 +2223,10 @@ module Sequel 
     | 
|
| 
       1902 
2223 
     | 
    
         
             
                  # Otherwise, return an array of hashes.
         
     | 
| 
       1903 
2224 
     | 
    
         
             
                  def _import(columns, values, opts=OPTS)
         
     | 
| 
       1904 
2225 
     | 
    
         
             
                    if @opts[:returning]
         
     | 
| 
       1905 
     | 
    
         
            -
                       
     | 
| 
       1906 
     | 
    
         
            -
                       
     | 
| 
       1907 
     | 
    
         
            -
                       
     | 
| 
       1908 
     | 
    
         
            -
                       
     | 
| 
       1909 
     | 
    
         
            -
                        statements.map{|st| returning_fetch_rows(st)}
         
     | 
| 
       1910 
     | 
    
         
            -
                      end.first.map{|v| v.length == 1 ? v.values.first : v}
         
     | 
| 
      
 2226 
     | 
    
         
            +
                      # no transaction: our multi_insert_sql_strategy should guarantee
         
     | 
| 
      
 2227 
     | 
    
         
            +
                      # that there's only ever a single statement.
         
     | 
| 
      
 2228 
     | 
    
         
            +
                      sql = multi_insert_sql(columns, values)[0]
         
     | 
| 
      
 2229 
     | 
    
         
            +
                      returning_fetch_rows(sql).map{|v| v.length == 1 ? v.values.first : v}
         
     | 
| 
       1911 
2230 
     | 
    
         
             
                    elsif opts[:return] == :primary_key
         
     | 
| 
       1912 
2231 
     | 
    
         
             
                      returning(insert_pk)._import(columns, values, opts)
         
     | 
| 
       1913 
2232 
     | 
    
         
             
                    else
         
     | 
| 
         @@ -1925,18 +2244,44 @@ module Sequel 
     | 
|
| 
       1925 
2244 
     | 
    
         | 
| 
       1926 
2245 
     | 
    
         
             
                  private
         
     | 
| 
       1927 
2246 
     | 
    
         | 
| 
      
 2247 
     | 
    
         
            +
                  # Append the INSERT sql used in a MERGE
         
     | 
| 
      
 2248 
     | 
    
         
            +
                  def _merge_insert_sql(sql, data)
         
     | 
| 
      
 2249 
     | 
    
         
            +
                    sql << " THEN INSERT "
         
     | 
| 
      
 2250 
     | 
    
         
            +
                    columns, values = _parse_insert_sql_args(data[:values])
         
     | 
| 
      
 2251 
     | 
    
         
            +
                    _insert_columns_sql(sql, columns)
         
     | 
| 
      
 2252 
     | 
    
         
            +
                    if override = data[:override]
         
     | 
| 
      
 2253 
     | 
    
         
            +
                      sql << override
         
     | 
| 
      
 2254 
     | 
    
         
            +
                    end
         
     | 
| 
      
 2255 
     | 
    
         
            +
                    _insert_values_sql(sql, values)
         
     | 
| 
      
 2256 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2257 
     | 
    
         
            +
             
     | 
| 
      
 2258 
     | 
    
         
            +
                  def _merge_matched_sql(sql, data)
         
     | 
| 
      
 2259 
     | 
    
         
            +
                    sql << " THEN DO NOTHING"
         
     | 
| 
      
 2260 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2261 
     | 
    
         
            +
                  alias _merge_not_matched_sql _merge_matched_sql
         
     | 
| 
      
 2262 
     | 
    
         
            +
             
     | 
| 
       1928 
2263 
     | 
    
         
             
                  # Format TRUNCATE statement with PostgreSQL specific options.
         
     | 
| 
       1929 
2264 
     | 
    
         
             
                  def _truncate_sql(table)
         
     | 
| 
       1930 
2265 
     | 
    
         
             
                    to = @opts[:truncate_opts] || OPTS
         
     | 
| 
       1931 
2266 
     | 
    
         
             
                    "TRUNCATE TABLE#{' ONLY' if to[:only]} #{table}#{' RESTART IDENTITY' if to[:restart]}#{' CASCADE' if to[:cascade]}"
         
     | 
| 
       1932 
2267 
     | 
    
         
             
                  end
         
     | 
| 
       1933 
2268 
     | 
    
         | 
| 
      
 2269 
     | 
    
         
            +
                  # Use from_self for aggregate dataset using VALUES.
         
     | 
| 
      
 2270 
     | 
    
         
            +
                  def aggreate_dataset_use_from_self?
         
     | 
| 
      
 2271 
     | 
    
         
            +
                    super || @opts[:values]
         
     | 
| 
      
 2272 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2273 
     | 
    
         
            +
                  
         
     | 
| 
       1934 
2274 
     | 
    
         
             
                  # Allow truncation of multiple source tables.
         
     | 
| 
       1935 
2275 
     | 
    
         
             
                  def check_truncation_allowed!
         
     | 
| 
       1936 
2276 
     | 
    
         
             
                    raise(InvalidOperation, "Grouped datasets cannot be truncated") if opts[:group]
         
     | 
| 
       1937 
2277 
     | 
    
         
             
                    raise(InvalidOperation, "Joined datasets cannot be truncated") if opts[:join]
         
     | 
| 
       1938 
2278 
     | 
    
         
             
                  end
         
     | 
| 
       1939 
2279 
     | 
    
         | 
| 
      
 2280 
     | 
    
         
            +
                  # The strftime format to use when literalizing the time.
         
     | 
| 
      
 2281 
     | 
    
         
            +
                  def default_timestamp_format
         
     | 
| 
      
 2282 
     | 
    
         
            +
                    "'%Y-%m-%d %H:%M:%S.%6N%z'"
         
     | 
| 
      
 2283 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2284 
     | 
    
         
            +
             
     | 
| 
       1940 
2285 
     | 
    
         
             
                  # Only include the primary table in the main delete clause
         
     | 
| 
       1941 
2286 
     | 
    
         
             
                  def delete_from_sql(sql)
         
     | 
| 
       1942 
2287 
     | 
    
         
             
                    sql << ' FROM '
         
     | 
| 
         @@ -1990,25 +2335,23 @@ module Sequel 
     | 
|
| 
       1990 
2335 
     | 
    
         | 
| 
       1991 
2336 
     | 
    
         
             
                  # Return the primary key to use for RETURNING in an INSERT statement
         
     | 
| 
       1992 
2337 
     | 
    
         
             
                  def insert_pk
         
     | 
| 
       1993 
     | 
    
         
            -
                     
     | 
| 
       1994 
     | 
    
         
            -
             
     | 
| 
       1995 
     | 
    
         
            -
             
     | 
| 
       1996 
     | 
    
         
            -
             
     | 
| 
       1997 
     | 
    
         
            -
             
     | 
| 
       1998 
     | 
    
         
            -
                        end
         
     | 
| 
      
 2338 
     | 
    
         
            +
                    (f = opts[:from]) && !f.empty? && (t = f.first)
         
     | 
| 
      
 2339 
     | 
    
         
            +
                    case t
         
     | 
| 
      
 2340 
     | 
    
         
            +
                    when Symbol, String, SQL::Identifier, SQL::QualifiedIdentifier
         
     | 
| 
      
 2341 
     | 
    
         
            +
                      if pk = db.primary_key(t)
         
     | 
| 
      
 2342 
     | 
    
         
            +
                        Sequel::SQL::Identifier.new(pk)
         
     | 
| 
       1999 
2343 
     | 
    
         
             
                      end
         
     | 
| 
       2000 
2344 
     | 
    
         
             
                    end
         
     | 
| 
       2001 
2345 
     | 
    
         
             
                  end
         
     | 
| 
       2002 
2346 
     | 
    
         | 
| 
       2003 
2347 
     | 
    
         
             
                  # Support OVERRIDING SYSTEM|USER VALUE in insert statements
         
     | 
| 
       2004 
     | 
    
         
            -
                  def  
     | 
| 
      
 2348 
     | 
    
         
            +
                  def insert_override_sql(sql)
         
     | 
| 
       2005 
2349 
     | 
    
         
             
                    case opts[:override]
         
     | 
| 
       2006 
2350 
     | 
    
         
             
                    when :system
         
     | 
| 
       2007 
2351 
     | 
    
         
             
                      sql << " OVERRIDING SYSTEM VALUE"
         
     | 
| 
       2008 
2352 
     | 
    
         
             
                    when :user
         
     | 
| 
       2009 
2353 
     | 
    
         
             
                      sql << " OVERRIDING USER VALUE"
         
     | 
| 
       2010 
2354 
     | 
    
         
             
                    end
         
     | 
| 
       2011 
     | 
    
         
            -
                    super
         
     | 
| 
       2012 
2355 
     | 
    
         
             
                  end
         
     | 
| 
       2013 
2356 
     | 
    
         | 
| 
       2014 
2357 
     | 
    
         
             
                  # For multiple table support, PostgreSQL requires at least
         
     | 
| 
         @@ -2023,6 +2366,17 @@ module Sequel 
     | 
|
| 
       2023 
2366 
     | 
    
         
             
                    end
         
     | 
| 
       2024 
2367 
     | 
    
         
             
                  end
         
     | 
| 
       2025 
2368 
     | 
    
         | 
| 
      
 2369 
     | 
    
         
            +
                  # Support table aliases for USING columns
         
     | 
| 
      
 2370 
     | 
    
         
            +
                  def join_using_clause_using_sql_append(sql, using_columns)
         
     | 
| 
      
 2371 
     | 
    
         
            +
                    if using_columns.is_a?(SQL::AliasedExpression)
         
     | 
| 
      
 2372 
     | 
    
         
            +
                      super(sql, using_columns.expression)
         
     | 
| 
      
 2373 
     | 
    
         
            +
                      sql << ' AS '
         
     | 
| 
      
 2374 
     | 
    
         
            +
                      identifier_append(sql, using_columns.alias)
         
     | 
| 
      
 2375 
     | 
    
         
            +
                    else
         
     | 
| 
      
 2376 
     | 
    
         
            +
                      super
         
     | 
| 
      
 2377 
     | 
    
         
            +
                    end
         
     | 
| 
      
 2378 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2379 
     | 
    
         
            +
                
         
     | 
| 
       2026 
2380 
     | 
    
         
             
                  # Use a generic blob quoting method, hopefully overridden in one of the subadapter methods
         
     | 
| 
       2027 
2381 
     | 
    
         
             
                  def literal_blob_append(sql, v)
         
     | 
| 
       2028 
2382 
     | 
    
         
             
                    sql << "'" << v.gsub(/[\000-\037\047\134\177-\377]/n){|b| "\\#{("%o" % b[0..1].unpack("C")[0]).rjust(3, '0')}"} << "'"
         
     | 
| 
         @@ -2046,6 +2400,22 @@ module Sequel 
     | 
|
| 
       2046 
2400 
     | 
    
         
             
                    end
         
     | 
| 
       2047 
2401 
     | 
    
         
             
                  end 
         
     | 
| 
       2048 
2402 
     | 
    
         | 
| 
      
 2403 
     | 
    
         
            +
                  # Handle Ruby integers outside PostgreSQL bigint range specially.
         
     | 
| 
      
 2404 
     | 
    
         
            +
                  def literal_integer(v)
         
     | 
| 
      
 2405 
     | 
    
         
            +
                    if v > 9223372036854775807 || v < -9223372036854775808
         
     | 
| 
      
 2406 
     | 
    
         
            +
                      literal_integer_outside_bigint_range(v)
         
     | 
| 
      
 2407 
     | 
    
         
            +
                    else
         
     | 
| 
      
 2408 
     | 
    
         
            +
                      v.to_s
         
     | 
| 
      
 2409 
     | 
    
         
            +
                    end
         
     | 
| 
      
 2410 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2411 
     | 
    
         
            +
             
     | 
| 
      
 2412 
     | 
    
         
            +
                  # Raise IntegerOutsideBigintRange when attempting to literalize Ruby integer
         
     | 
| 
      
 2413 
     | 
    
         
            +
                  # outside PostgreSQL bigint range, so PostgreSQL doesn't treat
         
     | 
| 
      
 2414 
     | 
    
         
            +
                  # the value as numeric.
         
     | 
| 
      
 2415 
     | 
    
         
            +
                  def literal_integer_outside_bigint_range(v)
         
     | 
| 
      
 2416 
     | 
    
         
            +
                    raise IntegerOutsideBigintRange, "attempt to literalize Ruby integer outside PostgreSQL bigint range: #{v}"
         
     | 
| 
      
 2417 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2418 
     | 
    
         
            +
             
     | 
| 
       2049 
2419 
     | 
    
         
             
                  # Assume that SQL standard quoting is on, per Sequel's defaults
         
     | 
| 
       2050 
2420 
     | 
    
         
             
                  def literal_string_append(sql, v)
         
     | 
| 
       2051 
2421 
     | 
    
         
             
                    sql << "'" << v.gsub("'", "''") << "'"
         
     | 
| 
         @@ -2141,6 +2511,41 @@ module Sequel 
     | 
|
| 
       2141 
2511 
     | 
    
         
             
                    opts[:with].any?{|w| w[:recursive]} ? "WITH RECURSIVE " : super
         
     | 
| 
       2142 
2512 
     | 
    
         
             
                  end
         
     | 
| 
       2143 
2513 
     | 
    
         | 
| 
      
 2514 
     | 
    
         
            +
                  # Support PostgreSQL 14+ CTE SEARCH/CYCLE clauses
         
     | 
| 
      
 2515 
     | 
    
         
            +
                  def select_with_sql_cte(sql, cte)
         
     | 
| 
      
 2516 
     | 
    
         
            +
                    super
         
     | 
| 
      
 2517 
     | 
    
         
            +
                    select_with_sql_cte_search_cycle(sql, cte)
         
     | 
| 
      
 2518 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2519 
     | 
    
         
            +
             
     | 
| 
      
 2520 
     | 
    
         
            +
                  def select_with_sql_cte_search_cycle(sql, cte)
         
     | 
| 
      
 2521 
     | 
    
         
            +
                    if search_opts = cte[:search]
         
     | 
| 
      
 2522 
     | 
    
         
            +
                      sql << if search_opts[:type] == :breadth
         
     | 
| 
      
 2523 
     | 
    
         
            +
                        " SEARCH BREADTH FIRST BY "
         
     | 
| 
      
 2524 
     | 
    
         
            +
                      else
         
     | 
| 
      
 2525 
     | 
    
         
            +
                        " SEARCH DEPTH FIRST BY "
         
     | 
| 
      
 2526 
     | 
    
         
            +
                      end
         
     | 
| 
      
 2527 
     | 
    
         
            +
             
     | 
| 
      
 2528 
     | 
    
         
            +
                      identifier_list_append(sql, Array(search_opts[:by]))
         
     | 
| 
      
 2529 
     | 
    
         
            +
                      sql << " SET "
         
     | 
| 
      
 2530 
     | 
    
         
            +
                      identifier_append(sql, search_opts[:set] || :ordercol)
         
     | 
| 
      
 2531 
     | 
    
         
            +
                    end
         
     | 
| 
      
 2532 
     | 
    
         
            +
             
     | 
| 
      
 2533 
     | 
    
         
            +
                    if cycle_opts = cte[:cycle]
         
     | 
| 
      
 2534 
     | 
    
         
            +
                      sql << " CYCLE "
         
     | 
| 
      
 2535 
     | 
    
         
            +
                      identifier_list_append(sql, Array(cycle_opts[:columns]))
         
     | 
| 
      
 2536 
     | 
    
         
            +
                      sql << " SET "
         
     | 
| 
      
 2537 
     | 
    
         
            +
                      identifier_append(sql, cycle_opts[:cycle_column] || :is_cycle)
         
     | 
| 
      
 2538 
     | 
    
         
            +
                      if cycle_opts.has_key?(:cycle_value)
         
     | 
| 
      
 2539 
     | 
    
         
            +
                        sql << " TO "
         
     | 
| 
      
 2540 
     | 
    
         
            +
                        literal_append(sql, cycle_opts[:cycle_value])
         
     | 
| 
      
 2541 
     | 
    
         
            +
                        sql << " DEFAULT "
         
     | 
| 
      
 2542 
     | 
    
         
            +
                        literal_append(sql, cycle_opts.fetch(:noncycle_value, false))
         
     | 
| 
      
 2543 
     | 
    
         
            +
                      end
         
     | 
| 
      
 2544 
     | 
    
         
            +
                      sql << " USING "
         
     | 
| 
      
 2545 
     | 
    
         
            +
                      identifier_append(sql, cycle_opts[:path_column] || :path)
         
     | 
| 
      
 2546 
     | 
    
         
            +
                    end
         
     | 
| 
      
 2547 
     | 
    
         
            +
                  end
         
     | 
| 
      
 2548 
     | 
    
         
            +
             
     | 
| 
       2144 
2549 
     | 
    
         
             
                  # The version of the database server
         
     | 
| 
       2145 
2550 
     | 
    
         
             
                  def server_version
         
     | 
| 
       2146 
2551 
     | 
    
         
             
                    db.server_version(@opts[:server])
         
     |