Module: ArJdbc::PostgreSQL

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

Overview

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

Constant Summary collapse

ADAPTER_NAME =
'PostgreSQL'.freeze
NATIVE_DATABASE_TYPES =
{
  bigserial:    'bigserial',
  primary_key:  'serial 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:     { name: 'timestamp' },
  decimal:      { name: 'decimal' }, # :limit => 1000
  float:        { name: 'float' },
  hstore:       { name: 'hstore' },
  inet:         { name: 'inet' },
  int4range:    { name: 'int4range' },
  int8range:    { name: 'int8range' },
  integer:      { name: 'integer' },
  interval:     { name: 'interval' }, # This doesn't get added to AR's postgres adapter until 5.1 but it fixes broken tests in 5.0 ...
  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' },
  path:         { name: 'path' },
  point:        { name: 'point' },
  polygon:      { name: 'polygon' },
  serial:       { name: 'serial' }, # auto-inc integer, bigserial, smallserial
  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' }
}

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.jdbc_connection_classObject



39
40
41
# File 'lib/arjdbc/postgresql/adapter.rb', line 39

def self.jdbc_connection_class
  ::ActiveRecord::ConnectionAdapters::PostgreSQLJdbcConnection
end

Instance Method Details

#adapter_nameObject



48
49
50
# File 'lib/arjdbc/postgresql/adapter.rb', line 48

def adapter_name
  ADAPTER_NAME
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.



443
444
445
446
447
448
449
450
451
# File 'lib/arjdbc/postgresql/adapter.rb', line 443

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



419
420
421
# File 'lib/arjdbc/postgresql/adapter.rb', line 419

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

#clear_cache!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



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

def clear_cache!
  super
  @connection.execute 'DEALLOCATE ALL' if supports_statement_cache? && @connection.active?
end

#client_min_messagesObject

Returns the current client message level.



424
425
426
427
428
# File 'lib/arjdbc/postgresql/adapter.rb', line 424

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.



431
432
433
434
435
436
# File 'lib/arjdbc/postgresql/adapter.rb', line 431

def client_min_messages=(level)
  # NOTE: for now simply ignore the writer (no warn on Redshift) so that
  # the AR copy-pasted PpstgreSQL parts stay the same as much as possible
  return nil if redshift? # not supported on Redshift
  execute("SET client_min_messages TO '#{level}'", 'SCHEMA')
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.



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/arjdbc/postgresql/adapter.rb', line 111

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::Base.default_timezone == :utc
    execute("SET time zone 'UTC'", 'SCHEMA')
  elsif tz = local_tz
    execute("SET time zone '#{tz}'", 'SCHEMA')
  end unless redshift?

  # 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
end

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

:nodoc:



409
410
411
412
413
# File 'lib/arjdbc/postgresql/adapter.rb', line 409

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) ⇒ Object



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

def disable_extension(name)
  execute("DROP EXTENSION IF EXISTS \"#{name}\" CASCADE")
end

#enable_extension(name) ⇒ Object



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

def enable_extension(name)
  execute("CREATE EXTENSION IF NOT EXISTS \"#{name}\"")
end

#escape_bytea(string) ⇒ Object

Note:

quote_string implemented as native



455
456
457
458
459
460
461
462
463
464
# File 'lib/arjdbc/postgresql/adapter.rb', line 455

def escape_bytea(string)
  return unless string
  if supports_hex_escaped_bytea?
    "\\x#{string.unpack("H*")[0]}"
  else
    result = ''
    string.each_byte { |c| result << sprintf('\\\\%03o', c) }
    result
  end
end

#exec_insert(sql, name, binds, pk = nil, sequence_name = nil) ⇒ Object



357
358
359
360
361
362
363
364
365
366
367
368
369
# File 'lib/arjdbc/postgresql/adapter.rb', line 357

def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
  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

#explain(arel, binds = []) ⇒ Object



371
372
373
374
# File 'lib/arjdbc/postgresql/adapter.rb', line 371

def explain(arel, binds = [])
  sql = "EXPLAIN #{to_sql(arel, binds)}"
  ActiveRecord::ConnectionAdapters::PostgreSQL::ExplainPrettyPrinter.new.pp(exec_query(sql, 'EXPLAIN', binds))
end

#extension_enabled?(name) ⇒ Boolean

Returns:

  • (Boolean)


307
308
309
310
311
312
313
# File 'lib/arjdbc/postgresql/adapter.rb', line 307

def extension_enabled?(name)
  if supports_extensions?
    rows = select_rows("SELECT EXISTS(SELECT * FROM pg_available_extensions WHERE name = '#{name}' AND installed_version IS NOT NULL)", 'SCHEMA')
    available = rows.first.first # true/false or 't'/'f'
    available == true || available == 't'
  end
end

#extensionsObject



315
316
317
318
319
320
321
322
# File 'lib/arjdbc/postgresql/adapter.rb', line 315

def extensions
  if supports_extensions?
    rows = select_rows "SELECT extname from pg_extension", "SCHEMA"
    rows.map { |row| row.first }
  else
    []
  end
end

#get_advisory_lock(lock_id) ⇒ Object

Came from postgres_adapter



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

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

#index_algorithmsObject



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

def index_algorithms
  { :concurrently => 'CONCURRENTLY' }
end

#indexes(table_name, name = nil) ⇒ Object

Returns an array of indexes for the given table.



526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
# File 'lib/arjdbc/postgresql/adapter.rb', line 526

def indexes(table_name, name = nil)
  # FIXME: AR version => table = Utils.extract_schema_qualified_name(table_name.to_s)
  schema, table = extract_schema_and_table(table_name.to_s)

  result = query(<<-SQL, 'SCHEMA')
        SELECT distinct i.relname, d.indisunique, d.indkey, pg_get_indexdef(d.indexrelid), t.oid,
                        pg_catalog.obj_description(i.oid, 'pg_class') AS comment,
        (SELECT COUNT(*) FROM pg_opclass o
           JOIN (SELECT unnest(string_to_array(d.indclass::text, ' '))::int oid) c
             ON o.oid = c.oid WHERE o.opcdefault = 'f')
        FROM pg_class t
        INNER JOIN pg_index d ON t.oid = d.indrelid
        INNER JOIN pg_class i ON d.indexrelid = i.oid
        LEFT JOIN pg_namespace n ON n.oid = i.relnamespace
        WHERE i.relkind = 'i'
          AND d.indisprimary = 'f'
          AND t.relname = '#{table}'
          AND n.nspname = #{schema ? "'#{schema}'" : 'ANY (current_schemas(false))'}
        ORDER BY i.relname
  SQL

  result.map do |row|
    index_name = row[0]
    # FIXME: These values [1,2] are returned in a different format than AR expects, maybe we could update it on the Java side to be more accurate
    unique = row[1].is_a?(String) ? row[1] == 't' : row[1] # JDBC gets us a boolean
    indkey = row[2].is_a?(Java::OrgPostgresqlUtil::PGobject) ? row[2].value : row[2]
    indkey = indkey.split(" ").map(&:to_i)
    inddef = row[3]
    oid = row[4]
    comment = row[5]
    opclass = row[6]

    using, expressions, where = inddef.scan(/ USING (\w+?) \((.+?)\)(?: WHERE (.+))?\z/).flatten

    if indkey.include?(0) || opclass > 0
      columns = expressions
    else
      columns = Hash[query(<<-SQL.strip_heredoc, "SCHEMA")].values_at(*indkey).compact
            SELECT a.attnum, a.attname
            FROM pg_attribute a
            WHERE a.attrelid = #{oid}
            AND a.attnum IN (#{indkey.join(",")})
      SQL

      # add info on sort order for columns (only desc order is explicitly specified, asc is the default)
      orders = Hash[
          expressions.scan(/(\w+) DESC/).flatten.map { |order_column| [order_column, :desc] }
      ]
    end

    IndexDefinition.new(table_name, index_name, unique, columns, [], orders, where, nil, using.to_sym, comment.presence)
  end.compact
end

#jdbc_column_classObject



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

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

#last_insert_id_result(sequence_name) ⇒ Object



415
416
417
# File 'lib/arjdbc/postgresql/adapter.rb', line 415

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

#max_identifier_lengthObject Also known as: table_alias_length, index_name_length

Returns the configured supported identifier length supported by PostgreSQL



351
352
353
# File 'lib/arjdbc/postgresql/adapter.rb', line 351

def max_identifier_length
  @max_identifier_length ||= select_one('SHOW max_identifier_length', 'SCHEMA'.freeze)['max_identifier_length'].to_i
end

#native_database_typesObject



196
197
198
# File 'lib/arjdbc/postgresql/adapter.rb', line 196

def native_database_types
  NATIVE_DATABASE_TYPES
end

#postgresql_versionObject

TODO: Update this to pull info from the DatabaseMetaData object?



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/arjdbc/postgresql/adapter.rb', line 53

def postgresql_version
  @postgresql_version ||=
    begin
      version = @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

#quote_table_name(name) ⇒ Object



467
468
469
470
471
472
473
474
475
476
# File 'lib/arjdbc/postgresql/adapter.rb', line 467

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

Came from postgres_adapter



343
344
345
346
347
348
# File 'lib/arjdbc/postgresql/adapter.rb', line 343

def release_advisory_lock(lock_id) # :nodoc:
  unless lock_id.is_a?(Integer) && lock_id.bit_length <= 63
    raise(ArgumentError, "Postgres requires advisory lock ids to be a signed 64 bit integer")
  end
  select_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



482
483
484
485
# File 'lib/arjdbc/postgresql/adapter.rb', line 482

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

#reset!Object



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

def reset!
  clear_cache!
  reset_transaction
  @connection.rollback # Have to deal with rollbacks differently than the AR adapter
  @connection.execute 'DISCARD ALL'
  @connection.configure_connection
end

#session_auth=(user) ⇒ Object

Set the authorized user for this session.



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

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

#set_client_encoding(encoding) ⇒ Object



104
105
106
107
# File 'lib/arjdbc/postgresql/adapter.rb', line 104

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

Enable standard-conforming strings if available.



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

def set_standard_conforming_strings
  self.standard_conforming_strings=(true)
end

#standard_conforming_strings=(enable) ⇒ Object

Enable standard-conforming strings if available.



210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/arjdbc/postgresql/adapter.rb', line 210

def standard_conforming_strings=(enable)
  client_min_messages = self.client_min_messages
  begin
    self.client_min_messages = 'panic'
    value = enable ? "on" : "off"
    execute("SET standard_conforming_strings = #{value}", 'SCHEMA')
    @standard_conforming_strings = ( value == "on" )
  rescue
    @standard_conforming_strings = :unsupported
  ensure
    self.client_min_messages = client_min_messages
  end
end

#standard_conforming_strings?Boolean

Returns:

  • (Boolean)


224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/arjdbc/postgresql/adapter.rb', line 224

def standard_conforming_strings?
  if @standard_conforming_strings.nil?
    client_min_messages = self.client_min_messages
    begin
      self.client_min_messages = 'panic'
      value = select_one('SHOW standard_conforming_strings', 'SCHEMA')['standard_conforming_strings']
      @standard_conforming_strings = ( value == "on" )
    rescue
      @standard_conforming_strings = :unsupported
    ensure
      self.client_min_messages = client_min_messages
    end
  end
  @standard_conforming_strings == true # return false if :unsupported
end

#supports_advisory_locks?Boolean

Returns:

  • (Boolean)


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

def supports_advisory_locks?; true end

#supports_comments?Boolean

Returns:

  • (Boolean)


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

def supports_comments?; true end

#supports_datetime_with_precision?Boolean

Returns:

  • (Boolean)


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

def supports_datetime_with_precision?; true end

#supports_ddl_transactions?Boolean

Returns:

  • (Boolean)


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

def supports_ddl_transactions?; true end

#supports_explain?Boolean

Returns:

  • (Boolean)


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

def supports_explain?; true end

#supports_expression_index?Boolean

Returns:

  • (Boolean)


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

def supports_expression_index?; true end

#supports_extensions?Boolean

Returns:

  • (Boolean)


295
296
297
# File 'lib/arjdbc/postgresql/adapter.rb', line 295

def supports_extensions?
  postgresql_version >= 90200
end

#supports_foreign_keys?Boolean

Returns:

  • (Boolean)


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

def supports_foreign_keys?; true end

#supports_hex_escaped_bytea?Boolean

Returns:

  • (Boolean)


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

def supports_hex_escaped_bytea?
  postgresql_version >= 90000
end

#supports_index_sort_order?Boolean

Returns:

  • (Boolean)


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

def supports_index_sort_order?; true end

#supports_insert_with_returning?Boolean

Returns:

  • (Boolean)


286
287
288
# File 'lib/arjdbc/postgresql/adapter.rb', line 286

def supports_insert_with_returning?
  postgresql_version >= 80200
end

#supports_json?Boolean

Returns:

  • (Boolean)


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

def supports_json?
  postgresql_version >= 90200
end

#supports_materialized_views?Boolean

Returns:

  • (Boolean)


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

def supports_materialized_views?
  postgresql_version >= 90300
end

#supports_migrations?Boolean

Returns:

  • (Boolean)


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

def supports_migrations?; true end

#supports_partial_index?Boolean

Returns:

  • (Boolean)


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

def supports_partial_index?; true end

#supports_primary_key?Boolean

Supports finding primary key on non-Active Record tables

Returns:

  • (Boolean)


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

def supports_primary_key?; true end

#supports_ranges?Boolean

Range data-types weren't introduced until PostgreSQL 9.2.

Returns:

  • (Boolean)


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

def supports_ranges?
  postgresql_version >= 90200
end

#supports_savepoints?Boolean

Returns:

  • (Boolean)


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

def supports_savepoints?; true end

#supports_standard_conforming_strings?Boolean

Does PostgreSQL support standard conforming strings?

Returns:

  • (Boolean)


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

def supports_standard_conforming_strings?
  standard_conforming_strings?
  @standard_conforming_strings != :unsupported
end

#supports_transaction_isolation?(level = nil) ⇒ Boolean

Returns:

  • (Boolean)


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

def supports_transaction_isolation?(level = nil); true end

#supports_views?Boolean

Returns:

  • (Boolean)


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

def supports_views?; true end

#truncate(table_name, name = nil) ⇒ Object



521
522
523
# File 'lib/arjdbc/postgresql/adapter.rb', line 521

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

#use_insert_returning?Boolean

Returns:

  • (Boolean)


97
98
99
100
101
102
# File 'lib/arjdbc/postgresql/adapter.rb', line 97

def use_insert_returning?
  if @use_insert_returning.nil?
    @use_insert_returning = supports_insert_with_returning?
  end
  @use_insert_returning
end

#valid_type?(type) ⇒ Boolean

Returns:

  • (Boolean)


200
201
202
# File 'lib/arjdbc/postgresql/adapter.rb', line 200

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