activerecord-cockroachdb-adapter 6.1.3 → 6.1.6

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: 55fcba0c750ea29dde5f7a7efcabd35c1c81d1cbabee65ad1aeca9e16ab3e9d6
4
+ data.tar.gz: 1f3b6c480c3430c53f632d11647afc4d76b8d5a05990e3a7b7f21191f093c746
5
5
  SHA512:
6
- metadata.gz: b2e9255a98a5114f7fd644baf0c2bd3e509f78b2fd73f4c5a85748b9e7ae8a1f212721ffcdf7e04f5bcb841bf752740ed4e0d2c97756f46b65677419fab89e10
7
- data.tar.gz: b7680180bc3c35f350f92912f447a988582b54f6f90f18414f3b7a730b7b57bfa49c6bfbf2c7668e58a1974f140b02979c9d5cbbae5fa81d0871d39c123b6b39
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 \
@@ -3,7 +3,7 @@
3
3
  set -euox pipefail
4
4
 
5
5
  # Download CockroachDB
6
- VERSION=v21.1.5
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
- cockroach sql --insecure -e "SET CLUSTER SETTING jobs.retention_time = '180s';"
39
- cockroach sql --insecure -e "SET CLUSTER SETTING sql.defaults.experimental_temporary_tables.enabled = 'true'"
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
- 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?
@@ -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 crdb_version")
232
- if crdb_version_string.include? "v1."
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.include? "v2."
235
- version_num 2
236
- elsif crdb_version_string.include? "v19.1."
237
- version_num = 191
238
- elsif crdb_version_string.include? "v19.2."
239
- version_num = 192
240
- elsif crdb_version_string.include? "v20.1."
241
- version_num = 201
242
- elsif crdb_version_string.include? "v20.2."
243
- version_num = 202
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 = 210
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 = super
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
- crdb_column_definition(field, table_name)
434
- else
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 crdb_column_definition(field, table_name)
445
- col_name = field[0]
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
- field[1] = data_type[0][0].downcase
454
- field
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
@@ -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.6"
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.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: 2021-07-29 00:00:00.000000000 Z
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.2.15
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: []