activerecord-jdbc-alt-adapter 61.2.0-java → 70.0.0.rc2-java
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/.github/workflows/main.yml +118 -0
 - data/.github/workflows/ruby.yml +273 -0
 - data/.gitignore +1 -0
 - data/.travis.yml +3 -4
 - data/Gemfile +9 -7
 - data/README.md +5 -1
 - data/Rakefile +1 -1
 - data/activerecord-jdbc-adapter.gemspec +2 -2
 - data/activerecord-jdbc-alt-adapter.gemspec +2 -2
 - data/lib/arel/visitors/compat.rb +5 -33
 - data/lib/arel/visitors/h2.rb +1 -13
 - data/lib/arel/visitors/hsqldb.rb +1 -21
 - data/lib/arel/visitors/sql_server.rb +2 -103
 - data/lib/arjdbc/abstract/core.rb +8 -9
 - data/lib/arjdbc/abstract/database_statements.rb +4 -4
 - data/lib/arjdbc/discover.rb +0 -67
 - data/lib/arjdbc/hsqldb/adapter.rb +2 -2
 - data/lib/arjdbc/jdbc/adapter.rb +3 -3
 - data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
 - data/lib/arjdbc/jdbc/adapter_require.rb +3 -1
 - data/lib/arjdbc/jdbc/column.rb +1 -26
 - data/lib/arjdbc/jdbc/type_cast.rb +2 -2
 - data/lib/arjdbc/jdbc.rb +0 -7
 - data/lib/arjdbc/mssql/adapter.rb +138 -108
 - data/lib/arjdbc/mssql/quoting.rb +26 -27
 - data/lib/arjdbc/mssql/schema_creation.rb +1 -1
 - data/lib/arjdbc/mssql/schema_definitions.rb +32 -17
 - data/lib/arjdbc/mssql/schema_dumper.rb +13 -1
 - data/lib/arjdbc/mssql/schema_statements.rb +61 -36
 - data/lib/arjdbc/mssql/transaction.rb +2 -2
 - data/lib/arjdbc/mssql/types/date_and_time_types.rb +6 -6
 - data/lib/arjdbc/mssql/types/numeric_types.rb +2 -2
 - data/lib/arjdbc/mssql.rb +1 -1
 - data/lib/arjdbc/mysql/adapter.rb +2 -1
 - data/lib/arjdbc/oracle/adapter.rb +4 -23
 - data/lib/arjdbc/postgresql/adapter.rb +152 -4
 - data/lib/arjdbc/postgresql/oid_types.rb +142 -106
 - data/lib/arjdbc/sqlite3/adapter.rb +132 -88
 - data/lib/arjdbc/tasks/database_tasks.rb +0 -12
 - data/lib/arjdbc/util/serialized_attributes.rb +0 -22
 - data/lib/arjdbc/util/table_copier.rb +2 -1
 - data/lib/arjdbc/version.rb +1 -1
 - data/rakelib/02-test.rake +3 -18
 - data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +17 -2
 - data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +5 -0
 - data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +33 -0
 - metadata +9 -40
 - data/lib/active_record/connection_adapters/as400_adapter.rb +0 -2
 - data/lib/active_record/connection_adapters/db2_adapter.rb +0 -1
 - data/lib/active_record/connection_adapters/derby_adapter.rb +0 -1
 - data/lib/active_record/connection_adapters/informix_adapter.rb +0 -1
 - data/lib/arel/visitors/db2.rb +0 -137
 - data/lib/arel/visitors/derby.rb +0 -112
 - data/lib/arel/visitors/firebird.rb +0 -79
 - data/lib/arjdbc/db2/adapter.rb +0 -808
 - data/lib/arjdbc/db2/as400.rb +0 -142
 - data/lib/arjdbc/db2/column.rb +0 -131
 - data/lib/arjdbc/db2/connection_methods.rb +0 -48
 - data/lib/arjdbc/db2.rb +0 -4
 - data/lib/arjdbc/derby/active_record_patch.rb +0 -13
 - data/lib/arjdbc/derby/adapter.rb +0 -521
 - data/lib/arjdbc/derby/connection_methods.rb +0 -20
 - data/lib/arjdbc/derby/schema_creation.rb +0 -15
 - data/lib/arjdbc/derby.rb +0 -3
 - data/lib/arjdbc/firebird/adapter.rb +0 -413
 - data/lib/arjdbc/firebird/connection_methods.rb +0 -23
 - data/lib/arjdbc/firebird.rb +0 -4
 - data/lib/arjdbc/informix/adapter.rb +0 -139
 - data/lib/arjdbc/informix/connection_methods.rb +0 -9
 - data/lib/arjdbc/sybase/adapter.rb +0 -47
 - data/lib/arjdbc/sybase.rb +0 -2
 - data/lib/arjdbc/tasks/db2_database_tasks.rb +0 -104
 - data/lib/arjdbc/tasks/derby_database_tasks.rb +0 -95
 - data/src/java/arjdbc/derby/DerbyModule.java +0 -178
 - data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +0 -152
 - data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +0 -174
 - data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +0 -75
 
| 
         @@ -27,10 +27,10 @@ module ActiveRecord 
     | 
|
| 
       27 
27 
     | 
    
         
             
                  module RealTransactionExt
         
     | 
| 
       28 
28 
     | 
    
         
             
                    attr_reader :initial_transaction_isolation
         
     | 
| 
       29 
29 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
                    def initialize(connection,  
     | 
| 
      
 30 
     | 
    
         
            +
                    def initialize(connection, isolation: nil, joinable: true, run_commit_callbacks: false)
         
     | 
| 
       31 
31 
     | 
    
         
             
                      @connection = connection
         
     | 
| 
       32 
32 
     | 
    
         | 
| 
       33 
     | 
    
         
            -
                      if  
     | 
| 
      
 33 
     | 
    
         
            +
                      if isolation
         
     | 
| 
       34 
34 
     | 
    
         
             
                        @initial_transaction_isolation = current_transaction_isolation
         
     | 
| 
       35 
35 
     | 
    
         
             
                      end
         
     | 
| 
       36 
36 
     | 
    
         | 
| 
         @@ -13,9 +13,9 @@ module ActiveRecord 
     | 
|
| 
       13 
13 
     | 
    
         
             
                        return %("#{value}") if value.acts_like?(:string)
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
                        if value.usec > 0
         
     | 
| 
       16 
     | 
    
         
            -
                          %("#{value. 
     | 
| 
      
 16 
     | 
    
         
            +
                          %("#{value.to_fs(:db)}.#{value.usec.to_s.remove(/0+$/)}")
         
     | 
| 
       17 
17 
     | 
    
         
             
                        else
         
     | 
| 
       18 
     | 
    
         
            -
                          %("#{value. 
     | 
| 
      
 18 
     | 
    
         
            +
                          %("#{value.to_fs(:db)}")
         
     | 
| 
       19 
19 
     | 
    
         
             
                        end
         
     | 
| 
       20 
20 
     | 
    
         
             
                      end
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
         @@ -54,9 +54,9 @@ module ActiveRecord 
     | 
|
| 
       54 
54 
     | 
    
         
             
                        return %("#{value}") if value.acts_like?(:string)
         
     | 
| 
       55 
55 
     | 
    
         | 
| 
       56 
56 
     | 
    
         
             
                        if value.usec > 0
         
     | 
| 
       57 
     | 
    
         
            -
                          %("#{value. 
     | 
| 
      
 57 
     | 
    
         
            +
                          %("#{value.to_fs(:db)}.#{value.usec.to_s.remove(/0+$/)}")
         
     | 
| 
       58 
58 
     | 
    
         
             
                        else
         
     | 
| 
       59 
     | 
    
         
            -
                          %("#{value. 
     | 
| 
      
 59 
     | 
    
         
            +
                          %("#{value.to_fs(:db)}")
         
     | 
| 
       60 
60 
     | 
    
         
             
                        end
         
     | 
| 
       61 
61 
     | 
    
         
             
                      end
         
     | 
| 
       62 
62 
     | 
    
         | 
| 
         @@ -100,9 +100,9 @@ module ActiveRecord 
     | 
|
| 
       100 
100 
     | 
    
         
             
                        return %("#{value}") if value.acts_like?(:string)
         
     | 
| 
       101 
101 
     | 
    
         | 
| 
       102 
102 
     | 
    
         
             
                        if value.usec > 0
         
     | 
| 
       103 
     | 
    
         
            -
                          %("#{value. 
     | 
| 
      
 103 
     | 
    
         
            +
                          %("#{value.to_fs(:db)}.#{value.usec.to_s.remove(/0+$/)}")
         
     | 
| 
       104 
104 
     | 
    
         
             
                        else
         
     | 
| 
       105 
     | 
    
         
            -
                          %("#{value. 
     | 
| 
      
 105 
     | 
    
         
            +
                          %("#{value.to_fs(:db)}")
         
     | 
| 
       106 
106 
     | 
    
         
             
                        end
         
     | 
| 
       107 
107 
     | 
    
         
             
                      end
         
     | 
| 
       108 
108 
     | 
    
         | 
| 
         @@ -35,7 +35,7 @@ module ActiveRecord 
     | 
|
| 
       35 
35 
     | 
    
         
             
                    end
         
     | 
| 
       36 
36 
     | 
    
         | 
| 
       37 
37 
     | 
    
         
             
                    class Money < Decimal
         
     | 
| 
       38 
     | 
    
         
            -
                      def initialize( 
     | 
| 
      
 38 
     | 
    
         
            +
                      def initialize(precision: nil, limit: nil, scale: nil)
         
     | 
| 
       39 
39 
     | 
    
         
             
                        super
         
     | 
| 
       40 
40 
     | 
    
         
             
                        @precision = 19
         
     | 
| 
       41 
41 
     | 
    
         
             
                        @scale = 4
         
     | 
| 
         @@ -46,7 +46,7 @@ module ActiveRecord 
     | 
|
| 
       46 
46 
     | 
    
         
             
                    end
         
     | 
| 
       47 
47 
     | 
    
         | 
| 
       48 
48 
     | 
    
         
             
                    class SmallMoney < Decimal
         
     | 
| 
       49 
     | 
    
         
            -
                      def initialize( 
     | 
| 
      
 49 
     | 
    
         
            +
                      def initialize(precision: nil, limit: nil, scale: nil)
         
     | 
| 
       50 
50 
     | 
    
         
             
                        super
         
     | 
| 
       51 
51 
     | 
    
         
             
                        @precision = 10
         
     | 
| 
       52 
52 
     | 
    
         
             
                        @scale = 4
         
     | 
    
        data/lib/arjdbc/mssql.rb
    CHANGED
    
    
    
        data/lib/arjdbc/mysql/adapter.rb
    CHANGED
    
    
| 
         @@ -40,7 +40,7 @@ module ArJdbc 
     | 
|
| 
       40 
40 
     | 
    
         
             
                  return if @@_initialized; @@_initialized = true
         
     | 
| 
       41 
41 
     | 
    
         | 
| 
       42 
42 
     | 
    
         
             
                  require 'arjdbc/util/serialized_attributes'
         
     | 
| 
       43 
     | 
    
         
            -
                  Util::SerializedAttributes.setup  
     | 
| 
      
 43 
     | 
    
         
            +
                  Util::SerializedAttributes.setup %r{LOB\(|LOB$}i, 'after_save_with_oracle_lob'
         
     | 
| 
       44 
44 
     | 
    
         | 
| 
       45 
45 
     | 
    
         
             
                  unless ActiveRecord::ConnectionAdapters::AbstractAdapter.
         
     | 
| 
       46 
46 
     | 
    
         
             
                      instance_methods(false).detect { |m| m.to_s == "prefetch_primary_key?" }
         
     | 
| 
         @@ -285,7 +285,7 @@ module ArJdbc 
     | 
|
| 
       285 
285 
     | 
    
         
             
                      execute "ALTER TABLE #{quote_table_name(table_name)} ADD CONSTRAINT #{quote_column_name(index_name)} #{index_type} (#{quoted_column_names})"
         
     | 
| 
       286 
286 
     | 
    
         
             
                    end
         
     | 
| 
       287 
287 
     | 
    
         
             
                  end
         
     | 
| 
       288 
     | 
    
         
            -
                end 
     | 
| 
      
 288 
     | 
    
         
            +
                end
         
     | 
| 
       289 
289 
     | 
    
         | 
| 
       290 
290 
     | 
    
         
             
                # @private
         
     | 
| 
       291 
291 
     | 
    
         
             
                def add_index_options(table_name, column_name, options = {})
         
     | 
| 
         @@ -309,7 +309,7 @@ module ArJdbc 
     | 
|
| 
       309 
309 
     | 
    
         | 
| 
       310 
310 
     | 
    
         
             
                  quoted_column_names = column_names.map { |e| quote_column_name_or_expression(e) }.join(", ")
         
     | 
| 
       311 
311 
     | 
    
         
             
                  [ index_name, index_type, quoted_column_names, tablespace, index_options ]
         
     | 
| 
       312 
     | 
    
         
            -
                end 
     | 
| 
      
 312 
     | 
    
         
            +
                end
         
     | 
| 
       313 
313 
     | 
    
         | 
| 
       314 
314 
     | 
    
         
             
                # @override
         
     | 
| 
       315 
315 
     | 
    
         
             
                def remove_index(table_name, options = {})
         
     | 
| 
         @@ -327,12 +327,7 @@ module ArJdbc 
     | 
|
| 
       327 
327 
     | 
    
         
             
                  end
         
     | 
| 
       328 
328 
     | 
    
         
             
                  execute "ALTER TABLE #{quote_table_name(table_name)} DROP CONSTRAINT #{quote_column_name(index_name)}" rescue nil
         
     | 
| 
       329 
329 
     | 
    
         
             
                  execute "DROP INDEX #{quote_column_name(index_name)}"
         
     | 
| 
       330 
     | 
    
         
            -
                end 
     | 
| 
       331 
     | 
    
         
            -
             
     | 
| 
       332 
     | 
    
         
            -
                # @private
         
     | 
| 
       333 
     | 
    
         
            -
                def remove_index(table_name, options = {})
         
     | 
| 
       334 
     | 
    
         
            -
                  execute "DROP INDEX #{index_name(table_name, options)}"
         
     | 
| 
       335 
     | 
    
         
            -
                end unless AR42
         
     | 
| 
      
 330 
     | 
    
         
            +
                end
         
     | 
| 
       336 
331 
     | 
    
         | 
| 
       337 
332 
     | 
    
         
             
                def change_column_default(table_name, column_name, default)
         
     | 
| 
       338 
333 
     | 
    
         
             
                  execute "ALTER TABLE #{quote_table_name(table_name)} MODIFY #{quote_column_name(column_name)} DEFAULT #{quote(default)}"
         
     | 
| 
         @@ -361,25 +356,11 @@ module ArJdbc 
     | 
|
| 
       361 
356 
     | 
    
         
             
                    "RENAME COLUMN #{quote_column_name(column_name)} TO #{quote_column_name(new_column_name)}"
         
     | 
| 
       362 
357 
     | 
    
         
             
                end
         
     | 
| 
       363 
358 
     | 
    
         | 
| 
       364 
     | 
    
         
            -
                if ActiveRecord::VERSION::MAJOR >= 4
         
     | 
| 
       365 
     | 
    
         
            -
             
     | 
| 
       366 
359 
     | 
    
         
             
                # @override
         
     | 
| 
       367 
360 
     | 
    
         
             
                def remove_column(table_name, column_name, type = nil, options = {})
         
     | 
| 
       368 
361 
     | 
    
         
             
                  do_remove_column(table_name, column_name)
         
     | 
| 
       369 
362 
     | 
    
         
             
                end
         
     | 
| 
       370 
363 
     | 
    
         | 
| 
       371 
     | 
    
         
            -
                else
         
     | 
| 
       372 
     | 
    
         
            -
             
     | 
| 
       373 
     | 
    
         
            -
                # @override
         
     | 
| 
       374 
     | 
    
         
            -
                def remove_column(table_name, *column_names)
         
     | 
| 
       375 
     | 
    
         
            -
                  for column_name in column_names.flatten
         
     | 
| 
       376 
     | 
    
         
            -
                    do_remove_column(table_name, column_name)
         
     | 
| 
       377 
     | 
    
         
            -
                  end
         
     | 
| 
       378 
     | 
    
         
            -
                end
         
     | 
| 
       379 
     | 
    
         
            -
                alias remove_columns remove_column
         
     | 
| 
       380 
     | 
    
         
            -
             
     | 
| 
       381 
     | 
    
         
            -
                end
         
     | 
| 
       382 
     | 
    
         
            -
             
     | 
| 
       383 
364 
     | 
    
         
             
                def do_remove_column(table_name, column_name)
         
     | 
| 
       384 
365 
     | 
    
         
             
                  execute "ALTER TABLE #{quote_table_name(table_name)} DROP COLUMN #{quote_column_name(column_name)}"
         
     | 
| 
       385 
366 
     | 
    
         
             
                end
         
     | 
| 
         @@ -81,7 +81,7 @@ module ArJdbc 
     | 
|
| 
       81 
81 
     | 
    
         
             
                  # If using Active Record's time zone support configure the connection to return
         
     | 
| 
       82 
82 
     | 
    
         
             
                  # TIMESTAMP WITH ZONE types in UTC.
         
     | 
| 
       83 
83 
     | 
    
         
             
                  # (SET TIME ZONE does not use an equals sign like other SET variables)
         
     | 
| 
       84 
     | 
    
         
            -
                  if ActiveRecord 
     | 
| 
      
 84 
     | 
    
         
            +
                  if ActiveRecord.default_timezone == :utc
         
     | 
| 
       85 
85 
     | 
    
         
             
                    execute("SET time zone 'UTC'", 'SCHEMA')
         
     | 
| 
       86 
86 
     | 
    
         
             
                  elsif tz = local_tz
         
     | 
| 
       87 
87 
     | 
    
         
             
                    execute("SET time zone '#{tz}'", 'SCHEMA')
         
     | 
| 
         @@ -320,6 +320,38 @@ module ArJdbc 
     | 
|
| 
       320 
320 
     | 
    
         
             
                  exec_query("SELECT extname FROM pg_extension", "SCHEMA").cast_values
         
     | 
| 
       321 
321 
     | 
    
         
             
                end
         
     | 
| 
       322 
322 
     | 
    
         | 
| 
      
 323 
     | 
    
         
            +
                # Returns a list of defined enum types, and their values.
         
     | 
| 
      
 324 
     | 
    
         
            +
                def enum_types
         
     | 
| 
      
 325 
     | 
    
         
            +
                  query = <<~SQL
         
     | 
| 
      
 326 
     | 
    
         
            +
                      SELECT
         
     | 
| 
      
 327 
     | 
    
         
            +
                        type.typname AS name,
         
     | 
| 
      
 328 
     | 
    
         
            +
                        string_agg(enum.enumlabel, ',' ORDER BY enum.enumsortorder) AS value
         
     | 
| 
      
 329 
     | 
    
         
            +
                      FROM pg_enum AS enum
         
     | 
| 
      
 330 
     | 
    
         
            +
                      JOIN pg_type AS type
         
     | 
| 
      
 331 
     | 
    
         
            +
                        ON (type.oid = enum.enumtypid)
         
     | 
| 
      
 332 
     | 
    
         
            +
                      GROUP BY type.typname;
         
     | 
| 
      
 333 
     | 
    
         
            +
                  SQL
         
     | 
| 
      
 334 
     | 
    
         
            +
                  exec_query(query, "SCHEMA").cast_values
         
     | 
| 
      
 335 
     | 
    
         
            +
                end
         
     | 
| 
      
 336 
     | 
    
         
            +
             
     | 
| 
      
 337 
     | 
    
         
            +
                # Given a name and an array of values, creates an enum type.
         
     | 
| 
      
 338 
     | 
    
         
            +
                def create_enum(name, values)
         
     | 
| 
      
 339 
     | 
    
         
            +
                  sql_values = values.map { |s| "'#{s}'" }.join(", ")
         
     | 
| 
      
 340 
     | 
    
         
            +
                  query = <<~SQL
         
     | 
| 
      
 341 
     | 
    
         
            +
                      DO $$
         
     | 
| 
      
 342 
     | 
    
         
            +
                      BEGIN
         
     | 
| 
      
 343 
     | 
    
         
            +
                          IF NOT EXISTS (
         
     | 
| 
      
 344 
     | 
    
         
            +
                            SELECT 1 FROM pg_type t
         
     | 
| 
      
 345 
     | 
    
         
            +
                            WHERE t.typname = '#{name}'
         
     | 
| 
      
 346 
     | 
    
         
            +
                          ) THEN
         
     | 
| 
      
 347 
     | 
    
         
            +
                              CREATE TYPE \"#{name}\" AS ENUM (#{sql_values});
         
     | 
| 
      
 348 
     | 
    
         
            +
                          END IF;
         
     | 
| 
      
 349 
     | 
    
         
            +
                      END
         
     | 
| 
      
 350 
     | 
    
         
            +
                      $$;
         
     | 
| 
      
 351 
     | 
    
         
            +
                  SQL
         
     | 
| 
      
 352 
     | 
    
         
            +
                  exec_query(query)
         
     | 
| 
      
 353 
     | 
    
         
            +
                end
         
     | 
| 
      
 354 
     | 
    
         
            +
             
     | 
| 
       323 
355 
     | 
    
         
             
                # Returns the configured supported identifier length supported by PostgreSQL
         
     | 
| 
       324 
356 
     | 
    
         
             
                def max_identifier_length
         
     | 
| 
       325 
357 
     | 
    
         
             
                  @max_identifier_length ||= query_value("SHOW max_identifier_length", "SCHEMA").to_i
         
     | 
| 
         @@ -672,6 +704,37 @@ module ActiveRecord::ConnectionAdapters 
     | 
|
| 
       672 
704 
     | 
    
         
             
              class PostgreSQLAdapter < AbstractAdapter
         
     | 
| 
       673 
705 
     | 
    
         
             
                class_attribute :create_unlogged_tables, default: false
         
     | 
| 
       674 
706 
     | 
    
         | 
| 
      
 707 
     | 
    
         
            +
                ##
         
     | 
| 
      
 708 
     | 
    
         
            +
                # :singleton-method:
         
     | 
| 
      
 709 
     | 
    
         
            +
                # PostgreSQL allows the creation of "unlogged" tables, which do not record
         
     | 
| 
      
 710 
     | 
    
         
            +
                # data in the PostgreSQL Write-Ahead Log. This can make the tables faster,
         
     | 
| 
      
 711 
     | 
    
         
            +
                # but significantly increases the risk of data loss if the database
         
     | 
| 
      
 712 
     | 
    
         
            +
                # crashes. As a result, this should not be used in production
         
     | 
| 
      
 713 
     | 
    
         
            +
                # environments. If you would like all created tables to be unlogged in
         
     | 
| 
      
 714 
     | 
    
         
            +
                # the test environment you can add the following line to your test.rb
         
     | 
| 
      
 715 
     | 
    
         
            +
                # file:
         
     | 
| 
      
 716 
     | 
    
         
            +
                #
         
     | 
| 
      
 717 
     | 
    
         
            +
                #   ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.create_unlogged_tables = true
         
     | 
| 
      
 718 
     | 
    
         
            +
                class_attribute :create_unlogged_tables, default: false
         
     | 
| 
      
 719 
     | 
    
         
            +
             
     | 
| 
      
 720 
     | 
    
         
            +
                ##
         
     | 
| 
      
 721 
     | 
    
         
            +
                # :singleton-method:
         
     | 
| 
      
 722 
     | 
    
         
            +
                # PostgreSQL supports multiple types for DateTimes. By default, if you use +datetime+
         
     | 
| 
      
 723 
     | 
    
         
            +
                # in migrations, Rails will translate this to a PostgreSQL "timestamp without time zone".
         
     | 
| 
      
 724 
     | 
    
         
            +
                # Change this in an initializer to use another NATIVE_DATABASE_TYPES. For example, to
         
     | 
| 
      
 725 
     | 
    
         
            +
                # store DateTimes as "timestamp with time zone":
         
     | 
| 
      
 726 
     | 
    
         
            +
                #
         
     | 
| 
      
 727 
     | 
    
         
            +
                #   ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.datetime_type = :timestamptz
         
     | 
| 
      
 728 
     | 
    
         
            +
                #
         
     | 
| 
      
 729 
     | 
    
         
            +
                # Or if you are adding a custom type:
         
     | 
| 
      
 730 
     | 
    
         
            +
                #
         
     | 
| 
      
 731 
     | 
    
         
            +
                #   ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:my_custom_type] = { name: "my_custom_type_name" }
         
     | 
| 
      
 732 
     | 
    
         
            +
                #   ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.datetime_type = :my_custom_type
         
     | 
| 
      
 733 
     | 
    
         
            +
                #
         
     | 
| 
      
 734 
     | 
    
         
            +
                # If you're using +:ruby+ as your +config.active_record.schema_format+ and you change this
         
     | 
| 
      
 735 
     | 
    
         
            +
                # setting, you should immediately run <tt>bin/rails db:migrate</tt> to update the types in your schema.rb.
         
     | 
| 
      
 736 
     | 
    
         
            +
                class_attribute :datetime_type, default: :timestamp
         
     | 
| 
      
 737 
     | 
    
         
            +
             
     | 
| 
       675 
738 
     | 
    
         
             
                # Try to use as much of the built in postgres logic as possible
         
     | 
| 
       676 
739 
     | 
    
         
             
                # maybe someday we can extend the actual adapter
         
     | 
| 
       677 
740 
     | 
    
         
             
                include ActiveRecord::ConnectionAdapters::PostgreSQL::ReferentialIntegrity
         
     | 
| 
         @@ -735,11 +798,96 @@ module ActiveRecord::ConnectionAdapters 
     | 
|
| 
       735 
798 
     | 
    
         | 
| 
       736 
799 
     | 
    
         
             
                private
         
     | 
| 
       737 
800 
     | 
    
         | 
| 
       738 
     | 
    
         
            -
                 
     | 
| 
       739 
     | 
    
         
            -
             
     | 
| 
      
 801 
     | 
    
         
            +
                FEATURE_NOT_SUPPORTED = "0A000" # :nodoc:
         
     | 
| 
      
 802 
     | 
    
         
            +
             
     | 
| 
      
 803 
     | 
    
         
            +
                def execute_and_clear(sql, name, binds, prepare: false, async: false)
         
     | 
| 
      
 804 
     | 
    
         
            +
                  sql = transform_query(sql)
         
     | 
| 
      
 805 
     | 
    
         
            +
                  check_if_write_query(sql)
         
     | 
| 
      
 806 
     | 
    
         
            +
             
     | 
| 
      
 807 
     | 
    
         
            +
                  if !prepare || without_prepared_statement?(binds)
         
     | 
| 
      
 808 
     | 
    
         
            +
                    result = exec_no_cache(sql, name, binds, async: async)
         
     | 
| 
      
 809 
     | 
    
         
            +
                  else
         
     | 
| 
      
 810 
     | 
    
         
            +
                    result = exec_cache(sql, name, binds, async: async)
         
     | 
| 
      
 811 
     | 
    
         
            +
                  end
         
     | 
| 
      
 812 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 813 
     | 
    
         
            +
                    ret = yield result
         
     | 
| 
      
 814 
     | 
    
         
            +
                  ensure
         
     | 
| 
      
 815 
     | 
    
         
            +
                    # Is this really result in AR PG?
         
     | 
| 
      
 816 
     | 
    
         
            +
            #        result.clear
         
     | 
| 
      
 817 
     | 
    
         
            +
                  end
         
     | 
| 
      
 818 
     | 
    
         
            +
                  ret
         
     | 
| 
      
 819 
     | 
    
         
            +
                end
         
     | 
| 
      
 820 
     | 
    
         
            +
             
     | 
| 
      
 821 
     | 
    
         
            +
                def exec_no_cache(sql, name, binds, async: false)
         
     | 
| 
      
 822 
     | 
    
         
            +
                  materialize_transactions
         
     | 
| 
      
 823 
     | 
    
         
            +
                  mark_transaction_written_if_write(sql)
         
     | 
| 
      
 824 
     | 
    
         
            +
             
     | 
| 
      
 825 
     | 
    
         
            +
                  # make sure we carry over any changes to ActiveRecord.default_timezone that have been
         
     | 
| 
      
 826 
     | 
    
         
            +
                  # made since we established the connection
         
     | 
| 
      
 827 
     | 
    
         
            +
                  update_typemap_for_default_timezone
         
     | 
| 
      
 828 
     | 
    
         
            +
             
     | 
| 
      
 829 
     | 
    
         
            +
                  type_casted_binds = type_casted_binds(binds)
         
     | 
| 
      
 830 
     | 
    
         
            +
                  log(sql, name, binds, type_casted_binds, async: async) do
         
     | 
| 
      
 831 
     | 
    
         
            +
                    ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
         
     | 
| 
      
 832 
     | 
    
         
            +
                      @connection.exec_params(sql, type_casted_binds)
         
     | 
| 
      
 833 
     | 
    
         
            +
                    end
         
     | 
| 
      
 834 
     | 
    
         
            +
                  end
         
     | 
| 
      
 835 
     | 
    
         
            +
                end
         
     | 
| 
      
 836 
     | 
    
         
            +
             
     | 
| 
      
 837 
     | 
    
         
            +
                def exec_cache(sql, name, binds, async: false)
         
     | 
| 
      
 838 
     | 
    
         
            +
                  materialize_transactions
         
     | 
| 
      
 839 
     | 
    
         
            +
                  mark_transaction_written_if_write(sql)
         
     | 
| 
      
 840 
     | 
    
         
            +
                  update_typemap_for_default_timezone
         
     | 
| 
      
 841 
     | 
    
         
            +
             
     | 
| 
      
 842 
     | 
    
         
            +
                  stmt_key = prepare_statement(sql, binds)
         
     | 
| 
      
 843 
     | 
    
         
            +
                  type_casted_binds = type_casted_binds(binds)
         
     | 
| 
      
 844 
     | 
    
         
            +
             
     | 
| 
      
 845 
     | 
    
         
            +
                  log(sql, name, binds, type_casted_binds, stmt_key, async: async) do
         
     | 
| 
      
 846 
     | 
    
         
            +
                    ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
         
     | 
| 
      
 847 
     | 
    
         
            +
                      @connection.exec_prepared(stmt_key, type_casted_binds)
         
     | 
| 
      
 848 
     | 
    
         
            +
                    end
         
     | 
| 
      
 849 
     | 
    
         
            +
                  end
         
     | 
| 
      
 850 
     | 
    
         
            +
                rescue ActiveRecord::StatementInvalid => e
         
     | 
| 
      
 851 
     | 
    
         
            +
                  raise unless is_cached_plan_failure?(e)
         
     | 
| 
      
 852 
     | 
    
         
            +
             
     | 
| 
      
 853 
     | 
    
         
            +
                  # Nothing we can do if we are in a transaction because all commands
         
     | 
| 
      
 854 
     | 
    
         
            +
                  # will raise InFailedSQLTransaction
         
     | 
| 
      
 855 
     | 
    
         
            +
                  if in_transaction?
         
     | 
| 
      
 856 
     | 
    
         
            +
                    raise ActiveRecord::PreparedStatementCacheExpired.new(e.cause.message)
         
     | 
| 
      
 857 
     | 
    
         
            +
                  else
         
     | 
| 
      
 858 
     | 
    
         
            +
                    @lock.synchronize do
         
     | 
| 
      
 859 
     | 
    
         
            +
                      # outside of transactions we can simply flush this query and retry
         
     | 
| 
      
 860 
     | 
    
         
            +
                      @statements.delete sql_key(sql)
         
     | 
| 
      
 861 
     | 
    
         
            +
                    end
         
     | 
| 
      
 862 
     | 
    
         
            +
                    retry
         
     | 
| 
      
 863 
     | 
    
         
            +
                  end
         
     | 
| 
      
 864 
     | 
    
         
            +
                end
         
     | 
| 
      
 865 
     | 
    
         
            +
             
     | 
| 
      
 866 
     | 
    
         
            +
                # Annoyingly, the code for prepared statements whose return value may
         
     | 
| 
      
 867 
     | 
    
         
            +
                # have changed is FEATURE_NOT_SUPPORTED.
         
     | 
| 
      
 868 
     | 
    
         
            +
                #
         
     | 
| 
      
 869 
     | 
    
         
            +
                # This covers various different error types so we need to do additional
         
     | 
| 
      
 870 
     | 
    
         
            +
                # work to classify the exception definitively as a
         
     | 
| 
      
 871 
     | 
    
         
            +
                # ActiveRecord::PreparedStatementCacheExpired
         
     | 
| 
      
 872 
     | 
    
         
            +
                #
         
     | 
| 
      
 873 
     | 
    
         
            +
                # Check here for more details:
         
     | 
| 
      
 874 
     | 
    
         
            +
                # https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/cache/plancache.c#l573
         
     | 
| 
      
 875 
     | 
    
         
            +
                def is_cached_plan_failure?(e)
         
     | 
| 
      
 876 
     | 
    
         
            +
                  pgerror = e.cause
         
     | 
| 
      
 877 
     | 
    
         
            +
                  pgerror.result.result_error_field(PG::PG_DIAG_SQLSTATE) == FEATURE_NOT_SUPPORTED &&
         
     | 
| 
      
 878 
     | 
    
         
            +
                    pgerror.result.result_error_field(PG::PG_DIAG_SOURCE_FUNCTION) == "RevalidateCachedQuery"
         
     | 
| 
      
 879 
     | 
    
         
            +
                rescue
         
     | 
| 
      
 880 
     | 
    
         
            +
                  false
         
     | 
| 
      
 881 
     | 
    
         
            +
                end
         
     | 
| 
      
 882 
     | 
    
         
            +
             
     | 
| 
      
 883 
     | 
    
         
            +
                def in_transaction?
         
     | 
| 
      
 884 
     | 
    
         
            +
                  open_transactions > 0
         
     | 
| 
      
 885 
     | 
    
         
            +
                end
         
     | 
| 
      
 886 
     | 
    
         
            +
             
     | 
| 
      
 887 
     | 
    
         
            +
                # Returns the statement identifier for the client side cache
         
     | 
| 
      
 888 
     | 
    
         
            +
                # of statements
         
     | 
| 
       740 
889 
     | 
    
         
             
                def sql_key(sql)
         
     | 
| 
       741 
890 
     | 
    
         
             
                  "#{schema_search_path}-#{sql}"
         
     | 
| 
       742 
891 
     | 
    
         
             
                end
         
     | 
| 
       743 
     | 
    
         
            -
             
     | 
| 
       744 
892 
     | 
    
         
             
              end
         
     | 
| 
       745 
893 
     | 
    
         
             
            end
         
     | 
| 
         @@ -92,7 +92,7 @@ module ArJdbc 
     | 
|
| 
       92 
92 
     | 
    
         | 
| 
       93 
93 
     | 
    
         
             
                  def get_oid_type(oid, fmod, column_name, sql_type = '') # :nodoc:
         
     | 
| 
       94 
94 
     | 
    
         
             
                    if !type_map.key?(oid)
         
     | 
| 
       95 
     | 
    
         
            -
                      load_additional_types( 
     | 
| 
      
 95 
     | 
    
         
            +
                      load_additional_types([oid])
         
     | 
| 
       96 
96 
     | 
    
         
             
                    end
         
     | 
| 
       97 
97 
     | 
    
         | 
| 
       98 
98 
     | 
    
         
             
                    type_map.fetch(oid, fmod, sql_type) {
         
     | 
| 
         @@ -103,132 +103,168 @@ module ArJdbc 
     | 
|
| 
       103 
103 
     | 
    
         
             
                    }
         
     | 
| 
       104 
104 
     | 
    
         
             
                  end
         
     | 
| 
       105 
105 
     | 
    
         | 
| 
      
 106 
     | 
    
         
            +
                  def reload_type_map
         
     | 
| 
      
 107 
     | 
    
         
            +
                      type_map.clear
         
     | 
| 
      
 108 
     | 
    
         
            +
                      initialize_type_map
         
     | 
| 
      
 109 
     | 
    
         
            +
                  end
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
                    def initialize_type_map_inner(m)
         
     | 
| 
      
 112 
     | 
    
         
            +
                      m.register_type "int2", Type::Integer.new(limit: 2)
         
     | 
| 
      
 113 
     | 
    
         
            +
                      m.register_type "int4", Type::Integer.new(limit: 4)
         
     | 
| 
      
 114 
     | 
    
         
            +
                      m.register_type "int8", Type::Integer.new(limit: 8)
         
     | 
| 
      
 115 
     | 
    
         
            +
                      m.register_type "oid", OID::Oid.new
         
     | 
| 
      
 116 
     | 
    
         
            +
                      m.register_type "float4", Type::Float.new
         
     | 
| 
      
 117 
     | 
    
         
            +
                      m.alias_type "float8", "float4"
         
     | 
| 
      
 118 
     | 
    
         
            +
                      m.register_type "text", Type::Text.new
         
     | 
| 
      
 119 
     | 
    
         
            +
                      register_class_with_limit m, "varchar", Type::String
         
     | 
| 
      
 120 
     | 
    
         
            +
                      m.alias_type "char", "varchar"
         
     | 
| 
      
 121 
     | 
    
         
            +
                      m.alias_type "name", "varchar"
         
     | 
| 
      
 122 
     | 
    
         
            +
                      m.alias_type "bpchar", "varchar"
         
     | 
| 
      
 123 
     | 
    
         
            +
                      m.register_type "bool", Type::Boolean.new
         
     | 
| 
      
 124 
     | 
    
         
            +
                      register_class_with_limit m, "bit", OID::Bit
         
     | 
| 
      
 125 
     | 
    
         
            +
                      register_class_with_limit m, "varbit", OID::BitVarying
         
     | 
| 
      
 126 
     | 
    
         
            +
                      m.register_type "date", OID::Date.new
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
                      m.register_type "money", OID::Money.new
         
     | 
| 
      
 129 
     | 
    
         
            +
                      m.register_type "bytea", OID::Bytea.new
         
     | 
| 
      
 130 
     | 
    
         
            +
                      m.register_type "point", OID::Point.new
         
     | 
| 
      
 131 
     | 
    
         
            +
                      m.register_type "hstore", OID::Hstore.new
         
     | 
| 
      
 132 
     | 
    
         
            +
                      m.register_type "json", Type::Json.new
         
     | 
| 
      
 133 
     | 
    
         
            +
                      m.register_type "jsonb", OID::Jsonb.new
         
     | 
| 
      
 134 
     | 
    
         
            +
                      m.register_type "cidr", OID::Cidr.new
         
     | 
| 
      
 135 
     | 
    
         
            +
                      m.register_type "inet", OID::Inet.new
         
     | 
| 
      
 136 
     | 
    
         
            +
                      m.register_type "uuid", OID::Uuid.new
         
     | 
| 
      
 137 
     | 
    
         
            +
                      m.register_type "xml", OID::Xml.new
         
     | 
| 
      
 138 
     | 
    
         
            +
                      m.register_type "tsvector", OID::SpecializedString.new(:tsvector)
         
     | 
| 
      
 139 
     | 
    
         
            +
                      m.register_type "macaddr", OID::Macaddr.new
         
     | 
| 
      
 140 
     | 
    
         
            +
                      m.register_type "citext", OID::SpecializedString.new(:citext)
         
     | 
| 
      
 141 
     | 
    
         
            +
                      m.register_type "ltree", OID::SpecializedString.new(:ltree)
         
     | 
| 
      
 142 
     | 
    
         
            +
                      m.register_type "line", OID::SpecializedString.new(:line)
         
     | 
| 
      
 143 
     | 
    
         
            +
                      m.register_type "lseg", OID::SpecializedString.new(:lseg)
         
     | 
| 
      
 144 
     | 
    
         
            +
                      m.register_type "box", OID::SpecializedString.new(:box)
         
     | 
| 
      
 145 
     | 
    
         
            +
                      m.register_type "path", OID::SpecializedString.new(:path)
         
     | 
| 
      
 146 
     | 
    
         
            +
                      m.register_type "polygon", OID::SpecializedString.new(:polygon)
         
     | 
| 
      
 147 
     | 
    
         
            +
                      m.register_type "circle", OID::SpecializedString.new(:circle)
         
     | 
| 
      
 148 
     | 
    
         
            +
                      m.register_type "regproc", OID::Enum.new
         
     | 
| 
      
 149 
     | 
    
         
            +
                      # FIXME: adding this vector type leads to quoting not handlign Array data in quoting.
         
     | 
| 
      
 150 
     | 
    
         
            +
                      #m.register_type "_int4", OID::Vector.new(",", m.lookup("int4"))
         
     | 
| 
      
 151 
     | 
    
         
            +
                      register_class_with_precision m, "time", Type::Time
         
     | 
| 
      
 152 
     | 
    
         
            +
                      register_class_with_precision m, "timestamp", OID::Timestamp
         
     | 
| 
      
 153 
     | 
    
         
            +
                      register_class_with_precision m, "timestamptz", OID::TimestampWithTimeZone
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
                      m.register_type "numeric" do |_, fmod, sql_type|
         
     | 
| 
      
 156 
     | 
    
         
            +
                        precision = extract_precision(sql_type)
         
     | 
| 
      
 157 
     | 
    
         
            +
                        scale = extract_scale(sql_type)
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
                        # The type for the numeric depends on the width of the field,
         
     | 
| 
      
 160 
     | 
    
         
            +
                        # so we'll do something special here.
         
     | 
| 
      
 161 
     | 
    
         
            +
                        #
         
     | 
| 
      
 162 
     | 
    
         
            +
                        # When dealing with decimal columns:
         
     | 
| 
      
 163 
     | 
    
         
            +
                        #
         
     | 
| 
      
 164 
     | 
    
         
            +
                        # places after decimal  = fmod - 4 & 0xffff
         
     | 
| 
      
 165 
     | 
    
         
            +
                        # places before decimal = (fmod - 4) >> 16 & 0xffff
         
     | 
| 
      
 166 
     | 
    
         
            +
                        if fmod && (fmod - 4 & 0xffff).zero?
         
     | 
| 
      
 167 
     | 
    
         
            +
                          # FIXME: Remove this class, and the second argument to
         
     | 
| 
      
 168 
     | 
    
         
            +
                          # lookups on PG
         
     | 
| 
      
 169 
     | 
    
         
            +
                          Type::DecimalWithoutScale.new(precision: precision)
         
     | 
| 
      
 170 
     | 
    
         
            +
                        else
         
     | 
| 
      
 171 
     | 
    
         
            +
                          OID::Decimal.new(precision: precision, scale: scale)
         
     | 
| 
      
 172 
     | 
    
         
            +
                        end
         
     | 
| 
      
 173 
     | 
    
         
            +
                      end
         
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
      
 175 
     | 
    
         
            +
                      m.register_type "interval" do |*args, sql_type|
         
     | 
| 
      
 176 
     | 
    
         
            +
                        precision = extract_precision(sql_type)
         
     | 
| 
      
 177 
     | 
    
         
            +
                        OID::Interval.new(precision: precision)
         
     | 
| 
      
 178 
     | 
    
         
            +
                      end
         
     | 
| 
      
 179 
     | 
    
         
            +
             
     | 
| 
      
 180 
     | 
    
         
            +
                      # pgjdbc returns these if the column is auto-incrmenting
         
     | 
| 
      
 181 
     | 
    
         
            +
                      m.alias_type 'serial', 'int4'
         
     | 
| 
      
 182 
     | 
    
         
            +
                      m.alias_type 'bigserial', 'int8'
         
     | 
| 
      
 183 
     | 
    
         
            +
                    end
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
                  # We differ from AR here because we will initialize type_map when adapter initializes
         
     | 
| 
       106 
187 
     | 
    
         
             
                  def type_map
         
     | 
| 
       107 
188 
     | 
    
         
             
                    @type_map
         
     | 
| 
       108 
189 
     | 
    
         
             
                  end
         
     | 
| 
       109 
190 
     | 
    
         | 
| 
       110 
     | 
    
         
            -
                  def  
     | 
| 
       111 
     | 
    
         
            -
                     
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
                      initialize_type_map(@type_map)
         
     | 
| 
       114 
     | 
    
         
            -
                    end
         
     | 
| 
      
 191 
     | 
    
         
            +
                  def initialize_type_map(m = type_map)
         
     | 
| 
      
 192 
     | 
    
         
            +
                    initialize_type_map_inner(m)
         
     | 
| 
      
 193 
     | 
    
         
            +
                    load_additional_types
         
     | 
| 
       115 
194 
     | 
    
         
             
                  end
         
     | 
| 
       116 
195 
     | 
    
         | 
| 
       117 
196 
     | 
    
         
             
                  private
         
     | 
| 
       118 
197 
     | 
    
         | 
| 
       119 
     | 
    
         
            -
                  def  
     | 
| 
       120 
     | 
    
         
            -
                    register_class_with_limit 
     | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
       124 
     | 
    
         
            -
                     
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
     | 
    
         
            -
             
     | 
| 
       128 
     | 
    
         
            -
                     
     | 
| 
       129 
     | 
    
         
            -
                     
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
       134 
     | 
    
         
            -
                    m.alias_type 'timestamptz', 'timestamp'
         
     | 
| 
       135 
     | 
    
         
            -
                    m.register_type 'date', OID::Date.new
         
     | 
| 
       136 
     | 
    
         
            -
             
     | 
| 
       137 
     | 
    
         
            -
                    m.register_type 'money', OID::Money.new
         
     | 
| 
       138 
     | 
    
         
            -
                    m.register_type 'bytea', OID::Bytea.new
         
     | 
| 
       139 
     | 
    
         
            -
                    m.register_type 'point', OID::Point.new
         
     | 
| 
       140 
     | 
    
         
            -
                    m.register_type 'hstore', OID::Hstore.new
         
     | 
| 
       141 
     | 
    
         
            -
                    m.register_type 'json', Type::Json.new
         
     | 
| 
       142 
     | 
    
         
            -
                    m.register_type 'jsonb', OID::Jsonb.new
         
     | 
| 
       143 
     | 
    
         
            -
                    m.register_type 'cidr', OID::Cidr.new
         
     | 
| 
       144 
     | 
    
         
            -
                    m.register_type 'inet', OID::Inet.new
         
     | 
| 
       145 
     | 
    
         
            -
                    m.register_type 'uuid', OID::Uuid.new
         
     | 
| 
       146 
     | 
    
         
            -
                    m.register_type 'xml', OID::Xml.new
         
     | 
| 
       147 
     | 
    
         
            -
                    m.register_type 'tsvector', OID::SpecializedString.new(:tsvector)
         
     | 
| 
       148 
     | 
    
         
            -
                    m.register_type 'macaddr', OID::Macaddr.new
         
     | 
| 
       149 
     | 
    
         
            -
                    m.register_type 'citext', OID::SpecializedString.new(:citext)
         
     | 
| 
       150 
     | 
    
         
            -
                    m.register_type 'ltree', OID::SpecializedString.new(:ltree)
         
     | 
| 
       151 
     | 
    
         
            -
                    m.register_type 'line', OID::SpecializedString.new(:line)
         
     | 
| 
       152 
     | 
    
         
            -
                    m.register_type 'lseg', OID::SpecializedString.new(:lseg)
         
     | 
| 
       153 
     | 
    
         
            -
                    m.register_type 'box', OID::SpecializedString.new(:box)
         
     | 
| 
       154 
     | 
    
         
            -
                    m.register_type 'path', OID::SpecializedString.new(:path)
         
     | 
| 
       155 
     | 
    
         
            -
                    m.register_type 'polygon', OID::SpecializedString.new(:polygon)
         
     | 
| 
       156 
     | 
    
         
            -
                    m.register_type 'circle', OID::SpecializedString.new(:circle)
         
     | 
| 
       157 
     | 
    
         
            -
             
     | 
| 
       158 
     | 
    
         
            -
                    m.register_type 'interval' do |*args, sql_type|
         
     | 
| 
       159 
     | 
    
         
            -
                      precision = extract_precision(sql_type)
         
     | 
| 
       160 
     | 
    
         
            -
                      OID::Interval.new(precision: precision)
         
     | 
| 
      
 198 
     | 
    
         
            +
                  def register_class_with_limit(...)
         
     | 
| 
      
 199 
     | 
    
         
            +
                    ::ActiveRecord::ConnectionAdapters::AbstractAdapter.send(:register_class_with_limit, ...)
         
     | 
| 
      
 200 
     | 
    
         
            +
                  end
         
     | 
| 
      
 201 
     | 
    
         
            +
             
     | 
| 
      
 202 
     | 
    
         
            +
                  def register_class_with_precision(...)
         
     | 
| 
      
 203 
     | 
    
         
            +
                    ::ActiveRecord::ConnectionAdapters::AbstractAdapter.send(:register_class_with_precision, ...)
         
     | 
| 
      
 204 
     | 
    
         
            +
                  end
         
     | 
| 
      
 205 
     | 
    
         
            +
             
     | 
| 
      
 206 
     | 
    
         
            +
                  def load_additional_types(oids = nil) # :nodoc:
         
     | 
| 
      
 207 
     | 
    
         
            +
                    initializer = ArjdbcTypeMapInitializer.new(type_map)
         
     | 
| 
      
 208 
     | 
    
         
            +
                    load_types_queries(initializer, oids) do |query|
         
     | 
| 
      
 209 
     | 
    
         
            +
                      execute_and_clear(query, "SCHEMA", []) do |records|
         
     | 
| 
      
 210 
     | 
    
         
            +
                        #puts "RECORDS: #{records.to_a}"
         
     | 
| 
      
 211 
     | 
    
         
            +
                        initializer.run(records)
         
     | 
| 
      
 212 
     | 
    
         
            +
                      end
         
     | 
| 
       161 
213 
     | 
    
         
             
                    end
         
     | 
| 
      
 214 
     | 
    
         
            +
                  end
         
     | 
| 
       162 
215 
     | 
    
         | 
| 
       163 
     | 
    
         
            -
             
     | 
| 
       164 
     | 
    
         
            -
                     
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
             
     | 
| 
       167 
     | 
    
         
            -
             
     | 
| 
       168 
     | 
    
         
            -
             
     | 
| 
       169 
     | 
    
         
            -
             
     | 
| 
       170 
     | 
    
         
            -
                       
     | 
| 
       171 
     | 
    
         
            -
             
     | 
| 
       172 
     | 
    
         
            -
                      #
         
     | 
| 
       173 
     | 
    
         
            -
                      # When dealing with decimal columns:
         
     | 
| 
       174 
     | 
    
         
            -
                      #
         
     | 
| 
       175 
     | 
    
         
            -
                      # places after decimal  = fmod - 4 & 0xffff
         
     | 
| 
       176 
     | 
    
         
            -
                      # places before decimal = (fmod - 4) >> 16 & 0xffff
         
     | 
| 
       177 
     | 
    
         
            -
                      if fmod && (fmod - 4 & 0xffff).zero?
         
     | 
| 
       178 
     | 
    
         
            -
                        # FIXME: Remove this class, and the second argument to
         
     | 
| 
       179 
     | 
    
         
            -
                        # lookups on PG
         
     | 
| 
       180 
     | 
    
         
            -
                        Type::DecimalWithoutScale.new(precision: precision)
         
     | 
| 
      
 216 
     | 
    
         
            +
                  def load_types_queries(initializer, oids)
         
     | 
| 
      
 217 
     | 
    
         
            +
                    query = <<~SQL
         
     | 
| 
      
 218 
     | 
    
         
            +
                        SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype
         
     | 
| 
      
 219 
     | 
    
         
            +
                        FROM pg_type as t
         
     | 
| 
      
 220 
     | 
    
         
            +
                        LEFT JOIN pg_range as r ON oid = rngtypid
         
     | 
| 
      
 221 
     | 
    
         
            +
                    SQL
         
     | 
| 
      
 222 
     | 
    
         
            +
                    if oids
         
     | 
| 
      
 223 
     | 
    
         
            +
                      if oids.all? { |e| e.kind_of? Numeric }
         
     | 
| 
      
 224 
     | 
    
         
            +
                        yield query + "WHERE t.oid IN (%s)" % oids.join(", ")
         
     | 
| 
       181 
225 
     | 
    
         
             
                      else
         
     | 
| 
       182 
     | 
    
         
            -
                         
     | 
| 
      
 226 
     | 
    
         
            +
                        in_list = oids.map { |e| %Q{'#{e}'} }.join(", ")
         
     | 
| 
      
 227 
     | 
    
         
            +
                        #puts caller[0..40]
         
     | 
| 
      
 228 
     | 
    
         
            +
                        puts "IN_LIST = #{in_list}"
         
     | 
| 
      
 229 
     | 
    
         
            +
                        yield query + "WHERE t.typname IN (%s)" % in_list
         
     | 
| 
       183 
230 
     | 
    
         
             
                      end
         
     | 
| 
      
 231 
     | 
    
         
            +
                    else
         
     | 
| 
      
 232 
     | 
    
         
            +
                      yield query + initializer.query_conditions_for_known_type_names
         
     | 
| 
      
 233 
     | 
    
         
            +
                      yield query + initializer.query_conditions_for_known_type_types
         
     | 
| 
      
 234 
     | 
    
         
            +
                      yield query + initializer.query_conditions_for_array_types
         
     | 
| 
       184 
235 
     | 
    
         
             
                    end
         
     | 
| 
       185 
     | 
    
         
            -
             
     | 
| 
       186 
     | 
    
         
            -
                    load_additional_types(m)
         
     | 
| 
       187 
     | 
    
         
            -
             
     | 
| 
       188 
     | 
    
         
            -
                    # pgjdbc returns these if the column is auto-incrmenting
         
     | 
| 
       189 
     | 
    
         
            -
                    m.alias_type 'serial', 'int4'
         
     | 
| 
       190 
     | 
    
         
            -
                    m.alias_type 'bigserial', 'int8'
         
     | 
| 
       191 
236 
     | 
    
         
             
                  end
         
     | 
| 
       192 
237 
     | 
    
         | 
| 
       193 
     | 
    
         
            -
                  def  
     | 
| 
       194 
     | 
    
         
            -
                     
     | 
| 
      
 238 
     | 
    
         
            +
                  def update_typemap_for_default_timezone
         
     | 
| 
      
 239 
     | 
    
         
            +
                    if @default_timezone != ActiveRecord.default_timezone && @timestamp_decoder
         
     | 
| 
      
 240 
     | 
    
         
            +
                      decoder_class = ActiveRecord.default_timezone == :utc ?
         
     | 
| 
      
 241 
     | 
    
         
            +
                                        PG::TextDecoder::TimestampUtc :
         
     | 
| 
      
 242 
     | 
    
         
            +
                                        PG::TextDecoder::TimestampWithoutTimeZone
         
     | 
| 
       195 
243 
     | 
    
         | 
| 
       196 
     | 
    
         
            -
             
     | 
| 
       197 
     | 
    
         
            -
                       
     | 
| 
       198 
     | 
    
         
            -
                          SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype,
         
     | 
| 
       199 
     | 
    
         
            -
                            ns.nspname, ns.nspname = ANY(current_schemas(true)) in_ns
         
     | 
| 
       200 
     | 
    
         
            -
                          FROM pg_type as t
         
     | 
| 
       201 
     | 
    
         
            -
                          LEFT JOIN pg_range as r ON oid = rngtypid
         
     | 
| 
       202 
     | 
    
         
            -
                          JOIN pg_namespace AS ns ON t.typnamespace = ns.oid
         
     | 
| 
       203 
     | 
    
         
            -
                      SQL
         
     | 
| 
       204 
     | 
    
         
            -
                    else
         
     | 
| 
       205 
     | 
    
         
            -
                      query = <<-SQL
         
     | 
| 
       206 
     | 
    
         
            -
                          SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, t.typtype, t.typbasetype,
         
     | 
| 
       207 
     | 
    
         
            -
                            ns.nspname, ns.nspname = ANY(current_schemas(true)) in_ns
         
     | 
| 
       208 
     | 
    
         
            -
                          FROM pg_type as t
         
     | 
| 
       209 
     | 
    
         
            -
                          JOIN pg_namespace AS ns ON t.typnamespace = ns.oid
         
     | 
| 
       210 
     | 
    
         
            -
                      SQL
         
     | 
| 
       211 
     | 
    
         
            -
                    end
         
     | 
| 
      
 244 
     | 
    
         
            +
                      @timestamp_decoder = decoder_class.new(@timestamp_decoder.to_h)
         
     | 
| 
      
 245 
     | 
    
         
            +
                      @connection.type_map_for_results.add_coder(@timestamp_decoder)
         
     | 
| 
       212 
246 
     | 
    
         | 
| 
       213 
     | 
    
         
            -
             
     | 
| 
       214 
     | 
    
         
            -
                      if oid.is_a? Numeric || oid.match(/^\d+$/)
         
     | 
| 
       215 
     | 
    
         
            -
                        # numeric OID
         
     | 
| 
       216 
     | 
    
         
            -
                        query += "WHERE t.oid = %s" % oid
         
     | 
| 
      
 247 
     | 
    
         
            +
                      @default_timezone = ActiveRecord.default_timezone
         
     | 
| 
       217 
248 
     | 
    
         | 
| 
       218 
     | 
    
         
            -
                       
     | 
| 
       219 
     | 
    
         
            -
             
     | 
| 
       220 
     | 
    
         
            -
             
     | 
| 
      
 249 
     | 
    
         
            +
                      # if default timezone has changed, we need to reconfigure the connection
         
     | 
| 
      
 250 
     | 
    
         
            +
                      # (specifically, the session time zone)
         
     | 
| 
      
 251 
     | 
    
         
            +
                      configure_connection
         
     | 
| 
      
 252 
     | 
    
         
            +
                    end
         
     | 
| 
      
 253 
     | 
    
         
            +
                  end
         
     | 
| 
       221 
254 
     | 
    
         | 
| 
       222 
     | 
    
         
            -
             
     | 
| 
       223 
     | 
    
         
            -
             
     | 
| 
       224 
     | 
    
         
            -
             
     | 
| 
       225 
     | 
    
         
            -
             
     | 
| 
       226 
     | 
    
         
            -
                    else
         
     | 
| 
       227 
     | 
    
         
            -
                      query += initializer.query_conditions_for_initial_load
         
     | 
| 
      
 255 
     | 
    
         
            +
                  def extract_scale(sql_type)
         
     | 
| 
      
 256 
     | 
    
         
            +
                    case sql_type
         
     | 
| 
      
 257 
     | 
    
         
            +
                    when /\((\d+)\)/ then 0
         
     | 
| 
      
 258 
     | 
    
         
            +
                    when /\((\d+)(,(\d+))\)/ then $3.to_i
         
     | 
| 
       228 
259 
     | 
    
         
             
                    end
         
     | 
| 
      
 260 
     | 
    
         
            +
                  end
         
     | 
| 
      
 261 
     | 
    
         
            +
             
     | 
| 
      
 262 
     | 
    
         
            +
                  def extract_precision(sql_type)
         
     | 
| 
      
 263 
     | 
    
         
            +
                    $1.to_i if sql_type =~ /\((\d+)(,\d+)?\)/
         
     | 
| 
      
 264 
     | 
    
         
            +
                  end
         
     | 
| 
       229 
265 
     | 
    
         | 
| 
       230 
     | 
    
         
            -
             
     | 
| 
       231 
     | 
    
         
            -
                     
     | 
| 
      
 266 
     | 
    
         
            +
                  def extract_limit(sql_type)
         
     | 
| 
      
 267 
     | 
    
         
            +
                    $1.to_i if sql_type =~ /\((.*)\)/
         
     | 
| 
       232 
268 
     | 
    
         
             
                  end
         
     | 
| 
       233 
269 
     | 
    
         | 
| 
       234 
270 
     | 
    
         
             
                  # Support arrays/ranges for defining attributes that don't exist in the db
         
     |