activerecord-cockroachdb-adapter 6.1.3 → 6.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/build/Dockerfile +1 -1
- data/build/teamcity-test.sh +23 -3
- data/docker.sh +2 -5
- data/lib/active_record/connection_adapters/cockroachdb/referential_integrity.rb +1 -1
- data/lib/active_record/connection_adapters/cockroachdb/schema_statements.rb +35 -0
- data/lib/active_record/connection_adapters/cockroachdb_adapter.rb +83 -35
- data/lib/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 55fcba0c750ea29dde5f7a7efcabd35c1c81d1cbabee65ad1aeca9e16ab3e9d6
|
4
|
+
data.tar.gz: 1f3b6c480c3430c53f632d11647afc4d76b8d5a05990e3a7b7f21191f093c746
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c29d9e502572a94a2a34ddf43f9cf09aac0aca3c63b6e489844a256cbbce7728ce90280acc8153ab4114dc9721eac37f26752936d5b3418c731fee17a2c1bd98
|
7
|
+
data.tar.gz: 68943312caf4a756081d806e7e6bb29a563d396f435226f2dadf595f2068649d1877f8bd79a88f2b65df9cc57ee998b4e2f7f6a81a7589f1ef03198cd3dc3a1d
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 6.1.6 - 2022-02-25
|
4
|
+
|
5
|
+
- Fix mixed versions of CockroachDB v21.1 and v21.2 not working.
|
6
|
+
|
7
|
+
## 6.1.5 - 2022-02-08
|
8
|
+
|
9
|
+
- Support `atttypmod` being sent for DECIMAL types.
|
10
|
+
This is needed for CockroachDB v22.1.
|
11
|
+
|
12
|
+
## 6.1.4 - 2021-12-09
|
13
|
+
|
14
|
+
- Add support for CockroachDB v21.2.
|
15
|
+
|
3
16
|
## 6.1.3 - 2021-07-28
|
4
17
|
|
5
18
|
- Santitize the input to the telemetry query that is issued on startup.
|
data/build/Dockerfile
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
FROM cockroachdb/example-orms-builder:20200413-1918
|
5
5
|
|
6
6
|
# Native dependencies for libxml-ruby and sqlite3.
|
7
|
-
RUN apt-get update -y && apt-get install -y \
|
7
|
+
RUN apt-get --allow-releaseinfo-change update -y && apt-get install -y \
|
8
8
|
libxslt-dev \
|
9
9
|
libxml2-dev \
|
10
10
|
libsqlite3-dev \
|
data/build/teamcity-test.sh
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
set -euox pipefail
|
4
4
|
|
5
5
|
# Download CockroachDB
|
6
|
-
VERSION=v21.
|
6
|
+
VERSION=v21.2.5
|
7
7
|
wget -qO- https://binaries.cockroachdb.com/cockroach-$VERSION.linux-amd64.tgz | tar xvz
|
8
8
|
readonly COCKROACH=./cockroach-$VERSION.linux-amd64/cockroach
|
9
9
|
|
@@ -35,8 +35,28 @@ run_cockroach() {
|
|
35
35
|
cockroach sql --insecure -e 'CREATE DATABASE activerecord_unittest2;'
|
36
36
|
cockroach sql --insecure -e 'SET CLUSTER SETTING sql.stats.automatic_collection.enabled = false;'
|
37
37
|
cockroach sql --insecure -e 'SET CLUSTER SETTING sql.stats.histogram_collection.enabled = false;'
|
38
|
-
|
39
|
-
cockroach sql --insecure -e "
|
38
|
+
|
39
|
+
cockroach sql --insecure -e "ALTER RANGE default CONFIGURE ZONE USING num_replicas = 1, gc.ttlseconds = 30;"
|
40
|
+
cockroach sql --insecure -e "ALTER TABLE system.public.jobs CONFIGURE ZONE USING num_replicas = 1, gc.ttlseconds = 30;"
|
41
|
+
cockroach sql --insecure -e "ALTER RANGE meta CONFIGURE ZONE USING num_replicas = 1, gc.ttlseconds = 30;"
|
42
|
+
cockroach sql --insecure -e "ALTER RANGE system CONFIGURE ZONE USING num_replicas = 1, gc.ttlseconds = 30;"
|
43
|
+
cockroach sql --insecure -e "ALTER RANGE liveness CONFIGURE ZONE USING num_replicas = 1, gc.ttlseconds = 30;"
|
44
|
+
|
45
|
+
cockroach sql --insecure -e "SET CLUSTER SETTING kv.range_merge.queue_interval = '50ms'"
|
46
|
+
cockroach sql --insecure -e "SET CLUSTER SETTING kv.raft_log.disable_synchronization_unsafe = 'true'"
|
47
|
+
cockroach sql --insecure -e "SET CLUSTER SETTING jobs.registry.interval.cancel = '180s';"
|
48
|
+
cockroach sql --insecure -e "SET CLUSTER SETTING jobs.registry.interval.gc = '30s';"
|
49
|
+
cockroach sql --insecure -e "SET CLUSTER SETTING jobs.retention_time = '15s';"
|
50
|
+
cockroach sql --insecure -e "SET CLUSTER SETTING sql.stats.automatic_collection.enabled = false;"
|
51
|
+
cockroach sql --insecure -e "SET CLUSTER SETTING kv.range_split.by_load_merge_delay = '5s';"
|
52
|
+
|
53
|
+
# Enable when we test with v22.1.
|
54
|
+
# cockroach sql --insecure -e "SET CLUSTER SETTING sql.catalog.unsafe_skip_system_config_trigger.enabled = true;"
|
55
|
+
|
56
|
+
# Enable experimental features.
|
57
|
+
cockroach sql --insecure -e "SET CLUSTER SETTING sql.defaults.experimental_temporary_tables.enabled = 'true';"
|
58
|
+
cockroach sql --insecure -e "SET CLUSTER SETTING sql.defaults.datestyle.enabled = true"
|
59
|
+
cockroach sql --insecure -e "SET CLUSTER SETTING sql.defaults.intervalstyle.enabled = true;"
|
40
60
|
}
|
41
61
|
|
42
62
|
# Install ruby dependencies.
|
data/docker.sh
CHANGED
@@ -4,10 +4,7 @@
|
|
4
4
|
|
5
5
|
set -euox pipefail
|
6
6
|
|
7
|
-
DOCKER_IMAGE_TAG=activerecord_test_container
|
8
|
-
|
9
|
-
# Build the docker image to use.
|
10
|
-
docker build -t ${DOCKER_IMAGE_TAG} build/
|
7
|
+
DOCKER_IMAGE_TAG=cockroachdb/activerecord_test_container:20210914
|
11
8
|
|
12
9
|
# Absolute path to this repository.
|
13
10
|
repo_root=$(cd "$(dirname "${0}")" && pwd)
|
@@ -26,7 +23,7 @@ container_root=${repo_root}/docker_root
|
|
26
23
|
mkdir -p "${container_root}"/{etc,home,home/"${username}"/activerecord-cockroachdb-adapter,home/.gems}
|
27
24
|
echo "${username}:x:${uid_gid}::/home/${username}:/bin/bash" > "${container_root}/etc/passwd"
|
28
25
|
|
29
|
-
docker run \
|
26
|
+
exec docker run \
|
30
27
|
--volume="${container_root}/etc/passwd:/etc/passwd" \
|
31
28
|
--volume="${container_root}/home/${username}:/home/${username}" \
|
32
29
|
--volume="${repo_root}:/home/${username}/activerecord-cockroachdb-adapter" \
|
@@ -22,7 +22,7 @@ module ActiveRecord
|
|
22
22
|
|
23
23
|
foreign_keys.each do |foreign_key|
|
24
24
|
begin
|
25
|
-
add_foreign_key(foreign_key.from_table, foreign_key.to_table, foreign_key.options)
|
25
|
+
add_foreign_key(foreign_key.from_table, foreign_key.to_table, **foreign_key.options)
|
26
26
|
rescue ActiveRecord::StatementInvalid => error
|
27
27
|
if error.cause.class == PG::DuplicateObject
|
28
28
|
# This error is safe to ignore because the yielded caller
|
@@ -32,6 +32,41 @@ module ActiveRecord
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
+
# override
|
36
|
+
# Modified version of the postgresql foreign_keys method.
|
37
|
+
# Replaces t2.oid::regclass::text with t2.relname since this is
|
38
|
+
# more efficient in CockroachDB.
|
39
|
+
def foreign_keys(table_name)
|
40
|
+
scope = quoted_scope(table_name)
|
41
|
+
fk_info = exec_query(<<~SQL, "SCHEMA")
|
42
|
+
SELECT t2.relname AS to_table, a1.attname AS column, a2.attname AS primary_key, c.conname AS name, c.confupdtype AS on_update, c.confdeltype AS on_delete, c.convalidated AS valid
|
43
|
+
FROM pg_constraint c
|
44
|
+
JOIN pg_class t1 ON c.conrelid = t1.oid
|
45
|
+
JOIN pg_class t2 ON c.confrelid = t2.oid
|
46
|
+
JOIN pg_attribute a1 ON a1.attnum = c.conkey[1] AND a1.attrelid = t1.oid
|
47
|
+
JOIN pg_attribute a2 ON a2.attnum = c.confkey[1] AND a2.attrelid = t2.oid
|
48
|
+
JOIN pg_namespace t3 ON c.connamespace = t3.oid
|
49
|
+
WHERE c.contype = 'f'
|
50
|
+
AND t1.relname = #{scope[:name]}
|
51
|
+
AND t3.nspname = #{scope[:schema]}
|
52
|
+
ORDER BY c.conname
|
53
|
+
SQL
|
54
|
+
|
55
|
+
fk_info.map do |row|
|
56
|
+
options = {
|
57
|
+
column: row["column"],
|
58
|
+
name: row["name"],
|
59
|
+
primary_key: row["primary_key"]
|
60
|
+
}
|
61
|
+
|
62
|
+
options[:on_delete] = extract_foreign_key_action(row["on_delete"])
|
63
|
+
options[:on_update] = extract_foreign_key_action(row["on_update"])
|
64
|
+
options[:validate] = row["valid"]
|
65
|
+
|
66
|
+
ForeignKeyDefinition.new(table_name, row["to_table"], options)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
35
70
|
# CockroachDB uses unique_rowid() for primary keys, not sequences. It's
|
36
71
|
# possible to force a table to use sequences, but since it's not the
|
37
72
|
# default behavior we'll always return nil for default_sequence_name.
|
@@ -46,7 +46,9 @@ module ActiveRecord
|
|
46
46
|
# This rescue flow appears in new_client, but it is needed here as well
|
47
47
|
# since Cockroach will sometimes not raise until a query is made.
|
48
48
|
rescue ActiveRecord::StatementInvalid => error
|
49
|
-
|
49
|
+
no_db_err_check1 = conn_params && conn_params[:dbname] && error.cause.message.include?(conn_params[:dbname])
|
50
|
+
no_db_err_check2 = conn_params && conn_params[:dbname] && error.cause.message.include?("pg_type")
|
51
|
+
if no_db_err_check1 || no_db_err_check2
|
50
52
|
raise ActiveRecord::NoDatabaseError
|
51
53
|
else
|
52
54
|
raise ActiveRecord::ConnectionNotEstablished, error.message
|
@@ -173,12 +175,11 @@ module ActiveRecord
|
|
173
175
|
end
|
174
176
|
|
175
177
|
def supports_partial_index?
|
176
|
-
@crdb_version >=
|
178
|
+
@crdb_version >= 2020
|
177
179
|
end
|
178
180
|
|
179
181
|
def supports_expression_index?
|
180
|
-
|
181
|
-
false
|
182
|
+
@crdb_version >= 2122
|
182
183
|
end
|
183
184
|
|
184
185
|
def supports_datetime_with_precision?
|
@@ -186,7 +187,7 @@ module ActiveRecord
|
|
186
187
|
end
|
187
188
|
|
188
189
|
def supports_comments?
|
189
|
-
@crdb_version >=
|
190
|
+
@crdb_version >= 2010
|
190
191
|
end
|
191
192
|
|
192
193
|
def supports_comments_in_create?
|
@@ -198,12 +199,11 @@ module ActiveRecord
|
|
198
199
|
end
|
199
200
|
|
200
201
|
def supports_virtual_columns?
|
201
|
-
# See cockroachdb/cockroach#20882.
|
202
202
|
false
|
203
203
|
end
|
204
204
|
|
205
205
|
def supports_string_to_array_coercion?
|
206
|
-
@crdb_version >=
|
206
|
+
@crdb_version >= 2020
|
207
207
|
end
|
208
208
|
|
209
209
|
def supports_partitioned_indexes?
|
@@ -228,23 +228,37 @@ module ActiveRecord
|
|
228
228
|
def initialize(connection, logger, conn_params, config)
|
229
229
|
super(connection, logger, conn_params, config)
|
230
230
|
|
231
|
-
crdb_version_string = query_value("SHOW
|
232
|
-
if crdb_version_string.
|
231
|
+
crdb_version_string = query_value("SHOW CLUSTER SETTING version")
|
232
|
+
if crdb_version_string.start_with? "1."
|
233
233
|
version_num = 1
|
234
|
-
elsif crdb_version_string.
|
235
|
-
version_num 2
|
236
|
-
elsif crdb_version_string.
|
237
|
-
version_num =
|
238
|
-
elsif crdb_version_string.
|
239
|
-
version_num =
|
240
|
-
elsif crdb_version_string.
|
241
|
-
version_num =
|
242
|
-
elsif crdb_version_string.
|
243
|
-
version_num =
|
234
|
+
elsif crdb_version_string.start_with? "2."
|
235
|
+
version_num = 2
|
236
|
+
elsif crdb_version_string.start_with? "19.1"
|
237
|
+
version_num = 1910
|
238
|
+
elsif crdb_version_string.start_with? "19.2"
|
239
|
+
version_num = 1920
|
240
|
+
elsif crdb_version_string.start_with? "20.1"
|
241
|
+
version_num = 2010
|
242
|
+
elsif crdb_version_string.start_with? "20.2"
|
243
|
+
version_num = 2020
|
244
|
+
elsif crdb_version_string.start_with? "21.1"
|
245
|
+
version_num = 2110
|
246
|
+
elsif crdb_version_string.start_with? "21.2"
|
247
|
+
version_num = 2120
|
244
248
|
else
|
245
|
-
version_num =
|
249
|
+
version_num = 2210
|
246
250
|
end
|
247
251
|
@crdb_version = version_num
|
252
|
+
|
253
|
+
# NOTE: this is normally in configure_connection, but that is run
|
254
|
+
# before crdb_version is determined. Once all supported versions
|
255
|
+
# of CockroachDB support SET intervalstyle it can safely be moved
|
256
|
+
# back.
|
257
|
+
# Set interval output format to ISO 8601 for ease of parsing by ActiveSupport::Duration.parse
|
258
|
+
if @crdb_version >= 2120
|
259
|
+
execute("SET intervalstyle_enabled = true", "SCHEMA")
|
260
|
+
execute("SET intervalstyle = iso_8601", "SCHEMA")
|
261
|
+
end
|
248
262
|
end
|
249
263
|
|
250
264
|
def self.database_exists?(config)
|
@@ -283,9 +297,19 @@ module ActiveRecord
|
|
283
297
|
precision = extract_precision(sql_type)
|
284
298
|
scale = extract_scale(sql_type)
|
285
299
|
|
300
|
+
|
301
|
+
# The type for the numeric depends on the width of the field,
|
302
|
+
# so we'll do something special here.
|
303
|
+
#
|
304
|
+
# When dealing with decimal columns:
|
305
|
+
#
|
306
|
+
# places after decimal = fmod - 4 & 0xffff
|
307
|
+
# places before decimal = (fmod - 4) >> 16 & 0xffff
|
308
|
+
#
|
309
|
+
# For older versions of CockroachDB (<v22.1), fmod is -1 for 0 width.
|
286
310
|
# If fmod is -1, that means that precision is defined but not
|
287
311
|
# scale, or neither is defined.
|
288
|
-
if fmod && fmod == -1 && !precision.nil?
|
312
|
+
if fmod && ((fmod == -1 && !precision.nil?) || (fmod - 4 & 0xffff).zero?)
|
289
313
|
# Below comment is from ActiveRecord
|
290
314
|
# FIXME: Remove this class, and the second argument to
|
291
315
|
# lookups on PG
|
@@ -352,7 +376,8 @@ module ActiveRecord
|
|
352
376
|
super ||
|
353
377
|
extract_escaped_string_from_default(default) ||
|
354
378
|
extract_time_from_default(default) ||
|
355
|
-
extract_empty_array_from_default(default)
|
379
|
+
extract_empty_array_from_default(default) ||
|
380
|
+
extract_decimal_from_default(default)
|
356
381
|
end
|
357
382
|
|
358
383
|
# Both PostgreSQL and CockroachDB use C-style string escapes under the
|
@@ -403,6 +428,14 @@ module ActiveRecord
|
|
403
428
|
return "{}"
|
404
429
|
end
|
405
430
|
|
431
|
+
# This method exists to extract the decimal defaults (e.g. scientific notation)
|
432
|
+
# that don't get parsed correctly
|
433
|
+
def extract_decimal_from_default(default)
|
434
|
+
Float(default).to_s
|
435
|
+
rescue
|
436
|
+
nil
|
437
|
+
end
|
438
|
+
|
406
439
|
# override
|
407
440
|
# This method makes a query to gather information about columns
|
408
441
|
# in a table. It returns an array of arrays (one for each col) and
|
@@ -416,7 +449,21 @@ module ActiveRecord
|
|
416
449
|
#
|
417
450
|
# @see: https://github.com/rails/rails/blob/8695b028261bdd244e254993255c6641bdbc17a5/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L829
|
418
451
|
def column_definitions(table_name)
|
419
|
-
fields =
|
452
|
+
fields = query(<<~SQL, "SCHEMA")
|
453
|
+
SELECT a.attname, format_type(a.atttypid, a.atttypmod),
|
454
|
+
pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
|
455
|
+
c.collname, NULL AS comment,
|
456
|
+
#{supports_virtual_columns? ? 'attgenerated' : quote('')} as attgenerated
|
457
|
+
FROM pg_attribute a
|
458
|
+
LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
|
459
|
+
LEFT JOIN pg_type t ON a.atttypid = t.oid
|
460
|
+
LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
|
461
|
+
WHERE a.attrelid = #{quote(quote_table_name(table_name))}::regclass
|
462
|
+
AND a.attnum > 0 AND NOT a.attisdropped
|
463
|
+
ORDER BY a.attnum
|
464
|
+
SQL
|
465
|
+
|
466
|
+
crdb_fields = crdb_column_definitions(table_name)
|
420
467
|
|
421
468
|
# Use regex comparison because if a type is an array it will
|
422
469
|
# have [] appended to the end of it.
|
@@ -426,32 +473,33 @@ module ActiveRecord
|
|
426
473
|
/interval/,
|
427
474
|
/numeric/
|
428
475
|
]
|
476
|
+
|
429
477
|
re = Regexp.union(target_types)
|
430
478
|
fields.map do |field|
|
431
479
|
dtype = field[1]
|
432
|
-
if re.match(dtype)
|
433
|
-
|
434
|
-
|
435
|
-
field
|
436
|
-
end
|
480
|
+
field[1] = crdb_fields[field[0]][2].downcase if re.match(dtype)
|
481
|
+
field[7] = crdb_fields[field[0]][1]&.gsub!(/^\'|\'?$/, '')
|
482
|
+
field
|
437
483
|
end
|
438
484
|
end
|
439
485
|
|
486
|
+
# Fetch the column comment because it's faster this way
|
440
487
|
# Use the crdb_sql_type instead of the sql_type returned by
|
441
488
|
# column_definitions. This will include limit,
|
442
489
|
# precision, and scale information in the type.
|
443
490
|
# Ex. geometry -> geometry(point, 4326)
|
444
|
-
def
|
445
|
-
|
446
|
-
data_type = \
|
491
|
+
def crdb_column_definitions(table_name)
|
492
|
+
fields = \
|
447
493
|
query(<<~SQL, "SCHEMA")
|
448
|
-
SELECT c.crdb_sql_type
|
494
|
+
SELECT c.column_name, c.column_comment, c.crdb_sql_type
|
449
495
|
FROM information_schema.columns c
|
450
496
|
WHERE c.table_name = #{quote(table_name)}
|
451
|
-
AND c.column_name = #{quote(col_name)}
|
452
497
|
SQL
|
453
|
-
|
454
|
-
|
498
|
+
|
499
|
+
fields.reduce({}) do |a, e|
|
500
|
+
a[e[0]] = e
|
501
|
+
a
|
502
|
+
end
|
455
503
|
end
|
456
504
|
|
457
505
|
# override
|
data/lib/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-cockroachdb-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.1.
|
4
|
+
version: 6.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cockroach Labs
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -101,7 +101,7 @@ licenses:
|
|
101
101
|
- Apache-2.0
|
102
102
|
metadata:
|
103
103
|
allowed_push_host: https://rubygems.org
|
104
|
-
post_install_message:
|
104
|
+
post_install_message:
|
105
105
|
rdoc_options: []
|
106
106
|
require_paths:
|
107
107
|
- lib
|
@@ -116,8 +116,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '0'
|
118
118
|
requirements: []
|
119
|
-
rubygems_version: 3.
|
120
|
-
signing_key:
|
119
|
+
rubygems_version: 3.0.3.1
|
120
|
+
signing_key:
|
121
121
|
specification_version: 4
|
122
122
|
summary: CockroachDB adapter for ActiveRecord.
|
123
123
|
test_files: []
|