activerecord-cockroachdb-adapter 6.1.3 → 6.1.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c2f121de56f7c6e8cf67c486533873cf2f081ec2dbe32a6d395849ecd9f7f958
4
- data.tar.gz: 698808276bece741fc6ec06a69e871ca482e6e69ff3b9e5e95b278619bf4ee02
3
+ metadata.gz: ee61867492cc8b0c28f58b9090625a08914e610e6a1732924a2b4d925a01a714
4
+ data.tar.gz: d7ae4281ca3738f92e84df29243c687693cf8aed64ba006d9c44541c25ba2029
5
5
  SHA512:
6
- metadata.gz: b2e9255a98a5114f7fd644baf0c2bd3e509f78b2fd73f4c5a85748b9e7ae8a1f212721ffcdf7e04f5bcb841bf752740ed4e0d2c97756f46b65677419fab89e10
7
- data.tar.gz: b7680180bc3c35f350f92912f447a988582b54f6f90f18414f3b7a730b7b57bfa49c6bfbf2c7668e58a1974f140b02979c9d5cbbae5fa81d0871d39c123b6b39
6
+ metadata.gz: c61ca3b032274dc8cc5063e55465fdc2b418bbda7c6d8a4093405d61c5c2b49758faaf77f95a76eb0c46101e3ec0a4f9c1442744abe49bcc747a0b86de64bec9
7
+ data.tar.gz: f91ea52d72dcef0c50e87186b12f10c7118882e48e10ef667c64e59da159493ea8dd23b5bbb4256c9222d703afaf89d7554831d2ef523096151af9fdf9faaf9f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 6.1.4 - 2021-12-09
4
+
5
+ - Add support for CockroachDB v21.2.
6
+
3
7
  ## 6.1.3 - 2021-07-28
4
8
 
5
9
  - 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 \
@@ -3,7 +3,7 @@
3
3
  set -euox pipefail
4
4
 
5
5
  # Download CockroachDB
6
- VERSION=v21.1.5
6
+ VERSION=v21.2.0
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
 
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
- if conn_params && conn_params[:dbname] && error.cause.message.include?(conn_params[:dbname])
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 >= 202
178
+ @crdb_version >= 2020
177
179
  end
178
180
 
179
181
  def supports_expression_index?
180
- # See cockroachdb/cockroach#9682
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 >= 201
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 >= 202
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 = 191
237
+ version_num = 1910
238
238
  elsif crdb_version_string.include? "v19.2."
239
- version_num = 192
239
+ version_num = 1920
240
240
  elsif crdb_version_string.include? "v20.1."
241
- version_num = 201
241
+ version_num = 2010
242
242
  elsif crdb_version_string.include? "v20.2."
243
- version_num = 202
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 = 210
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 = super
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
- crdb_column_definition(field, table_name)
434
- else
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 crdb_column_definition(field, table_name)
445
- col_name = field[0]
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
- field[1] = data_type[0][0].downcase
454
- field
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecord
4
- COCKROACH_DB_ADAPTER_VERSION = "6.1.3"
4
+ COCKROACH_DB_ADAPTER_VERSION = "6.1.4"
5
5
  end
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.3
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-07-29 00:00:00.000000000 Z
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.2.15
119
+ rubygems_version: 3.1.6
120
120
  signing_key:
121
121
  specification_version: 4
122
122
  summary: CockroachDB adapter for ActiveRecord.