activerecord-cockroachdb-adapter 7.0.2 → 7.1.0
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 +4 -4
- data/.editorconfig +7 -0
- data/.github/workflows/ci.yml +98 -0
- data/CHANGELOG.md +16 -0
- data/CONTRIBUTING.md +6 -26
- data/Gemfile +44 -44
- data/README.md +1 -1
- data/Rakefile +5 -15
- data/activerecord-cockroachdb-adapter.gemspec +3 -6
- data/bin/console +27 -7
- data/bin/console_schemas/default.rb +9 -0
- data/bin/console_schemas/schemas.rb +23 -0
- data/bin/start-cockroachdb +48 -0
- data/build/Dockerfile +1 -1
- data/build/teamcity-test.sh +2 -7
- data/lib/active_record/connection_adapters/cockroachdb/arel_tosql.rb +8 -0
- data/lib/active_record/connection_adapters/cockroachdb/column.rb +3 -11
- data/lib/active_record/connection_adapters/cockroachdb/column_methods.rb +8 -0
- data/lib/active_record/connection_adapters/cockroachdb/database_statements.rb +0 -83
- data/lib/active_record/connection_adapters/cockroachdb/database_tasks.rb +86 -2
- data/lib/active_record/connection_adapters/cockroachdb/quoting.rb +6 -0
- data/lib/active_record/connection_adapters/cockroachdb/referential_integrity.rb +14 -10
- data/lib/active_record/connection_adapters/cockroachdb/schema_statements.rb +43 -15
- data/lib/active_record/connection_adapters/cockroachdb/type.rb +7 -3
- data/lib/active_record/connection_adapters/cockroachdb_adapter.rb +88 -148
- data/lib/active_record/relation/query_methods_ext.rb +127 -0
- data/lib/activerecord-cockroachdb-adapter.rb +1 -1
- data/lib/arel/nodes/join_source_ext.rb +28 -0
- data/lib/version.rb +1 -1
- metadata +12 -5
@@ -1,5 +1,6 @@
|
|
1
1
|
require "rgeo/active_record"
|
2
2
|
|
3
|
+
require_relative "../../arel/nodes/join_source_ext"
|
3
4
|
require "active_record/connection_adapters/postgresql_adapter"
|
4
5
|
require "active_record/connection_adapters/cockroachdb/attribute_methods"
|
5
6
|
require "active_record/connection_adapters/cockroachdb/column_methods"
|
@@ -23,6 +24,8 @@ require "active_record/connection_adapters/cockroachdb/arel_tosql"
|
|
23
24
|
require_relative "../migration/cockroachdb/compatibility"
|
24
25
|
require_relative "../../version"
|
25
26
|
|
27
|
+
require_relative "../relation/query_methods_ext"
|
28
|
+
|
26
29
|
# Run to ignore spatial tables that will break schemna dumper.
|
27
30
|
# Defined in ./setup.rb
|
28
31
|
ActiveRecord::ConnectionAdapters::CockroachDB.initial_setup
|
@@ -158,7 +161,7 @@ module ActiveRecord
|
|
158
161
|
end
|
159
162
|
|
160
163
|
def supports_bulk_alter?
|
161
|
-
|
164
|
+
true
|
162
165
|
end
|
163
166
|
|
164
167
|
def supports_json?
|
@@ -179,7 +182,15 @@ module ActiveRecord
|
|
179
182
|
end
|
180
183
|
|
181
184
|
def supports_partial_index?
|
182
|
-
|
185
|
+
true
|
186
|
+
end
|
187
|
+
|
188
|
+
def supports_index_include?
|
189
|
+
false
|
190
|
+
end
|
191
|
+
|
192
|
+
def supports_exclusion_constraints?
|
193
|
+
false
|
183
194
|
end
|
184
195
|
|
185
196
|
def supports_expression_index?
|
@@ -194,7 +205,7 @@ module ActiveRecord
|
|
194
205
|
end
|
195
206
|
|
196
207
|
def supports_comments?
|
197
|
-
|
208
|
+
true
|
198
209
|
end
|
199
210
|
|
200
211
|
def supports_comments_in_create?
|
@@ -206,11 +217,11 @@ module ActiveRecord
|
|
206
217
|
end
|
207
218
|
|
208
219
|
def supports_virtual_columns?
|
209
|
-
|
220
|
+
true
|
210
221
|
end
|
211
222
|
|
212
223
|
def supports_string_to_array_coercion?
|
213
|
-
|
224
|
+
true
|
214
225
|
end
|
215
226
|
|
216
227
|
def supports_partitioned_indexes?
|
@@ -236,62 +247,30 @@ module ActiveRecord
|
|
236
247
|
alias index_name_length max_identifier_length
|
237
248
|
alias table_alias_length max_identifier_length
|
238
249
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
elsif crdb_version_string.include? "v19.1."
|
264
|
-
version_num = 1910
|
265
|
-
elsif crdb_version_string.include? "v19.2."
|
266
|
-
version_num = 1920
|
267
|
-
elsif crdb_version_string.include? "v20.1."
|
268
|
-
version_num = 2010
|
269
|
-
elsif crdb_version_string.include? "v20.2."
|
270
|
-
version_num = 2020
|
271
|
-
elsif crdb_version_string.include? "v21.1."
|
272
|
-
version_num = 2110
|
273
|
-
else
|
274
|
-
version_num = 2120
|
275
|
-
end
|
276
|
-
end
|
277
|
-
@crdb_version = version_num.to_i
|
278
|
-
|
279
|
-
# NOTE: this is normally in configure_connection, but that is run
|
280
|
-
# before crdb_version is determined. Once all supported versions
|
281
|
-
# of CockroachDB support SET intervalstyle it can safely be moved
|
282
|
-
# back.
|
283
|
-
# Set interval output format to ISO 8601 for ease of parsing by ActiveSupport::Duration.parse
|
284
|
-
if @crdb_version >= 2120
|
285
|
-
begin
|
286
|
-
execute("SET intervalstyle_enabled = true", "SCHEMA")
|
287
|
-
execute("SET intervalstyle = iso_8601", "SCHEMA")
|
288
|
-
rescue
|
289
|
-
# Ignore any error. This can happen with a cluster that has
|
290
|
-
# not yet finalized the v21.2 upgrade. v21.2 does not have
|
291
|
-
# a way to tell if the upgrade was finalized (see comment above).
|
292
|
-
end
|
293
|
-
end
|
294
|
-
end
|
250
|
+
# NOTE: This commented bit of code allows to have access to crdb version,
|
251
|
+
# which can be useful for feature detection. However, we currently don't
|
252
|
+
# need, hence we avoid the extra queries.
|
253
|
+
#
|
254
|
+
# def initialize(connection, logger, conn_params, config)
|
255
|
+
# super(connection, logger, conn_params, config)
|
256
|
+
|
257
|
+
# # crdb_version is the version of the binary running on the node. We
|
258
|
+
# # really want to use `SHOW CLUSTER SETTING version` to get the cluster
|
259
|
+
# # version, but that is only available to admins. Instead, we can use
|
260
|
+
# # crdb_internal.is_at_least_version, but that's only available in 22.1.
|
261
|
+
# crdb_version_string = query_value("SHOW crdb_version")
|
262
|
+
# if crdb_version_string.include? "v22.1"
|
263
|
+
# version_num = query_value(<<~SQL, "VERSION")
|
264
|
+
# SELECT
|
265
|
+
# CASE
|
266
|
+
# WHEN crdb_internal.is_at_least_version('22.2') THEN 2220
|
267
|
+
# WHEN crdb_internal.is_at_least_version('22.1') THEN 2210
|
268
|
+
# ELSE 2120
|
269
|
+
# END;
|
270
|
+
# SQL
|
271
|
+
# end
|
272
|
+
# @crdb_version = version_num.to_i
|
273
|
+
# end
|
295
274
|
|
296
275
|
def self.database_exists?(config)
|
297
276
|
!!ActiveRecord::Base.cockroachdb_connection(config)
|
@@ -304,12 +283,12 @@ module ActiveRecord
|
|
304
283
|
# (DO $$) that CockroachDB does not support.
|
305
284
|
#
|
306
285
|
# Given a name and an array of values, creates an enum type.
|
307
|
-
def create_enum(name, values)
|
308
|
-
sql_values = values.map { |s|
|
286
|
+
def create_enum(name, values, **options)
|
287
|
+
sql_values = values.map { |s| quote(s) }.join(", ")
|
309
288
|
query = <<~SQL
|
310
|
-
CREATE TYPE IF NOT EXISTS
|
289
|
+
CREATE TYPE IF NOT EXISTS #{quote_table_name(name)} AS ENUM (#{sql_values});
|
311
290
|
SQL
|
312
|
-
|
291
|
+
internal_exec_query(query).tap { reload_type_map }
|
313
292
|
end
|
314
293
|
|
315
294
|
class << self
|
@@ -367,56 +346,6 @@ module ActiveRecord
|
|
367
346
|
|
368
347
|
private
|
369
348
|
|
370
|
-
# Configures the encoding, verbosity, schema search path, and time zone of the connection.
|
371
|
-
# This is called by #connect and should not be called manually.
|
372
|
-
#
|
373
|
-
# NOTE(joey): This was cradled from postgresql_adapter.rb. This
|
374
|
-
# was due to needing to override configuration statements.
|
375
|
-
def configure_connection
|
376
|
-
if @config[:encoding]
|
377
|
-
@connection.set_client_encoding(@config[:encoding])
|
378
|
-
end
|
379
|
-
self.client_min_messages = @config[:min_messages] || "warning"
|
380
|
-
self.schema_search_path = @config[:schema_search_path] || @config[:schema_order]
|
381
|
-
|
382
|
-
# Use standard-conforming strings so we don't have to do the E'...' dance.
|
383
|
-
set_standard_conforming_strings
|
384
|
-
|
385
|
-
variables = @config.fetch(:variables, {}).stringify_keys
|
386
|
-
|
387
|
-
# If using Active Record's time zone support configure the connection to return
|
388
|
-
# TIMESTAMP WITH ZONE types in UTC.
|
389
|
-
unless variables["timezone"]
|
390
|
-
if ActiveRecord.default_timezone == :utc
|
391
|
-
variables["timezone"] = "UTC"
|
392
|
-
elsif @local_tz
|
393
|
-
variables["timezone"] = @local_tz
|
394
|
-
end
|
395
|
-
end
|
396
|
-
|
397
|
-
# NOTE(joey): This is a workaround as CockroachDB 1.1.x
|
398
|
-
# supports SET TIME ZONE <...> and SET "time zone" = <...> but
|
399
|
-
# not SET timezone = <...>.
|
400
|
-
if variables.key?("timezone")
|
401
|
-
tz = variables.delete("timezone")
|
402
|
-
execute("SET TIME ZONE #{quote(tz)}", "SCHEMA")
|
403
|
-
end
|
404
|
-
|
405
|
-
# SET statements from :variables config hash
|
406
|
-
# https://www.postgresql.org/docs/current/static/sql-set.html
|
407
|
-
variables.map do |k, v|
|
408
|
-
if v == ":default" || v == :default
|
409
|
-
# Sets the value to the global or compile default
|
410
|
-
|
411
|
-
# NOTE(joey): I am not sure if simply commenting this out
|
412
|
-
# is technically correct.
|
413
|
-
# execute("SET #{k} = DEFAULT", "SCHEMA")
|
414
|
-
elsif !v.nil?
|
415
|
-
execute("SET SESSION #{k} = #{quote(v)}", "SCHEMA")
|
416
|
-
end
|
417
|
-
end
|
418
|
-
end
|
419
|
-
|
420
349
|
# Override extract_value_from_default because the upstream definition
|
421
350
|
# doesn't handle the variations in CockroachDB's behavior.
|
422
351
|
def extract_value_from_default(default)
|
@@ -500,7 +429,8 @@ module ActiveRecord
|
|
500
429
|
SELECT a.attname, format_type(a.atttypid, a.atttypmod),
|
501
430
|
pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
|
502
431
|
c.collname, NULL AS comment,
|
503
|
-
|
432
|
+
attidentity,
|
433
|
+
attgenerated,
|
504
434
|
NULL as is_hidden
|
505
435
|
FROM pg_attribute a
|
506
436
|
LEFT JOIN pg_attrdef d ON a.attrelid = d.adrelid AND a.attnum = d.adnum
|
@@ -515,26 +445,31 @@ module ActiveRecord
|
|
515
445
|
|
516
446
|
# Use regex comparison because if a type is an array it will
|
517
447
|
# have [] appended to the end of it.
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
448
|
+
re = /\A(?:geometry|geography|interval|numeric)/
|
449
|
+
|
450
|
+
# 0: attname
|
451
|
+
# 1: type
|
452
|
+
# 2: default
|
453
|
+
# 3: attnotnull
|
454
|
+
# 4: atttypid
|
455
|
+
# 5: atttypmod
|
456
|
+
# 6: collname
|
457
|
+
# 7: comment
|
458
|
+
# 8: attidentity
|
459
|
+
# 9: attgenerated
|
460
|
+
# 10: is_hidden
|
526
461
|
fields.map do |field|
|
527
462
|
dtype = field[1]
|
528
463
|
field[1] = crdb_fields[field[0]][2].downcase if re.match(dtype)
|
529
464
|
field[7] = crdb_fields[field[0]][1]&.gsub!(/^\'|\'?$/, '')
|
530
|
-
field[
|
465
|
+
field[10] = true if crdb_fields[field[0]][3]
|
531
466
|
field
|
532
467
|
end
|
533
468
|
fields.delete_if do |field|
|
534
469
|
# Don't include rowid column if it is hidden and the primary key
|
535
470
|
# is not defined (meaning CRDB implicitly created it).
|
536
471
|
if field[0] == CockroachDBAdapter::DEFAULT_PRIMARY_KEY
|
537
|
-
field[
|
472
|
+
field[10] && !primary_key(table_name)
|
538
473
|
else
|
539
474
|
false # Keep this entry.
|
540
475
|
end
|
@@ -547,11 +482,14 @@ module ActiveRecord
|
|
547
482
|
# precision, and scale information in the type.
|
548
483
|
# Ex. geometry -> geometry(point, 4326)
|
549
484
|
def crdb_column_definitions(table_name)
|
485
|
+
table_name = PostgreSQL::Utils.extract_schema_qualified_name(table_name)
|
486
|
+
table = table_name.identifier
|
487
|
+
with_schema = " AND c.table_schema = #{quote(table_name.schema)}" if table_name.schema
|
550
488
|
fields = \
|
551
489
|
query(<<~SQL, "SCHEMA")
|
552
490
|
SELECT c.column_name, c.column_comment, c.crdb_sql_type, c.is_hidden::BOOLEAN
|
553
|
-
|
554
|
-
WHERE c.table_name = #{quote(
|
491
|
+
FROM information_schema.columns c
|
492
|
+
WHERE c.table_name = #{quote(table)}#{with_schema}
|
555
493
|
SQL
|
556
494
|
|
557
495
|
fields.reduce({}) do |a, e|
|
@@ -592,21 +530,10 @@ module ActiveRecord
|
|
592
530
|
def load_additional_types(oids = nil)
|
593
531
|
if @config[:use_follower_reads_for_type_introspection]
|
594
532
|
initializer = OID::TypeMapInitializer.new(type_map)
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
LEFT JOIN pg_range as r ON oid = rngtypid AS OF SYSTEM TIME '-10s'
|
600
|
-
SQL
|
601
|
-
|
602
|
-
if oids
|
603
|
-
query += "WHERE t.oid IN (%s)" % oids.join(", ")
|
604
|
-
else
|
605
|
-
query += initializer.query_conditions_for_initial_load
|
606
|
-
end
|
607
|
-
|
608
|
-
execute_and_clear(query, "SCHEMA", []) do |records|
|
609
|
-
initializer.run(records)
|
533
|
+
load_types_queries_with_aost(initializer, oids) do |query|
|
534
|
+
execute_and_clear(query, "SCHEMA", [], allow_retry: true, materialize_transactions: false) do |records|
|
535
|
+
initializer.run(records)
|
536
|
+
end
|
610
537
|
end
|
611
538
|
else
|
612
539
|
super
|
@@ -617,6 +544,21 @@ module ActiveRecord
|
|
617
544
|
super
|
618
545
|
end
|
619
546
|
|
547
|
+
def load_types_queries_with_aost(initializer, oids)
|
548
|
+
query = <<~SQL
|
549
|
+
SELECT t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype
|
550
|
+
FROM pg_type as t
|
551
|
+
LEFT JOIN pg_range as r ON oid = rngtypid AS OF SYSTEM TIME '-10s'
|
552
|
+
SQL
|
553
|
+
if oids
|
554
|
+
yield query + "WHERE t.oid IN (%s)" % oids.join(", ")
|
555
|
+
else
|
556
|
+
yield query + initializer.query_conditions_for_known_type_names
|
557
|
+
yield query + initializer.query_conditions_for_known_type_types
|
558
|
+
yield query + initializer.query_conditions_for_array_types
|
559
|
+
end
|
560
|
+
end
|
561
|
+
|
620
562
|
# override
|
621
563
|
# This method maps data types to their proper decoder.
|
622
564
|
#
|
@@ -647,15 +589,13 @@ module ActiveRecord
|
|
647
589
|
WHERE t.typname IN (%s)
|
648
590
|
SQL
|
649
591
|
|
650
|
-
coders = execute_and_clear(query, "SCHEMA", []) do |result|
|
651
|
-
result
|
652
|
-
.map { |row| construct_coder(row, coders_by_name[row["typname"]]) }
|
653
|
-
.compact
|
592
|
+
coders = execute_and_clear(query, "SCHEMA", [], allow_retry: true, materialize_transactions: false) do |result|
|
593
|
+
result.filter_map { |row| construct_coder(row, coders_by_name[row["typname"]]) }
|
654
594
|
end
|
655
595
|
|
656
596
|
map = PG::TypeMapByOid.new
|
657
597
|
coders.each { |coder| map.add_coder(coder) }
|
658
|
-
@
|
598
|
+
@raw_connection.type_map_for_results = map
|
659
599
|
|
660
600
|
@type_map_for_results = PG::TypeMapByOid.new
|
661
601
|
@type_map_for_results.default_type_map = map
|
@@ -0,0 +1,127 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
class Relation
|
5
|
+
module QueryMethodsExt
|
6
|
+
def aost!(time) # :nodoc:
|
7
|
+
unless time.nil? || time.is_a?(Time)
|
8
|
+
raise ArgumentError, "Unsupported argument type: #{time} (#{time.class})"
|
9
|
+
end
|
10
|
+
|
11
|
+
@aost = time
|
12
|
+
self
|
13
|
+
end
|
14
|
+
|
15
|
+
# Set system time for the current query. Using
|
16
|
+
# `.aost(nil)` resets.
|
17
|
+
#
|
18
|
+
# See cockroachlabs.com/docs/stable/as-of-system-time
|
19
|
+
def aost(time)
|
20
|
+
spawn.aost!(time)
|
21
|
+
end
|
22
|
+
|
23
|
+
def from!(...) # :nodoc:
|
24
|
+
@force_index = nil
|
25
|
+
@index_hint = nil
|
26
|
+
super
|
27
|
+
end
|
28
|
+
|
29
|
+
# Set table index hint for the query to the
|
30
|
+
# given `index_name`, and `direction` (either
|
31
|
+
# `ASC` or `DESC`).
|
32
|
+
#
|
33
|
+
# Any call to `ActiveRecord::QueryMethods#from`
|
34
|
+
# will reset the index hint. Index hints are
|
35
|
+
# not set if the `from` clause is not a table
|
36
|
+
# name.
|
37
|
+
#
|
38
|
+
# @see https://www.cockroachlabs.com/docs/v22.2/table-expressions#force-index-selection
|
39
|
+
def force_index(index_name, direction: nil)
|
40
|
+
spawn.force_index!(index_name, direction: direction)
|
41
|
+
end
|
42
|
+
|
43
|
+
def force_index!(index_name, direction: nil)
|
44
|
+
return self unless from_clause_is_a_table_name?
|
45
|
+
|
46
|
+
index_name = sanitize_sql(index_name.to_s)
|
47
|
+
direction = direction.to_s.upcase
|
48
|
+
direction = %w[ASC DESC].include?(direction) ? ",#{direction}" : ""
|
49
|
+
|
50
|
+
@force_index = "FORCE_INDEX=#{index_name}#{direction}"
|
51
|
+
self.from_clause = build_from_clause_with_hints
|
52
|
+
self
|
53
|
+
end
|
54
|
+
|
55
|
+
# Set table index hint for the query with the
|
56
|
+
# given `hint`. This allows more control over
|
57
|
+
# the hint than `ActiveRecord::Relation#force_index`.
|
58
|
+
# For instance, you could set it to `NO_FULL_SCAN`.
|
59
|
+
#
|
60
|
+
# Any call to `ActiveRecord::QueryMethods#from`
|
61
|
+
# will reset the index hint. Index hints are
|
62
|
+
# not set if the `from` clause is not a table
|
63
|
+
# name.
|
64
|
+
#
|
65
|
+
# @see https://www.cockroachlabs.com/docs/v22.2/table-expressions#force-index-selection
|
66
|
+
def index_hint(hint)
|
67
|
+
spawn.index_hint!(hint)
|
68
|
+
end
|
69
|
+
|
70
|
+
def index_hint!(hint)
|
71
|
+
return self unless from_clause_is_a_table_name?
|
72
|
+
|
73
|
+
hint = sanitize_sql(hint.to_s)
|
74
|
+
@index_hint = hint.to_s
|
75
|
+
self.from_clause = build_from_clause_with_hints
|
76
|
+
self
|
77
|
+
end
|
78
|
+
|
79
|
+
# TODO: reset or no reset?
|
80
|
+
|
81
|
+
def show_create
|
82
|
+
connection.execute("show create table #{connection.quote_table_name self.table_name}").first["create_statement"]
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def build_arel(...)
|
88
|
+
arel = super
|
89
|
+
arel.aost(@aost) if @aost.present?
|
90
|
+
arel
|
91
|
+
end
|
92
|
+
|
93
|
+
def from_clause_is_a_table_name?
|
94
|
+
# if empty, we are just dealing with the current table.
|
95
|
+
return true if from_clause.empty?
|
96
|
+
# `from_clause` can be a subquery.
|
97
|
+
return false unless from_clause.value.is_a?(String)
|
98
|
+
# `from_clause` can be a list of tables or a function.
|
99
|
+
# A simple way to check is to see if the string
|
100
|
+
# contains special characters. But we have to
|
101
|
+
# not check against an existing table hint.
|
102
|
+
return !from_clause.value.gsub(/\@{.*?\}/, "").match?(/[,\(]/)
|
103
|
+
end
|
104
|
+
|
105
|
+
def build_from_clause_with_hints
|
106
|
+
table_hints = [@index_hint, @force_index].compact.join(",")
|
107
|
+
|
108
|
+
table_name =
|
109
|
+
if from_clause.empty?
|
110
|
+
quoted_table_name
|
111
|
+
else
|
112
|
+
# Remove previous table hints if any. And spaces.
|
113
|
+
from_clause.value.partition("@").first.strip
|
114
|
+
end
|
115
|
+
Relation::FromClause.new("#{table_name}@{#{table_hints}}", nil)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
QueryMethods.prepend(QueryMethodsExt)
|
120
|
+
end
|
121
|
+
# `ActiveRecord::Base` ancestors do not include `QueryMethods`.
|
122
|
+
# But the `#all` method returns a relation, which has `QueryMethods`
|
123
|
+
# as ancestor. That is how active_record is doing is as well.
|
124
|
+
#
|
125
|
+
# @see https://github.com/rails/rails/blob/914130a9f/activerecord/lib/active_record/querying.rb#L23
|
126
|
+
Querying.delegate(:force_index, :index_hint, :aost, :show_create, to: :all)
|
127
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Arel
|
2
|
+
module Nodes
|
3
|
+
module JoinSourceExt
|
4
|
+
def initialize(...)
|
5
|
+
super
|
6
|
+
@aost = nil
|
7
|
+
end
|
8
|
+
|
9
|
+
def hash
|
10
|
+
[*super, aost].hash
|
11
|
+
end
|
12
|
+
|
13
|
+
def eql?(other)
|
14
|
+
super && aost == other.aost
|
15
|
+
end
|
16
|
+
alias_method :==, :eql?
|
17
|
+
end
|
18
|
+
JoinSource.attr_accessor :aost
|
19
|
+
JoinSource.prepend JoinSourceExt
|
20
|
+
end
|
21
|
+
module SelectManagerExt
|
22
|
+
def aost(time)
|
23
|
+
@ctx.source.aost = time
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
SelectManager.prepend SelectManagerExt
|
28
|
+
end
|
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: 7.0
|
4
|
+
version: 7.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cockroach Labs
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-01-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 7.0
|
19
|
+
version: 7.1.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 7.0
|
26
|
+
version: 7.1.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: pg
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -74,6 +74,8 @@ executables: []
|
|
74
74
|
extensions: []
|
75
75
|
extra_rdoc_files: []
|
76
76
|
files:
|
77
|
+
- ".editorconfig"
|
78
|
+
- ".github/workflows/ci.yml"
|
77
79
|
- ".github/workflows/docker.yml"
|
78
80
|
- ".gitignore"
|
79
81
|
- ".gitmodules"
|
@@ -86,7 +88,10 @@ files:
|
|
86
88
|
- Rakefile
|
87
89
|
- activerecord-cockroachdb-adapter.gemspec
|
88
90
|
- bin/console
|
91
|
+
- bin/console_schemas/default.rb
|
92
|
+
- bin/console_schemas/schemas.rb
|
89
93
|
- bin/setup
|
94
|
+
- bin/start-cockroachdb
|
90
95
|
- build/Dockerfile
|
91
96
|
- build/config.teamcity.yml
|
92
97
|
- build/local-test.sh
|
@@ -114,7 +119,9 @@ files:
|
|
114
119
|
- lib/active_record/connection_adapters/cockroachdb/type.rb
|
115
120
|
- lib/active_record/connection_adapters/cockroachdb_adapter.rb
|
116
121
|
- lib/active_record/migration/cockroachdb/compatibility.rb
|
122
|
+
- lib/active_record/relation/query_methods_ext.rb
|
117
123
|
- lib/activerecord-cockroachdb-adapter.rb
|
124
|
+
- lib/arel/nodes/join_source_ext.rb
|
118
125
|
- lib/version.rb
|
119
126
|
homepage: https://github.com/cockroachdb/activerecord-cockroachdb-adapter
|
120
127
|
licenses:
|
@@ -136,7 +143,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
143
|
- !ruby/object:Gem::Version
|
137
144
|
version: '0'
|
138
145
|
requirements: []
|
139
|
-
rubygems_version: 3.4.
|
146
|
+
rubygems_version: 3.4.10
|
140
147
|
signing_key:
|
141
148
|
specification_version: 4
|
142
149
|
summary: CockroachDB adapter for ActiveRecord.
|