activerecord-cockroachdb-adapter 6.1.3 → 6.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/build/Dockerfile +1 -1
- data/build/teamcity-test.sh +1 -1
- 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 +64 -26
- data/lib/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ee61867492cc8b0c28f58b9090625a08914e610e6a1732924a2b4d925a01a714
|
4
|
+
data.tar.gz: d7ae4281ca3738f92e84df29243c687693cf8aed64ba006d9c44541c25ba2029
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c61ca3b032274dc8cc5063e55465fdc2b418bbda7c6d8a4093405d61c5c2b49758faaf77f95a76eb0c46101e3ec0a4f9c1442744abe49bcc747a0b86de64bec9
|
7
|
+
data.tar.gz: f91ea52d72dcef0c50e87186b12f10c7118882e48e10ef667c64e59da159493ea8dd23b5bbb4256c9222d703afaf89d7554831d2ef523096151af9fdf9faaf9f
|
data/CHANGELOG.md
CHANGED
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
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?
|
@@ -234,17 +234,31 @@ module ActiveRecord
|
|
234
234
|
elsif crdb_version_string.include? "v2."
|
235
235
|
version_num 2
|
236
236
|
elsif crdb_version_string.include? "v19.1."
|
237
|
-
version_num =
|
237
|
+
version_num = 1910
|
238
238
|
elsif crdb_version_string.include? "v19.2."
|
239
|
-
version_num =
|
239
|
+
version_num = 1920
|
240
240
|
elsif crdb_version_string.include? "v20.1."
|
241
|
-
version_num =
|
241
|
+
version_num = 2010
|
242
242
|
elsif crdb_version_string.include? "v20.2."
|
243
|
-
version_num =
|
243
|
+
version_num = 2020
|
244
|
+
elsif crdb_version_string.include? "v21.1."
|
245
|
+
version_num = 2110
|
246
|
+
elsif crdb_version_string.include? "v21.2.0"
|
247
|
+
version_num = 2120
|
244
248
|
else
|
245
|
-
version_num =
|
249
|
+
version_num = 2121
|
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)
|
@@ -352,7 +366,8 @@ module ActiveRecord
|
|
352
366
|
super ||
|
353
367
|
extract_escaped_string_from_default(default) ||
|
354
368
|
extract_time_from_default(default) ||
|
355
|
-
extract_empty_array_from_default(default)
|
369
|
+
extract_empty_array_from_default(default) ||
|
370
|
+
extract_decimal_from_default(default)
|
356
371
|
end
|
357
372
|
|
358
373
|
# Both PostgreSQL and CockroachDB use C-style string escapes under the
|
@@ -403,6 +418,14 @@ module ActiveRecord
|
|
403
418
|
return "{}"
|
404
419
|
end
|
405
420
|
|
421
|
+
# This method exists to extract the decimal defaults (e.g. scientific notation)
|
422
|
+
# that don't get parsed correctly
|
423
|
+
def extract_decimal_from_default(default)
|
424
|
+
Float(default).to_s
|
425
|
+
rescue
|
426
|
+
nil
|
427
|
+
end
|
428
|
+
|
406
429
|
# override
|
407
430
|
# This method makes a query to gather information about columns
|
408
431
|
# in a table. It returns an array of arrays (one for each col) and
|
@@ -416,7 +439,21 @@ module ActiveRecord
|
|
416
439
|
#
|
417
440
|
# @see: https://github.com/rails/rails/blob/8695b028261bdd244e254993255c6641bdbc17a5/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L829
|
418
441
|
def column_definitions(table_name)
|
419
|
-
fields =
|
442
|
+
fields = query(<<~SQL, "SCHEMA")
|
443
|
+
SELECT a.attname, format_type(a.atttypid, a.atttypmod),
|
444
|
+
pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
|
445
|
+
c.collname, NULL AS comment,
|
446
|
+
#{supports_virtual_columns? ? 'attgenerated' : quote('')} as attgenerated
|
447
|
+
FROM pg_attribute a
|
448
|
+
LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
|
449
|
+
LEFT JOIN pg_type t ON a.atttypid = t.oid
|
450
|
+
LEFT JOIN pg_collation c ON a.attcollation = c.oid AND a.attcollation <> t.typcollation
|
451
|
+
WHERE a.attrelid = #{quote(quote_table_name(table_name))}::regclass
|
452
|
+
AND a.attnum > 0 AND NOT a.attisdropped
|
453
|
+
ORDER BY a.attnum
|
454
|
+
SQL
|
455
|
+
|
456
|
+
crdb_fields = crdb_column_definitions(table_name)
|
420
457
|
|
421
458
|
# Use regex comparison because if a type is an array it will
|
422
459
|
# have [] appended to the end of it.
|
@@ -426,32 +463,33 @@ module ActiveRecord
|
|
426
463
|
/interval/,
|
427
464
|
/numeric/
|
428
465
|
]
|
466
|
+
|
429
467
|
re = Regexp.union(target_types)
|
430
468
|
fields.map do |field|
|
431
469
|
dtype = field[1]
|
432
|
-
if re.match(dtype)
|
433
|
-
|
434
|
-
|
435
|
-
field
|
436
|
-
end
|
470
|
+
field[1] = crdb_fields[field[0]][2].downcase if re.match(dtype)
|
471
|
+
field[7] = crdb_fields[field[0]][1]&.gsub!(/^\'|\'?$/, '')
|
472
|
+
field
|
437
473
|
end
|
438
474
|
end
|
439
475
|
|
476
|
+
# Fetch the column comment because it's faster this way
|
440
477
|
# Use the crdb_sql_type instead of the sql_type returned by
|
441
478
|
# column_definitions. This will include limit,
|
442
479
|
# precision, and scale information in the type.
|
443
480
|
# Ex. geometry -> geometry(point, 4326)
|
444
|
-
def
|
445
|
-
|
446
|
-
data_type = \
|
481
|
+
def crdb_column_definitions(table_name)
|
482
|
+
fields = \
|
447
483
|
query(<<~SQL, "SCHEMA")
|
448
|
-
SELECT c.crdb_sql_type
|
484
|
+
SELECT c.column_name, c.column_comment, c.crdb_sql_type
|
449
485
|
FROM information_schema.columns c
|
450
486
|
WHERE c.table_name = #{quote(table_name)}
|
451
|
-
AND c.column_name = #{quote(col_name)}
|
452
487
|
SQL
|
453
|
-
|
454
|
-
|
488
|
+
|
489
|
+
fields.reduce({}) do |a, e|
|
490
|
+
a[e[0]] = e
|
491
|
+
a
|
492
|
+
end
|
455
493
|
end
|
456
494
|
|
457
495
|
# 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.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cockroach Labs
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -116,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '0'
|
118
118
|
requirements: []
|
119
|
-
rubygems_version: 3.
|
119
|
+
rubygems_version: 3.1.6
|
120
120
|
signing_key:
|
121
121
|
specification_version: 4
|
122
122
|
summary: CockroachDB adapter for ActiveRecord.
|