activerecord-cockroachdb-adapter
activerecord-cockroachdb-adapter copied to clipboard
Hash indexes are not supported
I can't create a hash index using:
add_index(
:users,
:username,
using: "hash",
algorithm: :concurrently,
if_not_exists: true
)
Which prints this error:
ActiveRecord::StatementInvalid: PG::FeatureNotSupported: ERROR: at or near "hash": syntax error: unimplemented: this syntax
DETAIL: source SQL:
CREATE INDEX CONCURRENTLY IF NOT EXISTS "index_users_on_username" ON "users" USING hash ("username")
^
HINT: You have attempted to use a feature that is not yet implemented.
As a workaround, we are using:
execute <<-SQL.squish
CREATE INDEX CONCURRENTLY index_users_on_username ON users(username) USING HASH;
SQL
Steps to reproduce
# frozen_string_literal: true
require 'bundler/inline'
gemfile(true) do
source 'https://rubygems.org'
gem 'activerecord'
gem 'activerecord-cockroachdb-adapter'
end
require 'active_record'
require 'activerecord-cockroachdb-adapter'
require 'minitest/autorun'
require 'logger'
# You might want to change the database name for another one.
ActiveRecord::Base.establish_connection('cockroachdb://root@localhost:26255/defaultdb')
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Schema.define do
create_table :users, force: true do |t|
t.string 'username'
end
end
class User < ActiveRecord::Base
end
class BugTest < ActiveSupport::TestCase
def dump_schema
stream = StringIO.new
ActiveRecord::SchemaDumper.dump(
ActiveRecord::Base.connection,
stream
)
stream.string
end
def test_schema_migration_with_hash_index
hash_index_migration = Class.new(ActiveRecord::Migration::Current) do
def up
add_index(
:users,
:username,
name: "index_users_on_username",
using: "hash",
algorithm: :concurrently,
if_not_exists: true
)
end
def down
remove_index :users, name: "index_users_on_username", algorithm: :concurrently, if_exists: true
end
end
hash_index_migration.migrate(:up)
schema = dump_schema
assert schema.include?('t.index ["crdb_internal_username_shard_16", "username"], name: "index_users_on_username"'), schema
assert schema.include?('t.virtual "crdb_internal_username_shard_16"'), schema
assert schema.include?('t.check_constraint "(crdb_internal_username_shard_16'), schema
hash_index_migration.migrate(:down)
schema = dump_schema
assert_not schema.include?('t.index ["crdb_internal_username_shard_16", "username"], name: "index_users_on_username"'), schema
assert_not schema.include?('t.virtual "crdb_internal_username_shard_16"'), schema
assert_not schema.include?('t.check_constraint "(crdb_internal_username_shard_16'), schema
hash_index_migration.migrate(:up)
end
end