# File lib/active_record/connection_adapters/cockroachdb/schema_statements.rb, line 25 def primary_key(table_name) pk = super if pk == CockroachDBAdapter::DEFAULT_PRIMARY_KEY nil else pk end end
module ActiveRecord::ConnectionAdapters::CockroachDB::SchemaStatements
Public Instance Methods
# File lib/active_record/connection_adapters/cockroachdb/schema_statements.rb, line 7 def add_index(table_name, column_name, **options) super rescue ActiveRecord::StatementInvalid => error if debugging? && error.cause.class == PG::FeatureNotSupported warn "#{error}\n\nThis error will be ignored and the index will not be created.\n\n" else raise error end end
override
# File lib/active_record/connection_adapters/cockroachdb/schema_statements.rb, line 145 def create_table_definition(*args, **kwargs) CockroachDB::TableDefinition.new(self, *args, **kwargs) end
CockroachDB
uses unique_rowid() for primary keys, not sequences. It's possible to force a table to use sequences, but since it's not the default behavior we'll always return nil for default_sequence_name.
# File lib/active_record/connection_adapters/cockroachdb/schema_statements.rb, line 38 def default_sequence_name(table_name, pk = "id") nil end
override
# File lib/active_record/connection_adapters/cockroachdb/schema_statements.rb, line 128 def native_database_types # Add spatial types super.merge( geography: { name: "geography" }, geometry: { name: "geometry" }, geometry_collection: { name: "geometry_collection" }, line_string: { name: "line_string" }, multi_line_string: { name: "multi_line_string" }, multi_point: { name: "multi_point" }, multi_polygon: { name: "multi_polygon" }, spatial: { name: "geometry" }, st_point: { name: "st_point" }, st_polygon: { name: "st_polygon" } ) end
# File lib/active_record/connection_adapters/cockroachdb/schema_statements.rb, line 44 def new_column_from_field(table_name, field) column_name, type, default, notnull, oid, fmod, collation, comment = field type_metadata = fetch_type_metadata(column_name, type, oid.to_i, fmod.to_i) default_value = extract_value_from_default(default) default_function = extract_default_function(default_value, default) serial = if (match = default_function&.match(/\Anextval\('"?(?<sequence_name>.+_(?<suffix>seq\d*))"?'::regclass\)\z/)) sequence_name_from_parts(table_name, column_name, match[:suffix]) == match[:sequence_name] end # {:dimension=>2, :has_m=>false, :has_z=>false, :name=>"latlon", :srid=>0, :type=>"GEOMETRY"} spatial = spatial_column_info(table_name).get(column_name, type_metadata.sql_type) PostgreSQL::Column.new( column_name, default_value, type_metadata, !notnull, default_function, collation: collation, comment: comment.presence, serial: serial, spatial: spatial ) end
ActiveRecord
allows for tables to exist without primary keys. Databases like PostgreSQL support this behavior, but CockroachDB
does not. If a table is created without a primary key, CockroachDB
will add a rowid column to serve as its primary key. This breaks a lot of ActiveRecord's assumptions so we'll treat tables with rowid primary keys as if they didn't have primary keys at all. www.cockroachlabs.com/docs/v19.2/create-table.html#create-a-table api.rubyonrails.org/v5.2.4/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-create_table
This overrides the method from PostegreSQL adapter Resets the sequence of a table's primary key to the maximum value.
# File lib/active_record/connection_adapters/cockroachdb/schema_statements.rb, line 104 def reset_pk_sequence!(table, pk = nil, sequence = nil) unless pk && sequence default_pk, default_sequence = pk_and_sequence_for(table) pk ||= default_pk sequence ||= default_sequence end if @logger && pk && !sequence @logger.warn "#{table} has primary key #{pk} with no default sequence." end if pk && sequence quoted_sequence = quote_table_name(sequence) max_pk = query_value("SELECT MAX(#{quote_column_name pk}) FROM #{quote_table_name(table)}", "SCHEMA") if max_pk.nil? minvalue = query_value("SELECT seqmin FROM pg_sequence WHERE seqrelid = #{quote(quoted_sequence)}::regclass", "SCHEMA") end query_value("SELECT setval(#{quote(quoted_sequence)}, #{max_pk ? max_pk : minvalue}, #{max_pk ? true : false})", "SCHEMA") end end
memoize hash of column infos for tables
# File lib/active_record/connection_adapters/cockroachdb/schema_statements.rb, line 150 def spatial_column_info(table_name) @spatial_column_info ||= {} @spatial_column_info[table_name.to_sym] ||= SpatialColumnInfo.new(self, table_name.to_s) end