Class: ActiveRecord::ConnectionAdapters::CockroachDBAdapter

Inherits:
PostgreSQLAdapter
  • Object
show all
Includes:
ActiveRecord::ConnectionAdapters::CockroachDB::DatabaseStatements, ActiveRecord::ConnectionAdapters::CockroachDB::Quoting, ActiveRecord::ConnectionAdapters::CockroachDB::ReferentialIntegrity, ActiveRecord::ConnectionAdapters::CockroachDB::SchemaStatements
Defined in:
lib/active_record/connection_adapters/cockroachdb_adapter.rb

Constant Summary collapse

ADAPTER_NAME =
"CockroachDB".freeze
DEFAULT_PRIMARY_KEY =
"rowid"
SPATIAL_COLUMN_OPTIONS =
{
  geography:           { geographic: true },
  geometry:            {},
  geometry_collection: {},
  line_string:         {},
  multi_line_string:   {},
  multi_point:         {},
  multi_polygon:       {},
  spatial:             {},
  st_point:            {},
  st_polygon:          {},
}
DEFAULT_SRID =
0

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ActiveRecord::ConnectionAdapters::CockroachDB::Quoting

#quote

Methods included from ActiveRecord::ConnectionAdapters::CockroachDB::DatabaseStatements

#insert_fixtures_set

Methods included from ActiveRecord::ConnectionAdapters::CockroachDB::ReferentialIntegrity

#check_all_foreign_keys_valid!, #disable_referential_integrity

Methods included from ActiveRecord::ConnectionAdapters::CockroachDB::SchemaStatements

#add_index, #create_schema_dumper, #create_table_definition, #default_sequence_name, #foreign_keys, #native_database_types, #new_column_from_field, #primary_key, #reset_pk_sequence!, #schema_creation, #spatial_column_info, #type_to_sql

Class Method Details

.database_exists?(config) ⇒ Boolean

# crdb_version is the version of the binary running on the node. We

  # really want to use `SHOW CLUSTER SETTING version` to get the cluster
  # version, but that is only available to admins. Instead, we can use
  # crdb_internal.is_at_least_version, but that's only available in 22.1.
  crdb_version_string = query_value("SHOW crdb_version")
  if crdb_version_string.include? "v22.1"
    version_num = query_value(<<~SQL, "VERSION")
      SELECT
        CASE
        WHEN crdb_internal.is_at_least_version('22.2') THEN 2220
        WHEN crdb_internal.is_at_least_version('22.1') THEN 2210
        ELSE 2120
        END;
    SQL
  end
  @crdb_version = version_num.to_i
end

Returns:

  • (Boolean)


275
276
277
278
279
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 275

def self.database_exists?(config)
  !!ActiveRecord::Base.cockroachdb_connection(config)
rescue ActiveRecord::NoDatabaseError
  false
end

.initialize_type_map(m = type_map) ⇒ Object



295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 295

def initialize_type_map(m = type_map)
  %w(
    geography
    geometry
    geometry_collection
    line_string
    multi_line_string
    multi_point
    multi_polygon
    st_point
    st_polygon
  ).each do |geo_type|
    m.register_type(geo_type) do |oid, _, sql_type|
      CockroachDB::OID::Spatial.new(oid, sql_type)
    end
  end

  # Belongs after other types are defined because of issues described
  # in this https://github.com/rails/rails/pull/38571
  # Once that PR is merged, we can call super at the top.
  super(m)

  # Override numeric type. This is almost identical to the default,
  # except that the conditional based on the fmod is changed.
  m.register_type "numeric" do |_, fmod, sql_type|
    precision = extract_precision(sql_type)
    scale = extract_scale(sql_type)


    # The type for the numeric depends on the width of the field,
    # so we'll do something special here.
    #
    # When dealing with decimal columns:
    #
    # places after decimal  = fmod - 4 & 0xffff
    # places before decimal = (fmod - 4) >> 16 & 0xffff
    #
    # For older versions of CockroachDB (<v22.1), fmod is -1 for 0 width.
    # If fmod is -1, that means that precision is defined but not
    # scale, or neither is defined.
    if fmod && ((fmod == -1 && !precision.nil?) || (fmod - 4 & 0xffff).zero?)
      # Below comment is from ActiveRecord
      # FIXME: Remove this class, and the second argument to
      # lookups on PG
      Type::DecimalWithoutScale.new(precision: precision)
    else
      ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Decimal.new(precision: precision, scale: scale)
    end
  end
end

.spatial_column_options(key) ⇒ Object



129
130
131
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 129

def self.spatial_column_options(key)
  SPATIAL_COLUMN_OPTIONS[key]
end

Instance Method Details

#create_enum(name, values, **options) ⇒ Object

override The PostgreSQLAdapter uses syntax for an anonymous function (DO $$) that CockroachDB does not support.

Given a name and an array of values, creates an enum type.



286
287
288
289
290
291
292
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 286

def create_enum(name, values, **options)
  sql_values = values.map { |s| quote(s) }.join(", ")
  query = <<~SQL
    CREATE TYPE IF NOT EXISTS #{quote_table_name(name)} AS ENUM (#{sql_values});
  SQL
  internal_exec_query(query).tap { reload_type_map }
end

#debugging?Boolean

Returns:

  • (Boolean)


150
151
152
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 150

def debugging?
  !!ENV["DEBUG_COCKROACHDB_ADAPTER"]
end

#default_sridObject



137
138
139
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 137

def default_srid
  DEFAULT_SRID
end

#max_identifier_lengthObject Also known as: index_name_length, table_alias_length

This is hardcoded to 63 (as previously was in ActiveRecord 5.0) to aid in migration from PostgreSQL to CockroachDB. In practice, this limitation is arbitrary since CockroachDB supports index name lengths and table alias lengths far greater than this value. For the time being though, we match the original behavior for PostgreSQL to simplify migrations.

Note that in the migration to ActiveRecord 5.1, this was changed in PostgreSQLAdapter to use ‘SHOW max_identifier_length` (which does not exist in CockroachDB). Therefore, we have to redefine this here.



244
245
246
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 244

def max_identifier_length
  63
end

#max_transaction_retriesObject



154
155
156
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 154

def max_transaction_retries
  @max_transaction_retries ||= @config.fetch(:max_transaction_retries, 3)
end

#postgis_lib_versionObject



133
134
135
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 133

def postgis_lib_version
  @postgis_lib_version ||= select_value("SELECT PostGIS_Lib_Version()")
end

#postgresql_versionObject

CockroachDB 20.1 can run queries that work against PostgreSQL 10+.



159
160
161
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 159

def postgresql_version
  100000
end

#srs_database_columnsObject



141
142
143
144
145
146
147
148
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 141

def srs_database_columns
  {
    auth_name_column: "auth_name",
    auth_srid_column: "auth_srid",
    proj4text_column: "proj4text",
    srtext_column:    "srtext",
  }
end

#supports_advisory_locks?Boolean

Returns:

  • (Boolean)


215
216
217
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 215

def supports_advisory_locks?
  false
end

#supports_bulk_alter?Boolean

Returns:

  • (Boolean)


163
164
165
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 163

def supports_bulk_alter?
  true
end

#supports_comments?Boolean

Returns:

  • (Boolean)


207
208
209
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 207

def supports_comments?
  true
end

#supports_comments_in_create?Boolean

Returns:

  • (Boolean)


211
212
213
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 211

def supports_comments_in_create?
  false
end

#supports_datetime_with_precision?Boolean

Returns:

  • (Boolean)


203
204
205
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 203

def supports_datetime_with_precision?
  false
end

#supports_ddl_transactions?Boolean

Returns:

  • (Boolean)


172
173
174
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 172

def supports_ddl_transactions?
  false
end

#supports_deferrable_constraints?Boolean

Returns:

  • (Boolean)


231
232
233
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 231

def supports_deferrable_constraints?
  false
end

#supports_exclusion_constraints?Boolean

Returns:

  • (Boolean)


192
193
194
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 192

def supports_exclusion_constraints?
  false
end

#supports_expression_index?Boolean

Returns:

  • (Boolean)


196
197
198
199
200
201
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 196

def supports_expression_index?
  # Expression indexes are partially supported by CockroachDB v21.2,
  # but activerecord requires "ON CONFLICT expression" support.
  # See https://github.com/cockroachdb/cockroach/issues/67893
  false
end

#supports_extensions?Boolean

Returns:

  • (Boolean)


176
177
178
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 176

def supports_extensions?
  false
end

#supports_index_include?Boolean

Returns:

  • (Boolean)


188
189
190
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 188

def supports_index_include?
  false
end

#supports_json?Boolean

Returns:

  • (Boolean)


167
168
169
170
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 167

def supports_json?
  # FIXME(joey): Add a version check.
  true
end

#supports_materialized_views?Boolean

Returns:

  • (Boolean)


180
181
182
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 180

def supports_materialized_views?
  false
end

#supports_partial_index?Boolean

Returns:

  • (Boolean)


184
185
186
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 184

def supports_partial_index?
  true
end

#supports_partitioned_indexes?Boolean

Returns:

  • (Boolean)


227
228
229
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 227

def supports_partitioned_indexes?
  false
end

#supports_string_to_array_coercion?Boolean

Returns:

  • (Boolean)


223
224
225
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 223

def supports_string_to_array_coercion?
  true
end

#supports_virtual_columns?Boolean

Returns:

  • (Boolean)


219
220
221
# File 'lib/active_record/connection_adapters/cockroachdb_adapter.rb', line 219

def supports_virtual_columns?
  true
end