activerecord-jdbc-adapter 51.8-java → 52.0-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/.gitignore +1 -2
- data/.travis.yml +26 -51
- data/README.md +9 -11
- data/Rakefile +19 -74
- data/activerecord-jdbc-adapter.gemspec +2 -2
- data/lib/active_record/connection_adapters/mssql_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +1 -0
- data/lib/arjdbc/abstract/core.rb +2 -12
- data/lib/arjdbc/abstract/database_statements.rb +24 -10
- data/lib/arjdbc/abstract/statement_cache.rb +4 -4
- data/lib/arjdbc/db2/adapter.rb +52 -2
- data/lib/arjdbc/jdbc.rb +4 -0
- data/lib/arjdbc/jdbc/column.rb +11 -5
- data/lib/arjdbc/jdbc/connection_methods.rb +9 -2
- data/lib/arjdbc/jdbc/jdbc.rake +4 -0
- data/lib/arjdbc/mssql.rb +7 -0
- data/lib/arjdbc/mssql/adapter.rb +804 -0
- data/lib/arjdbc/mssql/column.rb +200 -0
- data/lib/arjdbc/mssql/connection_methods.rb +79 -0
- data/lib/arjdbc/mssql/explain_support.rb +99 -0
- data/lib/arjdbc/mssql/limit_helpers.rb +231 -0
- data/lib/arjdbc/mssql/lock_methods.rb +77 -0
- data/lib/arjdbc/mssql/types.rb +343 -0
- data/lib/arjdbc/mssql/utils.rb +82 -0
- data/lib/arjdbc/mysql/adapter.rb +22 -14
- data/lib/arjdbc/mysql/connection_methods.rb +9 -18
- data/lib/arjdbc/postgresql/adapter.rb +102 -75
- data/lib/arjdbc/postgresql/column.rb +3 -6
- data/lib/arjdbc/postgresql/connection_methods.rb +3 -12
- data/lib/arjdbc/postgresql/oid_types.rb +12 -86
- data/lib/arjdbc/sqlite3/adapter.rb +88 -92
- data/lib/arjdbc/sqlite3/connection_methods.rb +0 -1
- data/lib/arjdbc/tasks/database_tasks.rb +36 -16
- data/lib/arjdbc/tasks/databases.rake +75 -32
- data/lib/arjdbc/tasks/databases3.rake +215 -0
- data/lib/arjdbc/tasks/databases4.rake +39 -0
- data/lib/arjdbc/version.rb +1 -1
- data/rakelib/01-tomcat.rake +2 -2
- data/rakelib/02-test.rake +3 -0
- data/rakelib/compile.rake +70 -0
- data/rakelib/db.rake +7 -21
- data/rakelib/rails.rake +4 -5
- data/src/java/arjdbc/ArJdbcModule.java +15 -5
- data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +2 -2
- data/src/java/arjdbc/jdbc/ConnectionFactory.java +87 -0
- data/src/java/arjdbc/jdbc/DataSourceConnectionFactory.java +1 -0
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +29 -113
- data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +14 -310
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +2 -2
- data/src/java/arjdbc/postgresql/PgResultSetMetaDataWrapper.java +23 -0
- data/src/java/arjdbc/postgresql/PostgreSQLResult.java +13 -21
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +50 -44
- data/src/java/arjdbc/util/DateTimeUtils.java +5 -141
- data/src/java/arjdbc/util/QuotingUtils.java +7 -6
- metadata +26 -11
- data/src/java/arjdbc/jdbc/RubyConnectionFactory.java +0 -61
- data/src/java/arjdbc/postgresql/PgDateTimeUtils.java +0 -52
data/lib/arjdbc/mysql/adapter.rb
CHANGED
@@ -31,16 +31,8 @@ module ActiveRecord
|
|
31
31
|
|
32
32
|
include ArJdbc::MySQL
|
33
33
|
|
34
|
-
def initialize(connection, logger,
|
35
|
-
|
36
|
-
is_jndi = ::ActiveRecord::ConnectionAdapters::JdbcConnection.jndi_config?(config)
|
37
|
-
@version = '8.1.5' if is_jndi
|
38
|
-
|
39
|
-
super
|
40
|
-
|
41
|
-
# set to nil to have it lazy-load the real value when required
|
42
|
-
@version = nil if is_jndi
|
43
|
-
|
34
|
+
def initialize(connection, logger, config)
|
35
|
+
super(connection, logger, nil, config)
|
44
36
|
@prepared_statements = false unless config.key?(:prepared_statements)
|
45
37
|
# configure_connection taken care of at ArJdbc::Abstract::Core
|
46
38
|
end
|
@@ -65,6 +57,10 @@ module ActiveRecord
|
|
65
57
|
true
|
66
58
|
end
|
67
59
|
|
60
|
+
def supports_set_server_option?
|
61
|
+
false
|
62
|
+
end
|
63
|
+
|
68
64
|
# HELPER METHODS ===========================================
|
69
65
|
|
70
66
|
# Reloading the type map in abstract/statement_cache.rb blows up postgres
|
@@ -90,10 +86,6 @@ module ActiveRecord
|
|
90
86
|
exception.error_code if exception.is_a?(JDBCError)
|
91
87
|
end
|
92
88
|
|
93
|
-
def create_table(table_name, **options) #:nodoc:
|
94
|
-
super(table_name, options: "ENGINE=InnoDB", **options)
|
95
|
-
end
|
96
|
-
|
97
89
|
#--
|
98
90
|
# QUOTING ==================================================
|
99
91
|
#+
|
@@ -146,6 +138,22 @@ module ActiveRecord
|
|
146
138
|
::ActiveRecord::ConnectionAdapters::MySQL::Column
|
147
139
|
end
|
148
140
|
|
141
|
+
# defined in MySQL::DatabaseStatements which is not included
|
142
|
+
def default_insert_value(column)
|
143
|
+
Arel.sql("DEFAULT") unless column.auto_increment?
|
144
|
+
end
|
145
|
+
|
146
|
+
# FIXME: optimize insert_fixtures_set by using JDBC Statement.addBatch()/executeBatch()
|
147
|
+
def combine_multi_statements(total_sql)
|
148
|
+
total_sql
|
149
|
+
end
|
150
|
+
|
151
|
+
def with_multi_statements
|
152
|
+
yield
|
153
|
+
end
|
154
|
+
|
155
|
+
def discard_remaining_results
|
156
|
+
end
|
149
157
|
end
|
150
158
|
end
|
151
159
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
ArJdbc::ConnectionMethods.module_eval do
|
3
3
|
def mysql_connection(config)
|
4
|
-
config = config.deep_dup
|
5
4
|
# NOTE: this isn't "really" necessary but Rails (in tests) assumes being able to :
|
6
5
|
# ActiveRecord::Base.mysql2_connection ActiveRecord::Base.configurations['arunit'].merge(database: ...)
|
7
6
|
config = symbolize_keys_if_necessary(config)
|
@@ -11,20 +10,14 @@ ArJdbc::ConnectionMethods.module_eval do
|
|
11
10
|
|
12
11
|
return jndi_connection(config) if jndi_config?(config)
|
13
12
|
|
14
|
-
driver = config[:driver]
|
15
|
-
|
16
|
-
mariadb_driver = ! mysql_driver && driver.to_s.start_with?('org.mariadb.')
|
13
|
+
driver = config[:driver] ||=
|
14
|
+
defined?(::Jdbc::MySQL.driver_name) ? ::Jdbc::MySQL.driver_name : 'com.mysql.jdbc.Driver'
|
17
15
|
|
18
16
|
begin
|
19
17
|
require 'jdbc/mysql'
|
20
18
|
::Jdbc::MySQL.load_driver(:require) if defined?(::Jdbc::MySQL.load_driver)
|
21
19
|
rescue LoadError # assuming driver.jar is on the class-path
|
22
|
-
end if mysql_driver
|
23
|
-
|
24
|
-
if driver.nil?
|
25
|
-
config[:driver] ||=
|
26
|
-
defined?(::Jdbc::MySQL.driver_name) ? ::Jdbc::MySQL.driver_name : 'com.mysql.jdbc.Driver'
|
27
|
-
end
|
20
|
+
end if mysql_driver = driver[0, 10] == 'com.mysql.'
|
28
21
|
|
29
22
|
config[:username] = 'root' unless config.key?(:username)
|
30
23
|
# jdbc:mysql://[host][,failoverhost...][:port]/[database]
|
@@ -32,16 +25,15 @@ ArJdbc::ConnectionMethods.module_eval do
|
|
32
25
|
# - if the port is not specified, it defaults to 3306
|
33
26
|
# - alternate fail-over syntax: [host:port],[host:port]/[database]
|
34
27
|
unless config[:url]
|
35
|
-
host = config[:host]
|
36
|
-
host ||= 'localhost' if mariadb_driver
|
37
|
-
host = host.join(',') if host.respond_to?(:join)
|
28
|
+
host = config[:host]; host = host.join(',') if host.respond_to?(:join)
|
38
29
|
config[:url] = "jdbc:mysql://#{host}#{ config[:port] ? ":#{config[:port]}" : nil }/#{config[:database]}"
|
39
30
|
end
|
40
31
|
|
32
|
+
mariadb_driver = ! mysql_driver && driver.start_with?('org.mariadb.')
|
33
|
+
|
41
34
|
properties = ( config[:properties] ||= {} )
|
42
35
|
if mysql_driver
|
43
|
-
properties['zeroDateTimeBehavior'] ||=
|
44
|
-
config[:driver].to_s.start_with?('com.mysql.cj.') ? 'CONVERT_TO_NULL' : 'convertToNull'
|
36
|
+
properties['zeroDateTimeBehavior'] ||= 'convertToNull'
|
45
37
|
properties['jdbcCompliantTruncation'] ||= false
|
46
38
|
# NOTE: this is "better" than passing what users are used to set on MRI
|
47
39
|
# e.g. 'utf8mb4' will fail cause the driver will check for a Java charset
|
@@ -71,8 +63,8 @@ ArJdbc::ConnectionMethods.module_eval do
|
|
71
63
|
end
|
72
64
|
if config[:sslkey] || sslcert = config[:sslcert] # || config[:use_ssl]
|
73
65
|
properties['useSSL'] ||= true # supported by MariaDB as well
|
66
|
+
properties['requireSSL'] ||= true if mysql_driver
|
74
67
|
if mysql_driver
|
75
|
-
properties['requireSSL'] ||= true
|
76
68
|
properties['clientCertificateKeyStoreUrl'] ||= java.io.File.new(sslcert).to_url.to_s if sslcert
|
77
69
|
if sslca = config[:sslca]
|
78
70
|
properties['trustCertificateKeyStoreUrl'] ||= java.io.File.new(sslca).to_url.to_s
|
@@ -113,8 +105,7 @@ ArJdbc::ConnectionMethods.module_eval do
|
|
113
105
|
rescue LoadError # assuming driver.jar is on the class-path
|
114
106
|
end
|
115
107
|
|
116
|
-
config[:driver] ||=
|
117
|
-
defined?(::Jdbc::MariaDB.driver_name) ? ::Jdbc::MariaDB.driver_name : 'org.mariadb.jdbc.Driver'
|
108
|
+
config[:driver] ||= 'org.mariadb.jdbc.Driver'
|
118
109
|
|
119
110
|
mysql_connection(config)
|
120
111
|
end
|
@@ -8,6 +8,7 @@ require 'active_record/connection_adapters/postgresql/explain_pretty_printer'
|
|
8
8
|
require 'active_record/connection_adapters/postgresql/quoting'
|
9
9
|
require 'active_record/connection_adapters/postgresql/referential_integrity'
|
10
10
|
require 'active_record/connection_adapters/postgresql/schema_creation'
|
11
|
+
require 'active_record/connection_adapters/postgresql/schema_definitions'
|
11
12
|
require 'active_record/connection_adapters/postgresql/schema_dumper'
|
12
13
|
require 'active_record/connection_adapters/postgresql/schema_statements'
|
13
14
|
require 'active_record/connection_adapters/postgresql/type_metadata'
|
@@ -30,9 +31,6 @@ module ArJdbc
|
|
30
31
|
# @private
|
31
32
|
IndexDefinition = ::ActiveRecord::ConnectionAdapters::IndexDefinition
|
32
33
|
|
33
|
-
# @private
|
34
|
-
ForeignKeyDefinition = ::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition
|
35
|
-
|
36
34
|
# @private
|
37
35
|
Type = ::ActiveRecord::Type
|
38
36
|
|
@@ -50,35 +48,12 @@ module ArJdbc
|
|
50
48
|
ADAPTER_NAME
|
51
49
|
end
|
52
50
|
|
53
|
-
# TODO: Update this to pull info from the DatabaseMetaData object?
|
54
51
|
def postgresql_version
|
55
52
|
@postgresql_version ||=
|
56
53
|
begin
|
57
54
|
version = @connection.database_product
|
58
|
-
if
|
59
|
-
|
60
|
-
# PostgreSQL version representation does not have more than 4 digits
|
61
|
-
# From version 10 onwards, PG has changed its versioning policy to
|
62
|
-
# limit it to only 2 digits. i.e. in 10.x, 10 being the major
|
63
|
-
# version and x representing the patch release
|
64
|
-
# Refer to:
|
65
|
-
# https://www.postgresql.org/support/versioning/
|
66
|
-
# https://www.postgresql.org/docs/10/static/libpq-status.html -> PQserverVersion()
|
67
|
-
# for more info
|
68
|
-
|
69
|
-
if version.size >= 3
|
70
|
-
(version[0] * 100 + version[1]) * 100 + version[2]
|
71
|
-
elsif version.size == 2
|
72
|
-
if version[0] >= 10
|
73
|
-
version[0] * 100 * 100 + version[1]
|
74
|
-
else
|
75
|
-
(version[0] * 100 + version[1]) * 100
|
76
|
-
end
|
77
|
-
elsif version.size == 1
|
78
|
-
version[0] * 100 * 100
|
79
|
-
else
|
80
|
-
0
|
81
|
-
end
|
55
|
+
if version =~ /PostgreSQL (\d+)\.(\d+)\.(\d+)/
|
56
|
+
($1.to_i * 10000) + ($2.to_i * 100) + $3.to_i
|
82
57
|
else
|
83
58
|
0
|
84
59
|
end
|
@@ -239,8 +214,6 @@ module ArJdbc
|
|
239
214
|
|
240
215
|
def supports_ddl_transactions?; true end
|
241
216
|
|
242
|
-
def supports_advisory_locks?; true end
|
243
|
-
|
244
217
|
def supports_explain?; true end
|
245
218
|
|
246
219
|
def supports_expression_index?; true end
|
@@ -257,26 +230,18 @@ module ArJdbc
|
|
257
230
|
|
258
231
|
def supports_views?; true end
|
259
232
|
|
260
|
-
def supports_datetime_with_precision?; true end
|
261
|
-
|
262
|
-
def supports_comments?; true end
|
263
|
-
|
264
233
|
# Does PostgreSQL support standard conforming strings?
|
265
234
|
def supports_standard_conforming_strings?
|
266
235
|
standard_conforming_strings?
|
267
236
|
@standard_conforming_strings != :unsupported
|
268
237
|
end
|
269
238
|
|
270
|
-
def
|
271
|
-
postgresql_version >= 90000
|
272
|
-
end
|
273
|
-
|
274
|
-
def supports_materialized_views?
|
239
|
+
def supports_foreign_tables? # we don't really support this yet, its a reminder :)
|
275
240
|
postgresql_version >= 90300
|
276
241
|
end
|
277
242
|
|
278
|
-
def
|
279
|
-
postgresql_version >=
|
243
|
+
def supports_hex_escaped_bytea?
|
244
|
+
postgresql_version >= 90000
|
280
245
|
end
|
281
246
|
|
282
247
|
def supports_insert_with_returning?
|
@@ -374,8 +339,8 @@ module ArJdbc
|
|
374
339
|
end
|
375
340
|
|
376
341
|
def explain(arel, binds = [])
|
377
|
-
sql =
|
378
|
-
ActiveRecord::ConnectionAdapters::PostgreSQL::ExplainPrettyPrinter.new.pp(exec_query(sql, 'EXPLAIN', binds))
|
342
|
+
sql, binds = to_sql_and_binds(arel, binds)
|
343
|
+
ActiveRecord::ConnectionAdapters::PostgreSQL::ExplainPrettyPrinter.new.pp(exec_query("EXPLAIN #{sql}", 'EXPLAIN', binds))
|
379
344
|
end
|
380
345
|
|
381
346
|
# @note Only for "better" AR 4.0 compatibility.
|
@@ -412,12 +377,6 @@ module ArJdbc
|
|
412
377
|
@connection.configure_connection
|
413
378
|
end
|
414
379
|
|
415
|
-
def default_sequence_name(table_name, pk = "id") #:nodoc:
|
416
|
-
serial_sequence(table_name, pk)
|
417
|
-
rescue ActiveRecord::StatementInvalid
|
418
|
-
%Q("#{table_name}_#{pk}_seq")
|
419
|
-
end
|
420
|
-
|
421
380
|
def last_insert_id_result(sequence_name)
|
422
381
|
exec_query("SELECT currval('#{sequence_name}')", 'SQL')
|
423
382
|
end
|
@@ -435,10 +394,8 @@ module ArJdbc
|
|
435
394
|
|
436
395
|
# Set the client message level.
|
437
396
|
def client_min_messages=(level)
|
438
|
-
#
|
439
|
-
|
440
|
-
return nil if redshift? # not supported on Redshift
|
441
|
-
execute("SET client_min_messages TO '#{level}'", 'SCHEMA')
|
397
|
+
# Not supported on Redshift
|
398
|
+
redshift? ? nil : super
|
442
399
|
end
|
443
400
|
|
444
401
|
# ORDER BY clause for the passed order option.
|
@@ -528,6 +485,77 @@ module ArJdbc
|
|
528
485
|
execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
|
529
486
|
end
|
530
487
|
|
488
|
+
# Returns an array of indexes for the given table.
|
489
|
+
def indexes(table_name)
|
490
|
+
|
491
|
+
# FIXME: AR version => table = Utils.extract_schema_qualified_name(table_name.to_s)
|
492
|
+
schema, table = extract_schema_and_table(table_name.to_s)
|
493
|
+
|
494
|
+
result = query(<<-SQL, 'SCHEMA')
|
495
|
+
SELECT distinct i.relname, d.indisunique, d.indkey, pg_get_indexdef(d.indexrelid), t.oid,
|
496
|
+
pg_catalog.obj_description(i.oid, 'pg_class') AS comment
|
497
|
+
FROM pg_class t
|
498
|
+
INNER JOIN pg_index d ON t.oid = d.indrelid
|
499
|
+
INNER JOIN pg_class i ON d.indexrelid = i.oid
|
500
|
+
LEFT JOIN pg_namespace n ON n.oid = i.relnamespace
|
501
|
+
WHERE i.relkind = 'i'
|
502
|
+
AND d.indisprimary = 'f'
|
503
|
+
AND t.relname = '#{table}'
|
504
|
+
AND n.nspname = #{schema ? "'#{schema}'" : 'ANY (current_schemas(false))'}
|
505
|
+
ORDER BY i.relname
|
506
|
+
SQL
|
507
|
+
|
508
|
+
result.map do |row|
|
509
|
+
index_name = row[0]
|
510
|
+
# 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
|
511
|
+
unique = row[1].is_a?(String) ? row[1] == 't' : row[1] # JDBC gets us a boolean
|
512
|
+
indkey = row[2].is_a?(Java::OrgPostgresqlUtil::PGobject) ? row[2].value : row[2]
|
513
|
+
indkey = indkey.split(" ").map(&:to_i)
|
514
|
+
inddef = row[3]
|
515
|
+
oid = row[4]
|
516
|
+
comment = row[5]
|
517
|
+
|
518
|
+
using, expressions, where = inddef.scan(/ USING (\w+?) \((.+?)\)(?: WHERE (.+))?\z/m).flatten
|
519
|
+
|
520
|
+
orders = {}
|
521
|
+
opclasses = {}
|
522
|
+
|
523
|
+
if indkey.include?(0)
|
524
|
+
columns = expressions
|
525
|
+
else
|
526
|
+
columns = Hash[query(<<-SQL.strip_heredoc, "SCHEMA")].values_at(*indkey).compact
|
527
|
+
SELECT a.attnum, a.attname
|
528
|
+
FROM pg_attribute a
|
529
|
+
WHERE a.attrelid = #{oid}
|
530
|
+
AND a.attnum IN (#{indkey.join(",")})
|
531
|
+
SQL
|
532
|
+
|
533
|
+
# add info on sort order (only desc order is explicitly specified, asc is the default)
|
534
|
+
# and non-default opclasses
|
535
|
+
expressions.scan(/(?<column>\w+)\s?(?<opclass>\w+_ops)?\s?(?<desc>DESC)?\s?(?<nulls>NULLS (?:FIRST|LAST))?/).each do |column, opclass, desc, nulls|
|
536
|
+
opclasses[column] = opclass.to_sym if opclass
|
537
|
+
if nulls
|
538
|
+
orders[column] = [desc, nulls].compact.join(' ')
|
539
|
+
elsif desc
|
540
|
+
orders[column] = :desc
|
541
|
+
end
|
542
|
+
end
|
543
|
+
end
|
544
|
+
|
545
|
+
IndexDefinition.new(
|
546
|
+
table_name,
|
547
|
+
index_name,
|
548
|
+
unique,
|
549
|
+
columns,
|
550
|
+
orders: orders,
|
551
|
+
opclasses: opclasses,
|
552
|
+
where: where,
|
553
|
+
using: using.to_sym,
|
554
|
+
comment: comment.presence
|
555
|
+
)
|
556
|
+
end
|
557
|
+
end
|
558
|
+
|
531
559
|
# @private
|
532
560
|
def column_name_for_operation(operation, node)
|
533
561
|
case operation
|
@@ -562,8 +590,6 @@ module ArJdbc
|
|
562
590
|
end
|
563
591
|
|
564
592
|
def translate_exception(exception, message)
|
565
|
-
return super unless exception.is_a?(ActiveRecord::JDBCError)
|
566
|
-
|
567
593
|
# TODO: Can we base these on an error code of some kind?
|
568
594
|
case exception.message
|
569
595
|
when /duplicate key value violates unique constraint/
|
@@ -580,6 +606,10 @@ module ArJdbc
|
|
580
606
|
::ActiveRecord::SerializationFailure.new(message)
|
581
607
|
when /deadlock detected/
|
582
608
|
::ActiveRecord::Deadlocked.new(message)
|
609
|
+
when /lock timeout/
|
610
|
+
::ActiveRecord::LockWaitTimeout.new(message)
|
611
|
+
when /canceling statement/ # This needs to come after lock timeout because the lock timeout message also contains "canceling statement"
|
612
|
+
::ActiveRecord::QueryCanceled.new(message)
|
583
613
|
else
|
584
614
|
super
|
585
615
|
end
|
@@ -627,7 +657,6 @@ module ActiveRecord::ConnectionAdapters
|
|
627
657
|
|
628
658
|
# Try to use as much of the built in postgres logic as possible
|
629
659
|
# maybe someday we can extend the actual adapter
|
630
|
-
include ActiveRecord::ConnectionAdapters::PostgreSQL::ColumnDumper
|
631
660
|
include ActiveRecord::ConnectionAdapters::PostgreSQL::ReferentialIntegrity
|
632
661
|
include ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements
|
633
662
|
include ActiveRecord::ConnectionAdapters::PostgreSQL::Quoting
|
@@ -651,14 +680,15 @@ module ActiveRecord::ConnectionAdapters
|
|
651
680
|
# AR expects OID to be available on the adapter
|
652
681
|
OID = ActiveRecord::ConnectionAdapters::PostgreSQL::OID
|
653
682
|
|
654
|
-
def initialize(connection, logger = nil,
|
683
|
+
def initialize(connection, logger = nil, config = {})
|
655
684
|
# @local_tz is initialized as nil to avoid warnings when connect tries to use it
|
656
685
|
@local_tz = nil
|
657
686
|
@max_identifier_length = nil
|
658
687
|
|
659
|
-
super
|
688
|
+
super # configure_connection happens in super
|
660
689
|
|
661
|
-
|
690
|
+
@type_map = Type::HashLookupTypeMap.new
|
691
|
+
initialize_type_map
|
662
692
|
|
663
693
|
@use_insert_returning = @config.key?(:insert_returning) ?
|
664
694
|
self.class.type_cast_config_to_boolean(@config[:insert_returning]) : nil
|
@@ -668,26 +698,23 @@ module ActiveRecord::ConnectionAdapters
|
|
668
698
|
Arel::Visitors::PostgreSQL.new(self)
|
669
699
|
end
|
670
700
|
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
Table = ActiveRecord::ConnectionAdapters::PostgreSQL::Table
|
701
|
+
def exec_query(sql, name = nil, binds = [], prepare: false)
|
702
|
+
super
|
703
|
+
rescue ActiveRecord::StatementInvalid => e
|
704
|
+
raise unless e.cause.message.include?('cached plan must not change result type'.freeze)
|
676
705
|
|
677
|
-
|
678
|
-
|
706
|
+
if open_transactions > 0
|
707
|
+
# In a transaction, have to fail it - See AR code for details
|
708
|
+
raise ActiveRecord::PreparedStatementCacheExpired.new(e.cause.message)
|
709
|
+
else
|
710
|
+
# Not in a transaction, clear the prepared statement and try again
|
711
|
+
delete_cached_statement(sql)
|
712
|
+
retry
|
713
|
+
end
|
679
714
|
end
|
680
715
|
|
681
716
|
public :sql_for_insert
|
682
717
|
|
683
|
-
def schema_creation # :nodoc:
|
684
|
-
PostgreSQL::SchemaCreation.new self
|
685
|
-
end
|
686
|
-
|
687
|
-
def update_table_definition(table_name, base)
|
688
|
-
Table.new(table_name, base)
|
689
|
-
end
|
690
|
-
|
691
718
|
def jdbc_connection_class(spec)
|
692
719
|
::ArJdbc::PostgreSQL.jdbc_connection_class
|
693
720
|
end
|
@@ -696,7 +723,7 @@ module ActiveRecord::ConnectionAdapters
|
|
696
723
|
|
697
724
|
# Prepared statements aren't schema aware so we need to make sure we
|
698
725
|
# store different PreparedStatement objects for different schemas
|
699
|
-
def
|
726
|
+
def cached_statement_key(sql)
|
700
727
|
"#{schema_search_path}-#{sql}"
|
701
728
|
end
|
702
729
|
|
@@ -15,7 +15,7 @@ module ArJdbc
|
|
15
15
|
end
|
16
16
|
|
17
17
|
# Extracts the value from a PostgreSQL column default definition.
|
18
|
-
def extract_value_from_default(default)
|
18
|
+
def extract_value_from_default(default) # :nodoc:
|
19
19
|
case default
|
20
20
|
# Quoted types
|
21
21
|
when /\A[\(B]?'(.*)'.*::"?([\w. ]+)"?(?:\[\])?\z/m
|
@@ -41,13 +41,10 @@ module ArJdbc
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
def extract_default_function(default_value, default)
|
45
|
-
default if
|
44
|
+
def extract_default_function(default_value, default) # :nodoc:
|
45
|
+
default if ! default_value && ( %r{\w+\(.*\)|\(.*\)::\w+} === default )
|
46
46
|
end
|
47
47
|
|
48
|
-
def has_default_function?(default_value, default)
|
49
|
-
!default_value && %r{\w+\(.*\)|\(.*\)::\w+|CURRENT_DATE|CURRENT_TIMESTAMP} === default
|
50
|
-
end
|
51
48
|
end
|
52
49
|
|
53
50
|
end
|