Class: ActiveRecord::ConnectionAdapters::PostgreSQLAdapter

Overview

The PostgreSQL adapter works with the native C (bitbucket.org/ged/ruby-pg) driver.

Options:

  • :host - Defaults to a Unix-domain socket in /tmp. On machines without Unix-domain sockets, the default is to connect to localhost.

  • :port - Defaults to 5432.

  • :username - Defaults to be the same as the operating system name of the user running the application.

  • :password - Password to be used if the server demands password authentication.

  • :database - Defaults to be the same as the user name.

  • :schema_search_path - An optional schema search path for the connection given as a string of comma-separated schema names. This is backward-compatible with the :schema_order option.

  • :encoding - An optional client encoding that is used in a SET client_encoding TO <encoding> call on the connection.

  • :min_messages - An optional client min messages that is used in a SET client_min_messages TO <min_messages> call on the connection.

  • :variables - An optional hash of additional parameters that will be used in SET SESSION key = val calls on the connection.

  • :insert_returning - An optional boolean to control the use of RETURNING for INSERT statements defaults to true.

Any further options are used as connection parameters to libpq. See www.postgresql.org/docs/9.1/static/libpq-connect.html for the list of parameters.

In addition, default connection parameters of libpq can be set per environment variables. See www.postgresql.org/docs/9.1/static/libpq-envars.html .

Defined Under Namespace

Classes: StatementPool

Constant Summary collapse

ADAPTER_NAME =
'PostgreSQL'.freeze
NATIVE_DATABASE_TYPES =
{
  primary_key: "serial primary key",
  bigserial: "bigserial",
  string:      { name: "character varying" },
  text:        { name: "text" },
  integer:     { name: "integer" },
  float:       { name: "float" },
  decimal:     { name: "decimal" },
  datetime:    { name: "timestamp" },
  time:        { name: "time" },
  date:        { name: "date" },
  daterange:   { name: "daterange" },
  numrange:    { name: "numrange" },
  tsrange:     { name: "tsrange" },
  tstzrange:   { name: "tstzrange" },
  int4range:   { name: "int4range" },
  int8range:   { name: "int8range" },
  binary:      { name: "bytea" },
  boolean:     { name: "boolean" },
  bigint:      { name: "bigint" },
  xml:         { name: "xml" },
  tsvector:    { name: "tsvector" },
  hstore:      { name: "hstore" },
  inet:        { name: "inet" },
  cidr:        { name: "cidr" },
  macaddr:     { name: "macaddr" },
  uuid:        { name: "uuid" },
  json:        { name: "json" },
  jsonb:       { name: "jsonb" },
  ltree:       { name: "ltree" },
  citext:      { name: "citext" },
  point:       { name: "point" },
  bit:         { name: "bit" },
  bit_varying: { name: "bit varying" },
  money:       { name: "money" },
}
OID =

:nodoc:

PostgreSQL::OID
OPERATION_ALIASES =

:nodoc:

{ # :nodoc:
  "maximum" => "max",
  "minimum" => "min",
  "average" => "avg",
}

Constants included from ActiveRecord::ConnectionAdapters::PostgreSQL::DatabaseStatements

ActiveRecord::ConnectionAdapters::PostgreSQL::DatabaseStatements::BYTEA_COLUMN_TYPE_OID, ActiveRecord::ConnectionAdapters::PostgreSQL::DatabaseStatements::MONEY_COLUMN_TYPE_OID

Constants inherited from AbstractAdapter

AbstractAdapter::SIMPLE_INT

Constants included from ActiveSupport::Callbacks

ActiveSupport::Callbacks::CALLBACK_FILTER_TYPES

Instance Attribute Summary

Attributes inherited from AbstractAdapter

#logger, #owner, #pool, #prepared_statements, #schema_cache, #visitor

Attributes included from QueryCache

#query_cache, #query_cache_enabled

Attributes included from DatabaseStatements

#transaction_manager

Instance Method Summary collapse

Methods included from Savepoints

#create_savepoint, #exec_rollback_to_savepoint, #release_savepoint, #supports_savepoints?

Methods included from ActiveRecord::ConnectionAdapters::PostgreSQL::DatabaseStatements

#begin_db_transaction, #begin_isolated_db_transaction, #commit_db_transaction, #create, #exec_delete, #exec_insert, #exec_query, #exec_rollback_db_transaction, #execute, #explain, #insert_sql, #query, #result_as_array, #select_rows, #select_value, #select_values, #sql_for_insert, #update_sql

Methods included from ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements

#add_column, #add_index, #change_column, #change_column_default, #change_column_null, #client_min_messages, #client_min_messages=, #collation, #columns, #columns_for_distinct, #create_database, #create_schema, #ctype, #current_database, #current_schema, #data_sources, #default_sequence_name, #drop_database, #drop_schema, #drop_table, #encoding, #extract_foreign_key_action, #foreign_keys, #index_name_exists?, #index_name_length, #indexes, #new_column, #pk_and_sequence_for, #primary_key, #recreate_database, #remove_index!, #rename_column, #rename_index, #rename_table, #reset_pk_sequence!, #schema_exists?, #schema_names, #schema_search_path, #schema_search_path=, #serial_sequence, #set_pk_sequence!, #table_exists?, #tables, #type_to_sql

Methods included from ActiveRecord::ConnectionAdapters::PostgreSQL::ReferentialIntegrity

#disable_referential_integrity, #supports_disable_referential_integrity?

Methods included from ActiveRecord::ConnectionAdapters::PostgreSQL::Quoting

#escape_bytea, #quote_column_name, #quote_default_value, #quote_string, #quote_table_name, #quote_table_name_for_assignment, #quoted_date, #unescape_bytea

Methods inherited from AbstractAdapter

#adapter_name, #case_insensitive_comparison, #case_sensitive_comparison, #case_sensitive_modifier, #close, #collector, #create_savepoint, #current_savepoint_name, #disable_referential_integrity, #expire, #lease, #new_column, #prefetch_primary_key?, #raw_connection, #release_savepoint, #requires_reloading?, #substitute_at, #supports_bulk_alter?, #supports_indexes_in_create?, #supports_savepoints?, type_cast_config_to_boolean, type_cast_config_to_integer, #type_map, #unprepared_statement, #verify!

Methods included from ColumnDumper

#column_spec

Methods included from ActiveSupport::Callbacks

#run_callbacks

Methods included from ActiveSupport::Concern

#append_features, #class_methods, extended, #included

Methods included from QueryCache

#cache, #clear_query_cache, dirties_query_cache, #disable_query_cache!, #enable_query_cache!, included, #select_all, #uncached

Methods included from DatabaseLimits

#allowed_index_name_length, #column_name_length, #columns_per_multicolumn_index, #columns_per_table, #in_clause_length, #index_name_length, #indexes_per_table, #joins_per_query, #sql_query_length, #table_name_length

Methods included from Quoting

#quote, #quote_column_name, #quote_string, #quote_table_name, #quote_table_name_for_assignment, #quoted_date, #quoted_false, #quoted_true, #type_cast, #unquoted_false, #unquoted_true

Methods included from DatabaseStatements

#add_transaction_record, #begin_db_transaction, #begin_isolated_db_transaction, #cacheable_query, #commit_db_transaction, #default_sequence_name, #delete, #empty_insert_statement_value, #exec_delete, #exec_insert, #exec_query, #exec_rollback_db_transaction, #exec_rollback_to_savepoint, #exec_update, #execute, #insert, #insert_fixture, #join_to_delete, #join_to_update, #reset_sequence!, #reset_transaction, #rollback_db_transaction, #rollback_to_savepoint, #sanitize_limit, #select_all, #select_one, #select_rows, #select_value, #select_values, #to_sql, #transaction, #transaction_isolation_levels, #transaction_open?, #transaction_state, #update

Methods included from SchemaStatements

#add_column, #add_foreign_key, #add_index, #add_index_options, #add_reference, #add_timestamps, #assume_migrated_upto_version, #change_column, #change_column_default, #change_column_null, #change_table, #column_exists?, #columns, #columns_for_distinct, #create_join_table, #create_table, #data_source_exists?, #data_sources, #drop_join_table, #drop_table, #dump_schema_information, #foreign_key_column_for, #foreign_keys, #index_exists?, #index_name, #index_name_exists?, #initialize_schema_migrations_table, #remove_column, #remove_columns, #remove_foreign_key, #remove_index, #remove_index!, #remove_reference, #remove_timestamps, #rename_column, #rename_index, #rename_table, #table_alias_for, #table_exists?, #type_to_sql

Methods included from TimestampDefaultDeprecation

#emit_warning_if_null_unspecified

Constructor Details

#initialize(connection, logger, connection_parameters, config) ⇒ PostgreSQLAdapter

Initializes and connects a PostgreSQL adapter.


226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 226

def initialize(connection, logger, connection_parameters, config)
  super(connection, logger)

  @visitor = Arel::Visitors::PostgreSQL.new self
  if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true })
    @prepared_statements = true
  else
    @prepared_statements = false
  end

  @connection_parameters, @config = connection_parameters, config

  # @local_tz is initialized as nil to avoid warnings when connect tries to use it
  @local_tz = nil
  @table_alias_length = nil

  connect
  @statements = StatementPool.new @connection,
                                  self.class.type_cast_config_to_integer(config.fetch(:statement_limit) { 1000 })

  if postgresql_version < 80200
    raise "Your version of PostgreSQL (#{postgresql_version}) is too old, please upgrade!"
  end

  @type_map = Type::HashLookupTypeMap.new
  initialize_type_map(type_map)
  @local_tz = execute('SHOW TIME ZONE', 'SCHEMA').first["TimeZone"]
  @use_insert_returning = @config.key?(:insert_returning) ? self.class.type_cast_config_to_boolean(@config[:insert_returning]) : true
end

Instance Method Details

#active?Boolean

Is this connection alive and ready for queries?


266
267
268
269
270
271
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 266

def active?
  @connection.query 'SELECT 1'
  true
rescue PGError
  false
end

#clear_cache!Object

Clears the prepared statements cache.


257
258
259
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 257

def clear_cache!
  @statements.clear
end

#column_name_for_operation(operation, node) ⇒ Object

:nodoc:


393
394
395
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 393

def column_name_for_operation(operation, node) # :nodoc:
  OPERATION_ALIASES.fetch(operation) { operation.downcase }
end

#disable_extension(name) ⇒ Object


343
344
345
346
347
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 343

def disable_extension(name)
  exec_query("DROP EXTENSION IF EXISTS \"#{name}\" CASCADE").tap {
    reload_type_map
  }
end

#disconnect!Object

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


292
293
294
295
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 292

def disconnect!
  super
  @connection.close rescue nil
end

#enable_extension(name) ⇒ Object


337
338
339
340
341
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 337

def enable_extension(name)
  exec_query("CREATE EXTENSION IF NOT EXISTS \"#{name}\"").tap {
    reload_type_map
  }
end

#extension_enabled?(name) ⇒ Boolean


349
350
351
352
353
354
355
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 349

def extension_enabled?(name)
  if supports_extensions?
    res = exec_query "SELECT EXISTS(SELECT * FROM pg_available_extensions WHERE name = '#{name}' AND installed_version IS NOT NULL) as enabled",
      'SCHEMA'
    res.cast_values.first
  end
end

#extensionsObject


357
358
359
360
361
362
363
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 357

def extensions
  if supports_extensions?
    exec_query("SELECT extname from pg_extension", "SCHEMA").cast_values
  else
    super
  end
end

#index_algorithmsObject


168
169
170
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 168

def index_algorithms
  { concurrently: 'CONCURRENTLY' }
end

#lookup_cast_type(sql_type) ⇒ Object

:nodoc:


388
389
390
391
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 388

def lookup_cast_type(sql_type) # :nodoc:
  oid = execute("SELECT #{quote(sql_type)}::regtype::oid", "SCHEMA").first['oid'].to_i
  super(oid)
end

#migration_keysObject

Adds :array as a valid migration key


138
139
140
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 138

def migration_keys
  super + [:array]
end

#native_database_typesObject

:nodoc:


297
298
299
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 297

def native_database_types #:nodoc:
  NATIVE_DATABASE_TYPES
end

#prepare_column_options(column, types) ⇒ Object

Adds :array option to the default set provided by the AbstractAdapter


130
131
132
133
134
135
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 130

def prepare_column_options(column, types) # :nodoc:
  spec = super
  spec[:array] = 'true' if column.respond_to?(:array) && column.array
  spec[:default] = "\"#{column.default_function}\"" if column.default_function
  spec
end

#reconnect!Object

Close then reopen the connection.


274
275
276
277
278
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 274

def reconnect!
  super
  @connection.reset
  configure_connection
end

#reset!Object


280
281
282
283
284
285
286
287
288
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 280

def reset!
  clear_cache!
  reset_transaction
  unless @connection.transaction_status == ::PG::PQTRANS_IDLE
    @connection.query 'ROLLBACK'
  end
  @connection.query 'DISCARD ALL'
  configure_connection
end

#schema_creationObject

:nodoc:


124
125
126
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 124

def schema_creation # :nodoc:
  PostgreSQL::SchemaCreation.new self
end

#session_auth=(user) ⇒ Object

Set the authorized user for this session


371
372
373
374
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 371

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

#set_standard_conforming_stringsObject


311
312
313
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 311

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

#supports_ddl_transactions?Boolean


315
316
317
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 315

def supports_ddl_transactions?
  true
end

#supports_explain?Boolean


319
320
321
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 319

def supports_explain?
  true
end

#supports_extensions?Boolean

Returns true if pg > 9.1


324
325
326
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 324

def supports_extensions?
  postgresql_version >= 90100
end

#supports_foreign_keys?Boolean


160
161
162
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 160

def supports_foreign_keys?
  true
end

#supports_index_sort_order?Boolean


148
149
150
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 148

def supports_index_sort_order?
  true
end

#supports_materialized_views?Boolean


333
334
335
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 333

def supports_materialized_views?
  postgresql_version >= 90300
end

#supports_migrations?Boolean

Returns true, since this connection adapter supports migrations.


302
303
304
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 302

def supports_migrations?
  true
end

#supports_partial_index?Boolean


152
153
154
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 152

def supports_partial_index?
  true
end

#supports_primary_key?Boolean

Does PostgreSQL support finding primary key on non-Active Record tables?


307
308
309
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 307

def supports_primary_key? #:nodoc:
  true
end

#supports_ranges?Boolean

Range datatypes weren't introduced until PostgreSQL 9.2


329
330
331
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 329

def supports_ranges?
  postgresql_version >= 90200
end

#supports_statement_cache?Boolean

Returns true, since this connection adapter supports prepared statement caching.


144
145
146
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 144

def supports_statement_cache?
  true
end

#supports_transaction_isolation?Boolean


156
157
158
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 156

def supports_transaction_isolation?
  true
end

#supports_views?Boolean


164
165
166
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 164

def supports_views?
  true
end

#table_alias_lengthObject

Returns the configured supported identifier length supported by PostgreSQL


366
367
368
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 366

def table_alias_length
  @table_alias_length ||= query('SHOW max_identifier_length', 'SCHEMA')[0][0].to_i
end

#truncate(table_name, name = nil) ⇒ Object


261
262
263
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 261

def truncate(table_name, name = nil)
  exec_query "TRUNCATE TABLE #{quote_table_name(table_name)}", name, []
end

#update_table_definition(table_name, base) ⇒ Object

:nodoc:


384
385
386
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 384

def update_table_definition(table_name, base) #:nodoc:
  PostgreSQL::Table.new(table_name, base)
end

#use_insert_returning?Boolean


376
377
378
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 376

def use_insert_returning?
  @use_insert_returning
end

#valid_type?(type) ⇒ Boolean


380
381
382
# File 'activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb', line 380

def valid_type?(type)
  !native_database_types[type].nil?
end