activerecord-jdbc-adapter 50.8-java → 51.1-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 +5 -5
- data/.gitignore +1 -2
- data/.travis.yml +26 -51
- data/Gemfile +3 -1
- data/README.md +9 -11
- data/Rakefile +15 -78
- 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 +4 -12
- data/lib/arjdbc/abstract/database_statements.rb +4 -10
- data/lib/arjdbc/abstract/statement_cache.rb +4 -4
- data/lib/arjdbc/abstract/transaction_support.rb +2 -9
- 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/error.rb +1 -1
- 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 +14 -11
- data/lib/arjdbc/mysql/connection_methods.rb +9 -18
- data/lib/arjdbc/postgresql/adapter.rb +108 -59
- data/lib/arjdbc/postgresql/column.rb +3 -6
- data/lib/arjdbc/postgresql/connection_methods.rb +3 -12
- data/lib/arjdbc/postgresql/oid_types.rb +14 -93
- data/lib/arjdbc/sqlite3/adapter.rb +171 -140
- data/lib/arjdbc/sqlite3/connection_methods.rb +1 -2
- 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 +41 -120
- data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +14 -310
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +2 -2
- data/src/java/arjdbc/postgresql/ByteaUtils.java +1 -0
- 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 +46 -41
- data/src/java/arjdbc/util/DateTimeUtils.java +5 -141
- data/src/java/arjdbc/util/QuotingUtils.java +7 -6
- data/src/java/arjdbc/util/StringHelper.java +20 -6
- metadata +25 -16
- 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
|
@@ -61,6 +53,10 @@ module ActiveRecord
|
|
61
53
|
true
|
62
54
|
end
|
63
55
|
|
56
|
+
def supports_transaction_isolation?
|
57
|
+
true
|
58
|
+
end
|
59
|
+
|
64
60
|
# HELPER METHODS ===========================================
|
65
61
|
|
66
62
|
# Reloading the type map in abstract/statement_cache.rb blows up postgres
|
@@ -92,7 +88,14 @@ module ActiveRecord
|
|
92
88
|
|
93
89
|
#--
|
94
90
|
# QUOTING ==================================================
|
95
|
-
|
91
|
+
#+
|
92
|
+
|
93
|
+
# FIXME: 5.1 crashes without this. I think this is Arel hitting a fallback path in to_sql.rb.
|
94
|
+
# So maybe an untested code path in their source. Still means we are doing something wrong to
|
95
|
+
# even hit it.
|
96
|
+
def quote(value, comment=nil)
|
97
|
+
super(value)
|
98
|
+
end
|
96
99
|
|
97
100
|
# NOTE: quote_string(string) provided by ArJdbc::MySQL (native code),
|
98
101
|
# this piece is also native (mysql2) under MRI: `@connection.escape(string)`
|
@@ -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
|
@@ -7,6 +7,7 @@ require 'active_record/connection_adapters/postgresql/column'
|
|
7
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
|
+
require 'active_record/connection_adapters/postgresql/schema_creation'
|
10
11
|
require 'active_record/connection_adapters/postgresql/schema_dumper'
|
11
12
|
require 'active_record/connection_adapters/postgresql/schema_statements'
|
12
13
|
require 'active_record/connection_adapters/postgresql/type_metadata'
|
@@ -54,30 +55,8 @@ module ArJdbc
|
|
54
55
|
@postgresql_version ||=
|
55
56
|
begin
|
56
57
|
version = @connection.database_product
|
57
|
-
if
|
58
|
-
|
59
|
-
# PostgreSQL version representation does not have more than 4 digits
|
60
|
-
# From version 10 onwards, PG has changed its versioning policy to
|
61
|
-
# limit it to only 2 digits. i.e. in 10.x, 10 being the major
|
62
|
-
# version and x representing the patch release
|
63
|
-
# Refer to:
|
64
|
-
# https://www.postgresql.org/support/versioning/
|
65
|
-
# https://www.postgresql.org/docs/10/static/libpq-status.html -> PQserverVersion()
|
66
|
-
# for more info
|
67
|
-
|
68
|
-
if version.size >= 3
|
69
|
-
(version[0] * 100 + version[1]) * 100 + version[2]
|
70
|
-
elsif version.size == 2
|
71
|
-
if version[0] >= 10
|
72
|
-
version[0] * 100 * 100 + version[1]
|
73
|
-
else
|
74
|
-
(version[0] * 100 + version[1]) * 100
|
75
|
-
end
|
76
|
-
elsif version.size == 1
|
77
|
-
version[0] * 100 * 100
|
78
|
-
else
|
79
|
-
0
|
80
|
-
end
|
58
|
+
if version =~ /PostgreSQL (\d+)\.(\d+)\.(\d+)/
|
59
|
+
($1.to_i * 10000) + ($2.to_i * 100) + $3.to_i
|
81
60
|
else
|
82
61
|
0
|
83
62
|
end
|
@@ -146,8 +125,7 @@ module ArJdbc
|
|
146
125
|
ActiveRecordError = ::ActiveRecord::ActiveRecordError
|
147
126
|
|
148
127
|
NATIVE_DATABASE_TYPES = {
|
149
|
-
|
150
|
-
primary_key: 'serial primary key',
|
128
|
+
primary_key: 'bigserial primary key',
|
151
129
|
bigint: { name: 'bigint' },
|
152
130
|
binary: { name: 'bytea' },
|
153
131
|
bit: { name: 'bit' },
|
@@ -178,10 +156,10 @@ module ArJdbc
|
|
178
156
|
money: { name: 'money' },
|
179
157
|
numeric: { name: 'numeric' },
|
180
158
|
numrange: { name: 'numrange' },
|
159
|
+
oid: { name: 'oid' },
|
181
160
|
path: { name: 'path' },
|
182
161
|
point: { name: 'point' },
|
183
162
|
polygon: { name: 'polygon' },
|
184
|
-
serial: { name: 'serial' }, # auto-inc integer, bigserial, smallserial
|
185
163
|
string: { name: 'character varying' },
|
186
164
|
text: { name: 'text' },
|
187
165
|
time: { name: 'time' },
|
@@ -239,8 +217,6 @@ module ArJdbc
|
|
239
217
|
|
240
218
|
def supports_ddl_transactions?; true end
|
241
219
|
|
242
|
-
def supports_advisory_locks?; true end
|
243
|
-
|
244
220
|
def supports_explain?; true end
|
245
221
|
|
246
222
|
def supports_expression_index?; true end
|
@@ -249,22 +225,14 @@ module ArJdbc
|
|
249
225
|
|
250
226
|
def supports_index_sort_order?; true end
|
251
227
|
|
252
|
-
def supports_migrations?; true end
|
253
|
-
|
254
228
|
def supports_partial_index?; true end
|
255
229
|
|
256
|
-
def supports_primary_key?; true end # Supports finding primary key on non-Active Record tables
|
257
|
-
|
258
230
|
def supports_savepoints?; true end
|
259
231
|
|
260
|
-
def supports_transaction_isolation
|
232
|
+
def supports_transaction_isolation?; true end
|
261
233
|
|
262
234
|
def supports_views?; true end
|
263
235
|
|
264
|
-
def supports_datetime_with_precision?; true end
|
265
|
-
|
266
|
-
def supports_comments?; true end
|
267
|
-
|
268
236
|
# Does PostgreSQL support standard conforming strings?
|
269
237
|
def supports_standard_conforming_strings?
|
270
238
|
standard_conforming_strings?
|
@@ -275,18 +243,14 @@ module ArJdbc
|
|
275
243
|
postgresql_version >= 90000
|
276
244
|
end
|
277
245
|
|
278
|
-
def supports_materialized_views?
|
279
|
-
postgresql_version >= 90300
|
280
|
-
end
|
281
|
-
|
282
|
-
def supports_json?
|
283
|
-
postgresql_version >= 90200
|
284
|
-
end
|
285
|
-
|
286
246
|
def supports_insert_with_returning?
|
287
247
|
postgresql_version >= 80200
|
288
248
|
end
|
289
249
|
|
250
|
+
def supports_pgcrypto_uuid?
|
251
|
+
postgresql_version >= 90400
|
252
|
+
end
|
253
|
+
|
290
254
|
# Range data-types weren't introduced until PostgreSQL 9.2.
|
291
255
|
def supports_ranges?
|
292
256
|
postgresql_version >= 90200
|
@@ -296,6 +260,11 @@ module ArJdbc
|
|
296
260
|
postgresql_version >= 90200
|
297
261
|
end
|
298
262
|
|
263
|
+
# From AR 5.1 postgres_adapter.rb
|
264
|
+
def default_index_type?(index) # :nodoc:
|
265
|
+
index.using == :btree || super
|
266
|
+
end
|
267
|
+
|
299
268
|
def enable_extension(name)
|
300
269
|
execute("CREATE EXTENSION IF NOT EXISTS \"#{name}\"")
|
301
270
|
end
|
@@ -347,7 +316,7 @@ module ArJdbc
|
|
347
316
|
select_value("SELECT pg_advisory_unlock(#{lock_id})")
|
348
317
|
end
|
349
318
|
|
350
|
-
# Returns the
|
319
|
+
# Returns the max identifier length supported by PostgreSQL
|
351
320
|
def max_identifier_length
|
352
321
|
@max_identifier_length ||= select_one('SHOW max_identifier_length', 'SCHEMA'.freeze)['max_identifier_length'].to_i
|
353
322
|
end
|
@@ -395,7 +364,8 @@ module ArJdbc
|
|
395
364
|
# 'DISCARD ALL' fails if we are inside a transaction
|
396
365
|
def clear_cache!
|
397
366
|
super
|
398
|
-
|
367
|
+
# Make sure all query plans are *really* gone
|
368
|
+
@connection.execute 'DEALLOCATE ALL' if active?
|
399
369
|
end
|
400
370
|
|
401
371
|
def reset!
|
@@ -406,12 +376,6 @@ module ArJdbc
|
|
406
376
|
@connection.configure_connection
|
407
377
|
end
|
408
378
|
|
409
|
-
def default_sequence_name(table_name, pk = "id") #:nodoc:
|
410
|
-
serial_sequence(table_name, pk)
|
411
|
-
rescue ActiveRecord::StatementInvalid
|
412
|
-
%Q("#{table_name}_#{pk}_seq")
|
413
|
-
end
|
414
|
-
|
415
379
|
def last_insert_id_result(sequence_name)
|
416
380
|
exec_query("SELECT currval('#{sequence_name}')", 'SQL')
|
417
381
|
end
|
@@ -511,7 +475,7 @@ module ArJdbc
|
|
511
475
|
col_description(a.attrelid, a.attnum) AS comment
|
512
476
|
FROM pg_attribute a
|
513
477
|
LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
|
514
|
-
WHERE a.attrelid =
|
478
|
+
WHERE a.attrelid = #{quote(quote_table_name(table_name))}::regclass
|
515
479
|
AND a.attnum > 0 AND NOT a.attisdropped
|
516
480
|
ORDER BY a.attnum
|
517
481
|
end_sql
|
@@ -522,6 +486,67 @@ module ArJdbc
|
|
522
486
|
execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
|
523
487
|
end
|
524
488
|
|
489
|
+
# Returns an array of indexes for the given table.
|
490
|
+
def indexes(table_name, name = nil)
|
491
|
+
if name
|
492
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
493
|
+
Passing name to #indexes is deprecated without replacement.
|
494
|
+
MSG
|
495
|
+
end
|
496
|
+
|
497
|
+
# FIXME: AR version => table = Utils.extract_schema_qualified_name(table_name.to_s)
|
498
|
+
schema, table = extract_schema_and_table(table_name.to_s)
|
499
|
+
|
500
|
+
result = query(<<-SQL, 'SCHEMA')
|
501
|
+
SELECT distinct i.relname, d.indisunique, d.indkey, pg_get_indexdef(d.indexrelid), t.oid,
|
502
|
+
pg_catalog.obj_description(i.oid, 'pg_class') AS comment,
|
503
|
+
(SELECT COUNT(*) FROM pg_opclass o
|
504
|
+
JOIN (SELECT unnest(string_to_array(d.indclass::text, ' '))::int oid) c
|
505
|
+
ON o.oid = c.oid WHERE o.opcdefault = 'f')
|
506
|
+
FROM pg_class t
|
507
|
+
INNER JOIN pg_index d ON t.oid = d.indrelid
|
508
|
+
INNER JOIN pg_class i ON d.indexrelid = i.oid
|
509
|
+
LEFT JOIN pg_namespace n ON n.oid = i.relnamespace
|
510
|
+
WHERE i.relkind = 'i'
|
511
|
+
AND d.indisprimary = 'f'
|
512
|
+
AND t.relname = '#{table}'
|
513
|
+
AND n.nspname = #{schema ? "'#{schema}'" : 'ANY (current_schemas(false))'}
|
514
|
+
ORDER BY i.relname
|
515
|
+
SQL
|
516
|
+
|
517
|
+
result.map do |row|
|
518
|
+
index_name = row[0]
|
519
|
+
# 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
|
520
|
+
unique = row[1].is_a?(String) ? row[1] == 't' : row[1] # JDBC gets us a boolean
|
521
|
+
indkey = row[2].is_a?(Java::OrgPostgresqlUtil::PGobject) ? row[2].value : row[2]
|
522
|
+
indkey = indkey.split(" ").map(&:to_i)
|
523
|
+
inddef = row[3]
|
524
|
+
oid = row[4]
|
525
|
+
comment = row[5]
|
526
|
+
opclass = row[6]
|
527
|
+
|
528
|
+
using, expressions, where = inddef.scan(/ USING (\w+?) \((.+?)\)(?: WHERE (.+))?\z/m).flatten
|
529
|
+
|
530
|
+
if indkey.include?(0) || opclass > 0
|
531
|
+
columns = expressions
|
532
|
+
else
|
533
|
+
columns = Hash[query(<<-SQL.strip_heredoc, "SCHEMA")].values_at(*indkey).compact
|
534
|
+
SELECT a.attnum, a.attname
|
535
|
+
FROM pg_attribute a
|
536
|
+
WHERE a.attrelid = #{oid}
|
537
|
+
AND a.attnum IN (#{indkey.join(",")})
|
538
|
+
SQL
|
539
|
+
|
540
|
+
# add info on sort order for columns (only desc order is explicitly specified, asc is the default)
|
541
|
+
orders = Hash[
|
542
|
+
expressions.scan(/(\w+) DESC/).flatten.map { |order_column| [order_column, :desc] }
|
543
|
+
]
|
544
|
+
end
|
545
|
+
|
546
|
+
IndexDefinition.new(table_name, index_name, unique, columns, [], orders, where, nil, using.to_sym, comment.presence)
|
547
|
+
end.compact
|
548
|
+
end
|
549
|
+
|
525
550
|
# @private
|
526
551
|
def column_name_for_operation(operation, node)
|
527
552
|
case operation
|
@@ -556,13 +581,22 @@ module ArJdbc
|
|
556
581
|
end
|
557
582
|
|
558
583
|
def translate_exception(exception, message)
|
584
|
+
# TODO: Can we base these on an error code of some kind?
|
559
585
|
case exception.message
|
560
586
|
when /duplicate key value violates unique constraint/
|
561
587
|
::ActiveRecord::RecordNotUnique.new(message)
|
588
|
+
when /violates not-null constraint/
|
589
|
+
::ActiveRecord::NotNullViolation.new(message)
|
562
590
|
when /violates foreign key constraint/
|
563
591
|
::ActiveRecord::InvalidForeignKey.new(message)
|
564
592
|
when /value too long/
|
565
593
|
::ActiveRecord::ValueTooLong.new(message)
|
594
|
+
when /out of range/
|
595
|
+
::ActiveRecord::RangeError.new(message)
|
596
|
+
when /could not serialize/
|
597
|
+
::ActiveRecord::SerializationFailure.new(message)
|
598
|
+
when /deadlock detected/
|
599
|
+
::ActiveRecord::Deadlocked.new(message)
|
566
600
|
else
|
567
601
|
super
|
568
602
|
end
|
@@ -634,11 +668,12 @@ module ActiveRecord::ConnectionAdapters
|
|
634
668
|
# AR expects OID to be available on the adapter
|
635
669
|
OID = ActiveRecord::ConnectionAdapters::PostgreSQL::OID
|
636
670
|
|
637
|
-
def initialize(connection, logger = nil,
|
671
|
+
def initialize(connection, logger = nil, config = {})
|
638
672
|
# @local_tz is initialized as nil to avoid warnings when connect tries to use it
|
639
673
|
@local_tz = nil
|
674
|
+
@max_identifier_length = nil
|
640
675
|
|
641
|
-
super
|
676
|
+
super # configure_connection happens in super
|
642
677
|
|
643
678
|
initialize_type_map(@type_map = Type::HashLookupTypeMap.new)
|
644
679
|
|
@@ -652,7 +687,6 @@ module ActiveRecord::ConnectionAdapters
|
|
652
687
|
|
653
688
|
require 'active_record/connection_adapters/postgresql/schema_definitions'
|
654
689
|
|
655
|
-
ColumnDefinition = ActiveRecord::ConnectionAdapters::PostgreSQL::ColumnDefinition
|
656
690
|
ColumnMethods = ActiveRecord::ConnectionAdapters::PostgreSQL::ColumnMethods
|
657
691
|
TableDefinition = ActiveRecord::ConnectionAdapters::PostgreSQL::TableDefinition
|
658
692
|
Table = ActiveRecord::ConnectionAdapters::PostgreSQL::Table
|
@@ -661,6 +695,21 @@ module ActiveRecord::ConnectionAdapters
|
|
661
695
|
TableDefinition.new(*args)
|
662
696
|
end
|
663
697
|
|
698
|
+
def exec_query(sql, name = nil, binds = [], prepare: false)
|
699
|
+
super
|
700
|
+
rescue ActiveRecord::StatementInvalid => e
|
701
|
+
raise unless e.cause.message.include?('cached plan must not change result type'.freeze)
|
702
|
+
|
703
|
+
if open_transactions > 0
|
704
|
+
# In a transaction, have to fail it - See AR code for details
|
705
|
+
raise ActiveRecord::PreparedStatementCacheExpired.new(e.cause.message)
|
706
|
+
else
|
707
|
+
# Not in a transaction, clear the prepared statement and try again
|
708
|
+
delete_cached_statement(sql)
|
709
|
+
retry
|
710
|
+
end
|
711
|
+
end
|
712
|
+
|
664
713
|
public :sql_for_insert
|
665
714
|
|
666
715
|
def schema_creation # :nodoc:
|
@@ -679,7 +728,7 @@ module ActiveRecord::ConnectionAdapters
|
|
679
728
|
|
680
729
|
# Prepared statements aren't schema aware so we need to make sure we
|
681
730
|
# store different PreparedStatement objects for different schemas
|
682
|
-
def
|
731
|
+
def cached_statement_key(sql)
|
683
732
|
"#{schema_search_path}-#{sql}"
|
684
733
|
end
|
685
734
|
|
@@ -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
|