activerecord-cockroachdb-adapter 7.1.0 → 7.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +22 -29
- data/.gitignore +1 -0
- data/CHANGELOG.md +11 -2
- data/CONTRIBUTING.md +35 -90
- data/Gemfile +8 -4
- data/LICENSE +1 -2
- data/README.md +7 -5
- data/activerecord-cockroachdb-adapter.gemspec +2 -2
- data/bin/console +2 -2
- data/bin/start-cockroachdb +5 -20
- data/lib/active_record/connection_adapters/cockroachdb/arel_tosql.rb +14 -0
- data/lib/active_record/connection_adapters/cockroachdb/attribute_methods.rb +16 -0
- data/lib/active_record/connection_adapters/cockroachdb/column.rb +16 -0
- data/lib/active_record/connection_adapters/cockroachdb/column_methods.rb +14 -0
- data/lib/active_record/connection_adapters/cockroachdb/database_statements.rb +16 -0
- data/lib/active_record/connection_adapters/cockroachdb/database_tasks.rb +20 -3
- data/lib/active_record/connection_adapters/cockroachdb/oid/date_time.rb +14 -0
- data/lib/active_record/connection_adapters/cockroachdb/oid/interval.rb +16 -0
- data/lib/active_record/connection_adapters/cockroachdb/oid/spatial.rb +14 -0
- data/lib/active_record/connection_adapters/cockroachdb/quoting.rb +16 -0
- data/lib/active_record/connection_adapters/cockroachdb/referential_integrity.rb +14 -0
- data/lib/active_record/connection_adapters/cockroachdb/schema_creation.rb +14 -1
- data/lib/active_record/connection_adapters/cockroachdb/schema_dumper.rb +14 -1
- data/lib/active_record/connection_adapters/cockroachdb/schema_statements.rb +102 -1
- data/lib/active_record/connection_adapters/cockroachdb/setup.rb +14 -0
- data/lib/active_record/connection_adapters/cockroachdb/spatial_column_info.rb +16 -0
- data/lib/active_record/connection_adapters/cockroachdb/table_definition.rb +14 -0
- data/lib/active_record/connection_adapters/cockroachdb/transaction_manager.rb +14 -0
- data/lib/active_record/connection_adapters/cockroachdb/type.rb +16 -0
- data/lib/active_record/connection_adapters/cockroachdb_adapter.rb +72 -126
- data/lib/active_record/migration/cockroachdb/compatibility.rb +16 -0
- data/lib/active_record/relation/query_methods_ext.rb +16 -3
- data/lib/activerecord-cockroachdb-adapter.rb +21 -0
- data/lib/arel/nodes/join_source_ext.rb +16 -0
- data/lib/version.rb +15 -1
- data/setup.sql +18 -0
- metadata +11 -12
- data/.ruby-version +0 -1
- data/lib/active_record/connection_adapters/cockroachdb/oid/type_map_initializer.rb +0 -26
@@ -1,3 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2024 The Cockroach Authors.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
1
17
|
module ActiveRecord
|
2
18
|
module ConnectionAdapters
|
3
19
|
module CockroachDB
|
@@ -1,5 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# Copyright 2024 The Cockroach Authors.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
3
17
|
# The PostgresSQL Adapter's ReferentialIntegrity module can disable and
|
4
18
|
# re-enable foreign key constraints by disabling all table triggers. Since
|
5
19
|
# triggers are not available in CockroachDB, we have to remove foreign keys and
|
@@ -1,5 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# Copyright 2024 The Cockroach Authors.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
3
17
|
module ActiveRecord
|
4
18
|
module ConnectionAdapters
|
5
19
|
module CockroachDB
|
@@ -15,4 +29,3 @@ module ActiveRecord
|
|
15
29
|
end
|
16
30
|
end
|
17
31
|
end
|
18
|
-
|
@@ -1,5 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# Copyright 2024 The Cockroach Authors.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
3
17
|
module ActiveRecord
|
4
18
|
module ConnectionAdapters
|
5
19
|
module CockroachDB
|
@@ -16,4 +30,3 @@ module ActiveRecord
|
|
16
30
|
end
|
17
31
|
end
|
18
32
|
end
|
19
|
-
|
@@ -1,9 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2024 The Cockroach Authors.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
1
17
|
module ActiveRecord
|
2
18
|
module ConnectionAdapters
|
3
19
|
module CockroachDB
|
4
20
|
module SchemaStatements
|
5
21
|
include ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements
|
6
22
|
|
23
|
+
# OVERRIDE: We do not want to see the crdb_internal schema in the names.
|
24
|
+
#
|
25
|
+
# Returns an array of schema names.
|
26
|
+
def schema_names
|
27
|
+
super - ["crdb_internal"]
|
28
|
+
end
|
29
|
+
|
7
30
|
def add_index(table_name, column_name, **options)
|
8
31
|
super
|
9
32
|
rescue ActiveRecord::StatementInvalid => error
|
@@ -32,6 +55,84 @@ module ActiveRecord
|
|
32
55
|
end
|
33
56
|
end
|
34
57
|
|
58
|
+
# OVERRIDE: CockroachDB does not support deferrable constraints.
|
59
|
+
# See: https://go.crdb.dev/issue-v/31632/v23.1
|
60
|
+
def foreign_key_options(from_table, to_table, options)
|
61
|
+
options = super
|
62
|
+
options.delete(:deferrable) unless supports_deferrable_constraints?
|
63
|
+
options
|
64
|
+
end
|
65
|
+
|
66
|
+
# OVERRIDE: Added `unique_rowid` to the last line of the second query.
|
67
|
+
# This is a CockroachDB-specific function used for primary keys.
|
68
|
+
# Also make sure we don't consider `NOT VISIBLE` columns.
|
69
|
+
#
|
70
|
+
# Returns a table's primary key and belonging sequence.
|
71
|
+
def pk_and_sequence_for(table) # :nodoc:
|
72
|
+
# First try looking for a sequence with a dependency on the
|
73
|
+
# given table's primary key.
|
74
|
+
result = query(<<~SQL, "SCHEMA")[0]
|
75
|
+
SELECT attr.attname, nsp.nspname, seq.relname
|
76
|
+
FROM pg_class seq,
|
77
|
+
pg_attribute attr,
|
78
|
+
pg_depend dep,
|
79
|
+
pg_constraint cons,
|
80
|
+
pg_namespace nsp,
|
81
|
+
-- TODO: use the pg_catalog.pg_attribute(attishidden) column when
|
82
|
+
-- it is added instead of joining on crdb_internal.
|
83
|
+
-- See https://github.com/cockroachdb/cockroach/pull/126397
|
84
|
+
crdb_internal.table_columns tc
|
85
|
+
WHERE seq.oid = dep.objid
|
86
|
+
AND seq.relkind = 'S'
|
87
|
+
AND attr.attrelid = dep.refobjid
|
88
|
+
AND attr.attnum = dep.refobjsubid
|
89
|
+
AND attr.attrelid = cons.conrelid
|
90
|
+
AND attr.attnum = cons.conkey[1]
|
91
|
+
AND seq.relnamespace = nsp.oid
|
92
|
+
AND attr.attrelid = tc.descriptor_id
|
93
|
+
AND attr.attname = tc.column_name
|
94
|
+
AND tc.hidden = false
|
95
|
+
AND cons.contype = 'p'
|
96
|
+
AND dep.classid = 'pg_class'::regclass
|
97
|
+
AND dep.refobjid = #{quote(quote_table_name(table))}::regclass
|
98
|
+
SQL
|
99
|
+
|
100
|
+
if result.nil? || result.empty?
|
101
|
+
result = query(<<~SQL, "SCHEMA")[0]
|
102
|
+
SELECT attr.attname, nsp.nspname,
|
103
|
+
CASE
|
104
|
+
WHEN pg_get_expr(def.adbin, def.adrelid) !~* 'nextval' THEN NULL
|
105
|
+
WHEN split_part(pg_get_expr(def.adbin, def.adrelid), '''', 2) ~ '.' THEN
|
106
|
+
substr(split_part(pg_get_expr(def.adbin, def.adrelid), '''', 2),
|
107
|
+
strpos(split_part(pg_get_expr(def.adbin, def.adrelid), '''', 2), '.')+1)
|
108
|
+
ELSE split_part(pg_get_expr(def.adbin, def.adrelid), '''', 2)
|
109
|
+
END
|
110
|
+
FROM pg_class t
|
111
|
+
JOIN pg_attribute attr ON (t.oid = attrelid)
|
112
|
+
JOIN pg_attrdef def ON (adrelid = attrelid AND adnum = attnum)
|
113
|
+
JOIN pg_constraint cons ON (conrelid = adrelid AND adnum = conkey[1])
|
114
|
+
JOIN pg_namespace nsp ON (t.relnamespace = nsp.oid)
|
115
|
+
-- TODO: use the pg_catalog.pg_attribute(attishidden) column when
|
116
|
+
-- it is added instead of joining on crdb_internal.
|
117
|
+
-- See https://github.com/cockroachdb/cockroach/pull/126397
|
118
|
+
JOIN crdb_internal.table_columns tc ON (attr.attrelid = tc.descriptor_id AND attr.attname = tc.column_name)
|
119
|
+
WHERE t.oid = #{quote(quote_table_name(table))}::regclass
|
120
|
+
AND tc.hidden = false
|
121
|
+
AND cons.contype = 'p'
|
122
|
+
AND pg_get_expr(def.adbin, def.adrelid) ~* 'nextval|uuid_generate|gen_random_uuid|unique_rowid'
|
123
|
+
SQL
|
124
|
+
end
|
125
|
+
|
126
|
+
pk = result.shift
|
127
|
+
if result.last
|
128
|
+
[pk, PostgreSQL::Name.new(*result)]
|
129
|
+
else
|
130
|
+
[pk, nil]
|
131
|
+
end
|
132
|
+
rescue
|
133
|
+
nil
|
134
|
+
end
|
135
|
+
|
35
136
|
# override
|
36
137
|
# Modified version of the postgresql foreign_keys method.
|
37
138
|
# Replaces t2.oid::regclass::text with t2.relname since this is
|
@@ -40,7 +141,7 @@ module ActiveRecord
|
|
40
141
|
# so we append it manually.
|
41
142
|
def foreign_keys(table_name)
|
42
143
|
scope = quoted_scope(table_name)
|
43
|
-
fk_info =
|
144
|
+
fk_info = internal_exec_query(<<~SQL, "SCHEMA")
|
44
145
|
SELECT CASE
|
45
146
|
WHEN n2.nspname = current_schema()
|
46
147
|
THEN ''
|
@@ -1,5 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# Copyright 2024 The Cockroach Authors.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
3
17
|
module ActiveRecord # :nodoc:
|
4
18
|
module ConnectionAdapters # :nodoc:
|
5
19
|
module CockroachDB # :nodoc:
|
@@ -1,3 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2024 The Cockroach Authors.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
1
17
|
module ActiveRecord
|
2
18
|
module ConnectionAdapters
|
3
19
|
module CockroachDB
|
@@ -1,5 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# Copyright 2024 The Cockroach Authors.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
3
17
|
module ActiveRecord # :nodoc:
|
4
18
|
module ConnectionAdapters # :nodoc:
|
5
19
|
module CockroachDB # :nodoc:
|
@@ -1,5 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# Copyright 2024 The Cockroach Authors.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
3
17
|
module ActiveRecord
|
4
18
|
module ConnectionAdapters
|
5
19
|
module CockroachDB
|
@@ -1,3 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2024 The Cockroach Authors.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
1
17
|
module ActiveRecord
|
2
18
|
module Type
|
3
19
|
module CRDBExt
|
@@ -1,3 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2024 The Cockroach Authors.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
1
17
|
require "rgeo/active_record"
|
2
18
|
|
3
19
|
require_relative "../../arel/nodes/join_source_ext"
|
@@ -16,7 +32,6 @@ require "active_record/connection_adapters/cockroachdb/type"
|
|
16
32
|
require "active_record/connection_adapters/cockroachdb/column"
|
17
33
|
require "active_record/connection_adapters/cockroachdb/spatial_column_info"
|
18
34
|
require "active_record/connection_adapters/cockroachdb/setup"
|
19
|
-
require "active_record/connection_adapters/cockroachdb/oid/type_map_initializer"
|
20
35
|
require "active_record/connection_adapters/cockroachdb/oid/spatial"
|
21
36
|
require "active_record/connection_adapters/cockroachdb/oid/interval"
|
22
37
|
require "active_record/connection_adapters/cockroachdb/oid/date_time"
|
@@ -30,40 +45,6 @@ require_relative "../relation/query_methods_ext"
|
|
30
45
|
# Defined in ./setup.rb
|
31
46
|
ActiveRecord::ConnectionAdapters::CockroachDB.initial_setup
|
32
47
|
|
33
|
-
module ActiveRecord
|
34
|
-
module ConnectionHandling
|
35
|
-
def cockroachdb_connection(config)
|
36
|
-
# This is copied from the PostgreSQL adapter.
|
37
|
-
conn_params = config.symbolize_keys.compact
|
38
|
-
|
39
|
-
# Map ActiveRecords param names to PGs.
|
40
|
-
conn_params[:user] = conn_params.delete(:username) if conn_params[:username]
|
41
|
-
conn_params[:dbname] = conn_params.delete(:database) if conn_params[:database]
|
42
|
-
|
43
|
-
# Forward only valid config params to PG::Connection.connect.
|
44
|
-
valid_conn_param_keys = PG::Connection.conndefaults_hash.keys + [:requiressl]
|
45
|
-
conn_params.slice!(*valid_conn_param_keys)
|
46
|
-
|
47
|
-
ConnectionAdapters::CockroachDBAdapter.new(
|
48
|
-
ConnectionAdapters::CockroachDBAdapter.new_client(conn_params),
|
49
|
-
logger,
|
50
|
-
conn_params,
|
51
|
-
config
|
52
|
-
)
|
53
|
-
# This rescue flow appears in new_client, but it is needed here as well
|
54
|
-
# since Cockroach will sometimes not raise until a query is made.
|
55
|
-
rescue ActiveRecord::StatementInvalid => error
|
56
|
-
no_db_err_check1 = conn_params && conn_params[:dbname] && error.cause.message.include?(conn_params[:dbname])
|
57
|
-
no_db_err_check2 = conn_params && conn_params[:dbname] && error.cause.message.include?("pg_type")
|
58
|
-
if no_db_err_check1 || no_db_err_check2
|
59
|
-
raise ActiveRecord::NoDatabaseError
|
60
|
-
else
|
61
|
-
raise ActiveRecord::ConnectionNotEstablished, error.message
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
48
|
module ActiveRecord
|
68
49
|
module ConnectionAdapters
|
69
50
|
module CockroachDBConnectionPool
|
@@ -101,7 +82,7 @@ module ActiveRecord
|
|
101
82
|
ConnectionPool.prepend(CockroachDBConnectionPool)
|
102
83
|
|
103
84
|
class CockroachDBAdapter < PostgreSQLAdapter
|
104
|
-
ADAPTER_NAME = "CockroachDB"
|
85
|
+
ADAPTER_NAME = "CockroachDB"
|
105
86
|
DEFAULT_PRIMARY_KEY = "rowid"
|
106
87
|
|
107
88
|
SPATIAL_COLUMN_OPTIONS =
|
@@ -155,18 +136,29 @@ module ActiveRecord
|
|
155
136
|
@max_transaction_retries ||= @config.fetch(:max_transaction_retries, 3)
|
156
137
|
end
|
157
138
|
|
158
|
-
|
159
|
-
|
160
|
-
|
139
|
+
def get_database_version
|
140
|
+
with_raw_connection do |conn|
|
141
|
+
conn.async_exec("SHOW crdb_version") do |result|
|
142
|
+
major, minor, patch = result
|
143
|
+
.getvalue(0, 0)
|
144
|
+
.match(/v(\d+).(\d+).(\d+)/)
|
145
|
+
.captures
|
146
|
+
.map(&:to_i)
|
147
|
+
major * 100 * 100 + minor * 100 + patch
|
148
|
+
end
|
149
|
+
end
|
161
150
|
end
|
151
|
+
undef :postgresql_version
|
152
|
+
alias :cockroachdb_version :database_version
|
162
153
|
|
163
|
-
def
|
154
|
+
def supports_datetime_with_precision?
|
155
|
+
# https://github.com/cockroachdb/cockroach/pull/111400
|
164
156
|
true
|
165
157
|
end
|
166
158
|
|
167
|
-
def
|
168
|
-
#
|
169
|
-
|
159
|
+
def supports_nulls_not_distinct?
|
160
|
+
# https://github.com/cockroachdb/cockroach/issues/115836
|
161
|
+
false
|
170
162
|
end
|
171
163
|
|
172
164
|
def supports_ddl_transactions?
|
@@ -178,10 +170,6 @@ module ActiveRecord
|
|
178
170
|
end
|
179
171
|
|
180
172
|
def supports_materialized_views?
|
181
|
-
false
|
182
|
-
end
|
183
|
-
|
184
|
-
def supports_partial_index?
|
185
173
|
true
|
186
174
|
end
|
187
175
|
|
@@ -200,14 +188,6 @@ module ActiveRecord
|
|
200
188
|
false
|
201
189
|
end
|
202
190
|
|
203
|
-
def supports_datetime_with_precision?
|
204
|
-
false
|
205
|
-
end
|
206
|
-
|
207
|
-
def supports_comments?
|
208
|
-
true
|
209
|
-
end
|
210
|
-
|
211
191
|
def supports_comments_in_create?
|
212
192
|
false
|
213
193
|
end
|
@@ -229,53 +209,47 @@ module ActiveRecord
|
|
229
209
|
end
|
230
210
|
|
231
211
|
def supports_deferrable_constraints?
|
212
|
+
# https://go.crdb.dev/issue-v/31632/v23.1
|
232
213
|
false
|
233
214
|
end
|
234
215
|
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
#
|
241
|
-
# Note that in the migration to ActiveRecord 5.1, this was changed in
|
242
|
-
# PostgreSQLAdapter to use `SHOW max_identifier_length` (which does not
|
243
|
-
# exist in CockroachDB). Therefore, we have to redefine this here.
|
244
|
-
def max_identifier_length
|
245
|
-
63
|
216
|
+
def check_version # :nodoc:
|
217
|
+
# https://www.cockroachlabs.com/docs/releases/release-support-policy
|
218
|
+
if database_version < 23_01_12 # < 23.1.12
|
219
|
+
raise "Your version of CockroachDB (#{database_version}) is too old. Active Record supports CockroachDB >= 23.1.12."
|
220
|
+
end
|
246
221
|
end
|
247
|
-
alias index_name_length max_identifier_length
|
248
|
-
alias table_alias_length max_identifier_length
|
249
222
|
|
250
|
-
|
251
|
-
|
252
|
-
|
223
|
+
def configure_connection(...)
|
224
|
+
super
|
225
|
+
|
226
|
+
# This rescue flow appears in new_client, but it is needed here as well
|
227
|
+
# since Cockroach will sometimes not raise until a query is made.
|
253
228
|
#
|
254
|
-
#
|
255
|
-
#
|
256
|
-
|
257
|
-
#
|
258
|
-
#
|
259
|
-
#
|
260
|
-
#
|
261
|
-
#
|
262
|
-
#
|
263
|
-
#
|
264
|
-
#
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
false
|
229
|
+
# See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/pull/337#issuecomment-2328419453
|
230
|
+
#
|
231
|
+
# The error conditions used to differ from the ones in new_client, but
|
232
|
+
# the reasons why are no longer relevant. We keep this in sync with new_client
|
233
|
+
# even though some conditions might never be checked.
|
234
|
+
#
|
235
|
+
# See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/pull/229
|
236
|
+
#
|
237
|
+
# We have to rescue `ActiveRecord::StatementInvalid` instead of `::PG::Error`
|
238
|
+
# here as the error has already been casted (in `#with_raw_connection` as
|
239
|
+
# of Rails 7.2.1).
|
240
|
+
rescue ActiveRecord::StatementInvalid => error
|
241
|
+
conn_params = @connection_parameters
|
242
|
+
if conn_params && conn_params[:dbname] == "postgres"
|
243
|
+
raise ActiveRecord::ConnectionNotEstablished, error.message
|
244
|
+
elsif conn_params && conn_params[:dbname] && error.cause.message.include?(conn_params[:dbname])
|
245
|
+
raise ActiveRecord::NoDatabaseError.db_error(conn_params[:dbname])
|
246
|
+
elsif conn_params && conn_params[:user] && error.cause.message.include?(conn_params[:user])
|
247
|
+
raise ActiveRecord::DatabaseConnectionError.username_error(conn_params[:user])
|
248
|
+
elsif conn_params && conn_params[:host] && error.cause.message.include?(conn_params[:host])
|
249
|
+
raise ActiveRecord::DatabaseConnectionError.hostname_error(conn_params[:host])
|
250
|
+
else
|
251
|
+
raise ActiveRecord::ConnectionNotEstablished, error.message
|
252
|
+
end
|
279
253
|
end
|
280
254
|
|
281
255
|
# override
|
@@ -320,7 +294,6 @@ module ActiveRecord
|
|
320
294
|
precision = extract_precision(sql_type)
|
321
295
|
scale = extract_scale(sql_type)
|
322
296
|
|
323
|
-
|
324
297
|
# The type for the numeric depends on the width of the field,
|
325
298
|
# so we'll do something special here.
|
326
299
|
#
|
@@ -351,7 +324,6 @@ module ActiveRecord
|
|
351
324
|
def extract_value_from_default(default)
|
352
325
|
super ||
|
353
326
|
extract_escaped_string_from_default(default) ||
|
354
|
-
extract_time_from_default(default) ||
|
355
327
|
extract_empty_array_from_default(default) ||
|
356
328
|
extract_decimal_from_default(default)
|
357
329
|
end
|
@@ -369,32 +341,6 @@ module ActiveRecord
|
|
369
341
|
"\"#{$1}\"".undump.gsub("\\'".freeze, "'".freeze)
|
370
342
|
end
|
371
343
|
|
372
|
-
# This method exists to extract the correct time and date defaults for a
|
373
|
-
# couple of reasons.
|
374
|
-
# 1) There's a bug in CockroachDB where the date type is missing from
|
375
|
-
# the column info query.
|
376
|
-
# https://github.com/cockroachdb/cockroach/issues/47285
|
377
|
-
# 2) PostgreSQL's timestamp without time zone type maps to CockroachDB's
|
378
|
-
# TIMESTAMP type. TIMESTAMP includes a UTC time zone while timestamp
|
379
|
-
# without time zone doesn't.
|
380
|
-
# https://www.cockroachlabs.com/docs/v19.2/timestamp.html#variants
|
381
|
-
def extract_time_from_default(default)
|
382
|
-
return unless default =~ /\A'(.*)'\z/
|
383
|
-
|
384
|
-
# If default has a UTC time zone, we'll drop the time zone information
|
385
|
-
# so it acts like PostgreSQL's timestamp without time zone. Then, try
|
386
|
-
# to parse the resulting string to verify if it's a time.
|
387
|
-
time = if default =~ /\A'(.*)(\+00:00)'\z/
|
388
|
-
$1
|
389
|
-
else
|
390
|
-
default
|
391
|
-
end
|
392
|
-
|
393
|
-
Time.parse(time).to_s
|
394
|
-
rescue
|
395
|
-
nil
|
396
|
-
end
|
397
|
-
|
398
344
|
# CockroachDB stores default values for arrays in the `ARRAY[...]` format.
|
399
345
|
# In general, it is hard to parse that, but it is easy to handle the common
|
400
346
|
# case of an empty array.
|
@@ -566,7 +512,7 @@ module ActiveRecord
|
|
566
512
|
# so this modified query uses AS OF SYSTEM TIME '-10s' to read historical data.
|
567
513
|
def add_pg_decoders
|
568
514
|
if @config[:use_follower_reads_for_type_introspection]
|
569
|
-
@
|
515
|
+
@mapped_default_timezone = nil
|
570
516
|
@timestamp_decoder = nil
|
571
517
|
|
572
518
|
coders_by_name = {
|
@@ -581,6 +527,7 @@ module ActiveRecord
|
|
581
527
|
"timestamp" => PG::TextDecoder::TimestampUtc,
|
582
528
|
"timestamptz" => PG::TextDecoder::TimestampWithTimeZone,
|
583
529
|
}
|
530
|
+
coders_by_name["date"] = PG::TextDecoder::Date if decode_dates
|
584
531
|
|
585
532
|
known_coder_types = coders_by_name.keys.map { |n| quote(n) }
|
586
533
|
query = <<~SQL % known_coder_types.join(", ")
|
@@ -588,7 +535,6 @@ module ActiveRecord
|
|
588
535
|
FROM pg_type as t AS OF SYSTEM TIME '-10s'
|
589
536
|
WHERE t.typname IN (%s)
|
590
537
|
SQL
|
591
|
-
|
592
538
|
coders = execute_and_clear(query, "SCHEMA", [], allow_retry: true, materialize_transactions: false) do |result|
|
593
539
|
result.filter_map { |row| construct_coder(row, coders_by_name[row["typname"]]) }
|
594
540
|
end
|
@@ -1,3 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2024 The Cockroach Authors.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
1
17
|
require "active_record/migration"
|
2
18
|
require "active_record/migration/compatibility"
|
3
19
|
|
@@ -1,5 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# Copyright 2024 The Cockroach Authors.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
3
17
|
module ActiveRecord
|
4
18
|
class Relation
|
5
19
|
module QueryMethodsExt
|
@@ -76,10 +90,9 @@ module ActiveRecord
|
|
76
90
|
self
|
77
91
|
end
|
78
92
|
|
79
|
-
# TODO: reset or no reset?
|
80
|
-
|
81
93
|
def show_create
|
82
|
-
|
94
|
+
quoted_table = connection.quote_table_name self.table_name
|
95
|
+
connection.select_one("show create table #{quoted_table}")["create_statement"]
|
83
96
|
end
|
84
97
|
|
85
98
|
private
|