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 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: []