activerecord-cockroachdb-adapter 6.1.0beta1 → 6.1.2

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: 5d0954fd425d90342f04c1b6559b78e398be9e523e67779476d81f925a1aa611
4
- data.tar.gz: 1f990c34784394bafa77933eb0d49965a0eac81151f2468c92a66c1bc9beb78a
3
+ metadata.gz: 2d0c9c46ba26129c6660d4c7dcc7fab97e62e6544cf97be3de59876df04b8b49
4
+ data.tar.gz: 35952dc2b491d58a1550a8466a0010ce1530465f7e5c17d3cb1863de9d17c304
5
5
  SHA512:
6
- metadata.gz: 3074426e81a83bb4ae2e50047c6db97dc75d9b8a822c3fd1153fb3403457bb56e7f36acb42802e5dd777c056dd0864db7dc26e875e7a644cb158f0a1c8001f3a
7
- data.tar.gz: 8ff7c637812c1b262452ca1ef6ad8308a3f620a47e3798c6ef7b93096fedb362ce52372f6c0b870af1b475a31cf83f670f4e6d65498c231f5759a475820568af
6
+ metadata.gz: d1d62e4dc3ef136ebb472b4439f0a500cd64e4c16a1d7f6f1f75d7426ddfd85dc871eb26889b3d617dc80816c3d47533c6d46b9dce6fbc42df8049d76f680cf8
7
+ data.tar.gz: 02b1e634681a6e2d25d88d2d78dd0c658bf4125decbce637fa5fa672e3651c099106ee79de86ffa2037ceb3f6fc13e80e8e870b6154e4dbd96f5405b3829003d
data/CHANGELOG.md ADDED
@@ -0,0 +1,32 @@
1
+ # Changelog
2
+
3
+ ## 6.1.2 - 2021-05-20
4
+
5
+ - Fix a bug where starting the driver can result in a ConnectionNotEstablished error.
6
+
7
+ ## 6.1.1 - 2021-05-14
8
+
9
+ - Fix a bug where starting the driver can result in a NoDatabaseError.
10
+
11
+ ## 6.1.0 - 2021-04-26
12
+
13
+ - Add a telemetry query on start-up. This helps the Cockroach Labs team
14
+ prioritize support for the adapter. It can be disabled by setting the
15
+ `disable_cockroachdb_telemetry` configuration option to false.
16
+
17
+ ## 6.1.0-beta.3 - 2021-04-02
18
+
19
+ - Added a configuration option named `use_follower_reads_for_type_introspection`.
20
+ If true, it improves the speed of type introspection by allowing potentially stale
21
+ type metadata to be read. Defaults to false.
22
+
23
+ ## 6.1.0-beta.2 - 2021-03-06
24
+
25
+ - Improved connection performance by refactoring an introspection
26
+ that loads types.
27
+ - Changed version numbers to semver.
28
+
29
+ ## 6.1.0beta1
30
+
31
+ - Initial support for Rails 6.1.
32
+ - Support for spatial functionality.
data/README.md CHANGED
@@ -1,16 +1,18 @@
1
1
  # ActiveRecord CockroachDB Adapter
2
2
 
3
- CockroachDB adapter for ActiveRecord 4 and 5. This is a lightweight extension of the PostgreSQL adapter that establishes compatibility with [CockroachDB](https://github.com/cockroachdb/cockroach).
3
+ CockroachDB adapter for ActiveRecord 5 and 6. This is a lightweight extension of the PostgreSQL adapter that establishes compatibility with [CockroachDB](https://github.com/cockroachdb/cockroach).
4
4
 
5
5
  ## Installation
6
6
 
7
7
  Add this line to your project's Gemfile:
8
8
 
9
9
  ```ruby
10
- gem 'activerecord-cockroachdb-adapter', '~> 5.2.0'
10
+ gem 'activerecord-cockroachdb-adapter', '~> 6.1.0'
11
11
  ```
12
12
 
13
- If you're using Rails 4.x, use the `0.1.x` versions of this gem.
13
+ If you're using Rails 5.2, use the `5.2.x` versions of this gem.
14
+
15
+ If you're using Rails 6.0, use the `6.0.x` versions of this gem.
14
16
 
15
17
  In `database.yml`, use the following adapter setting:
16
18
 
@@ -22,6 +24,13 @@ development:
22
24
  user: <username>
23
25
  ```
24
26
 
27
+ ## Configuration
28
+
29
+ In addition to the standard adapter settings, CockroachDB also supports the following:
30
+
31
+ - `use_follower_reads_for_type_introspection`: Use follower reads on queries to the `pg_type` catalog when set to `true`. This helps to speed up initialization by reading historical data, but may not find recently created user-defined types.
32
+ - `disable_cockroachdb_telemetry`: Determines if a telemetry call is made to the database when the connection pool is initialized. Setting this to `true` will prevent the call from being made.
33
+
25
34
  ## Working with Spatial Data
26
35
 
27
36
  The adapter uses [RGeo](https://github.com/rgeo/rgeo) and [RGeo-ActiveRecord](https://github.com/rgeo/rgeo-activerecord) to represent geometric and geographic data as Ruby objects and easily interface them with the adapter. The following is a brief introduction to RGeo and tips to help setup your spatial application. More documentation about RGeo can be found in the [YARD Docs](https://rubydoc.info/github/rgeo/rgeo) and [wiki](https://github.com/rgeo/rgeo/wiki).
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "activerecord-cockroachdb-adapter"
7
- spec.version = "6.1.0beta1"
7
+ spec.version = "6.1.2"
8
8
  spec.licenses = ["Apache-2.0"]
9
9
  spec.authors = ["Cockroach Labs"]
10
10
  spec.email = ["cockroach-db@googlegroups.com"]
@@ -11,6 +11,7 @@ connections:
11
11
  user: root
12
12
  requiressl: disable
13
13
  min_messages: warning
14
+ disable_cockroachdb_telemetry: true
14
15
  arunit_without_prepared_statements:
15
16
  database: activerecord_unittest
16
17
  host: localhost
@@ -19,6 +20,7 @@ connections:
19
20
  requiressl: disable
20
21
  min_messages: warning
21
22
  prepared_statements: false
23
+ disable_cockroachdb_telemetry: true
22
24
  arunit2:
23
25
  database: activerecord_unittest2
24
26
  host: localhost
@@ -26,3 +28,4 @@ connections:
26
28
  user: root
27
29
  requiressl: disable
28
30
  min_messages: warning
31
+ disable_cockroachdb_telemetry: true
@@ -0,0 +1,26 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ module CockroachDB
4
+ module OID
5
+ module TypeMapInitializer
6
+ # override
7
+ # Replaces the query with a faster version that doesn't rely on the
8
+ # use of 'array_in(cstring,oid,integer)'::regprocedure.
9
+ def query_conditions_for_initial_load
10
+ known_type_names = @store.keys.map { |n| "'#{n}'" }
11
+ known_type_types = %w('r' 'e' 'd')
12
+ <<~SQL % [known_type_names.join(", "), known_type_types.join(", ")]
13
+ WHERE
14
+ t.typname IN (%s)
15
+ OR t.typtype IN (%s)
16
+ OR (t.typarray = 0 AND t.typcategory='A')
17
+ OR t.typelem != 0
18
+ SQL
19
+ end
20
+ end
21
+
22
+ PostgreSQL::OID::TypeMapInitializer.prepend(TypeMapInitializer)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -13,6 +13,7 @@ require "active_record/connection_adapters/cockroachdb/attribute_methods"
13
13
  require "active_record/connection_adapters/cockroachdb/column"
14
14
  require "active_record/connection_adapters/cockroachdb/spatial_column_info"
15
15
  require "active_record/connection_adapters/cockroachdb/setup"
16
+ require "active_record/connection_adapters/cockroachdb/oid/type_map_initializer"
16
17
  require "active_record/connection_adapters/cockroachdb/oid/spatial"
17
18
  require "active_record/connection_adapters/cockroachdb/oid/interval"
18
19
  require "active_record/connection_adapters/cockroachdb/arel_tosql"
@@ -55,6 +56,35 @@ end
55
56
 
56
57
  module ActiveRecord
57
58
  module ConnectionAdapters
59
+ module CockroachDBConnectionPool
60
+ def initialize(pool_config)
61
+ super(pool_config)
62
+ disable_telemetry = pool_config.db_config.configuration_hash[:disable_cockroachdb_telemetry]
63
+ adapter = pool_config.db_config.configuration_hash[:adapter]
64
+ return if disable_telemetry || adapter != "cockroachdb"
65
+
66
+
67
+ begin
68
+ with_connection do |conn|
69
+ if conn.active?
70
+ begin
71
+ query = "SELECT crdb_internal.increment_feature_counter('ActiveRecord %d.%d')"
72
+ conn.execute(query % [ActiveRecord::VERSION::MAJOR, ActiveRecord::VERSION::MINOR])
73
+ rescue ActiveRecord::StatementInvalid
74
+ # The increment_feature_counter built-in is not supported on this
75
+ # CockroachDB version. Ignore.
76
+ rescue StandardError => e
77
+ conn.logger.warn "Unexpected error when incrementing feature counter: #{e}"
78
+ end
79
+ end
80
+ end
81
+ rescue StandardError
82
+ # Prevent failures on db creation and parallel testing.
83
+ end
84
+ end
85
+ end
86
+ ConnectionPool.prepend(CockroachDBConnectionPool)
87
+
58
88
  class CockroachDBAdapter < PostgreSQLAdapter
59
89
  ADAPTER_NAME = "CockroachDB".freeze
60
90
  DEFAULT_PRIMARY_KEY = "rowid"
@@ -73,7 +103,7 @@ module ActiveRecord
73
103
  st_polygon: {},
74
104
  }
75
105
 
76
- # http://postgis.17.x6.nabble.com/Default-SRID-td5001115.html
106
+ # http://postgis.17.x6.nabble.com/Default-SRID-td5001115.html
77
107
  DEFAULT_SRID = 0
78
108
 
79
109
  include CockroachDB::SchemaStatements
@@ -172,6 +202,10 @@ module ActiveRecord
172
202
  @crdb_version >= 202
173
203
  end
174
204
 
205
+ def supports_partitioned_indexes?
206
+ false
207
+ end
208
+
175
209
  # This is hardcoded to 63 (as previously was in ActiveRecord 5.0) to aid in
176
210
  # migration from PostgreSQL to CockroachDB. In practice, this limitation
177
211
  # is arbitrary since CockroachDB supports index name lengths and table alias
@@ -189,6 +223,7 @@ module ActiveRecord
189
223
 
190
224
  def initialize(connection, logger, conn_params, config)
191
225
  super(connection, logger, conn_params, config)
226
+
192
227
  crdb_version_string = query_value("SHOW crdb_version")
193
228
  if crdb_version_string.include? "v1."
194
229
  version_num = 1
@@ -242,12 +277,9 @@ module ActiveRecord
242
277
  precision = extract_precision(sql_type)
243
278
  scale = extract_scale(sql_type)
244
279
 
245
- # TODO(#178) this should never use DecimalWithoutScale since scale
246
- # is assumed to be 0 if it is not explicitly defined.
247
- #
248
280
  # If fmod is -1, that means that precision is defined but not
249
281
  # scale, or neither is defined.
250
- if fmod && fmod == -1
282
+ if fmod && fmod == -1 && !precision.nil?
251
283
  # Below comment is from ActiveRecord
252
284
  # FIXME: Remove this class, and the second argument to
253
285
  # lookups on PG
@@ -360,7 +392,7 @@ module ActiveRecord
360
392
  # In general, it is hard to parse that, but it is easy to handle the common
361
393
  # case of an empty array.
362
394
  def extract_empty_array_from_default(default)
363
- return unless supports_string_to_array_coercion?
395
+ return unless supports_string_to_array_coercion?
364
396
  return unless default =~ /\AARRAY\[\]\z/
365
397
  return "{}"
366
398
  end
@@ -439,6 +471,97 @@ module ActiveRecord
439
471
  false
440
472
  end
441
473
 
474
+ # override
475
+ # This method loads info about data types from the database to
476
+ # populate the TypeMap.
477
+ #
478
+ # Currently, querying from the pg_type catalog can be slow due to geo-partitioning
479
+ # so this modified query uses AS OF SYSTEM TIME '-10s' to read historical data.
480
+ def load_additional_types(oids = nil)
481
+ if @config[:use_follower_reads_for_type_introspection]
482
+ initializer = OID::TypeMapInitializer.new(type_map)
483
+
484
+ query = <<~SQL
485
+ SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype
486
+ FROM pg_type as t
487
+ LEFT JOIN pg_range as r ON oid = rngtypid AS OF SYSTEM TIME '-10s'
488
+ SQL
489
+
490
+ if oids
491
+ query += "WHERE t.oid IN (%s)" % oids.join(", ")
492
+ else
493
+ query += initializer.query_conditions_for_initial_load
494
+ end
495
+
496
+ execute_and_clear(query, "SCHEMA", []) do |records|
497
+ initializer.run(records)
498
+ end
499
+ else
500
+ super
501
+ end
502
+ rescue ActiveRecord::StatementInvalid => e
503
+ raise e unless e.cause.is_a? PG::InvalidCatalogName
504
+ # use original if database is younger than 10s
505
+ super
506
+ end
507
+
508
+ # override
509
+ # This method maps data types to their proper decoder.
510
+ #
511
+ # Currently, querying from the pg_type catalog can be slow due to geo-partitioning
512
+ # so this modified query uses AS OF SYSTEM TIME '-10s' to read historical data.
513
+ def add_pg_decoders
514
+ if @config[:use_follower_reads_for_type_introspection]
515
+ @default_timezone = nil
516
+ @timestamp_decoder = nil
517
+
518
+ coders_by_name = {
519
+ "int2" => PG::TextDecoder::Integer,
520
+ "int4" => PG::TextDecoder::Integer,
521
+ "int8" => PG::TextDecoder::Integer,
522
+ "oid" => PG::TextDecoder::Integer,
523
+ "float4" => PG::TextDecoder::Float,
524
+ "float8" => PG::TextDecoder::Float,
525
+ "numeric" => PG::TextDecoder::Numeric,
526
+ "bool" => PG::TextDecoder::Boolean,
527
+ "timestamp" => PG::TextDecoder::TimestampUtc,
528
+ "timestamptz" => PG::TextDecoder::TimestampWithTimeZone,
529
+ }
530
+
531
+ known_coder_types = coders_by_name.keys.map { |n| quote(n) }
532
+ query = <<~SQL % known_coder_types.join(", ")
533
+ SELECT t.oid, t.typname
534
+ FROM pg_type as t AS OF SYSTEM TIME '-10s'
535
+ WHERE t.typname IN (%s)
536
+ SQL
537
+
538
+ coders = execute_and_clear(query, "SCHEMA", []) do |result|
539
+ result
540
+ .map { |row| construct_coder(row, coders_by_name[row["typname"]]) }
541
+ .compact
542
+ end
543
+
544
+ map = PG::TypeMapByOid.new
545
+ coders.each { |coder| map.add_coder(coder) }
546
+ @connection.type_map_for_results = map
547
+
548
+ @type_map_for_results = PG::TypeMapByOid.new
549
+ @type_map_for_results.default_type_map = map
550
+ @type_map_for_results.add_coder(PG::TextDecoder::Bytea.new(oid: 17, name: "bytea"))
551
+ @type_map_for_results.add_coder(MoneyDecoder.new(oid: 790, name: "money"))
552
+
553
+ # extract timestamp decoder for use in update_typemap_for_default_timezone
554
+ @timestamp_decoder = coders.find { |coder| coder.name == "timestamp" }
555
+ update_typemap_for_default_timezone
556
+ else
557
+ super
558
+ end
559
+ rescue ActiveRecord::StatementInvalid => e
560
+ raise e unless e.cause.is_a? PG::InvalidCatalogName
561
+ # use original if database is younger than 10s
562
+ super
563
+ end
564
+
442
565
  def arel_visitor
443
566
  Arel::Visitors::CockroachDB.new(self)
444
567
  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.0beta1
4
+ version: 6.1.2
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-02-10 00:00:00.000000000 Z
11
+ date: 2021-05-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -62,6 +62,7 @@ extra_rdoc_files: []
62
62
  files:
63
63
  - ".gitignore"
64
64
  - ".gitmodules"
65
+ - CHANGELOG.md
65
66
  - CONTRIBUTING.md
66
67
  - Gemfile
67
68
  - LICENSE
@@ -83,6 +84,7 @@ files:
83
84
  - lib/active_record/connection_adapters/cockroachdb/database_tasks.rb
84
85
  - lib/active_record/connection_adapters/cockroachdb/oid/interval.rb
85
86
  - lib/active_record/connection_adapters/cockroachdb/oid/spatial.rb
87
+ - lib/active_record/connection_adapters/cockroachdb/oid/type_map_initializer.rb
86
88
  - lib/active_record/connection_adapters/cockroachdb/quoting.rb
87
89
  - lib/active_record/connection_adapters/cockroachdb/referential_integrity.rb
88
90
  - lib/active_record/connection_adapters/cockroachdb/schema_statements.rb
@@ -109,9 +111,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
109
111
  version: '0'
110
112
  required_rubygems_version: !ruby/object:Gem::Requirement
111
113
  requirements:
112
- - - ">"
114
+ - - ">="
113
115
  - !ruby/object:Gem::Version
114
- version: 1.3.1
116
+ version: '0'
115
117
  requirements: []
116
118
  rubygems_version: 3.0.3
117
119
  signing_key: