Module: ActiveRecord::ConnectionAdapters::CockroachDB::SchemaStatements

Includes:
PostgreSQL::SchemaStatements
Included in:
ActiveRecord::ConnectionAdapters::CockroachDBAdapter
Defined in:
lib/active_record/connection_adapters/cockroachdb/schema_statements.rb

Instance Method Summary collapse

Instance Method Details

#add_index(table_name, column_name, options = {}) ⇒ Object



7
8
9
10
11
12
13
14
15
# 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

#columns(table_name) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/active_record/connection_adapters/cockroachdb/schema_statements.rb', line 42

def columns(table_name)
  # Limit, precision, and scale are all handled by the superclass.
  column_definitions(table_name).map do |column_name, type, default, notnull, oid, fmod, collation, comment|
    oid = oid.to_i
    fmod = fmod.to_i
     = (column_name, type, oid, fmod)
    cast_type = get_oid_type(oid.to_i, fmod.to_i, column_name, type)
    default_value = extract_value_from_default(default)

    default_function = extract_default_function(default_value, default)
    new_column(table_name, column_name, default_value, cast_type, , !notnull,
               default_function, collation, comment)
  end
end

#create_table_definition(*args, **kwargs) ⇒ Object

override



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

def create_table_definition(*args, **kwargs)
  CockroachDB::TableDefinition.new(*args, **kwargs)
end

#default_sequence_name(table_name, pk = "id") ⇒ Object

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.



38
39
40
# File 'lib/active_record/connection_adapters/cockroachdb/schema_statements.rb', line 38

def default_sequence_name(table_name, pk = "id")
  nil
end

#native_database_typesObject

override



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/active_record/connection_adapters/cockroachdb/schema_statements.rb', line 112

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

#new_column(table_name, column_name, default, cast_type, sql_type_metadata = nil, null = true, default_function = nil, collation = nil, comment = nil) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/active_record/connection_adapters/cockroachdb/schema_statements.rb', line 57

def new_column(table_name, column_name, default, cast_type,  = nil,
                null = true, default_function = nil, collation = nil, comment = nil)
  # JDBC gets true/false in Rails 4, where other platforms get 't'/'f' strings.
  if null.is_a?(String)
    null = (null == "t")
  end

  column_info = spatial_column_info(table_name).get(column_name, .sql_type)

  PostgreSQLColumn.new(
    column_name,
    default,
    ,
    null,
    table_name,
    default_function,
    collation,
    comment,
    cast_type,
    column_info
  )
end

#primary_key(table_name) ⇒ Object

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



25
26
27
28
29
30
31
32
33
# 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

#spatial_column_info(table_name) ⇒ Object

memoize hash of column infos for tables



134
135
136
137
# File 'lib/active_record/connection_adapters/cockroachdb/schema_statements.rb', line 134

def spatial_column_info(table_name)
  @spatial_column_info ||= {}
  @spatial_column_info[table_name.to_sym] ||= SpatialColumnInfo.new(self, table_name.to_s)
end

#type_to_sql(type, limit: nil, precision: nil, scale: nil, array: nil) ⇒ Object

CockroachDB will use INT8 if the SQL type is INTEGER, so we make it use INT4 explicitly when needed.

For spatial columns, include the limit to properly format the column name since type alone is not enough to format the column. Ex. type_to_sql(:geography, limit: “Point,4326”)

> “geography(Point,4326)”



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/active_record/connection_adapters/cockroachdb/schema_statements.rb', line 88

def type_to_sql(type, limit: nil, precision: nil, scale: nil, array: nil, **) # :nodoc:
  sql = \
    case type.to_s
    when "integer"
      case limit
      when nil; "int"
      when 1, 2; "int2"
      when 3, 4; "int4"
      when 5..8; "int8"
      else super
      end
    when "geometry", "geography"
      "#{type}(#{limit})"
    else
      super
    end
  # The call to super might have appeneded [] already.
  if array && type != :primary_key && !sql.end_with?("[]")
    sql = "#{sql}[]" 
  end
  sql
end