Module: ArJdbc::PostgreSQL

Included in:
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter, ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
Defined in:
lib/arjdbc/postgresql/adapter.rb,
lib/arjdbc/postgresql/column.rb,
lib/arjdbc/postgresql/oid_types.rb,
lib/arjdbc/postgresql/schema_statements.rb,
lib/arjdbc/postgresql/database_statements.rb

Overview

Strives to provide Rails built-in PostgreSQL adapter (API) compatibility.

Defined Under Namespace

Modules: DatabaseStatements, SchemaStatements Classes: ArjdbcTypeMapInitializer

Constant Summary collapse

ADAPTER_NAME =
'PostgreSQL'
NATIVE_DATABASE_TYPES =
{
  primary_key:  'bigserial primary key',
  bigint:       { name: 'bigint' },
  binary:       { name: 'bytea' },
  bit:          { name: 'bit' },
  bit_varying:  { name: 'bit varying' },
  boolean:      { name: 'boolean' },
  box:          { name: 'box' },
  char:         { name: 'char' },
  cidr:         { name: 'cidr' },
  circle:       { name: 'circle' },
  citext:       { name: 'citext' },
  date:         { name: 'date' },
  daterange:    { name: 'daterange' },
  datetime:     {}, # set dynamically based on datetime_type
  timestamptz:  { name: 'timestamptz' },
  decimal:      { name: 'decimal' }, # :limit => 1000
  float:        { name: 'float' },
  hstore:       { name: 'hstore' },
  inet:         { name: 'inet' },
  int4range:    { name: 'int4range' },
  int8range:    { name: 'int8range' },
  integer:      { name: 'integer', limit: 4 },
  interval:     { name: 'interval' },
  json:         { name: 'json' },
  jsonb:        { name: 'jsonb' },
  line:         { name: 'line' },
  lseg:         { name: 'lseg' },
  ltree:        { name: 'ltree' },
  macaddr:      { name: 'macaddr' },
  money:        { name: 'money' },
  numeric:      { name: 'numeric' },
  numrange:     { name: 'numrange' },
  oid:          { name: 'oid' },
  path:         { name: 'path' },
  point:        { name: 'point' },
  polygon:      { name: 'polygon' },
  string:       { name: 'character varying' },
  text:         { name: 'text' },
  time:         { name: 'time' },
  timestamp:    { name: 'timestamp' },
  tsrange:      { name: 'tsrange' },
  tstzrange:    { name: 'tstzrange' },
  tsvector:     { name: 'tsvector' },
  uuid:         { name: 'uuid' },
  xml:          { name: 'xml' },
  enum:         {} # special type https://www.postgresql.org/docs/current/datatype-enum.html
}

Instance Method Summary collapse

Instance Method Details

#adapter_nameObject



50
51
52
# File 'lib/arjdbc/postgresql/adapter.rb', line 50

def adapter_name
  ADAPTER_NAME
end

#add_enum_value(type_name, value, options = {}) ⇒ Object

Add enum value to an existing enum type.



411
412
413
414
415
416
417
418
419
420
421
422
423
424
# File 'lib/arjdbc/postgresql/adapter.rb', line 411

def add_enum_value(type_name, value, options = {})
  before, after = options.values_at(:before, :after)
  sql = +"ALTER TYPE #{quote_table_name(type_name)} ADD VALUE '#{value}'"

  if before && after
    raise ArgumentError, "Cannot have both :before and :after at the same time"
  elsif before
    sql << " BEFORE '#{before}'"
  elsif after
    sql << " AFTER '#{after}'"
  end

  execute(sql).tap { reload_type_map }
end

#add_order_by_for_association_limiting!(sql, options) ⇒ Object

ORDER BY clause for the passed order option.

PostgreSQL does not allow arbitrary ordering when using DISTINCT ON, so we work around this by wrapping the SQL as a sub-select and ordering in that query.



610
611
612
613
614
615
616
617
618
# File 'lib/arjdbc/postgresql/adapter.rb', line 610

def add_order_by_for_association_limiting!(sql, options)
  return sql if options[:order].blank?

  order = options[:order].split(',').collect { |s| s.strip }.reject(&:blank?)
  order.map! { |s| 'DESC' if s =~ /\bdesc$/i }
  order = order.zip((0...order.size).to_a).map { |s,i| "id_list.alias_#{i} #{s}" }.join(', ')

  sql.replace "SELECT * FROM (#{sql}) AS id_list ORDER BY #{order}"
end

#all_schemasObject



588
589
590
# File 'lib/arjdbc/postgresql/adapter.rb', line 588

def all_schemas
  select('SELECT nspname FROM pg_namespace').map { |row| row["nspname"] }
end

#build_insert_sql(insert) ⇒ Object

:nodoc:



492
493
494
495
496
497
498
499
500
501
502
503
504
505
# File 'lib/arjdbc/postgresql/adapter.rb', line 492

def build_insert_sql(insert) # :nodoc:
  sql = +"INSERT #{insert.into} #{insert.values_list}"

  if insert.skip_duplicates?
    sql << " ON CONFLICT #{insert.conflict_target} DO NOTHING"
  elsif insert.update_duplicates?
    sql << " ON CONFLICT #{insert.conflict_target} DO UPDATE SET "
    sql << insert.touch_model_timestamps_unless { |column| "#{insert.model.quoted_table_name}.#{column} IS NOT DISTINCT FROM excluded.#{column}" }
    sql << insert.updatable_columns.map { |column| "#{column}=excluded.#{column}" }.join(",")
  end

  sql << " RETURNING #{insert.returning}" if insert.returning
  sql
end

#build_truncate_statements(table_names) ⇒ Object



584
585
586
# File 'lib/arjdbc/postgresql/adapter.rb', line 584

def build_truncate_statements(table_names)
  ["TRUNCATE TABLE #{table_names.map(&method(:quote_table_name)).join(", ")}"]
end

#check_versionObject

:nodoc:



507
508
509
510
511
# File 'lib/arjdbc/postgresql/adapter.rb', line 507

def check_version # :nodoc:
  if database_version < 90300
    raise "Your version of PostgreSQL (#{database_version}) is too old. Active Record supports PostgreSQL >= 9.3."
  end
end

#client_min_messagesObject

Returns the current client message level.



593
594
595
596
597
# File 'lib/arjdbc/postgresql/adapter.rb', line 593

def client_min_messages
  return nil if redshift? # not supported on Redshift
  # Need to use #execute so we don't try to access the type map before it is initialized
  execute('SHOW client_min_messages', 'SCHEMA').values.first.first
end

#client_min_messages=(level) ⇒ Object

Set the client message level.



600
601
602
603
# File 'lib/arjdbc/postgresql/adapter.rb', line 600

def client_min_messages=(level)
  # Not supported on Redshift
  redshift? ? nil : super
end

#configure_connectionObject

Configures the encoding, verbosity, schema search path, and time zone of the connection. This is called on connection.connect and should not be called manually.



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/arjdbc/postgresql/adapter.rb', line 71

def configure_connection
  #if encoding = config[:encoding]
    # The client_encoding setting is set by the driver and should not be altered.
    # If the driver detects a change it will abort the connection.
    # see http://jdbc.postgresql.org/documentation/91/connect.html
    # self.set_client_encoding(encoding)
  #end
  self.client_min_messages = @config[:min_messages] || 'warning'
  self.schema_search_path = @config[:schema_search_path] || @config[:schema_order]

  # Use standard-conforming strings if available so we don't have to do the E'...' dance.
  set_standard_conforming_strings

  # If using Active Record's time zone support configure the connection to return
  # TIMESTAMP WITH ZONE types in UTC.
  # (SET TIME ZONE does not use an equals sign like other SET variables)
  if ActiveRecord.default_timezone == :utc
    execute("SET time zone 'UTC'", 'SCHEMA')
  elsif tz = local_tz
    execute("SET time zone '#{tz}'", 'SCHEMA')
  end unless redshift?

  # Set interval output format to ISO 8601 for ease of parsing by ActiveSupport::Duration.parse
  execute("SET intervalstyle = iso_8601", "SCHEMA")

  # SET statements from :variables config hash
  # http://www.postgresql.org/docs/8.3/static/sql-set.html
  (@config[:variables] || {}).map do |k, v|
    if v == ':default' || v == :default
      # Sets the value to the global or compile default
      execute("SET SESSION #{k} TO DEFAULT", 'SCHEMA')
    elsif ! v.nil?
      execute("SET SESSION #{k} TO #{quote(v)}", 'SCHEMA')
    end
  end

  reload_type_map
end

#create_enum(name, values, **options) ⇒ Object

Given a name and an array of values, creates an enum type.



365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
# File 'lib/arjdbc/postgresql/adapter.rb', line 365

def create_enum(name, values, **options)
  sql_values = values.map { |s| quote(s) }.join(", ")
  scope = quoted_scope(name)
  query = <<~SQL
    DO $$
    BEGIN
        IF NOT EXISTS (
          SELECT 1
          FROM pg_type t
          JOIN pg_namespace n ON t.typnamespace = n.oid
          WHERE t.typname = #{scope[:name]}
            AND n.nspname = #{scope[:schema]}
        ) THEN
            CREATE TYPE #{quote_table_name(name)} AS ENUM (#{sql_values});
        END IF;
    END
    $$;
  SQL

  internal_exec_query(query).tap { reload_type_map }
end

#default_index_type?(index) ⇒ Boolean

:nodoc:

Returns:

  • (Boolean)


488
489
490
# File 'lib/arjdbc/postgresql/adapter.rb', line 488

def default_index_type?(index) # :nodoc:
  index.using == :btree || super
end

#default_sequence_name(table_name, pk = "id") ⇒ Object

:nodoc:



574
575
576
577
578
# File 'lib/arjdbc/postgresql/adapter.rb', line 574

def default_sequence_name(table_name, pk = "id") #:nodoc:
  serial_sequence(table_name, pk)
rescue ActiveRecord::StatementInvalid
  %Q("#{table_name}_#{pk}_seq")
end

#disable_extension(name, force: false) ⇒ Object

Removes an extension from the database.

[:force] Set to +:cascade+ to drop dependent objects as well. Defaults to false.



323
324
325
326
327
# File 'lib/arjdbc/postgresql/adapter.rb', line 323

def disable_extension(name, force: false)
  internal_exec_query("DROP EXTENSION IF EXISTS \"#{name}\"#{' CASCADE' if force == :cascade}").tap {
    reload_type_map
  }
end

#disconnect!Object

Disconnects from the database if already connected. Otherwise, this method does nothing.



566
567
568
569
570
571
572
# File 'lib/arjdbc/postgresql/adapter.rb', line 566

def disconnect!
  @lock.synchronize do
    super
    @raw_connection&.close
    @raw_connection = nil
  end
end

#drop_enum(name, values = nil, **options) ⇒ Object

Drops an enum type.

If the if_exists: true option is provided, the enum is dropped only if it exists. Otherwise, if the enum doesn't exist, an error is raised.

The +values+ parameter will be ignored if present. It can be helpful to provide this in a migration's +change+ method so it can be reverted. In that case, +values+ will be used by #create_enum.



396
397
398
399
400
401
# File 'lib/arjdbc/postgresql/adapter.rb', line 396

def drop_enum(name, values = nil, **options)
  query = <<~SQL
    DROP TYPE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(name)};
  SQL
  internal_exec_query(query).tap { reload_type_map }
end

#enable_extension(name) ⇒ Object



310
311
312
313
314
315
316
# File 'lib/arjdbc/postgresql/adapter.rb', line 310

def enable_extension(name, **)
  schema, name = name.to_s.split(".").values_at(-2, -1)
  sql = +"CREATE EXTENSION IF NOT EXISTS \"#{name}\""
  sql << " SCHEMA #{schema}" if schema

  internal_exec_query(sql).tap { reload_type_map }
end

#enum_typesObject

Returns a list of defined enum types, and their values.



342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
# File 'lib/arjdbc/postgresql/adapter.rb', line 342

def enum_types
  query = <<~SQL
    SELECT
      type.typname AS name,
      type.OID AS oid,
      n.nspname AS schema,
      array_agg(enum.enumlabel ORDER BY enum.enumsortorder) AS value
    FROM pg_enum AS enum
    JOIN pg_type AS type ON (type.oid = enum.enumtypid)
    JOIN pg_namespace n ON type.typnamespace = n.oid
    WHERE n.nspname = ANY (current_schemas(false))
    GROUP BY type.OID, n.nspname, type.typname;
  SQL

  internal_exec_query(query, "SCHEMA", allow_retry: true, materialize_transactions: false).cast_values.each_with_object({}) do |row, memo|
    name, schema = row[0], row[2]
    schema = nil if schema == current_schema
    full_name = [schema, name].compact.join(".")
    memo[full_name] = row.last
  end.to_a
end

#escape_bytea(string) ⇒ Object

Note:

quote_string implemented as native



622
623
624
625
# File 'lib/arjdbc/postgresql/adapter.rb', line 622

def escape_bytea(string)
  return unless string
  "\\x#{string.unpack("H*")[0]}"
end

#exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil, returning: nil) ⇒ Object

:nodoc:



513
514
515
516
517
518
519
520
521
522
523
524
525
# File 'lib/arjdbc/postgresql/adapter.rb', line 513

def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil, returning: nil) # :nodoc:
  val = super
  if !use_insert_returning? && pk
    unless sequence_name
      table_ref = extract_table_ref_from_insert_sql(sql)
      sequence_name = default_sequence_name(table_ref, pk)
      return val unless sequence_name
    end
    last_insert_id_result(sequence_name)
  else
    val
  end
end

#execute_batch(statements, name = nil) ⇒ Object



527
528
529
# File 'lib/arjdbc/postgresql/adapter.rb', line 527

def execute_batch(statements, name = nil)
  execute(combine_multi_statements(statements), name)
end

#extension_available?(name) ⇒ Boolean

Returns:

  • (Boolean)


329
330
331
# File 'lib/arjdbc/postgresql/adapter.rb', line 329

def extension_available?(name)
  query_value("SELECT true FROM pg_available_extensions WHERE name = #{quote(name)}", "SCHEMA")
end

#extension_enabled?(name) ⇒ Boolean

Returns:

  • (Boolean)


333
334
335
# File 'lib/arjdbc/postgresql/adapter.rb', line 333

def extension_enabled?(name)
  query_value("SELECT installed_version IS NOT NULL FROM pg_available_extensions WHERE name = #{quote(name)}", "SCHEMA")
end

#extensionsObject



337
338
339
# File 'lib/arjdbc/postgresql/adapter.rb', line 337

def extensions
  internal_exec_query("SELECT extname FROM pg_extension", "SCHEMA", allow_retry: true, materialize_transactions: false).cast_values
end

#get_advisory_lock(lock_id) ⇒ Object

:nodoc:



296
297
298
299
300
301
# File 'lib/arjdbc/postgresql/adapter.rb', line 296

def get_advisory_lock(lock_id) # :nodoc:
  unless lock_id.is_a?(Integer) && lock_id.bit_length <= 63
    raise(ArgumentError, "PostgreSQL requires advisory lock ids to be a signed 64 bit integer")
  end
  query_value("SELECT pg_try_advisory_lock(#{lock_id})")
end

#get_database_versionObject

:nodoc:



455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
# File 'lib/arjdbc/postgresql/adapter.rb', line 455

def get_database_version # :nodoc:
  begin
    version = valid_raw_connection.database_product
    if match = version.match(/([\d\.]*\d).*?/)
      version = match[1].split('.').map(&:to_i)
      # PostgreSQL version representation does not have more than 4 digits
      # From version 10 onwards, PG has changed its versioning policy to
      # limit it to only 2 digits. i.e. in 10.x, 10 being the major
      # version and x representing the patch release
      # Refer to:
      #   https://www.postgresql.org/support/versioning/
      #   https://www.postgresql.org/docs/10/static/libpq-status.html -> PQserverVersion()
      # for more info

      if version.size >= 3
        (version[0] * 100 + version[1]) * 100 + version[2]
      elsif version.size == 2
        if version[0] >= 10
          version[0] * 100 * 100 + version[1]
        else
          (version[0] * 100 + version[1]) * 100
        end
      elsif version.size == 1
        version[0] * 100 * 100
      else
        0
      end
    else
      0
    end
  end
end

#index_algorithmsObject



245
246
247
# File 'lib/arjdbc/postgresql/adapter.rb', line 245

def index_algorithms
  { concurrently: 'CONCURRENTLY' }
end

#jdbc_column_classObject



46
# File 'lib/arjdbc/postgresql/adapter.rb', line 46

def jdbc_column_class; ::ActiveRecord::ConnectionAdapters::PostgreSQLColumn end

#last_insert_id_result(sequence_name) ⇒ Object



580
581
582
# File 'lib/arjdbc/postgresql/adapter.rb', line 580

def last_insert_id_result(sequence_name)
  exec_query("SELECT currval('#{sequence_name}')", 'SQL')
end

#max_identifier_lengthObject

Returns the configured supported identifier length supported by PostgreSQL



441
442
443
# File 'lib/arjdbc/postgresql/adapter.rb', line 441

def max_identifier_length
  @max_identifier_length ||= query_value("SHOW max_identifier_length", "SCHEMA").to_i
end

#quote_table_name(name) ⇒ Object



628
629
630
631
632
633
634
635
636
637
# File 'lib/arjdbc/postgresql/adapter.rb', line 628

def quote_table_name(name)
  schema, name_part = extract_pg_identifier_from_name(name.to_s)

  unless name_part
    quote_column_name(schema)
  else
    table_name, name_part = extract_pg_identifier_from_name(name_part)
    "#{quote_column_name(schema)}.#{quote_column_name(table_name)}"
  end
end

#release_advisory_lock(lock_id) ⇒ Object

:nodoc:



303
304
305
306
307
308
# File 'lib/arjdbc/postgresql/adapter.rb', line 303

def release_advisory_lock(lock_id) # :nodoc:
  unless lock_id.is_a?(Integer) && lock_id.bit_length <= 63
    raise(ArgumentError, "PostgreSQL requires advisory lock ids to be a signed 64 bit integer")
  end
  query_value("SELECT pg_advisory_unlock(#{lock_id})")
end

#remove_column(table_name, column_name, type = nil, **options) ⇒ Object

Need to clear the cache even though the AR adapter doesn't for some reason



643
644
645
646
# File 'lib/arjdbc/postgresql/adapter.rb', line 643

def remove_column(table_name, column_name, type = nil, **options)
  super
  clear_cache!
end

#rename_enum(name, options = {}) ⇒ Object

Rename an existing enum type to something else.



404
405
406
407
408
# File 'lib/arjdbc/postgresql/adapter.rb', line 404

def rename_enum(name, options = {})
  to = options.fetch(:to) { raise ArgumentError, ":to is required" }

  exec_query("ALTER TYPE #{quote_table_name(name)} RENAME TO #{to}").tap { reload_type_map }
end

#rename_enum_value(type_name, options = {}) ⇒ Object

Rename enum value on an existing enum type.



427
428
429
430
431
432
433
434
435
436
437
438
# File 'lib/arjdbc/postgresql/adapter.rb', line 427

def rename_enum_value(type_name, options = {})
  unless database_version >= 10_00_00 # >= 10.0
    raise ArgumentError, "Renaming enum values is only supported in PostgreSQL 10 or later"
  end

  from = options.fetch(:from) { raise ArgumentError, ":from is required" }
  to = options.fetch(:to) { raise ArgumentError, ":to is required" }

  execute("ALTER TYPE #{quote_table_name(type_name)} RENAME VALUE '#{from}' TO '#{to}'").tap {
    reload_type_map
  }
end

#reset!Object

We need to make sure to deallocate all the prepared statements since apparently calling close on the statement object doesn't always free the server resources and calling 'DISCARD ALL' fails if we are inside a transaction def clear_cache! super # Make sure all query plans are really gone @connection.execute 'DEALLOCATE ALL' if active? end



551
552
553
554
555
556
557
558
559
560
561
562
# File 'lib/arjdbc/postgresql/adapter.rb', line 551

def reset!
  @lock.synchronize do
    return connect! unless @raw_connection

    # Have to deal with rollbacks differently than the AR adapter
    @raw_connection.rollback

    @raw_connection.execute("DISCARD ALL")

    super
  end
end

#session_auth=(user) ⇒ Object

Set the authorized user for this session



446
447
448
449
# File 'lib/arjdbc/postgresql/adapter.rb', line 446

def session_auth=(user)
  clear_cache!
  execute("SET SESSION AUTHORIZATION #{user}")
end

#set_client_encoding(encoding) ⇒ Object



64
65
66
67
# File 'lib/arjdbc/postgresql/adapter.rb', line 64

def set_client_encoding(encoding)
  ActiveRecord::Base.logger.warn "client_encoding is set by the driver and should not be altered, ('#{encoding}' ignored)"
  ActiveRecord::Base.logger.debug "Set the 'allowEncodingChanges' driver property (e.g. using config[:properties]) if you need to override the client encoding when doing a copy."
end

#set_standard_conforming_stringsObject



162
163
164
# File 'lib/arjdbc/postgresql/adapter.rb', line 162

def set_standard_conforming_strings
  execute("SET standard_conforming_strings = on", "SCHEMA")
end

#supports_advisory_locks?Boolean

Returns:

  • (Boolean)


253
254
255
# File 'lib/arjdbc/postgresql/adapter.rb', line 253

def supports_advisory_locks?
  true
end

#supports_bulk_alter?Boolean

Returns:

  • (Boolean)


166
167
168
# File 'lib/arjdbc/postgresql/adapter.rb', line 166

def supports_bulk_alter?
  true
end

#supports_check_constraints?Boolean

Returns:

  • (Boolean)


194
195
196
# File 'lib/arjdbc/postgresql/adapter.rb', line 194

def supports_check_constraints?
  true
end

#supports_comments?Boolean

Returns:

  • (Boolean)


214
215
216
# File 'lib/arjdbc/postgresql/adapter.rb', line 214

def supports_comments?
  true
end

#supports_common_table_expressions?Boolean

Returns:

  • (Boolean)


288
289
290
# File 'lib/arjdbc/postgresql/adapter.rb', line 288

def supports_common_table_expressions?
  true
end

#supports_datetime_with_precision?Boolean

Returns:

  • (Boolean)


206
207
208
# File 'lib/arjdbc/postgresql/adapter.rb', line 206

def supports_datetime_with_precision?
  true
end

#supports_ddl_transactions?Boolean

Returns:

  • (Boolean)


249
250
251
# File 'lib/arjdbc/postgresql/adapter.rb', line 249

def supports_ddl_transactions?
  true
end

#supports_explain?Boolean

Returns:

  • (Boolean)


257
258
259
# File 'lib/arjdbc/postgresql/adapter.rb', line 257

def supports_explain?
  true
end

#supports_expression_index?Boolean

Returns:

  • (Boolean)


182
183
184
# File 'lib/arjdbc/postgresql/adapter.rb', line 182

def supports_expression_index?
  true
end

#supports_extensions?Boolean

Returns:

  • (Boolean)


261
262
263
# File 'lib/arjdbc/postgresql/adapter.rb', line 261

def supports_extensions?
  database_version >= 90200
end

#supports_foreign_keys?Boolean

Returns:

  • (Boolean)


190
191
192
# File 'lib/arjdbc/postgresql/adapter.rb', line 190

def supports_foreign_keys?
  true
end

#supports_foreign_tables?Boolean

Returns:

  • (Boolean)


273
274
275
# File 'lib/arjdbc/postgresql/adapter.rb', line 273

def supports_foreign_tables?
  database_version >= 90300
end

#supports_identity_columns?Boolean

:nodoc:

Returns:

  • (Boolean)


237
238
239
# File 'lib/arjdbc/postgresql/adapter.rb', line 237

def supports_identity_columns? # :nodoc:
  database_version >= 10_00_00 # >= 10.0
end

#supports_index_sort_order?Boolean

Returns:

  • (Boolean)


170
171
172
# File 'lib/arjdbc/postgresql/adapter.rb', line 170

def supports_index_sort_order?
  true
end

#supports_insert_on_conflict?Boolean Also known as: supports_insert_on_duplicate_skip?, supports_insert_on_duplicate_update?, supports_insert_conflict_target?

Returns:

  • (Boolean)


226
227
228
# File 'lib/arjdbc/postgresql/adapter.rb', line 226

def supports_insert_on_conflict?
  database_version >= 90500
end

#supports_insert_returning?Boolean

Returns:

  • (Boolean)


222
223
224
# File 'lib/arjdbc/postgresql/adapter.rb', line 222

def supports_insert_returning?
  true
end

#supports_json?Boolean

Returns:

  • (Boolean)


210
211
212
# File 'lib/arjdbc/postgresql/adapter.rb', line 210

def supports_json?
  database_version >= 90200
end

#supports_lazy_transactions?Boolean

Returns:

  • (Boolean)


292
293
294
# File 'lib/arjdbc/postgresql/adapter.rb', line 292

def supports_lazy_transactions?
  true
end

#supports_materialized_views?Boolean

Returns:

  • (Boolean)


269
270
271
# File 'lib/arjdbc/postgresql/adapter.rb', line 269

def supports_materialized_views?
  database_version >= 90300
end

#supports_nulls_not_distinct?Boolean

Returns:

  • (Boolean)


241
242
243
# File 'lib/arjdbc/postgresql/adapter.rb', line 241

def supports_nulls_not_distinct?
  database_version >= 15_00_00 # >= 15.0
end

#supports_optimizer_hints?Boolean

Returns:

  • (Boolean)


281
282
283
284
285
286
# File 'lib/arjdbc/postgresql/adapter.rb', line 281

def supports_optimizer_hints?
  unless defined?(@has_pg_hint_plan)
    @has_pg_hint_plan = extension_available?("pg_hint_plan")
  end
  @has_pg_hint_plan
end

#supports_partial_index?Boolean

Returns:

  • (Boolean)


178
179
180
# File 'lib/arjdbc/postgresql/adapter.rb', line 178

def supports_partial_index?
  true
end

#supports_partitioned_indexes?Boolean

Returns:

  • (Boolean)


174
175
176
# File 'lib/arjdbc/postgresql/adapter.rb', line 174

def supports_partitioned_indexes?
  database_version >= 110_000
end

#supports_pgcrypto_uuid?Boolean

Returns:

  • (Boolean)


277
278
279
# File 'lib/arjdbc/postgresql/adapter.rb', line 277

def supports_pgcrypto_uuid?
  database_version >= 90400
end

#supports_ranges?Boolean

Returns:

  • (Boolean)


265
266
267
# File 'lib/arjdbc/postgresql/adapter.rb', line 265

def supports_ranges?
  database_version >= 90200
end

#supports_savepoints?Boolean

Returns:

  • (Boolean)


218
219
220
# File 'lib/arjdbc/postgresql/adapter.rb', line 218

def supports_savepoints?
  true
end

#supports_transaction_isolation?Boolean

Returns:

  • (Boolean)


186
187
188
# File 'lib/arjdbc/postgresql/adapter.rb', line 186

def supports_transaction_isolation?
  true
end

#supports_validate_constraints?Boolean

Returns:

  • (Boolean)


198
199
200
# File 'lib/arjdbc/postgresql/adapter.rb', line 198

def supports_validate_constraints?
  true
end

#supports_views?Boolean

Returns:

  • (Boolean)


202
203
204
# File 'lib/arjdbc/postgresql/adapter.rb', line 202

def supports_views?
  true
end

#supports_virtual_columns?Boolean

Returns:

  • (Boolean)


233
234
235
# File 'lib/arjdbc/postgresql/adapter.rb', line 233

def supports_virtual_columns?
  database_version >= 12_00_00 # >= 12.0
end

#use_insert_returning?Boolean

Returns:

  • (Boolean)


451
452
453
# File 'lib/arjdbc/postgresql/adapter.rb', line 451

def use_insert_returning?
  @use_insert_returning
end

#write_query?(sql) ⇒ Boolean

:nodoc:

Returns:

  • (Boolean)


537
538
539
# File 'lib/arjdbc/postgresql/adapter.rb', line 537

def write_query?(sql) # :nodoc:
  !READ_QUERY.match?(sql)
end