├── .editorconfig ├── .github ├── issue_template.md ├── reproduction_scripts │ ├── migrations.rb │ └── models_and_database.rb └── workflows │ ├── ci.yml │ └── docker.yml ├── .gitignore ├── .gitmodules ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── activerecord-cockroachdb-adapter.gemspec ├── bin ├── console ├── console_schemas │ ├── default.rb │ └── schemas.rb ├── setup └── start-cockroachdb ├── build ├── Dockerfile ├── config.teamcity.yml ├── local-test.sh └── teamcity-test.sh ├── docker.sh ├── lib ├── active_record │ ├── connection_adapters │ │ ├── cockroachdb │ │ │ ├── arel_tosql.rb │ │ │ ├── attribute_methods.rb │ │ │ ├── column.rb │ │ │ ├── column_methods.rb │ │ │ ├── database_statements.rb │ │ │ ├── database_tasks.rb │ │ │ ├── oid │ │ │ │ ├── date_time.rb │ │ │ │ ├── interval.rb │ │ │ │ └── spatial.rb │ │ │ ├── quoting.rb │ │ │ ├── referential_integrity.rb │ │ │ ├── schema_creation.rb │ │ │ ├── schema_dumper.rb │ │ │ ├── schema_statements.rb │ │ │ ├── setup.rb │ │ │ ├── spatial_column_info.rb │ │ │ ├── table_definition.rb │ │ │ ├── transaction_manager.rb │ │ │ └── type.rb │ │ └── cockroachdb_adapter.rb │ ├── migration │ │ └── cockroachdb │ │ │ └── compatibility.rb │ └── relation │ │ └── query_methods_ext.rb ├── activerecord-cockroachdb-adapter.rb ├── arel │ └── nodes │ │ └── join_source_ext.rb └── version.rb ├── setup.sql └── test ├── cases ├── adapter_test.rb ├── adapters │ └── postgresql │ │ ├── active_schema_test.rb │ │ ├── change_schema_test.rb │ │ ├── connection_test.rb │ │ ├── ddl_test.rb │ │ ├── interval_test.rb │ │ ├── nested_class_test.rb │ │ ├── numeric_test.rb │ │ ├── postgis_test.rb │ │ ├── postgresql_adapter_test.rb │ │ ├── quoting_test.rb │ │ ├── schema_statements_test.rb │ │ ├── serial_test.rb │ │ ├── spatial_queries_test.rb │ │ ├── spatial_setup_test.rb │ │ ├── spatial_type_test.rb │ │ ├── timestamp_test.rb │ │ └── virtual_column_test.rb ├── associations │ ├── eager_load_nested_include_test.rb │ └── left_outer_join_association_test.rb ├── associations_test.rb ├── base_test.rb ├── comment_test.rb ├── connection_adapters │ └── type_test.rb ├── database_configurations │ └── resolver_test.rb ├── defaults_test.rb ├── dirty_test.rb ├── fixtures_test.rb ├── helper_cockroachdb.rb ├── inheritance_test.rb ├── invertible_migration_test.rb ├── marshal_serialization_test.rb ├── migration │ ├── change_schema_test.rb │ ├── check_constraint_test.rb │ ├── columns_test.rb │ ├── create_join_table_test.rb │ ├── foreign_key_test.rb │ ├── hidden_column_test.rb │ └── references_foreign_key_test.rb ├── migration_test.rb ├── persistence_test.rb ├── primary_keys_test.rb ├── relation │ ├── aost_test.rb │ ├── or_test.rb │ └── table_hints_test.rb ├── relation_test.rb ├── relations_test.rb ├── schema_dumper_test.rb ├── show_create_test.rb ├── strict_loading_test.rb ├── tasks │ └── cockroachdb_rake_test.rb ├── test_fixtures_test.rb ├── transactions_test.rb └── unsafe_raw_sql_test.rb ├── config.yml ├── excludes ├── ActiveRecord │ ├── AdapterForeignKeyTest.rb │ ├── AdapterTest.rb │ ├── AdapterTestWithoutTransaction.rb │ ├── ConnectionAdapters │ │ ├── PoolConfig │ │ │ └── ResolverTest.rb │ │ ├── PostgreSQLAdapter │ │ │ ├── BindParameterTest.rb │ │ │ └── QuotingTest.rb │ │ ├── PostgreSQLAdapterPreventWritesLegacyTest.rb │ │ ├── PostgreSQLAdapterPreventWritesTest.rb │ │ ├── PostgreSQLAdapterTest.rb │ │ └── RegistrationIsolatedTest.rb │ ├── Encryption │ │ ├── EncryptionPerformanceTest.rb │ │ ├── EnvelopeEncryptionPerformanceTest.rb │ │ ├── ExtendedDeterministicQueriesPerformanceTest.rb │ │ └── StoragePerformanceTest.rb │ ├── InvertibleMigrationTest.rb │ ├── Migration │ │ ├── ChangeSchemaTest.rb │ │ ├── CheckConstraintTest.rb │ │ ├── ColumnsTest.rb │ │ ├── CompatibilityTest.rb │ │ ├── CompositeForeignKeyTest.rb │ │ ├── CreateJoinTableTest.rb │ │ ├── ForeignKeyInCreateTest.rb │ │ ├── ForeignKeyTest.rb │ │ ├── InvalidOptionsTest.rb │ │ ├── PGChangeSchemaTest.rb │ │ ├── ReferencesForeignKeyTest.rb │ │ ├── ReferencesIndexTest.rb │ │ └── ReferencesStatementsTest.rb │ ├── MysqlDBCreateWithInvalidPermissionsTest.rb │ ├── OrTest.rb │ ├── PostgreSQLStructureDumpTest.rb │ ├── PostgresqlConnectionTest.rb │ ├── PostgresqlTransactionNestedTest.rb │ ├── PostgresqlTransactionTest.rb │ ├── RelationTest.rb │ └── TooManyOrTest.rb ├── ActiveSupportSubclassWithFixturesTest.rb ├── BasicsTest.rb ├── BulkAlterTableMigrationsTest.rb ├── CalculationsTest.rb ├── CommentTest.rb ├── CoreTest.rb ├── CreateOrFindByWithinTransactions.rb ├── DefaultsUsingMultipleSchemasAndDomainTest.rb ├── DirtyTest.rb ├── EachTest.rb ├── EagerLoadPolyAssocsTest.rb ├── ExplicitlyNamedIndexMigrationTest.rb ├── FixturesResetPkSequenceTest.rb ├── FixturesTest.rb ├── FixturesWithForeignKeyViolationsTest.rb ├── ForeignTableTest.rb ├── InheritanceComputeTypeTest.rb ├── LeftOuterJoinAssociationTest.rb ├── LegacyPrimaryKeyTest │ ├── V4_2.rb │ └── V5_0.rb ├── MarshalSerializationTest.rb ├── MaterializedViewTest.rb ├── MigrationTest.rb ├── MultiDbMigratorTest.rb ├── NestedRelationScopingTest.rb ├── OrTest.rb ├── PersistenceTest.rb ├── PessimisticLockingTest.rb ├── PostgreSQLExplainTest.rb ├── PostgreSQLGeometricLineTest.rb ├── PostgreSQLGeometricTypesTest.rb ├── PostgreSQLPartitionsTest.rb ├── PostgreSQLReferentialIntegrityTest.rb ├── PostgresqlArrayTest.rb ├── PostgresqlBigSerialTest.rb ├── PostgresqlBitStringTest.rb ├── PostgresqlByteaTest.rb ├── PostgresqlCitextTest.rb ├── PostgresqlCollationTest.rb ├── PostgresqlCompositeTest.rb ├── PostgresqlCompositeWithCustomOIDTest.rb ├── PostgresqlDataTypeTest.rb ├── PostgresqlDefaultExpressionTest.rb ├── PostgresqlDeferredConstraintsTest.rb ├── PostgresqlDomainTest.rb ├── PostgresqlExtensionMigrationTest.rb ├── PostgresqlFullTextTest.rb ├── PostgresqlGeometricTest.rb ├── PostgresqlHstoreTest.rb ├── PostgresqlInfinityTest.rb ├── PostgresqlIntervalTest.rb ├── PostgresqlJSONBTest.rb ├── PostgresqlJSONTest.rb ├── PostgresqlLtreeTest.rb ├── PostgresqlMoneyTest.rb ├── PostgresqlNetworkTest.rb ├── PostgresqlNumberTest.rb ├── PostgresqlPointTest.rb ├── PostgresqlRangeTest.rb ├── PostgresqlRenameTableTest.rb ├── PostgresqlSerialTest.rb ├── PostgresqlTimestampFixtureTest.rb ├── PostgresqlTimestampMigrationTest.rb ├── PostgresqlTypeLookupTest.rb ├── PostgresqlUUIDGenerationTest.rb ├── PostgresqlUUIDTest.rb ├── PostgresqlVirtualColumnTest.rb ├── PostgresqlXMLTest.rb ├── PrimaryKeyIntegerNilDefaultTest.rb ├── PrimaryKeyIntegerTest.rb ├── PrimaryKeysTest.rb ├── RelationMergingTest.rb ├── RelationTest.rb ├── ReservedWordsMigrationTest.rb ├── SameNameDifferentDatabaseFixturesTest.rb ├── SanitizeTest.rb ├── SchemaAuthorizationTest.rb ├── SchemaCreateTableOptionsTest.rb ├── SchemaDumperDefaultsTest.rb ├── SchemaDumperTest.rb ├── SchemaForeignKeyTest.rb ├── SchemaIndexNullsOrderTest.rb ├── SchemaIndexOpclassTest.rb ├── SchemaTest.rb ├── SequenceNameDetectionTestCases │ ├── CollidedSequenceNameTest.rb │ └── LongerSequenceNameDetectionTest.rb ├── StrictLoadingFixturesTest.rb ├── TestFixturesTest.rb ├── TransactionInstrumentationTest.rb ├── TransactionIsolationTest.rb ├── TypeTest.rb ├── UniquenessValidationTest.rb ├── UnloggedTablesTest.rb ├── UnsafeRawSqlTest.rb ├── UpdateableViewTest.rb └── WithAnnotationsTest.rb ├── models ├── building.rb └── spatial_model.rb ├── schema └── cockroachdb_specific_schema.rb └── support ├── copy_cat.rb ├── exclude_from_transactional_tests.rb ├── paths_cockroachdb.rb ├── rake_helpers.rb ├── sql_logger.rb └── template_creator.rb /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*.rb] 4 | indent_style = space 5 | indent_size = 2 6 | trim_trailing_whitespace = true 7 | insert_final_newline = true 8 | -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ### Steps to reproduce 4 | 5 | 7 | 8 | 9 | 10 | ```ruby 11 | # Your reproduction script goes here 12 | ``` 13 | 14 | ### Expected behavior 15 | 16 | 17 | 18 | ### Actual behavior 19 | 20 | 21 | 22 | ### System configuration 23 | 24 | 33 | 34 | 39 | 40 | **Rails version**: 41 | 42 | **Ruby version**: 43 | 44 | **Adapter version**: 45 | 46 | **CockroachDB version**: 47 | -------------------------------------------------------------------------------- /.github/reproduction_scripts/migrations.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | # 3 | # Adapted from https://github.com/rails/rails/blob/main/guides/bug_report_templates/active_record_migrations.rb 4 | 5 | require "bundler/inline" 6 | 7 | gemfile(true) do 8 | source "https://rubygems.org" 9 | 10 | gem "activerecord" 11 | 12 | gem "activerecord-cockroachdb-adapter" 13 | end 14 | 15 | require "activerecord-cockroachdb-adapter" 16 | require "minitest/autorun" 17 | require "logger" 18 | 19 | # You might want to change the database name for another one. 20 | ActiveRecord::Base.establish_connection("cockroachdb://root@localhost:26257/defaultdb") 21 | ActiveRecord::Base.logger = Logger.new(STDOUT) 22 | 23 | ActiveRecord::Schema.define do 24 | create_table :payments, force: true do |t| 25 | t.decimal :amount, precision: 10, scale: 0, default: 0, null: false 26 | end 27 | end 28 | 29 | class Payment < ActiveRecord::Base 30 | end 31 | 32 | class ChangeAmountToAddScale < ActiveRecord::Migration::Current # or use a specific version via `Migration[number]` 33 | def change 34 | reversible do |dir| 35 | dir.up do 36 | change_column :payments, :amount, :decimal, precision: 10, scale: 2 37 | end 38 | 39 | dir.down do 40 | change_column :payments, :amount, :decimal, precision: 10, scale: 0 41 | end 42 | end 43 | end 44 | end 45 | 46 | class BugTest < ActiveSupport::TestCase 47 | def test_migration_up 48 | ChangeAmountToAddScale.migrate(:up) 49 | Payment.reset_column_information 50 | 51 | assert_equal "decimal(10,2)", Payment.columns.last.sql_type 52 | end 53 | 54 | def test_migration_down 55 | ChangeAmountToAddScale.migrate(:down) 56 | Payment.reset_column_information 57 | 58 | assert_equal "decimal(10)", Payment.columns.last.sql_type 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /.github/reproduction_scripts/models_and_database.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | # 3 | # Adapted from https://github.com/rails/rails/blob/main/guides/bug_report_templates/active_record.rb 4 | 5 | require "bundler/inline" 6 | 7 | gemfile(true) do 8 | source "https://rubygems.org" 9 | 10 | gem "activerecord" 11 | 12 | gem "activerecord-cockroachdb-adapter" 13 | end 14 | 15 | require "activerecord-cockroachdb-adapter" 16 | require "minitest/autorun" 17 | require "logger" 18 | 19 | # You might want to change the database name for another one. 20 | ActiveRecord::Base.establish_connection("cockroachdb://root@localhost:26257/defaultdb") 21 | ActiveRecord::Base.logger = Logger.new(STDOUT) 22 | 23 | ActiveRecord::Schema.define do 24 | create_table :posts, force: true do |t| 25 | end 26 | 27 | create_table :comments, force: true do |t| 28 | t.integer :post_id 29 | end 30 | end 31 | 32 | class Post < ActiveRecord::Base 33 | has_many :comments 34 | end 35 | 36 | class Comment < ActiveRecord::Base 37 | belongs_to :post 38 | end 39 | 40 | class BugTest < ActiveSupport::TestCase 41 | def test_association_stuff 42 | post = Post.create! 43 | post.comments << Comment.create! 44 | 45 | assert_equal 1, post.comments.count 46 | assert_equal 1, Comment.count 47 | assert_equal post.id, Comment.first.post.id 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /.github/workflows/docker.yml: -------------------------------------------------------------------------------- 1 | # This workflow is based off of the example at 2 | # https://github.com/docker/metadata-action 3 | # 4 | # Multi-platform configuration from 5 | # https://github.com/docker/build-push-action/blob/master/docs/advanced/multi-platform.md 6 | # 7 | # Caching from 8 | # https://github.com/docker/build-push-action/blob/master/docs/advanced/cache.md 9 | name: Docker 10 | permissions: 11 | contents: read 12 | on: 13 | push: 14 | branches: [ master ] 15 | paths: 16 | - 'build/Dockerfile' 17 | # Only build, but don't push, on a PR if it touches the Dockerfile, 18 | # since this takes a while to execute. 19 | pull_request: 20 | paths: 21 | - 'build/Dockerfile' 22 | jobs: 23 | docker: 24 | runs-on: ubuntu-latest 25 | steps: 26 | - name: Checkout 27 | uses: actions/checkout@v3 28 | - name: Set up QEMU 29 | uses: docker/setup-qemu-action@v2 30 | - name: Set up Docker Buildx 31 | uses: docker/setup-buildx-action@v2 32 | - name: Docker meta 33 | id: meta 34 | uses: docker/metadata-action@v4 35 | with: 36 | images: cockroachdb/activerecord_test_container 37 | labels: | 38 | org.opencontainers.image.title=Active Record CockroachDB Adapter Test Image 39 | org.opencontainers.image.vendor=Cockroach Labs Inc. 40 | org.opencontainers.image.description=Environment for running tests 41 | - name: Login to DockerHub 42 | if: github.event_name != 'pull_request' 43 | uses: docker/login-action@v2 44 | with: 45 | username: ${{ secrets.DOCKERHUB_USERNAME }} 46 | password: ${{ secrets.DOCKERHUB_TOKEN }} 47 | - name: Build and push 48 | uses: docker/build-push-action@v4 49 | with: 50 | context: . 51 | file: build/Dockerfile 52 | platforms: linux/amd64,linux/arm64 53 | push: ${{ github.event_name != 'pull_request' }} 54 | tags: ${{ steps.meta.outputs.tags }} 55 | labels: ${{ steps.meta.outputs.labels }} 56 | cache-from: type=gha 57 | cache-to: type=gha,mode=max 58 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /Gemfile.lock 4 | /_yardoc/ 5 | /coverage/ 6 | /doc/ 7 | /pkg/ 8 | /spec/reports/ 9 | /tmp/ 10 | *.gem 11 | /debug.log 12 | /cockroach-url 13 | /cockroach-data/ 14 | /cockroach-*.linux-amd64/ 15 | /docker_root/ 16 | /ruby-build/ 17 | /test/db/ 18 | /.ruby-version 19 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cockroachdb/activerecord-cockroachdb-adapter/b010da133fb9c17811a4ee8f08f2044015639b9d/.gitmodules -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | gemspec 6 | 7 | 8 | module RailsTag 9 | class << self 10 | def call 11 | req = gemspec_requirement 12 | "v" + all_activerecord_versions.find { req.satisfied_by?(_1) }.version 13 | rescue => e 14 | warn "Unable to determine Rails version. Using last used. Error: #{e.message}" 15 | lockfile = File.expand_path("Gemfile.lock", __dir__) 16 | File.foreach(lockfile, chomp: true).find { _1[/tag: (.*)$/] } 17 | Regexp.last_match(1) 18 | end 19 | 20 | def gemspec_requirement 21 | File 22 | .foreach(File.expand_path("activerecord-cockroachdb-adapter.gemspec", __dir__), chomp: true) 23 | .find { _1[/add_dependency\s.activerecord.,\s.(.*)./] } 24 | 25 | Gem::Requirement.new(Regexp.last_match(1)) 26 | end 27 | 28 | def all_activerecord_versions 29 | require 'net/http' 30 | require 'yaml' 31 | 32 | uri = URI.parse "https://rubygems.org/api/v1/versions/activerecord.yaml" 33 | http = Net::HTTP.new(uri.host, uri.port) 34 | http.use_ssl = true 35 | http.verify_mode = OpenSSL::SSL::VERIFY_NONE 36 | 37 | YAML.load( 38 | http.request(Net::HTTP::Get.new(uri.request_uri)).body 39 | ).map { Gem::Version.new(_1["number"]) } 40 | end 41 | end 42 | end 43 | 44 | 45 | group :development, :test do 46 | # We need to load the gem from git to have access to activerecord's test files. 47 | # You can use `path: "some/local/rails"` if you want to test the gem against 48 | # a specific rails codebase. 49 | gem "rails", github: "rails/rails", tag: RailsTag.call 50 | 51 | # Needed for the test suite 52 | gem "msgpack", ">= 1.7.0" 53 | gem "mutex_m", "~> 0.2.0" 54 | 55 | gem "rake" 56 | gem "debug" 57 | gem "minitest-excludes", "~> 2.0.1" 58 | gem "minitest-github_action_reporter", github: "BuonOmo/minitest-github_action_reporter", require: "minitest/github_action_reporter_plugin" 59 | gem "ostruct", "~> 0.6" 60 | 61 | # Gems used for tests meta-programming. 62 | gem "parser" 63 | gem "prism" # Parser is being softly deprecated, but Prism doesn't have rewriting capabilities 64 | 65 | # Gems used by the ActiveRecord test suite 66 | gem "bcrypt", "~> 3.1" 67 | gem "sqlite3", "~> 2.1" 68 | 69 | gem "minitest", "~> 5.15" 70 | end 71 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | require "rake/testtask" 3 | require_relative 'test/support/paths_cockroachdb' 4 | require_relative 'test/support/rake_helpers' 5 | require_relative 'test/support/template_creator' 6 | 7 | task default: [:test] 8 | 9 | namespace :db do 10 | task "create_test_template" do 11 | ENV['DEBUG_COCKROACHDB_ADAPTER'] = "1" 12 | ENV['COCKROACH_SKIP_LOAD_SCHEMA'] = "1" 13 | 14 | TemplateCreator.connect 15 | require_relative 'test/cases/helper' 16 | 17 | # TODO: look into this more, but for some reason the blob alias 18 | # is not defined while running this task. 19 | ActiveRecord::ConnectionAdapters::CockroachDB::TableDefinition.class_eval do 20 | alias :blob :binary 21 | end 22 | 23 | TemplateCreator.create_test_template 24 | end 25 | end 26 | 27 | Rake::TestTask.new do |t| 28 | t.libs = ARTest::CockroachDB.test_load_paths 29 | t.test_files = RakeHelpers.test_files 30 | t.warning = !!ENV["WARNING"] 31 | t.verbose = false 32 | end 33 | -------------------------------------------------------------------------------- /activerecord-cockroachdb-adapter.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative 'lib/version' 4 | version = ActiveRecord::COCKROACH_DB_ADAPTER_VERSION 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = "activerecord-cockroachdb-adapter" 8 | spec.version = version 9 | spec.licenses = ["Apache-2.0"] 10 | spec.authors = ["Cockroach Labs"] 11 | spec.email = ["cockroach-db@googlegroups.com"] 12 | 13 | spec.summary = "CockroachDB adapter for ActiveRecord." 14 | spec.description = "Allows the use of CockroachDB as a backend for ActiveRecord and Rails apps." 15 | spec.homepage = "https://github.com/cockroachdb/activerecord-cockroachdb-adapter" 16 | 17 | spec.add_dependency "activerecord", "~> 8.0.0" 18 | spec.add_dependency "pg", "~> 1.5" 19 | spec.add_dependency "rgeo-activerecord", "~> 8.0.0" 20 | 21 | spec.add_development_dependency "benchmark-ips", "~> 2.9.1" 22 | 23 | # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host' 24 | # to allow pushing to a single host or delete this section to allow pushing to any host. 25 | if spec.respond_to?(:metadata) 26 | spec.metadata['allowed_push_host'] = "https://rubygems.org" 27 | else 28 | raise "RubyGems 2.0 or newer is required to protect against " \ 29 | "public gem pushes." 30 | end 31 | 32 | spec.files = `git ls-files -z`.split("\x0").reject do |f| 33 | f.match(%r{^(test|spec|features)/}) 34 | end 35 | spec.bindir = "exe" 36 | spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } 37 | spec.require_paths = ["lib"] 38 | end 39 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | $:.unshift(File.expand_path("../lib", __dir__)) 4 | 5 | # require "bundler/setup" 6 | # Bundler.require :development 7 | 8 | require "activerecord-cockroachdb-adapter" 9 | # This allows playing with the rake task as well. Ex: 10 | # 11 | # ActiveRecord::Tasks::DatabaseTasks. 12 | # structure_load(Post.connection_db_config, "awesome-file.sql") 13 | require "active_record/connection_adapters/cockroachdb/database_tasks" 14 | 15 | DB_NAME = "ar_crdb_console" 16 | 17 | schema_kind = ENV.fetch("SCHEMA_KIND", ENV.fetch("SCHEMA", "default")) 18 | 19 | system("cockroach sql --insecure --host=localhost:26257 --execute='drop database if exists #{DB_NAME}'", 20 | exception: true) 21 | system("cockroach sql --insecure --host=localhost:26257 --execute='create database #{DB_NAME}'", 22 | exception: true) 23 | 24 | ActiveRecord::Base.establish_connection( 25 | #Alternative version: "cockroachdb://root@localhost:26257/#{DB_NAME}" 26 | adapter: "cockroachdb", 27 | host: "localhost", 28 | port: 26257, 29 | user: "root", 30 | database: DB_NAME 31 | ) 32 | 33 | load "#{__dir__}/console_schemas/#{schema_kind}.rb" 34 | 35 | require "irb" 36 | IRB.start(__FILE__) 37 | -------------------------------------------------------------------------------- /bin/console_schemas/default.rb: -------------------------------------------------------------------------------- 1 | class Post < ActiveRecord::Base 2 | end 3 | 4 | ActiveRecord::Schema.define do 5 | create_table("posts") do |t| 6 | t.string :title 7 | t.text :body 8 | end 9 | 10 | add_index("posts", ["title"], name: "index_posts_on_title", unique: true) 11 | end 12 | -------------------------------------------------------------------------------- /bin/console_schemas/schemas.rb: -------------------------------------------------------------------------------- 1 | class Post < ActiveRecord::Base 2 | self.table_name = "bar.posts" 3 | end 4 | 5 | class Comment < ActiveRecord::Base 6 | self.table_name = "foo.comments" 7 | end 8 | 9 | ActiveRecord::Schema.define do 10 | create_schema("foo") 11 | create_schema("bar") 12 | create_table("bar.posts") do |t| 13 | t.string :title 14 | t.text :body 15 | end 16 | 17 | create_table("foo.comments") do |t| 18 | t.integer :post_id 19 | t.text :body 20 | end 21 | 22 | add_foreign_key "foo.comments", "bar.posts", column: "post_id" 23 | end 24 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | set -vx 5 | 6 | bundle install 7 | 8 | # Do any other automated setup that you need to do here 9 | -------------------------------------------------------------------------------- /bin/start-cockroachdb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zsh 2 | 3 | set -eu 4 | 5 | die() { echo "$0: $*" 1>&2 ; false; } 6 | 7 | root_dir="$(dirname $(dirname "$0:A"))" 8 | pid_file="$root_dir/tmp/cockroach.pid" 9 | log_file="$root_dir/tmp/cockroachdb.log" 10 | 11 | mkdir -p "$root_dir/tmp" 12 | [[ -f "$pid_file" ]] && kill -9 $(cat "$pid_file") || true 13 | rm -f "$pid_file" 14 | 15 | if ! (( ${+commands[cockroach]} )); then 16 | die 'the `cockroach` toolchain is not installed. 17 | See https://www.cockroachlabs.com/docs/stable/install-cockroachdb.html' 18 | fi 19 | 20 | cockroach start-single-node \ 21 | --insecure --store=type=mem,size=0.25 --advertise-addr=localhost \ 22 | --spatial-libs="$(geos-config --includes)" \ 23 | --pid-file "$pid_file" \ 24 | &> "$log_file" & 25 | 26 | until [[ -f "$pid_file" ]]; do 27 | sleep 1 28 | done 29 | 30 | 31 | cat "$root_dir/setup.sql" | cockroach sql --insecure --host=localhost:26257 > /dev/null 32 | 33 | echo "CockroachDB started. PID: $(cat "$pid_file"). log: $log_file" 34 | -------------------------------------------------------------------------------- /build/Dockerfile: -------------------------------------------------------------------------------- 1 | # This Dockerfile extends the Examples-ORM testing image in order to 2 | # install specific dependencies required for ActiveRecord tests. 3 | 4 | FROM us-east1-docker.pkg.dev/crl-ci-images/cockroach/example-orms-builder:20200413-1918 5 | 6 | # Native dependencies for libxml-ruby and sqlite3. 7 | RUN apt-get --allow-releaseinfo-change update -y && apt-get install -y \ 8 | libxslt-dev \ 9 | libxml2-dev \ 10 | libsqlite3-dev \ 11 | rbenv \ 12 | && rm -rf /var/lib/apt/lists/* 13 | 14 | RUN rm -rf ~/ruby-build; git clone https://github.com/sstephenson/ruby-build.git ~/ruby-build; sh ~/ruby-build/install.sh 15 | -------------------------------------------------------------------------------- /build/config.teamcity.yml: -------------------------------------------------------------------------------- 1 | default_connection: cockroachdb 2 | 3 | with_manual_interventions: false 4 | 5 | connections: 6 | cockroachdb: 7 | arunit: 8 | database: activerecord_unittest 9 | host: localhost 10 | port: 26257 11 | user: root 12 | requiressl: disable 13 | min_messages: warning 14 | disable_cockroachdb_telemetry: true 15 | arunit_without_prepared_statements: 16 | database: activerecord_unittest 17 | host: localhost 18 | port: 26257 19 | user: root 20 | requiressl: disable 21 | min_messages: warning 22 | prepared_statements: false 23 | disable_cockroachdb_telemetry: true 24 | arunit2: 25 | database: activerecord_unittest2 26 | host: localhost 27 | port: 26257 28 | user: root 29 | requiressl: disable 30 | min_messages: warning 31 | disable_cockroachdb_telemetry: true 32 | -------------------------------------------------------------------------------- /build/local-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | readonly urlfile=cockroach-url 6 | 7 | # Start a CockroachDB server, wait for it to become ready, and arrange for it to 8 | # be force-killed when the script exits. 9 | rm -f "$urlfile" 10 | # Clean out a past CockroachDB instance. This happens if a build was 11 | # canceled on an agent. 12 | rm -rf $HOME/tmp/rails & 13 | # Start CockroachDB. 14 | cockroach start --insecure --host=localhost --listening-url-file="$urlfile" --store=path=$HOME/tmp/rails & 15 | trap "echo 'Exit routine: Killing CockroachDB.' && kill -9 $! &> /dev/null" EXIT 16 | for i in {0..3} 17 | do 18 | [[ -f "$urlfile" ]] && break 19 | backoff=$((2 ** i)) 20 | echo "server not yet available; sleeping for $backoff seconds" 21 | sleep $backoff 22 | done 23 | 24 | # Target the Rails dependency file. 25 | export BUNDLE_GEMFILE=$(pwd)/rails/Gemfile 26 | 27 | # Run the tests. 28 | cp build/config.teamcity.yml rails/activerecord/test/config.yml 29 | echo "Rebuilding database" 30 | (cd rails/activerecord && bundle exec rake db:cockroachdb:rebuild) 31 | echo "Starting tests" 32 | (cd rails/activerecord && bundle exec rake test:cockroachdb TESTFILES=$1) 33 | -------------------------------------------------------------------------------- /build/teamcity-test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euox pipefail 4 | 5 | eval "$(rbenv init -)" 6 | 7 | rbenv install --skip-existing --verbose 8 | 9 | rbenv rehash 10 | 11 | ruby -v 12 | 13 | # Download CockroachDB 14 | VERSION=v23.1.2 15 | wget -qO- https://binaries.cockroachdb.com/cockroach-$VERSION.linux-amd64.tgz | tar xvz 16 | readonly COCKROACH=./cockroach-$VERSION.linux-amd64/cockroach 17 | 18 | # Make sure cockroach can be found on the path. This is required for the 19 | # ActiveRecord Rakefile that rebuilds the test database. 20 | export PATH=./cockroach-$VERSION.linux-amd64/:$PATH 21 | readonly urlfile=cockroach-url 22 | 23 | run_cockroach() { 24 | # Start a CockroachDB server, wait for it to become ready, and arrange 25 | # for it to be force-killed when the script exits. 26 | rm -f "$urlfile" 27 | rm -rf cockroach-data 28 | # Start CockroachDB. 29 | cockroach start-single-node --max-sql-memory=25% --cache=25% --insecure --host=localhost --spatial-libs=./cockroach-$VERSION.linux-amd64/lib --listening-url-file="$urlfile" >/dev/null 2>&1 & 30 | # Ensure CockroachDB is stopped on script exit. 31 | trap "echo 'Exit routine: Killing CockroachDB.' && kill -9 $! &> /dev/null" EXIT 32 | # Wait until CockroachDB has started. 33 | for i in {0..3}; do 34 | [[ -f "$urlfile" ]] && break 35 | backoff=$((2 ** i)) 36 | echo "server not yet available; sleeping for $backoff seconds" 37 | sleep $backoff 38 | done 39 | cockroach sql --insecure -e 'CREATE DATABASE activerecord_unittest;' 40 | cockroach sql --insecure -e 'CREATE DATABASE activerecord_unittest2;' 41 | cockroach sql --insecure -e 'SET CLUSTER SETTING sql.stats.automatic_collection.enabled = false;' 42 | cockroach sql --insecure -e 'SET CLUSTER SETTING sql.stats.histogram_collection.enabled = false;' 43 | cockroach sql --insecure -e "SET CLUSTER SETTING jobs.retention_time = '180s';" 44 | cockroach sql --insecure -e "SET CLUSTER SETTING sql.defaults.experimental_alter_column_type.enabled = 'true'" 45 | 46 | cockroach sql --insecure -e "ALTER RANGE default CONFIGURE ZONE USING num_replicas = 1, gc.ttlseconds = 30;" 47 | cockroach sql --insecure -e "ALTER TABLE system.public.jobs CONFIGURE ZONE USING num_replicas = 1, gc.ttlseconds = 30;" 48 | cockroach sql --insecure -e "ALTER RANGE meta CONFIGURE ZONE USING num_replicas = 1, gc.ttlseconds = 30;" 49 | cockroach sql --insecure -e "ALTER RANGE system CONFIGURE ZONE USING num_replicas = 1, gc.ttlseconds = 30;" 50 | cockroach sql --insecure -e "ALTER RANGE liveness CONFIGURE ZONE USING num_replicas = 1, gc.ttlseconds = 30;" 51 | 52 | cockroach sql --insecure -e "SET CLUSTER SETTING kv.range_merge.queue_interval = '50ms'" 53 | cockroach sql --insecure -e "SET CLUSTER SETTING kv.raft_log.disable_synchronization_unsafe = 'true'" 54 | cockroach sql --insecure -e "SET CLUSTER SETTING jobs.registry.interval.cancel = '180s';" 55 | cockroach sql --insecure -e "SET CLUSTER SETTING jobs.registry.interval.gc = '30s';" 56 | cockroach sql --insecure -e "SET CLUSTER SETTING kv.range_split.by_load_merge_delay = '5s';" 57 | 58 | # Enable experimental features. 59 | cockroach sql --insecure -e "SET CLUSTER SETTING sql.defaults.experimental_temporary_tables.enabled = 'true';" 60 | } 61 | 62 | gem env 63 | 64 | # Install ruby dependencies. 65 | gem install bundler:2.4.9 rake:13.0.6 66 | 67 | bundle install 68 | 69 | run_cockroach 70 | 71 | if ! (RUBYOPT="-W0" TESTOPTS="-v" bundle exec rake test); then 72 | echo "Tests failed" 73 | exit 1 74 | fi 75 | 76 | echo "Tests passed" 77 | -------------------------------------------------------------------------------- /docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # This file is largely cargo-culted from cockroachdb/cockroach/build/builder.sh. 4 | 5 | set -euox pipefail 6 | 7 | DOCKER_IMAGE_TAG=cockroachdb/activerecord_test_container:master 8 | 9 | # Absolute path to this repository. 10 | repo_root=$(cd "$(dirname "${0}")" && pwd) 11 | 12 | # Make a fake passwd file for the invoking user. 13 | # 14 | # This setup is so that files created from inside the container in a mounted 15 | # volume end up being owned by the invoking user and not by root. 16 | # We'll mount a fresh directory owned by the invoking user as /root inside the 17 | # container because the container needs a $HOME (without one the default is /) 18 | # and because various utilities (e.g. bash writing to .bash_history) need to be 19 | # able to write to there. 20 | username=$(id -un) 21 | uid_gid=$(id -u):$(id -g) 22 | container_root=${repo_root}/docker_root 23 | mkdir -p "${container_root}"/{etc,home,home/"${username}"/activerecord-cockroachdb-adapter,home/.gems} 24 | echo "${username}:x:${uid_gid}::/home/${username}:/bin/bash" > "${container_root}/etc/passwd" 25 | 26 | exec docker run \ 27 | --volume="${container_root}/etc/passwd:/etc/passwd" \ 28 | --volume="${container_root}/home/${username}:/home/${username}" \ 29 | --volume="${repo_root}:/home/${username}/activerecord-cockroachdb-adapter" \ 30 | --workdir="/home/${username}/activerecord-cockroachdb-adapter" \ 31 | --env=PIP_USER=1 \ 32 | --env=GEM_HOME="/home/${username}/.gems" \ 33 | --user="${uid_gid}" \ 34 | "${DOCKER_IMAGE_TAG}" \ 35 | "$@" 36 | -------------------------------------------------------------------------------- /lib/active_record/connection_adapters/cockroachdb/arel_tosql.rb: -------------------------------------------------------------------------------- 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 | 17 | module RGeo 18 | module ActiveRecord 19 | ## 20 | # Extend rgeo-activerecord visitors to use PostGIS specific functionality 21 | module SpatialToPostGISSql 22 | def visit_in_spatial_context(node, collector) 23 | # Use ST_GeomFromEWKT for EWKT geometries 24 | if node.is_a?(String) && node =~ /SRID=[\d+]{0,};/ 25 | collector << "#{st_func('ST_GeomFromEWKT')}(#{quote(node)})" 26 | else 27 | super(node, collector) 28 | end 29 | end 30 | end 31 | end 32 | end 33 | RGeo::ActiveRecord::SpatialToSql.prepend RGeo::ActiveRecord::SpatialToPostGISSql 34 | 35 | module Arel # :nodoc: 36 | module Visitors # :nodoc: 37 | class CockroachDB < PostgreSQL # :nodoc: 38 | include RGeo::ActiveRecord::SpatialToSql 39 | 40 | def visit_Arel_Nodes_JoinSource(o, collector) 41 | super 42 | if o.aost 43 | collector << " AS OF SYSTEM TIME '#{o.aost.iso8601}'" 44 | end 45 | collector 46 | end 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /lib/active_record/connection_adapters/cockroachdb/attribute_methods.rb: -------------------------------------------------------------------------------- 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 | 17 | module ActiveRecord 18 | module CockroachDB 19 | module AttributeMethodsMonkeyPatch 20 | 21 | private 22 | 23 | # Filter out rowid so it doesn't get inserted by ActiveRecord. rowid is a 24 | # column added by CockroachDB for tables that don't define primary keys. 25 | # CockroachDB will automatically insert rowid values. See 26 | # https://www.cockroachlabs.com/docs/v19.2/create-table.html#create-a-table. 27 | def attributes_for_create(attribute_names) 28 | super.reject { |name| name == ConnectionAdapters::CockroachDBAdapter::DEFAULT_PRIMARY_KEY } 29 | end 30 | 31 | # Filter out rowid so it doesn't get updated by ActiveRecord. rowid is a 32 | # column added by CockroachDB for tables that don't define primary keys. 33 | # CockroachDB will automatically insert rowid values. See 34 | # https://www.cockroachlabs.com/docs/v19.2/create-table.html#create-a-table. 35 | def attributes_for_update(attribute_names) 36 | super.reject { |name| name == ConnectionAdapters::CockroachDBAdapter::DEFAULT_PRIMARY_KEY } 37 | end 38 | end 39 | end 40 | 41 | class Base 42 | prepend CockroachDB::AttributeMethodsMonkeyPatch 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /lib/active_record/connection_adapters/cockroachdb/column_methods.rb: -------------------------------------------------------------------------------- 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 | 17 | module ActiveRecord 18 | module ConnectionAdapters 19 | module CockroachDB 20 | module ColumnMethods 21 | def spatial(name, options = {}) 22 | raise "You must set a type. For example: 't.spatial type: :st_point'" unless options[:type] 23 | 24 | column(name, options[:type], **options) 25 | end 26 | 27 | def geography(name, options = {}) 28 | column(name, :geography, **options) 29 | end 30 | 31 | def geometry(name, options = {}) 32 | column(name, :geometry, **options) 33 | end 34 | 35 | def geometry_collection(name, options = {}) 36 | column(name, :geometry_collection, **options) 37 | end 38 | 39 | def line_string(name, options = {}) 40 | column(name, :line_string, **options) 41 | end 42 | 43 | def multi_line_string(name, options = {}) 44 | column(name, :multi_line_string, **options) 45 | end 46 | 47 | def multi_point(name, options = {}) 48 | column(name, :multi_point, **options) 49 | end 50 | 51 | def multi_polygon(name, options = {}) 52 | column(name, :multi_polygon, **options) 53 | end 54 | 55 | def st_point(name, options = {}) 56 | column(name, :st_point, **options) 57 | end 58 | 59 | def st_polygon(name, options = {}) 60 | column(name, :st_polygon, **options) 61 | end 62 | 63 | private 64 | 65 | def valid_column_definition_options 66 | spatial = [:srid, :has_z, :has_m, :geographic, :spatial_type] 67 | crdb = [:hidden] 68 | super + spatial + crdb 69 | end 70 | end 71 | end 72 | 73 | PostgreSQL::Table.include CockroachDB::ColumnMethods 74 | end 75 | end 76 | -------------------------------------------------------------------------------- /lib/active_record/connection_adapters/cockroachdb/database_statements.rb: -------------------------------------------------------------------------------- 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 | 17 | module ActiveRecord 18 | module ConnectionAdapters 19 | module CockroachDB 20 | module DatabaseStatements 21 | # Overridden to avoid using transactions for schema creation. 22 | def insert_fixtures_set(fixture_set, tables_to_delete = []) 23 | fixture_inserts = build_fixture_statements(fixture_set) 24 | table_deletes = tables_to_delete.map { |table| "DELETE FROM #{quote_table_name(table)}" } 25 | statements = table_deletes + fixture_inserts 26 | 27 | begin # much faster without disabling referential integrity, worth trying. 28 | transaction(requires_new: true) do 29 | execute_batch(statements, "Fixtures Load") 30 | end 31 | rescue 32 | disable_referential_integrity do 33 | execute_batch(statements, "Fixtures Load") 34 | end 35 | end 36 | end 37 | end 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /lib/active_record/connection_adapters/cockroachdb/oid/date_time.rb: -------------------------------------------------------------------------------- 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 | 17 | module ActiveRecord 18 | module ConnectionAdapters 19 | module CockroachDB 20 | module OID 21 | module DateTime 22 | protected 23 | 24 | # override 25 | # Uses CockroachDBAdapter instead of PostgreSQLAdapter 26 | def real_type_unless_aliased(real_type) 27 | ActiveRecord::ConnectionAdapters::CockroachDBAdapter.datetime_type == real_type ? :datetime : real_type 28 | end 29 | end 30 | 31 | PostgreSQL::OID::DateTime.prepend(DateTime) 32 | end 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /lib/active_record/connection_adapters/cockroachdb/quoting.rb: -------------------------------------------------------------------------------- 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 | 17 | module ActiveRecord 18 | module ConnectionAdapters 19 | module CockroachDB 20 | module Quoting 21 | # CockroachDB does not allow inserting integer values into string 22 | # columns, but ActiveRecord expects this to work. CockroachDB will 23 | # however allow inserting string values into integer columns. It will 24 | # try to parse string values and convert them to integers so they can be 25 | # inserted in integer columns. 26 | # 27 | # We take advantage of this behavior here by forcing numeric values to 28 | # always be strings. Then, we won't have to make any additional changes 29 | # to ActiveRecord to support inserting integer values into string 30 | # columns. 31 | # 32 | # For spatial types, data is stored as Well-known Binary (WKB) strings 33 | # (https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry#Well-known_binary) 34 | # but when creating objects, using RGeo features is more convenient than 35 | # converting to WKB, so this does it automatically. 36 | def quote(value) 37 | if value.is_a?(Numeric) 38 | # NOTE: The fact that integers are quoted is important and helps 39 | # mitigate a potential vulnerability. 40 | # 41 | # See 42 | # - https://nvd.nist.gov/vuln/detail/CVE-2022-44566 43 | # - https://github.com/cockroachdb/activerecord-cockroachdb-adapter/pull/280#discussion_r1288692977 44 | "'#{quote_string(value.to_s)}'" 45 | elsif RGeo::Feature::Geometry.check_type(value) 46 | "'#{RGeo::WKRep::WKBGenerator.new(hex_format: true, type_format: :ewkb, emit_ewkb_srid: true).generate(value)}'" 47 | elsif value.is_a?(RGeo::Cartesian::BoundingBox) 48 | "'#{value.min_x},#{value.min_y},#{value.max_x},#{value.max_y}'::box" 49 | else 50 | super 51 | end 52 | end 53 | 54 | def quoted_date(value) 55 | # CockroachDB differs from PostgreSQL in its representation of 56 | # a `timestamp with timezone`, it does not always include the 57 | # timezone offset (e.g. `+00`), so we need to add it here. 58 | # This is tested by `BasicsTest#test_default_in_local_time`. 59 | super + value.strftime("%z") 60 | end 61 | end 62 | end 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /lib/active_record/connection_adapters/cockroachdb/schema_creation.rb: -------------------------------------------------------------------------------- 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 | 17 | module ActiveRecord 18 | module ConnectionAdapters 19 | module CockroachDB 20 | class SchemaCreation < PostgreSQL::SchemaCreation # :nodoc: 21 | private 22 | def add_column_options!(sql, options) 23 | if options[:hidden] 24 | sql << " NOT VISIBLE" 25 | end 26 | super 27 | end 28 | end 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/active_record/connection_adapters/cockroachdb/schema_dumper.rb: -------------------------------------------------------------------------------- 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 | 17 | module ActiveRecord 18 | module ConnectionAdapters 19 | module CockroachDB 20 | class SchemaDumper < ConnectionAdapters::PostgreSQL::SchemaDumper # :nodoc: 21 | private 22 | def prepare_column_options(column) 23 | spec = super 24 | if column.hidden? 25 | spec[:hidden] = true 26 | end 27 | spec 28 | end 29 | end 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/active_record/connection_adapters/cockroachdb/setup.rb: -------------------------------------------------------------------------------- 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 | 17 | module ActiveRecord # :nodoc: 18 | module ConnectionAdapters # :nodoc: 19 | module CockroachDB # :nodoc: 20 | def self.initial_setup 21 | ::ActiveRecord::SchemaDumper.ignore_tables |= %w[ 22 | geography_columns 23 | geometry_columns 24 | layer 25 | raster_columns 26 | raster_overviews 27 | spatial_ref_sys 28 | topology 29 | ] 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /lib/active_record/connection_adapters/cockroachdb/spatial_column_info.rb: -------------------------------------------------------------------------------- 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 | 17 | module ActiveRecord 18 | module ConnectionAdapters 19 | module CockroachDB 20 | class SpatialColumnInfo 21 | def initialize(adapter, table_name) 22 | @adapter = adapter 23 | @table_name = table_name 24 | end 25 | 26 | def all 27 | info = @adapter.query( 28 | "SELECT f_geometry_column,coord_dimension,srid,type FROM geometry_columns WHERE f_table_name='#{@table_name}'" 29 | ) 30 | result = {} 31 | info.each do |row| 32 | name = row[0] 33 | type = row[3] 34 | dimension = row[1].to_i 35 | has_m = !!(type =~ /m$/i) 36 | type.sub!(/m$/, '') 37 | has_z = dimension > 3 || dimension == 3 && !has_m 38 | result[name] = { 39 | dimension: dimension, 40 | has_m: has_m, 41 | has_z: has_z, 42 | name: name, 43 | srid: row[2].to_i, 44 | type: type 45 | } 46 | end 47 | result 48 | end 49 | 50 | # do not query the database for non-spatial columns/tables 51 | def get(column_name, type) 52 | return unless CockroachDBAdapter.spatial_column_options(type.to_sym) 53 | 54 | @spatial_column_info ||= all 55 | @spatial_column_info[column_name] 56 | end 57 | end 58 | end 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /lib/active_record/connection_adapters/cockroachdb/table_definition.rb: -------------------------------------------------------------------------------- 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 | 17 | module ActiveRecord # :nodoc: 18 | module ConnectionAdapters # :nodoc: 19 | module CockroachDB # :nodoc: 20 | class TableDefinition < PostgreSQL::TableDefinition # :nodoc: 21 | include ColumnMethods 22 | 23 | # Support for spatial columns in tables 24 | # super: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb 25 | def new_column_definition(name, type, **options) 26 | if (info = CockroachDBAdapter.spatial_column_options(type.to_sym)) 27 | if (limit = options.delete(:limit)) && limit.is_a?(::Hash) 28 | options.merge!(limit) 29 | end 30 | 31 | geo_type = ColumnDefinitionUtils.geo_type(options[:type] || type || info[:type]) 32 | base_type = info[:type] || (options[:geographic] ? :geography : :geometry) 33 | 34 | options[:limit] = ColumnDefinitionUtils.limit_from_options(geo_type, options) 35 | options[:spatial_type] = geo_type 36 | column = super(name, base_type, **options) 37 | else 38 | column = super(name, type, **options) 39 | end 40 | 41 | column 42 | end 43 | end 44 | 45 | module ColumnDefinitionUtils 46 | class << self 47 | def geo_type(type = 'GEOMETRY') 48 | g_type = type.to_s.delete('_').upcase 49 | return 'POINT' if g_type == 'STPOINT' 50 | return 'POLYGON' if g_type == 'STPOLYGON' 51 | 52 | g_type 53 | end 54 | 55 | def limit_from_options(type, options = {}) 56 | spatial_type = geo_type(type) 57 | spatial_type << 'Z' if options[:has_z] 58 | spatial_type << 'M' if options[:has_m] 59 | spatial_type << ",#{options[:srid] || default_srid(options)}" 60 | spatial_type 61 | end 62 | 63 | def default_srid(options) 64 | options[:geographic] ? 4326 : CockroachDBAdapter::DEFAULT_SRID 65 | end 66 | end 67 | end 68 | end 69 | end 70 | end 71 | -------------------------------------------------------------------------------- /lib/active_record/connection_adapters/cockroachdb/type.rb: -------------------------------------------------------------------------------- 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 | 17 | module ActiveRecord 18 | module Type 19 | module CRDBExt 20 | # Return :postgresql instead of :cockroachdb for current_adapter_name so 21 | # we can continue using the ActiveRecord::Types defined in 22 | # PostgreSQLAdapter. 23 | def adapter_name_from(model) 24 | name = super 25 | return :postgresql if name == :cockroachdb 26 | 27 | name 28 | end 29 | end 30 | singleton_class.prepend CRDBExt 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/active_record/migration/cockroachdb/compatibility.rb: -------------------------------------------------------------------------------- 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 | 17 | require "active_record/migration" 18 | require "active_record/migration/compatibility" 19 | 20 | module ActiveRecord 21 | class Migration 22 | module CockroachDB 23 | module Compatibility 24 | module V7_0Patch 25 | # Override. Use "CockroachDB" instead of "PostgreSQL" 26 | def compatible_timestamp_type(type, connection) 27 | if connection.adapter_name == "CockroachDB" 28 | # For Rails <= 6.1, :datetime was aliased to :timestamp 29 | # See: https://github.com/rails/rails/blob/v6.1.3.2/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L108 30 | # From Rails 7 onwards, you can define what :datetime resolves to (the default is still :timestamp) 31 | # See `ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.datetime_type` 32 | type.to_sym == :datetime ? :timestamp : type 33 | else 34 | type 35 | end 36 | end 37 | end 38 | end 39 | end 40 | end 41 | end 42 | 43 | prepend_mod = ActiveRecord::Migration::CockroachDB::Compatibility::V7_0Patch 44 | ActiveRecord::Migration::Compatibility::V6_1::PostgreSQLCompat.singleton_class.prepend(prepend_mod) 45 | -------------------------------------------------------------------------------- /lib/activerecord-cockroachdb-adapter.rb: -------------------------------------------------------------------------------- 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 | 17 | if defined?(Rails::Railtie) 18 | module ActiveRecord 19 | module ConnectionAdapters 20 | class CockroachDBRailtie < ::Rails::Railtie 21 | rake_tasks do 22 | load "active_record/connection_adapters/cockroachdb/database_tasks.rb" 23 | end 24 | end 25 | end 26 | end 27 | end 28 | 29 | require "active_record" 30 | require "active_record/connection_adapters" 31 | 32 | ActiveRecord::ConnectionAdapters.register "cockroachdb", "ActiveRecord::ConnectionAdapters::CockroachDBAdapter", "active_record/connection_adapters/cockroachdb_adapter" 33 | -------------------------------------------------------------------------------- /lib/arel/nodes/join_source_ext.rb: -------------------------------------------------------------------------------- 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 | 17 | module Arel 18 | module Nodes 19 | module JoinSourceExt 20 | def initialize(...) 21 | super 22 | @aost = nil 23 | end 24 | 25 | def hash 26 | [*super, aost].hash 27 | end 28 | 29 | def eql?(other) 30 | super && aost == other.aost 31 | end 32 | alias_method :==, :eql? 33 | end 34 | JoinSource.attr_accessor :aost 35 | JoinSource.prepend JoinSourceExt 36 | end 37 | module SelectManagerExt 38 | def aost(time) 39 | @ctx.source.aost = time 40 | nil 41 | end 42 | end 43 | SelectManager.prepend SelectManagerExt 44 | end 45 | -------------------------------------------------------------------------------- /lib/version.rb: -------------------------------------------------------------------------------- 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 | 17 | module ActiveRecord 18 | COCKROACH_DB_ADAPTER_VERSION = "8.0.1" 19 | end 20 | -------------------------------------------------------------------------------- /setup.sql: -------------------------------------------------------------------------------- 1 | -- https://www.cockroachlabs.com/docs/stable/local-testing.html 2 | SET CLUSTER SETTING kv.range_merge.queue_interval = '50ms'; 3 | SET CLUSTER SETTING jobs.registry.interval.gc = '30s'; 4 | SET CLUSTER SETTING jobs.registry.interval.cancel = '180s'; 5 | SET CLUSTER SETTING jobs.retention_time = '15s'; 6 | SET CLUSTER SETTING sql.stats.automatic_collection.enabled = false; 7 | SET CLUSTER SETTING kv.range_split.by_load_merge_delay = '5s'; 8 | ALTER RANGE default CONFIGURE ZONE USING "gc.ttlseconds" = 600; 9 | ALTER DATABASE system CONFIGURE ZONE USING "gc.ttlseconds" = 600; 10 | 11 | CREATE DATABASE activerecord_unittest; 12 | CREATE DATABASE activerecord_unittest2; 13 | 14 | SET CLUSTER SETTING sql.stats.automatic_collection.enabled = false; 15 | SET CLUSTER SETTING sql.stats.histogram_collection.enabled = false; 16 | 17 | SET CLUSTER SETTING sql.defaults.experimental_alter_column_type.enabled = 'true'; 18 | SET CLUSTER SETTING sql.defaults.experimental_temporary_tables.enabled = 'true'; 19 | -------------------------------------------------------------------------------- /test/cases/adapters/postgresql/active_schema_test.rb: -------------------------------------------------------------------------------- 1 | require "cases/helper_cockroachdb" 2 | 3 | module CockroachDB 4 | class PostgresqlActiveSchemaTest < ActiveRecord::PostgreSQLTestCase 5 | def setup 6 | ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.class_eval do 7 | def execute(sql, name = nil) sql end 8 | end 9 | end 10 | 11 | teardown do 12 | ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.class_eval do 13 | remove_method :execute 14 | end 15 | end 16 | 17 | # This replaces the same test that's been excluded from 18 | # PostgresqlActiveSchemaTest. It is almost exactly the same, but it excludes 19 | # assertions against partial indexes because they're not supported in 20 | # CockroachDB. 21 | # See test/excludes/PostgresqlActiveSchemaTest.rb 22 | def test_add_index 23 | # add_index calls index_name_exists? which can't work since execute is stubbed 24 | ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send(:define_method, :index_name_exists?) { |*| false } 25 | 26 | expected = %(CREATE UNIQUE INDEX "index_people_on_lower_last_name" ON "people" (lower(last_name))) 27 | assert_equal expected, add_index(:people, "lower(last_name)", unique: true) 28 | 29 | expected = %(CREATE UNIQUE INDEX "index_people_on_last_name_varchar_pattern_ops" ON "people" (last_name varchar_pattern_ops)) 30 | assert_equal expected, add_index(:people, "last_name varchar_pattern_ops", unique: true) 31 | 32 | expected = %(CREATE INDEX CONCURRENTLY "index_people_on_last_name" ON "people" ("last_name")) 33 | assert_equal expected, add_index(:people, :last_name, algorithm: :concurrently) 34 | 35 | expected = %(CREATE INDEX "index_people_on_last_name_and_first_name" ON "people" ("last_name" DESC, "first_name" ASC)) 36 | assert_equal expected, add_index(:people, [:last_name, :first_name], order: { last_name: :desc, first_name: :asc }) 37 | assert_equal expected, add_index(:people, ["last_name", :first_name], order: { last_name: :desc, "first_name" => :asc }) 38 | 39 | %w(gin gist hash btree).each do |type| 40 | expected = %(CREATE INDEX "index_people_on_last_name" ON "people" USING #{type} ("last_name")) 41 | assert_equal expected, add_index(:people, :last_name, using: type) 42 | 43 | expected = %(CREATE INDEX CONCURRENTLY "index_people_on_last_name" ON "people" USING #{type} ("last_name")) 44 | assert_equal expected, add_index(:people, :last_name, using: type, algorithm: :concurrently) 45 | 46 | expected = %(CREATE UNIQUE INDEX "index_people_on_lower_last_name" ON "people" USING #{type} (lower(last_name))) 47 | assert_equal expected, add_index(:people, "lower(last_name)", using: type, unique: true) 48 | end 49 | 50 | expected = %(CREATE INDEX "index_people_on_last_name" ON "people" USING gist ("last_name" bpchar_pattern_ops)) 51 | assert_equal expected, add_index(:people, :last_name, using: :gist, opclass: { last_name: :bpchar_pattern_ops }) 52 | 53 | expected = %(CREATE INDEX "index_people_on_last_name_and_first_name" ON "people" ("last_name" DESC NULLS LAST, "first_name" ASC)) 54 | assert_equal expected, add_index(:people, [:last_name, :first_name], order: { last_name: "DESC NULLS LAST", first_name: :asc }) 55 | 56 | expected = %(CREATE INDEX "index_people_on_last_name" ON "people" ("last_name" NULLS FIRST)) 57 | assert_equal expected, add_index(:people, :last_name, order: "NULLS FIRST") 58 | 59 | assert_raise ArgumentError do 60 | add_index(:people, :last_name, algorithm: :copy) 61 | end 62 | 63 | ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send :remove_method, :index_name_exists? 64 | end 65 | 66 | private 67 | def method_missing(...) 68 | ActiveRecord::Base.lease_connection.send(...) 69 | end 70 | end 71 | end 72 | -------------------------------------------------------------------------------- /test/cases/adapters/postgresql/change_schema_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "cases/helper" 4 | require "cases/helper_cockroachdb" 5 | 6 | module ActiveRecord 7 | module CockroachDB 8 | class Migration 9 | class PGChangeSchemaTest < ActiveRecord::PostgreSQLTestCase 10 | self.use_transactional_tests = false 11 | attr_reader :connection 12 | 13 | def setup 14 | super 15 | @connection = ActiveRecord::Base.lease_connection 16 | connection.create_table(:strings) do |t| 17 | t.string :somedate 18 | end 19 | end 20 | 21 | def teardown 22 | connection.drop_table :strings 23 | end 24 | 25 | def test_change_string_to_date 26 | connection.change_column :strings, :somedate, :timestamp, using: 'CAST("somedate" AS timestamp)' 27 | assert_equal :datetime, connection.columns(:strings).find { |c| c.name == "somedate" }.type 28 | end 29 | 30 | def test_change_type_with_symbol 31 | connection.change_column :strings, :somedate, :timestamp, cast_as: :timestamp 32 | assert_equal :datetime, connection.columns(:strings).find { |c| c.name == "somedate" }.type 33 | end 34 | 35 | def test_change_type_with_symbol_with_timestamptz 36 | connection.change_column :strings, :somedate, :timestamptz, cast_as: :timestamptz 37 | assert_equal :timestamptz, connection.columns(:strings).find { |c| c.name == "somedate" }.type 38 | end 39 | 40 | def test_change_type_with_symbol_using_datetime 41 | connection.change_column :strings, :somedate, :datetime, cast_as: :datetime 42 | assert_equal :datetime, connection.columns(:strings).find { |c| c.name == "somedate" }.type 43 | end 44 | 45 | def test_change_type_with_symbol_using_timestamp_with_timestamptz_as_default 46 | with_cockroachdb_datetime_type(:timestamptz) do 47 | connection.change_column :strings, :somedate, :timestamp, cast_as: :timestamp 48 | assert_equal :timestamp, connection.columns(:strings).find { |c| c.name == "somedate" }.type 49 | end 50 | end 51 | 52 | def test_change_type_with_symbol_with_timestamptz_as_default 53 | with_cockroachdb_datetime_type(:timestamptz) do 54 | connection.change_column :strings, :somedate, :timestamptz, cast_as: :timestamptz 55 | assert_equal :datetime, connection.columns(:strings).find { |c| c.name == "somedate" }.type 56 | end 57 | end 58 | 59 | def test_change_type_with_symbol_using_datetime_with_timestamptz_as_default 60 | with_cockroachdb_datetime_type(:timestamptz) do 61 | connection.change_column :strings, :somedate, :datetime, cast_as: :datetime 62 | assert_equal :datetime, connection.columns(:strings).find { |c| c.name == "somedate" }.type 63 | end 64 | end 65 | 66 | def test_change_type_with_array 67 | connection.change_column :strings, :somedate, :timestamp, array: true, cast_as: :timestamp 68 | column = connection.columns(:strings).find { |c| c.name == "somedate" } 69 | assert_equal :datetime, column.type 70 | assert_predicate column, :array? 71 | end 72 | end 73 | end 74 | end 75 | end 76 | -------------------------------------------------------------------------------- /test/cases/adapters/postgresql/connection_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "cases/helper_cockroachdb" 4 | 5 | 6 | module ActiveRecord 7 | module CockroachDB 8 | class PostgresqlConnectionTest < ActiveRecord::PostgreSQLTestCase 9 | include ConnectionHelper 10 | 11 | def test_set_session_variable_true 12 | run_without_connection do |orig_connection| 13 | ActiveRecord::Base.establish_connection(orig_connection.deep_merge(variables: { null_ordered_last: true })) 14 | set_true = ActiveRecord::Base.lease_connection.exec_query "SHOW NULL_ORDERED_LAST" 15 | assert_equal [["on"]], set_true.rows 16 | end 17 | end 18 | 19 | def test_set_session_variable_false 20 | run_without_connection do |orig_connection| 21 | ActiveRecord::Base.establish_connection(orig_connection.deep_merge(variables: { null_ordered_last: false })) 22 | set_false = ActiveRecord::Base.lease_connection.exec_query "SHOW NULL_ORDERED_LAST" 23 | assert_equal [["off"]], set_false.rows 24 | end 25 | end 26 | 27 | def test_set_session_variable_nil 28 | run_without_connection do |orig_connection| 29 | # This should be a no-op that does not raise an error 30 | assert_nothing_raised do 31 | ActiveRecord::Base.establish_connection(orig_connection.deep_merge(variables: { null_ordered_last: nil })) 32 | end 33 | end 34 | end 35 | 36 | def test_set_session_variable_default 37 | run_without_connection do |orig_connection| 38 | # This should execute a query that does not raise an error 39 | assert_nothing_raised do 40 | ActiveRecord::Base.establish_connection(orig_connection.deep_merge(variables: { null_ordered_last: :default })) 41 | end 42 | end 43 | end 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /test/cases/adapters/postgresql/nested_class_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cases/helper_cockroachdb' 4 | 5 | class NestedClassTest < ActiveRecord::PostgreSQLTestCase 6 | module Foo 7 | def self.table_name_prefix 8 | 'foo_' 9 | end 10 | 11 | class Bar < ActiveRecord::Base 12 | end 13 | end 14 | 15 | def test_nested_model 16 | Foo::Bar.lease_connection.create_table(:foo_bars, force: true) do |t| 17 | t.column 'latlon', :st_point, srid: 3785 18 | end 19 | assert_empty Foo::Bar.all 20 | Foo::Bar.lease_connection.drop_table(:foo_bars) 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /test/cases/adapters/postgresql/numeric_test.rb: -------------------------------------------------------------------------------- 1 | require "cases/helper_cockroachdb" 2 | 3 | # Load dependencies from ActiveRecord test suite 4 | require "support/schema_dumping_helper" 5 | 6 | module CockroachDB 7 | class PostgresqlNumberTest < ActiveRecord::PostgreSQLTestCase 8 | include SchemaDumpingHelper 9 | 10 | class PostgresqlNumber < ActiveRecord::Base; end 11 | 12 | setup do 13 | @connection = ActiveRecord::Base.lease_connection 14 | @connection.create_table("postgresql_numbers", force: true) do |t| 15 | t.decimal 'decimal_default' 16 | end 17 | end 18 | 19 | teardown do 20 | @connection.drop_table "postgresql_decimals", if_exists: true 21 | end 22 | 23 | def test_decimal_values 24 | record = PostgresqlNumber.new(decimal_default: 111.222) 25 | assert_equal record.decimal_default, 111.222 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /test/cases/adapters/postgresql/quoting_test.rb: -------------------------------------------------------------------------------- 1 | require "cases/helper_cockroachdb" 2 | 3 | # Load dependencies from ActiveRecord test suite 4 | require "support/schema_dumping_helper" 5 | 6 | module CockroachDB 7 | class PostgresqlQuotingTest < ActiveRecord::PostgreSQLTestCase 8 | def setup 9 | @conn = ActiveRecord::Base.lease_connection 10 | @raise_int_wider_than_64bit = ActiveRecord.raise_int_wider_than_64bit 11 | end 12 | 13 | # Replace the original test since numbers are quoted. 14 | def test_do_not_raise_when_int_is_not_wider_than_64bit 15 | value = 9223372036854775807 16 | assert_equal "'9223372036854775807'", @conn.quote(value) 17 | 18 | value = -9223372036854775808 19 | assert_equal "'-9223372036854775808'", @conn.quote(value) 20 | end 21 | 22 | # Replace the original test since numbers are quoted. 23 | def test_do_not_raise_when_raise_int_wider_than_64bit_is_false 24 | ActiveRecord.raise_int_wider_than_64bit = false 25 | value = 9223372036854775807 + 1 26 | assert_equal "'9223372036854775808'", @conn.quote(value) 27 | ActiveRecord.raise_int_wider_than_64bit = @raise_int_wider_than_64bit 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /test/cases/adapters/postgresql/schema_statements_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cases/helper_cockroachdb' 4 | require 'models/building' 5 | 6 | class SchemaStatementsTest < ActiveRecord::PostgreSQLTestCase 7 | def test_no_crdb_internal_in_schema_names 8 | assert_not_includes Building.lease_connection.schema_names, "crdb_internal" 9 | end 10 | 11 | def test_initialize_type_map 12 | initialized_types = Building.lease_connection.send(:type_map).keys 13 | 14 | # PostGIS types must be initialized first, so 15 | # ActiveRecord::ConnectionAdapters::PostgreSQLAdapter#load_additional_types can use them. 16 | # https://github.com/rails/rails/blob/8d57cb39a88787bb6cfb7e1c481556ef6d8ede7a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L593 17 | assert_equal initialized_types.first(9), %w[ 18 | geography 19 | geometry 20 | geometry_collection 21 | line_string 22 | multi_line_string 23 | multi_point 24 | multi_polygon 25 | st_point 26 | st_polygon 27 | ] 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /test/cases/adapters/postgresql/spatial_setup_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cases/helper_cockroachdb' 4 | 5 | class SpatialSetupTest < ActiveRecord::PostgreSQLTestCase 6 | def test_ignore_tables 7 | expect_to_ignore = %w[ 8 | geography_columns 9 | geometry_columns 10 | layer 11 | raster_columns 12 | raster_overviews 13 | spatial_ref_sys 14 | topology 15 | ] 16 | assert_equal expect_to_ignore, ::ActiveRecord::SchemaDumper.ignore_tables 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /test/cases/adapters/postgresql/spatial_type_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'cases/helper_cockroachdb' 4 | 5 | class SpatialTypeTest < ActiveRecord::PostgreSQLTestCase 6 | def test_parse_simple_type 7 | assert_equal ['geometry', 0, false, false], spatial.parse_sql_type('geometry') 8 | assert_equal ['geography', 0, false, false], spatial.parse_sql_type('geography') 9 | end 10 | 11 | def test_parse_geo_type 12 | assert_equal ['Point', 0, false, false], spatial.parse_sql_type('geography(Point)') 13 | assert_equal ['Point', 0, false, true], spatial.parse_sql_type('geography(PointM)') 14 | assert_equal ['Point', 0, true, false], spatial.parse_sql_type('geography(PointZ)') 15 | assert_equal ['Point', 0, true, true], spatial.parse_sql_type('geography(PointZM)') 16 | assert_equal ['Polygon', 0, false, false], spatial.parse_sql_type('geography(Polygon)') 17 | assert_equal ['Polygon', 0, true, false], spatial.parse_sql_type('geography(PolygonZ)') 18 | assert_equal ['Polygon', 0, false, true], spatial.parse_sql_type('geography(PolygonM)') 19 | assert_equal ['Polygon', 0, true, true], spatial.parse_sql_type('geography(PolygonZM)') 20 | end 21 | 22 | def test_parse_type_with_srid 23 | assert_equal ['Point', 4326, false, false], spatial.parse_sql_type('geography(Point,4326)') 24 | assert_equal ['Polygon', 4327, true, false], spatial.parse_sql_type('geography(PolygonZ,4327)') 25 | assert_equal ['Point', 4328, false, true], spatial.parse_sql_type('geography(PointM,4328)') 26 | assert_equal ['Point', 4329, true, true], spatial.parse_sql_type('geography(PointZM,4329)') 27 | assert_equal ['MultiPolygon', 4326, false, false], spatial.parse_sql_type('geometry(MultiPolygon,4326)') 28 | end 29 | 30 | def test_parse_non_geo_types 31 | assert_equal ['x', 0, false, false], spatial.parse_sql_type('x') 32 | assert_equal ['foo', 0, false, false], spatial.parse_sql_type('foo') 33 | assert_equal ['foo(A,1234)', 0, false, false], spatial.parse_sql_type('foo(A,1234)') 34 | end 35 | 36 | private 37 | 38 | def spatial 39 | ActiveRecord::ConnectionAdapters::CockroachDB::OID::Spatial 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /test/cases/adapters/postgresql/timestamp_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "cases/helper_cockroachdb" 4 | require "models/developer" 5 | require "models/topic" 6 | 7 | module CockroachDB 8 | class PostgresqlTimestampMigrationTest < ActiveRecord::PostgreSQLTestCase 9 | self.use_transactional_tests = false 10 | 11 | class PostgresqlTimestampWithZone < ActiveRecord::Base; end 12 | 13 | def test_adds_column_as_timestamp 14 | original, $stdout = $stdout, StringIO.new 15 | 16 | ActiveRecord::Migration.new.add_column :postgresql_timestamp_with_zones, :times, :datetime 17 | 18 | assert_equal({ "data_type" => "timestamp without time zone" }, 19 | PostgresqlTimestampWithZone.lease_connection.execute("select data_type from information_schema.columns where column_name = 'times'").to_a.first) 20 | ensure 21 | ActiveRecord::Migration.new.remove_column :postgresql_timestamp_with_zones, :times, if_exists: true 22 | $stdout = original 23 | end 24 | 25 | def test_adds_column_as_timestamptz_if_datetime_type_changed 26 | original, $stdout = $stdout, StringIO.new 27 | 28 | with_cockroachdb_datetime_type(:timestamptz) do 29 | ActiveRecord::Migration.new.add_column :postgresql_timestamp_with_zones, :times, :datetime 30 | 31 | assert_equal({ "data_type" => "timestamp with time zone" }, 32 | PostgresqlTimestampWithZone.lease_connection.execute("select data_type from information_schema.columns where column_name = 'times'").to_a.first) 33 | end 34 | ensure 35 | ActiveRecord::Migration.new.remove_column :postgresql_timestamp_with_zones, :times, if_exists: true 36 | $stdout = original 37 | end 38 | 39 | def test_adds_column_as_custom_type 40 | original, $stdout = $stdout, StringIO.new 41 | 42 | PostgresqlTimestampWithZone.lease_connection.execute("CREATE TYPE custom_time_format AS ENUM ('past', 'present', 'future');") 43 | 44 | ActiveRecord::ConnectionAdapters::CockroachDBAdapter::NATIVE_DATABASE_TYPES[:datetimes_as_enum] = { name: "custom_time_format" } 45 | with_cockroachdb_datetime_type(:datetimes_as_enum) do 46 | ActiveRecord::Migration.new.add_column :postgresql_timestamp_with_zones, :times, :datetime, precision: nil 47 | 48 | assert_equal({ "data_type" => "USER-DEFINED", "udt_name" => "custom_time_format" }, 49 | PostgresqlTimestampWithZone.lease_connection.execute("select data_type, udt_name from information_schema.columns where column_name = 'times'").to_a.first) 50 | end 51 | ensure 52 | ActiveRecord::ConnectionAdapters::CockroachDBAdapter::NATIVE_DATABASE_TYPES.delete(:datetimes_as_enum) 53 | ActiveRecord::Migration.new.remove_column :postgresql_timestamp_with_zones, :times, if_exists: true 54 | ActiveRecord::Base.lease_connection.execute("DROP TYPE IF EXISTS custom_time_format") 55 | $stdout = original 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /test/cases/adapters/postgresql/virtual_column_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "cases/helper" 4 | require "support/schema_dumping_helper" 5 | 6 | module CockroachDB 7 | if ActiveRecord::Base.lease_connection.supports_virtual_columns? 8 | class PostgresqlVirtualColumnTest < ActiveRecord::PostgreSQLTestCase 9 | include SchemaDumpingHelper 10 | 11 | self.use_transactional_tests = false 12 | 13 | class VirtualColumn < ActiveRecord::Base 14 | end 15 | 16 | def setup 17 | @connection = ActiveRecord::Base.lease_connection 18 | @connection.create_table :virtual_columns, force: true do |t| 19 | t.string :name 20 | t.virtual :upper_name, type: :string, as: "UPPER(name)", stored: true 21 | t.virtual :name_length, type: :integer, as: "LENGTH(name)", stored: true 22 | t.virtual :name_octet_length, type: :integer, as: "OCTET_LENGTH(name)", stored: true 23 | t.integer :column1 24 | t.virtual :column2, type: :integer, as: "column1 + 1", stored: true 25 | end 26 | VirtualColumn.create(name: "Rails") 27 | end 28 | 29 | # TODO: is this test result acceptable? 30 | def test_schema_dumping 31 | output = dump_table_schema("virtual_columns") 32 | assert_match(/t\.virtual\s+"upper_name",\s+type: :string,\s+as: "upper\(name\)", stored: true$/i, output) 33 | assert_match(/t\.virtual\s+"name_length",\s+type: :bigint,\s+as: "length\(name\)", stored: true$/i, output) 34 | assert_match(/t\.virtual\s+"name_octet_length",\s+type: :bigint,\s+as: "octet_length\(name\)", stored: true$/i, output) 35 | assert_match(/t\.virtual\s+"column2",\s+type: :bigint,\s+as: "column1 \+ 1", stored: true$/i, output) 36 | end 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /test/cases/associations/left_outer_join_association_test.rb: -------------------------------------------------------------------------------- 1 | require "cases/helper_cockroachdb" 2 | 3 | # Load dependencies from ActiveRecord test suite 4 | require "models/post" 5 | require "models/author" 6 | 7 | module CockroachDB 8 | class LeftOuterJoinAssociationTest < ActiveRecord::TestCase 9 | fixtures :author_addresses, :authors, :posts 10 | 11 | # This replaces the same test that's been excluded from 12 | # LeftOuterJoinAssociationTest. The query has been updated to guarantee the 13 | # result order. 14 | # See test/excludes/LeftOuterJoinAssociationTest.rb 15 | def test_construct_finder_sql_applies_aliases_tables_on_association_conditions 16 | result = Author.left_outer_joins(:thinking_posts, :welcome_posts).order(:id).to_a 17 | assert_equal authors(:david), result.first 18 | end 19 | 20 | # This replaces the same test that's been excluded from 21 | # LeftOuterJoinAssociationTest. The select query has been updated so the 22 | # integer columns are casted to strings for concatenation. 23 | # See test/excludes/LeftOuterJoinAssociationTest.rb 24 | def test_does_not_override_select 25 | authors = Author.select("authors.name, #{%{(authors.author_address_id::STRING || ' ' || authors.author_address_extra_id::STRING) as addr_id}}").left_outer_joins(:posts) 26 | assert_predicate authors, :any? 27 | assert_respond_to authors.first, :addr_id 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /test/cases/associations_test.rb: -------------------------------------------------------------------------------- 1 | require "cases/helper_cockroachdb" 2 | 3 | require "support/connection_helper" 4 | 5 | require "models/bird" 6 | require "models/parrot" 7 | require "models/pirate" 8 | require "models/price_estimate" 9 | require "models/ship" 10 | require "models/treasure" 11 | 12 | module CockroachDB 13 | class WithAnnotationsTest < ActiveRecord::TestCase 14 | self.use_transactional_tests = false 15 | 16 | fixtures :pirates, :treasures, :parrots 17 | 18 | def test_belongs_to_with_annotation_includes_a_query_comment 19 | pirate = SpacePirate.where.not(parrot_id: nil).first 20 | assert pirate, "should have a Pirate record" 21 | 22 | log = capture_sql do 23 | pirate.parrot 24 | end 25 | assert_not_predicate log, :empty? 26 | assert_predicate log.select { |query| query.match?(%r{/\*}) }, :empty? 27 | 28 | assert_queries_match(%r{/\* that tells jokes \*/}) do 29 | pirate.parrot_with_annotation 30 | end 31 | end 32 | 33 | def test_has_and_belongs_to_many_with_annotation_includes_a_query_comment 34 | pirate = SpacePirate.first 35 | assert pirate, "should have a Pirate record" 36 | 37 | log = capture_sql do 38 | pirate.parrots.first 39 | end 40 | assert_not_predicate log, :empty? 41 | assert_predicate log.select { |query| query.match?(%r{/\*}) }, :empty? 42 | 43 | assert_queries_match(%r{/\* that are very colorful \*/}) do 44 | pirate.parrots_with_annotation.first 45 | end 46 | end 47 | 48 | def test_has_one_with_annotation_includes_a_query_comment 49 | pirate = SpacePirate.first 50 | assert pirate, "should have a Pirate record" 51 | 52 | log = capture_sql do 53 | pirate.ship 54 | end 55 | assert_not_predicate log, :empty? 56 | assert_predicate log.select { |query| query.match?(%r{/\*}) }, :empty? 57 | 58 | assert_queries_match(%r{/\* that is a rocket \*/}) do 59 | pirate.ship_with_annotation 60 | end 61 | end 62 | 63 | def test_has_many_with_annotation_includes_a_query_comment 64 | pirate = SpacePirate.first 65 | assert pirate, "should have a Pirate record" 66 | 67 | log = capture_sql do 68 | pirate.birds.first 69 | end 70 | assert_not_predicate log, :empty? 71 | assert_predicate log.select { |query| query.match?(%r{/\*}) }, :empty? 72 | 73 | assert_queries_match(%r{/\* that are also parrots \*/}) do 74 | pirate.birds_with_annotation.first 75 | end 76 | end 77 | 78 | def test_has_many_through_with_annotation_includes_a_query_comment 79 | pirate = SpacePirate.first 80 | assert pirate, "should have a Pirate record" 81 | 82 | log = capture_sql do 83 | pirate.treasure_estimates.first 84 | end 85 | assert_not_predicate log, :empty? 86 | assert_predicate log.select { |query| query.match?(%r{/\*}) }, :empty? 87 | 88 | assert_queries_match(%r{/\* yarrr \*/}) do 89 | pirate.treasure_estimates_with_annotation.first 90 | end 91 | end 92 | 93 | def test_has_many_through_with_annotation_includes_a_query_comment_when_eager_loading 94 | pirate = SpacePirate.first 95 | assert pirate, "should have a Pirate record" 96 | 97 | log = capture_sql do 98 | pirate.treasure_estimates.first 99 | end 100 | assert_not_predicate log, :empty? 101 | assert_predicate log.select { |query| query.match?(%r{/\*}) }, :empty? 102 | 103 | assert_queries_match(%r{/\* yarrr \*/}) do 104 | SpacePirate.includes(:treasure_estimates_with_annotation, :treasures).first 105 | end 106 | end 107 | end 108 | end 109 | -------------------------------------------------------------------------------- /test/cases/base_test.rb: -------------------------------------------------------------------------------- 1 | require "cases/helper_cockroachdb" 2 | 3 | module CockroachDB 4 | class BasicsTest < ActiveRecord::TestCase 5 | # This replaces the same test that's been excluded from BasicsTest. It's 6 | # exactly the same, except badchar has an entry for CockroachDBAdapter. 7 | def test_column_names_are_escaped 8 | conn = ActiveRecord::Base.lease_connection 9 | classname = conn.class.name[/[^:]*$/] 10 | badchar = { 11 | "SQLite3Adapter" => '"', 12 | "Mysql2Adapter" => "`", 13 | "PostgreSQLAdapter" => '"', 14 | "OracleAdapter" => '"', 15 | "FbAdapter" => '"', 16 | "CockroachDBAdapter" => '"' 17 | }.fetch(classname) { 18 | raise "need a bad char for #{classname}" 19 | } 20 | 21 | quoted = conn.quote_column_name "foo#{badchar}bar" 22 | if current_adapter?(:OracleAdapter) 23 | # Oracle does not allow double quotes in table and column names at all 24 | # therefore quoting removes them 25 | assert_equal("#{badchar}foobar#{badchar}", quoted) 26 | else 27 | assert_equal("#{badchar}foo#{badchar * 2}bar#{badchar}", quoted) 28 | end 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /test/cases/comment_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "cases/helper" 4 | require "support/schema_dumping_helper" 5 | 6 | # Copy of comment_test from ActiveRecord with all but two tests removed. 7 | # We can get these tests to pass by enabling an experimental feature in 8 | # setup, so we exclude them from the AR test cases and run them here. 9 | if ActiveRecord::Base.lease_connection.supports_comments? 10 | module CockroachDB 11 | class CommentTest < ActiveRecord::TestCase 12 | include SchemaDumpingHelper 13 | 14 | self.use_transactional_tests = false 15 | 16 | class Commented < ActiveRecord::Base 17 | self.table_name = "commenteds" 18 | end 19 | 20 | setup do 21 | @connection = ActiveRecord::Base.lease_connection 22 | 23 | @connection.create_table("commenteds", comment: "A table with comment", force: true) do |t| 24 | t.string "name", comment: "Comment should help clarify the column purpose" 25 | t.boolean "obvious", comment: "Question is: should you comment obviously named objects?" 26 | t.string "content" 27 | t.index "name", comment: %Q["Very important" index that powers all the performance.\nAnd it's fun!] 28 | end 29 | 30 | Commented.reset_column_information 31 | end 32 | 33 | teardown do 34 | @connection.drop_table "commenteds", if_exists: true 35 | end 36 | 37 | # This test is modified from the original 38 | # The original changes the column type from a boolean to a string, 39 | # but once this happens, comment changes don't work, so I'm not altering 40 | # the type here. 41 | def test_remove_comment_from_column 42 | @connection.change_column :commenteds, :obvious, :boolean, comment: nil 43 | 44 | Commented.reset_column_information 45 | column = Commented.columns_hash["obvious"] 46 | 47 | assert_equal :boolean, column.type 48 | assert_nil column.comment 49 | end 50 | 51 | def test_schema_dump_with_comments 52 | # Do all the stuff from other tests 53 | @connection.add_column :commenteds, :rating, :integer, comment: "I am running out of imagination" 54 | @connection.change_column :commenteds, :content, :string, comment: "Whoa, content describes itself!" 55 | @connection.change_column :commenteds, :content, :string 56 | @connection.change_column :commenteds, :obvious, :boolean, comment: nil 57 | @connection.add_index :commenteds, :obvious, name: "idx_obvious", comment: "We need to see obvious comments" 58 | 59 | # And check that these changes are reflected in dump 60 | output = dump_table_schema "commenteds" 61 | assert_match %r[create_table "commenteds",.*\s+comment: "A table with comment"], output 62 | assert_match %r[t\.string\s+"name",\s+comment: "Comment should help clarify the column purpose"], output 63 | assert_match %r[t\.boolean\s+"obvious"\n], output 64 | assert_match %r[t\.string\s+"content",\s+comment: "Whoa, content describes itself!"], output 65 | if current_adapter?(:OracleAdapter) 66 | assert_match %r[t\.integer\s+"rating",\s+precision: 38,\s+comment: "I am running out of imagination"], output 67 | else 68 | assert_match %r[t\.bigint\s+"rating",\s+comment: "I am running out of imagination"], output 69 | assert_match %r[t\.index\s+.+\s+comment: "\\\"Very important\\\" index that powers all the performance.\\nAnd it's fun!"], output 70 | assert_match %r[t\.index\s+.+\s+name: "idx_obvious",\s+comment: "We need to see obvious comments"], output 71 | end 72 | end 73 | end 74 | end 75 | end 76 | -------------------------------------------------------------------------------- /test/cases/connection_adapters/type_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "cases/helper_cockroachdb" 4 | require "models/account" 5 | 6 | module CockroachDB 7 | module ConnectionAdapters 8 | class TypeTest < ActiveRecord::TestCase 9 | fixtures :accounts 10 | class FakeModel < ActiveRecord::Base 11 | establish_connection( 12 | adapter: "fake" 13 | ) 14 | end 15 | def test_type_can_be_used_with_various_db 16 | skip "Fails in CI, see issue #341" 17 | assert_equal( 18 | :postgresql, 19 | ActiveRecord::Type.adapter_name_from(Account) 20 | ) 21 | assert_equal( 22 | :fake, 23 | ActiveRecord::Type.adapter_name_from(FakeModel) 24 | ) 25 | end 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /test/cases/database_configurations/resolver_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "cases/helper_cockroachdb" 4 | require "support/copy_cat" 5 | 6 | module CockroachDB 7 | class ResolverTest < ::ActiveRecord::ConnectionAdapters::PoolConfig::ResolverTest 8 | CopyCat.copy_methods(self, ::ActiveRecord::ConnectionAdapters::PoolConfig::ResolverTest, 9 | :test_url_invalid_adapter) do 10 | # We're not in the ActiveRecord namespace anymore. 11 | def on_const(node) 12 | return unless node in [:const, nil, :AdapterNotFound|:Base] 13 | 14 | insert_before(node.loc.expression, "ActiveRecord::") 15 | end 16 | 17 | def on_str(node) 18 | return unless node in [:str, /\ADatabase config/] 19 | 20 | replace(node.loc.expression, node.children.first.sub("abstract,", "abstract, cockroachdb,").inspect) 21 | end 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /test/cases/defaults_test.rb: -------------------------------------------------------------------------------- 1 | require "cases/helper_cockroachdb" 2 | 3 | # Load dependencies from ActiveRecord test suite 4 | require "support/schema_dumping_helper" 5 | 6 | module CockroachDB 7 | class DefaultExpressionTest < ActiveRecord::TestCase 8 | include SchemaDumpingHelper 9 | 10 | # This replaces the same test that's been excluded from 11 | # PostgresqlDefaultExpressionTest. The assertions have updated to match 12 | # against CockroachDB's current_date() and current_timestamp() functions. 13 | # See test/excludes/PostgresqlDefaultExpressionTest.rb. 14 | test "schema dump includes default expression" do 15 | output = dump_table_schema("defaults") 16 | 17 | assert_match %r/t\.date\s+"modified_date",\s+default: -> { \"current_date\(\)\" }/, output 18 | assert_match %r/t\.datetime\s+"modified_time",\s+default: -> { "current_timestamp\(\)" }/, output 19 | 20 | assert_match %r/t\.date\s+"modified_date_function",\s+default: -> { "now\(\)" }/, output 21 | assert_match %r/t\.datetime\s+"modified_time_function",\s+default: -> { "now\(\)" }/, output 22 | end 23 | end 24 | 25 | class DefaultNumbersTest < ActiveRecord::TestCase 26 | class DefaultNumber < ActiveRecord::Base; end 27 | 28 | setup do 29 | @connection = ActiveRecord::Base.lease_connection 30 | @connection.create_table :default_numbers do |t| 31 | t.decimal :decimal_number, precision: 32, scale: 16, default: 0 32 | end 33 | end 34 | 35 | teardown do 36 | @connection.drop_table :default_numbers, if_exists: true 37 | end 38 | 39 | def test_default_decimal_zero_with_large_scale 40 | record = DefaultNumber.new 41 | assert_equal 0.0, record.decimal_number 42 | assert_equal "0.0000000000000000", record.decimal_number_before_type_cast 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /test/cases/dirty_test.rb: -------------------------------------------------------------------------------- 1 | require "cases/helper" 2 | 3 | module CockroachDB 4 | class DirtyTest < ActiveRecord::TestCase 5 | self.use_transactional_tests = false 6 | 7 | class Testings < ActiveRecord::Base; end 8 | 9 | # This replaces the same test that's been excluded from DirtyTest. We can 10 | # run it here with use_transactional_tests set to false. 11 | # See test/excludes/DirtyTest.rb 12 | def test_field_named_field 13 | ActiveRecord::Base.lease_connection.create_table :testings do |t| 14 | t.string :field 15 | end 16 | assert_nothing_raised do 17 | Testings.new.attributes 18 | end 19 | ensure 20 | ActiveRecord::Base.lease_connection.drop_table :testings, if_exists: true 21 | ActiveRecord::Base.clear_cache! 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /test/cases/inheritance_test.rb: -------------------------------------------------------------------------------- 1 | require "cases/helper_cockroachdb" 2 | 3 | # Load dependencies from ActiveRecord test suite 4 | require "models/company" 5 | 6 | module CockroachDB 7 | class InheritanceComputeTypeTest < ActiveRecord::TestCase 8 | 9 | # This replaces the same test that's been excluded from 10 | # InheritanceComputeTypeTest. New, unsaved records won't have 11 | # string default values if the default has been changed in the database. 12 | # This happens because once a column default is changed in CockroachDB, the 13 | # type information on the value is missing. 14 | # We can still verify the desired behavior by persisting the test records. 15 | # When ActiveRecord fetches the records from the database, they'll have 16 | # their default values. 17 | # See test/excludes/InheritanceComputeTypeTest.rb 18 | def test_inheritance_new_with_subclass_as_default 19 | original_type = Company.columns_hash["type"].default 20 | ActiveRecord::Base.lease_connection.change_column_default :companies, :type, "Firm" 21 | Company.reset_column_information 22 | 23 | # Instead of using an unsaved Company record, persist one and fetch it 24 | # from the database to get the new default value for type. 25 | Company.create!(name: "Acme Co.", firm_name: "Shri Hans Plastic") # with arguments 26 | firm = Company.last 27 | assert_equal "Firm", firm.type 28 | assert_instance_of Firm, firm 29 | 30 | client = Client.new 31 | assert_equal "Client", client.type 32 | assert_instance_of Client, client 33 | 34 | firm = Company.new(type: "Client") # overwrite the default type 35 | assert_equal "Client", firm.type 36 | assert_instance_of Client, firm 37 | ensure 38 | ActiveRecord::Base.lease_connection.change_column_default :companies, :type, original_type 39 | Company.reset_column_information 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /test/cases/invertible_migration_test.rb: -------------------------------------------------------------------------------- 1 | require "cases/helper_cockroachdb" 2 | 3 | module CockroachDB 4 | class Horse < ActiveRecord::Base 5 | end 6 | 7 | class InvertibleMigrationTest < ActiveRecord::TestCase 8 | class SilentMigration < ActiveRecord::Migration::Current 9 | def write(text = "") 10 | # sssshhhhh!! 11 | end 12 | end 13 | 14 | class ChangeColumnDefault1 < SilentMigration 15 | def change 16 | create_table("horses") do |t| 17 | t.column :name, :string, default: "Sekitoba" 18 | end 19 | end 20 | end 21 | 22 | class ChangeColumnDefault2 < SilentMigration 23 | def change 24 | change_column_default :horses, :name, from: "Sekitoba", to: "Diomed" 25 | end 26 | end 27 | 28 | self.use_transactional_tests = false 29 | 30 | setup do 31 | @verbose_was, ActiveRecord::Migration.verbose = ActiveRecord::Migration.verbose, false 32 | end 33 | 34 | teardown do 35 | %w[horses new_horses].each do |table| 36 | if ActiveRecord::Base.lease_connection.table_exists?(table) 37 | ActiveRecord::Base.lease_connection.drop_table(table) 38 | end 39 | end 40 | ActiveRecord::Migration.verbose = @verbose_was 41 | end 42 | 43 | # This replaces the same test that's been excluded from 44 | # ActiveRecord::InvertibleMigrationTest. New, unsaved records won't have 45 | # string default values if the default has been changed in the database. 46 | # This happens because once a column default is changed in CockroachDB, the 47 | # type information on the value is missing. 48 | # We can still verify the desired behavior by persisting the test records. 49 | # When ActiveRecord fetches the records from the database, they'll have 50 | # their default values. 51 | # See test/excludes/ActiveRecord/InvertibleMigrationTest.rb 52 | def test_migrate_revert_change_column_default 53 | migration1 = ChangeColumnDefault1.new 54 | migration1.migrate(:up) 55 | assert_equal "Sekitoba", Horse.new.name 56 | 57 | # Instead of using an unsaved Horse record, persist one and fetch it from 58 | # the database to get the new default value for name. 59 | migration2 = ChangeColumnDefault2.new 60 | migration2.migrate(:up) 61 | Horse.reset_column_information 62 | Horse.create! 63 | assert_equal "Diomed", Horse.last.name 64 | 65 | # Instead of using an unsaved Horse record, persist one and fetch it from 66 | # the database to get the new default value for name. 67 | migration2.migrate(:down) 68 | Horse.reset_column_information 69 | Horse.create! 70 | assert_equal "Sekitoba", Horse.last.name 71 | end 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /test/cases/marshal_serialization_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "cases/helper" 4 | require "models/topic" 5 | require "models/reply" 6 | require "support/paths_cockroachdb" 7 | 8 | module CockroachDB 9 | class MarshalSerializationTest < ActiveRecord::TestCase 10 | # This test file is identical to the one in Rails, except that 11 | # the marshal_fixture_path method specifies to use the PostgreSQL 12 | # directory instead of using the adapter name. 13 | fixtures :topics 14 | 15 | def test_deserializing_rails_6_1_marshal_basic 16 | topic = Marshal.load(marshal_fixture("rails_6_1_topic")) 17 | 18 | assert_not_predicate topic, :new_record? 19 | assert_equal 1, topic.id 20 | assert_equal "The First Topic", topic.title 21 | assert_equal "Have a nice day", topic.content 22 | end 23 | 24 | def test_deserializing_rails_6_1_marshal_with_loaded_association_cache 25 | topic = Marshal.load(marshal_fixture("rails_6_1_topic_associations")) 26 | 27 | assert_not_predicate topic, :new_record? 28 | assert_equal 1, topic.id 29 | assert_equal "The First Topic", topic.title 30 | assert_equal "Have a nice day", topic.content 31 | end 32 | 33 | private 34 | def marshal_fixture(file_name) 35 | File.binread(marshal_fixture_path(file_name)) 36 | end 37 | 38 | def marshal_fixture_path(file_name) 39 | File.expand_path( 40 | "support/marshal_compatibility_fixtures/PostgreSQL/#{file_name}.dump", 41 | ARTest::CockroachDB.root_activerecord_test 42 | ) 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /test/cases/migration/columns_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "cases/migration/helper" 4 | 5 | module ActiveRecord 6 | module CockroachDB 7 | class Migration 8 | class ColumnsTest < ActiveRecord::TestCase 9 | include ActiveRecord::Migration::TestHelper 10 | 11 | self.use_transactional_tests = false 12 | 13 | # This file replaces the same tests that have been excluded from ColumnsTest 14 | # (see test/excludes/ActiveRecord/Migration/ColumnsTest.rb). New, unsaved 15 | # records won't have string default values if the default has been changed 16 | # in the database. This happens because once a column default is changed 17 | # in CockroachDB, the type information on the value is missing. 18 | # We can still verify the desired behavior by persisting the test records. 19 | # When ActiveRecord fetches the records from the database, they'll have 20 | # their default values. 21 | 22 | def test_change_column_default 23 | add_column "test_models", "first_name", :string 24 | connection.change_column_default "test_models", "first_name", "Tester" 25 | TestModel.reset_column_information 26 | 27 | # Instead of using an unsaved TestModel record, persist one and fetch 28 | # it from the database to get the new default value for type. 29 | 30 | TestModel.create! 31 | test_model = TestModel.last 32 | assert_equal "Tester", test_model.first_name 33 | end 34 | 35 | def test_change_column_default_with_from_and_to 36 | add_column "test_models", "first_name", :string 37 | connection.change_column_default "test_models", "first_name", from: nil, to: "Tester" 38 | TestModel.reset_column_information 39 | 40 | # Instead of using an unsaved TestModel record, persist one and fetch 41 | # it from the database to get the new default value for type. 42 | 43 | TestModel.create! 44 | test_model = TestModel.last 45 | assert_equal "Tester", test_model.first_name 46 | end 47 | end 48 | end 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /test/cases/migration/create_join_table_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "cases/helper" 4 | 5 | module ActiveRecord 6 | module CockroachDB 7 | class Migration 8 | class CreateJoinTableTest < ActiveRecord::TestCase 9 | attr_reader :connection 10 | 11 | self.use_transactional_tests = false 12 | 13 | def setup 14 | super 15 | @connection = ActiveRecord::Base.lease_connection 16 | end 17 | 18 | teardown do 19 | %w(artists_musics musics_videos catalog).each do |table_name| 20 | connection.drop_table table_name, if_exists: true 21 | end 22 | end 23 | 24 | # This test is identical to the one found in Rails, save for the fact 25 | # that transactions are turned off for test runs. It is necessary to disable 26 | # transactional tests in order to assert on schema changes due to how 27 | # CockroachDB handles transactions. 28 | def test_create_join_table_with_index 29 | connection.create_join_table :artists, :musics do |t| 30 | t.index [:artist_id, :music_id] 31 | end 32 | 33 | assert_equal [%w(artist_id music_id)], connection.indexes(:artists_musics).map(&:columns) 34 | end 35 | 36 | # This test is identical to the one found in Rails, save for the fact 37 | # that transactions are turned off for test runs. It is necessary to disable 38 | # transactional tests in order to assert on schema changes due to how 39 | # CockroachDB handles transactions. 40 | def test_create_and_drop_join_table_with_common_prefix 41 | with_table_cleanup do 42 | connection.create_join_table "audio_artists", "audio_musics" 43 | assert connection.table_exists?("audio_artists_musics") 44 | 45 | connection.drop_join_table "audio_artists", "audio_musics" 46 | assert !connection.table_exists?("audio_artists_musics"), "Should have dropped join table, but didn't" 47 | end 48 | end 49 | 50 | private 51 | 52 | def with_table_cleanup 53 | tables_before = connection.data_sources 54 | 55 | yield 56 | ensure 57 | tables_after = connection.data_sources - tables_before 58 | 59 | tables_after.each do |table| 60 | connection.drop_table table 61 | end 62 | end 63 | end 64 | end 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /test/cases/migration/hidden_column_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "cases/helper" 4 | require "support/schema_dumping_helper" 5 | 6 | module ActiveRecord 7 | module CockroachDB 8 | class Migration 9 | class HiddenColumnTest < ActiveRecord::TestCase 10 | include SchemaDumpingHelper 11 | include ActiveSupport::Testing::Stream 12 | 13 | self.use_transactional_tests = false 14 | 15 | class Rocket < ActiveRecord::Base 16 | end 17 | 18 | class Astronaut < ActiveRecord::Base 19 | end 20 | 21 | setup do 22 | @connection = ActiveRecord::Base.lease_connection 23 | @connection.create_table "rockets", force: true do |t| 24 | t.string :name 25 | end 26 | 27 | @connection.create_table "astronauts", force: true do |t| 28 | t.string :name 29 | t.bigint :secret_id, hidden: true 30 | end 31 | end 32 | 33 | teardown do 34 | @connection.drop_table "astronauts", if_exists: true 35 | @connection.drop_table "rockets", if_exists: true 36 | end 37 | 38 | # rowid is a special hidden column. CRDB implicitly adds it, so it should 39 | # not appear in the schema dump. 40 | def test_rowid_not_in_dump 41 | output = dump_table_schema "rockets" 42 | assert_match %r{create_table "rockets", id: false, force: :cascade do |t|"$}, output 43 | assert_no_match %r{rowid}, output 44 | end 45 | 46 | def test_hidden_column 47 | output = dump_table_schema "astronauts" 48 | assert_match %r{t.bigint "secret_id", hidden: true$}, output 49 | end 50 | 51 | def test_add_hidden_column 52 | @connection.add_column :rockets, :new_col, :uuid, hidden: true 53 | output = dump_table_schema "rockets" 54 | assert_match %r{t.uuid "new_col", hidden: true$}, output 55 | end 56 | 57 | # Since 24.2.2, hash sharded indexes add a hidden column to the table. 58 | # This tests ensure that the user can still drop the index even if they 59 | # call `#remove_index` with the column name rather than the index name. 60 | def test_remove_index_with_a_hidden_column 61 | @connection.execute <<-SQL 62 | CREATE INDEX hash_idx ON rockets (name) USING HASH WITH (bucket_count=8); 63 | SQL 64 | @connection.remove_index :rockets, :name 65 | assert :ok 66 | end 67 | end 68 | end 69 | end 70 | end 71 | -------------------------------------------------------------------------------- /test/cases/persistence_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "cases/helper" 4 | require "models/topic" 5 | 6 | module CockroachDB 7 | class PersistenceTest < ActiveRecord::TestCase 8 | fixtures :topics 9 | 10 | self.use_transactional_tests = false 11 | 12 | # This test is identical to the one found in Rails, except we need to run 13 | # it with transactions turned off in order to properly assert on the newly 14 | # added column. 15 | def test_reset_column_information_resets_children 16 | child_class = Class.new(Topic) 17 | child_class.new # force schema to load 18 | 19 | ActiveRecord::Base.lease_connection.add_column(:topics, :foo, :string) 20 | Topic.reset_column_information 21 | 22 | # this should redefine attribute methods 23 | child_class.new 24 | 25 | assert child_class.instance_methods.include?(:foo) 26 | assert child_class.instance_methods.include?(:foo_changed?) 27 | assert_equal "bar", child_class.new(foo: :bar).foo 28 | ensure 29 | ActiveRecord::Base.lease_connection.remove_column(:topics, :foo) 30 | Topic.reset_column_information 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /test/cases/relation/aost_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "cases/helper_cockroachdb" 4 | require "models/post" 5 | require "models/comment" 6 | 7 | module CockroachDB 8 | class AostTest < ActiveRecord::TestCase 9 | def test_simple_aost 10 | time = 2.days.ago 11 | re_time = Regexp.quote(time.iso8601) 12 | assert_match(/from "posts" as of system time '#{re_time}'/i, Post.aost(time).to_sql) 13 | assert_match(/from "posts" as of system time '#{re_time}'/i, Post.where(name: "foo").aost(time).to_sql) 14 | end 15 | 16 | def test_reset_aost 17 | time = 1.second.from_now 18 | assert_match(/from "posts"\z/i, Post.aost(time).aost(nil).to_sql) 19 | end 20 | 21 | def test_aost_with_join 22 | time = Time.now 23 | assert_match( 24 | /FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" AS OF SYSTEM TIME '#{Regexp.quote time.iso8601}'/, 25 | Post.joins(:comments).aost(time).to_sql 26 | ) 27 | end 28 | 29 | def test_aost_with_subquery 30 | time = 4.seconds.ago 31 | assert_match(/from \(.*?\) subquery as of system time '#{Regexp.quote time.iso8601}'/i, Post.from(Post.where(name: "foo")).aost(time).to_sql) 32 | end 33 | 34 | def test_only_time_input 35 | time = 1.second.ago 36 | expected = "SELECT \"posts\".* FROM \"posts\" AS OF SYSTEM TIME '#{time.iso8601}'" 37 | assert_equal expected, Post.aost(time).to_sql 38 | assert_raises(ArgumentError) { Post.aost("no time") } 39 | assert_raises(ArgumentError) { Post.aost(true) } 40 | end 41 | end 42 | 43 | class AostNoTransactionTest < ActiveRecord::TestCase 44 | # AOST per query is not compatible with transactions. 45 | self.use_transactional_tests = false 46 | 47 | def test_aost_with_multiple_queries 48 | time = 1.second.ago 49 | queries = capture_sql { 50 | Post.aost(time).limit(2).find_each(batch_size: 1).to_a 51 | } 52 | queries.each do 53 | assert_match %r(FROM "posts" AS OF SYSTEM TIME '#{Regexp.quote time.iso8601}'), _1 54 | end 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /test/cases/relation/or_test.rb: -------------------------------------------------------------------------------- 1 | # This test has been copied to fix a bug in the test setup. It can be removed 2 | # once the bugfix has been released in Rails - see rails/rails#38978. 3 | # See test/excludes/OrTest.rb 4 | 5 | require "cases/helper_cockroachdb" 6 | 7 | # Load dependencies from ActiveRecord test suite 8 | require "cases/helper" 9 | require "models/post" 10 | require "models/author" 11 | require "models/categorization" 12 | 13 | module ActiveRecord 14 | module CockroachDB 15 | class OrTest < ActiveRecord::TestCase 16 | fixtures :posts 17 | fixtures :authors, :author_addresses 18 | 19 | def test_or_when_grouping 20 | groups = Post.where("id < 10").group("body") 21 | expected = groups.having("COUNT(*) > 1 OR body like 'Such%'").count 22 | assert_equal expected, groups.having("COUNT(*) > 1").or(groups.having("body like 'Such%'")).count 23 | end 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /test/cases/relation_test.rb: -------------------------------------------------------------------------------- 1 | require "cases/helper_cockroachdb" 2 | 3 | require "cases/helper" 4 | require "models/post" 5 | require "models/comment" 6 | require "models/author" 7 | require "models/rating" 8 | require "models/categorization" 9 | 10 | module ActiveRecord 11 | module CockroachDB 12 | class RelationTest < ActiveRecord::TestCase 13 | fixtures :posts 14 | 15 | def test_relation_with_annotation_includes_comment_in_to_sql 16 | post_with_annotation = Post.where(id: 1).annotate("foo") 17 | assert_match %r{= '1' /\* foo \*/}, post_with_annotation.to_sql 18 | end 19 | 20 | def test_relation_with_annotation_filters_sql_comment_delimiters 21 | post_with_annotation = Post.where(id: 1).annotate("**//foo//**") 22 | assert_includes post_with_annotation.to_sql, "= '1' /* ** //foo// ** */" 23 | end 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /test/cases/relations_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "cases/helper" 4 | require "models/post" 5 | require "models/comment" 6 | 7 | module CockroachDB 8 | class RelationTest < ActiveRecord::TestCase 9 | fixtures :posts, :comments 10 | 11 | def test_finding_with_subquery_with_eager_loading_in_from 12 | relation = Comment.includes(:post).where("posts.type": "Post").order(:id) 13 | assert_equal relation.to_a, Comment.select("*").from(relation).order(:id).to_a 14 | assert_equal relation.to_a, Comment.select("subquery.*").from(relation).order(:id).to_a 15 | assert_equal relation.to_a, Comment.select("a.*").from(relation, :a).order(:id).to_a 16 | end 17 | 18 | def test_finding_with_arel_sql_order 19 | query = Tag.order(Arel.sql("field(id, ?)", [1, 3, 2])).to_sql 20 | assert_match(/field\(id, '1', '3', '2'\)/, query) 21 | 22 | query = Tag.order(Arel.sql("field(id, ?)", [])).to_sql 23 | assert_match(/field\(id, NULL\)/, query) 24 | 25 | query = Tag.order(Arel.sql("field(id, ?)", nil)).to_sql 26 | assert_match(/field\(id, NULL\)/, query) 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /test/cases/show_create_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "cases/helper_cockroachdb" 4 | require "models/post" 5 | 6 | module CockroachDB 7 | class ShowCreateTest < ActiveRecord::TestCase 8 | fixtures :posts 9 | 10 | def test_show_create 11 | assert_match(/CREATE TABLE public\.posts/, Post.show_create) 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /test/cases/strict_loading_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "cases/helper" 4 | require "models/developer" 5 | require "models/computer" 6 | require "models/mentor" 7 | require "models/project" 8 | require "models/ship" 9 | require "models/strict_zine" 10 | require "models/interest" 11 | 12 | module CockroachDB 13 | class StrictLoadingFixturesTest < ActiveRecord::TestCase 14 | # This test is identical to the ActiveRecord version except 15 | # that transactional tests are disabled, so create_fixtures 16 | # will work. 17 | self.use_transactional_tests = false 18 | 19 | fixtures :strict_zines 20 | 21 | test "strict loading violations are ignored on fixtures" do 22 | ActiveRecord::FixtureSet.reset_cache 23 | create_fixtures("strict_zines") 24 | 25 | assert_nothing_raised do 26 | strict_zines(:going_out).interests.to_a 27 | end 28 | 29 | assert_raises(ActiveRecord::StrictLoadingViolationError) do 30 | StrictZine.first.interests.to_a 31 | end 32 | end 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /test/cases/test_fixtures_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "cases/helper" 4 | require "tempfile" 5 | require "fileutils" 6 | require "models/zine" 7 | module CockroachDB 8 | class TestFixturesTest < ActiveRecord::TestCase 9 | setup do 10 | @klass = Class.new 11 | @klass.include(ActiveRecord::TestFixtures) 12 | end 13 | 14 | # This is identical to the Rails version, except that we set 15 | # use_transactional_tests to false. This is necessary because otherwise 16 | # the fixtures are created inside of a transaction, which causes a 17 | # DuplicateKey error and ultimately an InFailedSqlTransaction error. 18 | # Setting transactional tests to false allows the schema to update so that 19 | # we do not have an erroneous DuplicateKey error when re-creating the 20 | # foreign keys. 21 | self.use_transactional_tests = false 22 | 23 | unless in_memory_db? 24 | def test_doesnt_rely_on_active_support_test_case_specific_methods 25 | tmp_dir = Dir.mktmpdir 26 | File.write(File.join(tmp_dir, "zines.yml"), <<~YML) 27 | going_out: 28 | title: Hello 29 | YML 30 | 31 | klass = Class.new(Minitest::Test) do 32 | include ActiveRecord::TestFixtures 33 | 34 | self.fixture_paths = [tmp_dir] 35 | 36 | fixtures :all 37 | 38 | def test_run_successfully 39 | assert_equal("Hello", Zine.first.title) 40 | assert_equal("Hello", zines(:going_out).title) 41 | end 42 | end 43 | 44 | old_handler = ActiveRecord::Base.connection_handler 45 | ActiveRecord::Base.connection_handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new 46 | ActiveRecord::Base.establish_connection(:arunit) 47 | 48 | test_result = klass.new("test_run_successfully").run 49 | assert_predicate(test_result, :passed?) 50 | ensure 51 | ActiveRecord::Base.connection_handler = old_handler 52 | clean_up_connection_handler 53 | FileUtils.rm_r(tmp_dir) 54 | end 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /test/cases/transactions_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "cases/helper_cockroachdb" 4 | 5 | module CockroachDB 6 | class TransactionsTest < ActiveRecord::TestCase 7 | self.use_transactional_tests = false 8 | 9 | class Avenger < ActiveRecord::Base 10 | singleton_class.attr_accessor :cyclic_barrier 11 | 12 | validate :validate_unique_username 13 | 14 | def validate_unique_username 15 | self.class.cyclic_barrier.wait 16 | duplicate = self.class.where(name: name).any? 17 | errors.add("Duplicate username!") if duplicate 18 | end 19 | end 20 | 21 | def test_concurrent_insert_with_processes 22 | conn = ActiveRecord::Base.lease_connection 23 | conn.create_table :avengers, force: true do |t| 24 | t.string :name 25 | end 26 | ActiveRecord::Base.reset_column_information 27 | 28 | avengers = %w[Hulk Thor Loki] 29 | Avenger.cyclic_barrier = Concurrent::CyclicBarrier.new(avengers.size - 1) 30 | Thread.current[:name] = "Main" # For debug logs. 31 | 32 | assert_queries_match(/ROLLBACK/) do # Ensure we are properly testing the retry mechanism. 33 | avengers.map do |name| 34 | Thread.fork do 35 | Thread.current[:name] = name # For debug logs. 36 | Avenger.create!(name: name) 37 | end 38 | end.each(&:join) 39 | end 40 | 41 | assert_equal avengers.size, Avenger.count 42 | ensure 43 | Thread.current[:name] = nil 44 | conn = ActiveRecord::Base.lease_connection 45 | conn.drop_table :avengers, if_exists: true 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /test/cases/unsafe_raw_sql_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "cases/helper_cockroachdb" 4 | require "models/post" 5 | require "models/comment" 6 | 7 | module CockroachDB 8 | class UnsafeRawSqlTest < ActiveRecord::TestCase 9 | fixtures :posts, :comments 10 | 11 | # OVERRIDE: We use the PostgreSQL `collation_name` for our adapter. 12 | test "order: allows valid arguments with COLLATE" do 13 | collation_name = "C" # <- Here is the overriden part. 14 | 15 | ids_expected = Post.order(Arel.sql(%Q'author_id, title COLLATE "#{collation_name}" DESC')).pluck(:id) 16 | 17 | ids = Post.order(["author_id", %Q'title COLLATE "#{collation_name}" DESC']).pluck(:id) 18 | 19 | assert_equal ids_expected, ids 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /test/config.yml: -------------------------------------------------------------------------------- 1 | default_connection: cockroachdb 2 | connections: 3 | cockroachdb: 4 | arunit: &arunit 5 | min_messages: warning 6 | host: 127.0.0.1 7 | port: 26257 8 | user: root 9 | disable_cockroachdb_telemetry: true 10 | # `autocommit_before_ddl` changed to default true in CockroachDB v25.1. 11 | # This does not work with active record's test suite. 12 | # 13 | # This options keyword is referenced here in libpq: 14 | # https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNECT-OPTIONS 15 | options: "-c autocommit_before_ddl=false" 16 | arunit_without_prepared_statements: 17 | <<: *arunit 18 | prepared_statements: false 19 | arunit2: 20 | <<: *arunit 21 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/AdapterForeignKeyTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_foreign_key_violations_are_translated_to_specific_exception_with_validate_false, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_foreign_key_violations_on_insert_are_translated_to_specific_exception, "This is override to prevent an intermittent error. Table fk_test_has_pk has constrain droped and not created back" 3 | exclude :test_foreign_key_violations_on_delete_are_translated_to_specific_exception, "This is override to prevent an intermittent error. Table fk_test_has_pk has constrain droped and not created back" 4 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/AdapterTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_indexes, "Rails transactional tests are being used while making schema changes. See https://www.cockroachlabs.com/docs/stable/online-schema-changes.html#limited-support-for-schema-changes-within-transactions." 2 | exclude :test_remove_index_when_name_and_wrong_column_name_specified, "Rails transactional tests are being used while making schema changes. See https://www.cockroachlabs.com/docs/stable/online-schema-changes.html#limited-support-for-schema-changes-within-transactions." 3 | exclude :test_remove_index_when_name_and_wrong_column_name_specified_positional_argument, "Rails transactional tests are being used while making schema changes. See https://www.cockroachlabs.com/docs/stable/online-schema-changes.html#limited-support-for-schema-changes-within-transactions." 4 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/AdapterTestWithoutTransaction.rb: -------------------------------------------------------------------------------- 1 | exclude :test_reset_empty_table_with_custom_pk, "The test fails because serial primary keys in CockroachDB are created with unique_rowid() where PostgreSQL will create them with a sequence. See https://www.cockroachlabs.com/docs/v19.2/serial.html#modes-of-operation" 2 | exclude :test_truncate_tables, "This is override to prevent an intermittent error. Table fk_test_has_pk has constrain droped and not created back" 3 | exclude :test_truncate_tables_with_query_cache, "This is override to prevent an intermittent error. Table fk_test_has_pk has constrain droped and not created back" 4 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/ConnectionAdapters/PoolConfig/ResolverTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_url_invalid_adapter, "rewritten to include cockroachdb in test" 2 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapter/BindParameterTest.rb: -------------------------------------------------------------------------------- 1 | require "support/copy_cat" 2 | 3 | # CockroachDB quotes numbers as strings. 4 | CopyCat.copy_methods(self, self, 5 | :test_where_with_float_for_string_column_using_bind_parameters, 6 | :test_where_with_decimal_for_string_column_using_bind_parameters, 7 | :test_where_with_rational_for_string_column_using_bind_parameters, 8 | :test_where_with_integer_for_string_column_using_bind_parameters) do 9 | def on_str(node) 10 | str = node.children[0] 11 | return unless ["0.0", "0", "0/1"].include?(str) 12 | 13 | replace(node.loc.expression, "'#{str}'".inspect) 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapter/QuotingTest.rb: -------------------------------------------------------------------------------- 1 | comment = "This adapter quotes integers as string, as CRDB is capable of " \ 2 | "implicitely converting, and checking for out of bound errors. " \ 3 | "See quoting.rb for more information." 4 | exclude :test_do_not_raise_when_int_is_not_wider_than_64bit, comment 5 | exclude :test_do_not_raise_when_raise_int_wider_than_64bit_is_false, comment 6 | exclude :test_raise_when_int_is_wider_than_64bit, comment 7 | 8 | require "support/copy_cat" 9 | 10 | CopyCat.copy_methods(self, self, 11 | :test_quote_big_decimal, 12 | :test_quote_rational, 13 | :test_quote_integer) do 14 | def on_str(node) 15 | return if defined?(@already_quoted) 16 | @already_quoted = true 17 | node => [:str, str] 18 | return unless ["4.2", "3/4", "42"].include?(str) 19 | 20 | replace(node.loc.expression, "'#{str}'".inspect) 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapterPreventWritesLegacyTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_doesnt_error_when_a_read_query_with_cursors_is_called_while_preventing_writes, "CockroachDB does not currently support declaring a cursor. See https://github.com/cockroachdb/cockroach/issues/41412." 2 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapterPreventWritesTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_doesnt_error_when_a_read_query_with_cursors_is_called_while_preventing_writes, "CockroachDB does not currently support declaring a cursor. See https://github.com/cockroachdb/cockroach/issues/41412." 2 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/ConnectionAdapters/RegistrationIsolatedTest.rb: -------------------------------------------------------------------------------- 1 | exclude "test_#resolve_raises_if_the_adapter_is_using_the_pre_7.2_adapter_registration_API", "One adapter is missing in the test, added below" 2 | 3 | test "#resolve raises if the adapter is using the pre 7.2 adapter registration API with CRDB" do 4 | exception = assert_raises(ActiveRecord::AdapterNotFound) do 5 | ActiveRecord::ConnectionAdapters.resolve("fake_legacy") 6 | end 7 | 8 | assert_equal( 9 | "Database configuration specifies nonexistent 'fake_legacy' adapter. Available adapters are: abstract, cockroachdb, fake, mysql2, postgresql, sqlite3, trilogy. Ensure that the adapter is spelled correctly in config/database.yml and that you've added the necessary adapter gem to your Gemfile if it's not in the list of available adapters.", 10 | exception.message 11 | ) 12 | ensure 13 | ActiveRecord::ConnectionAdapters.instance_variable_get(:@adapters).delete("fake_legacy") 14 | end 15 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/Encryption/EncryptionPerformanceTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_reading_an_encrypted_attribute_multiple_times_is_as_fast_as_reading_a_regular_attribute, "Test is flaky and tests an internal rails feature" 2 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/Encryption/EnvelopeEncryptionPerformanceTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_performance_when_saving_records, "Test is flaky and tests an internal rails feature" 2 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/Encryption/ExtendedDeterministicQueriesPerformanceTest.rb: -------------------------------------------------------------------------------- 1 | exclude "test_finding_without_prepared_statement_caching_by_encrypted_columns_(deterministic)", "Test is flaky and tests an internal rails feature" 2 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/Encryption/StoragePerformanceTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_storage_overload_storing_keys_is_acceptable_for_EnvelopeEncryptionKeyProvider, "Test is flaky and tests an internal rails feature" 2 | exclude :test_storage_overload_storing_keys_is_acceptable_for_DerivedSecretKeyProvider, "Test is flaky and tests an internal rails feature" 3 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/InvertibleMigrationTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_migrate_enable_and_disable_extension, "CockroachDB doesn't support enabling/disabling extensions." 2 | exclude :test_migrate_revert_change_column_default, "The test fails because type information is stripped from string column default values when the default is changed in the database. Possibly caused by https://github.com/cockroachdb/cockroach/issues/47285." 3 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/Migration/ChangeSchemaTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_change_column_quotes_column_names, "This functionality is not yet implemented in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/9851" 2 | exclude :test_create_table_without_id, "Tables cannot be created without a pk in CockroachDB" 3 | exclude :test_create_table_with_limits, "The only assertion that fails is on the default sql_type; this is bigint instead of integer in CockroachDB" 4 | exclude :test_add_column_with_primary_key_attribute, "PK can be re-assigned to a new column, but it must be done in a separate statement. In other words, the target column must already exist. See https://www.cockroachlabs.com/docs/v20.1/alter-primary-key.html" 5 | exclude :test_drop_table_if_exists, "It's not possible to check for the result of an operation in the same txn as which the operation is performed" 6 | exclude :test_change_column_null, "It's not possible to check for the result of an operation in the same txn as which the operation is performed" 7 | exclude :test_keeping_default_and_notnull_constraints_on_change, "It's not possible to check for the result of an operation in the same txn as which the operation is performed" 8 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/Migration/CheckConstraintTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_validate_check_constraint_by_name, "This test is failing with transactions due to cockroachdb/cockroach#19444" 2 | exclude :test_remove_check_constraint, "This test is failing with transactions due to cockroachdb/cockroach#19444" 3 | exclude :test_check_constraints, "Re-implementing because some constraints are now written in parenthesis" 4 | exclude :test_add_check_constraint, "Re-implementing because some constraints are now written in parenthesis" 5 | exclude :test_schema_dumping_with_validate_false, "Re-implementing because some constraints are now written in parenthesis" 6 | exclude :test_schema_dumping_with_validate_true, "Re-implementing because some constraints are now written in parenthesis" 7 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/Migration/ColumnsTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_change_column, "This operation is not currently supported in CockroachDB, see cockroachdb/cockroach#9851" 2 | exclude :test_change_column_default, "This test fails because type information is stripped from string column default values when the default is changed in the database. Possibly caused by https://github.com/cockroachdb/cockroach/issues/47285." 3 | exclude :test_change_column_default_with_from_and_to, "This test fails because type information is stripped from string column default values when the default is changed in the database. Possibly caused by https://github.com/cockroachdb/cockroach/issues/47285." 4 | exclude :test_remove_column_with_multi_column_index, "This test fails because it lacks the requisite CASCADE clause to fully remove the column" 5 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/Migration/CompatibilityTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_legacy_change_column_with_null_executes_update, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_legacy_add_foreign_key_with_deferrable_true, "CRDB does not support DEFERRABLE constraints" 3 | exclude :test_disable_extension_on_7_0, "CRDB does not support enabling/disabling extensions." 4 | 5 | # exclude :test_add_index_errors_on_too_long_name_7_0, "The max length in CRDB is 128, not 64." 6 | # exclude :test_create_table_add_index_errors_on_too_long_name_7_0, "The max length in CRDB is 128, not 64." 7 | 8 | require "support/copy_cat" 9 | 10 | CopyCat.copy_methods(self, self, 11 | :test_add_index_errors_on_too_long_name_7_0, 12 | :test_create_table_add_index_errors_on_too_long_name_7_0 13 | ) do 14 | def on_sym(node) 15 | return unless node.children[0] == :very_long_column_name_to_test_with 16 | 17 | insert_after(node.loc.expression, "_and_actually_way_longer_because_cockroach_is_in_the_128_game") 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/Migration/CompositeForeignKeyTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_add_composite_foreign_key_raises_without_options, "Updated regexp to remove quotes" 2 | exclude :test_schema_dumping, ExcludeMessage::VALIDATE_BUG 3 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/Migration/CreateJoinTableTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_create_join_table_with_index, "Results of an operation cannot be accessed prior to completion of that operation's transaction. See https://www.cockroachlabs.com/docs/v19.2/architecture/transaction-layer.html#transaction-conflicts" 2 | exclude :test_create_and_drop_join_table_with_common_prefix, "Results of an operation cannot be accessed prior to completion of that operation's transaction. See https://www.cockroachlabs.com/docs/v19.2/architecture/transaction-layer.html#transaction-conflicts" 3 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/Migration/ForeignKeyInCreateTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_foreign_keys, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/Migration/InvalidOptionsTest.rb: -------------------------------------------------------------------------------- 1 | module Ext 2 | def invalid_add_column_option_exception_message(key) 3 | default_keys = [":limit", ":precision", ":scale", ":default", ":null", ":collation", ":comment", ":primary_key", ":if_exists", ":if_not_exists"] 4 | 5 | # PostgreSQL specific options 6 | default_keys.concat([":array", ":using", ":cast_as", ":as", ":type", ":enum_type", ":stored"]) 7 | 8 | # CockroachDB specific options 9 | default_keys.concat([":srid", ":has_z", ":has_m", ":geographic", ":spatial_type", ":hidden"]) 10 | 11 | "Unknown key: :#{key}. Valid keys are: #{default_keys.join(", ")}" 12 | end 13 | end 14 | prepend Ext 15 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/Migration/PGChangeSchemaTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_change_string_to_date, "Changing column data types is not supported in a transaction in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/9851." 2 | exclude :test_change_type_with_symbol, "Changing column data types is not supported in a transaction in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/9851." 3 | exclude :test_change_type_with_symbol_with_timestamptz, "Changing column data types is not supported in a transaction in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/9851." 4 | exclude :test_change_type_with_symbol_using_datetime, "Changing column data types is not supported in a transaction in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/9851." 5 | exclude :test_change_type_with_symbol_using_timestamp_with_timestamptz_as_default, "Changing column data types is not supported in a transaction in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/9851." 6 | exclude :test_change_type_with_symbol_with_timestamptz_as_default, "Changing column data types is not supported in a transaction in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/9851." 7 | exclude :test_change_type_with_symbol_using_datetime_with_timestamptz_as_default, "Changing column data types is not supported in a transaction in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/9851." 8 | exclude :test_change_type_with_array, "Changing column data types is not supported in a transaction in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/9851." 9 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/Migration/ReferencesForeignKeyTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_foreign_keys_can_be_created_while_changing_the_table, "Results of an operation cannot be accessed prior to completion of that operation's transaction. See https://www.cockroachlabs.com/docs/v19.2/architecture/transaction-layer.html#transaction-conflicts" 2 | exclude :test_foreign_keys_accept_options_when_changing_the_table, "Results of an operation cannot be accessed prior to completion of that operation's transaction. See https://www.cockroachlabs.com/docs/v19.2/architecture/transaction-layer.html#transaction-conflicts" 3 | exclude :test_foreign_key_column_can_be_removed, "Results of an operation cannot be accessed prior to completion of that operation's transaction. See https://www.cockroachlabs.com/docs/v19.2/architecture/transaction-layer.html#transaction-conflicts" 4 | exclude :test_removing_column_removes_foreign_key, "Results of an operation cannot be accessed prior to completion of that operation's transaction. See https://www.cockroachlabs.com/docs/v19.2/architecture/transaction-layer.html#transaction-conflicts" 5 | exclude :test_foreign_key_methods_respect_pluralize_table_names, "Results of an operation cannot be accessed prior to completion of that operation's transaction. See https://www.cockroachlabs.com/docs/v19.2/architecture/transaction-layer.html#transaction-conflicts" 6 | exclude :test_multiple_foreign_keys_can_be_removed_to_the_selected_one, "Results of an operation cannot be accessed prior to completion of that operation's transaction. See https://www.cockroachlabs.com/docs/v19.2/architecture/transaction-layer.html#transaction-conflicts" 7 | exclude :test_multiple_foreign_keys_can_be_added_to_the_same_table, "Results of an operation cannot be accessed prior to completion of that operation's transaction. See https://www.cockroachlabs.com/docs/v19.2/architecture/transaction-layer.html#transaction-conflicts" 8 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/Migration/ReferencesIndexTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_creates_index_by_default_even_if_index_option_is_not_passed, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_creates_index_for_existing_table_even_if_index_option_is_not_passed, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 3 | exclude :test_creates_index_with_options, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 4 | exclude :test_creates_polymorphic_index_for_existing_table, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 5 | exclude :test_creates_index_for_existing_table, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 6 | exclude :test_creates_polymorphic_index, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 7 | exclude :test_creates_index, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 8 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/Migration/ReferencesStatementsTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_deletes_reference_type_column, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_does_not_delete_reference_type_column, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 3 | exclude :test_deletes_polymorphic_index, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 4 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/MysqlDBCreateWithInvalidPermissionsTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_raises_error, "No link with MySQL" 2 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/OrTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_or_when_grouping, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/PostgreSQLStructureDumpTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_structure_dump, "Skipping for now because the exclusion of postgis tables from the SchemaDumper is causing the test to fail due to expected argument mismatch (because our arguments include the excluded tables)." 2 | exclude :test_structure_dump_execution_fails, "Skipping for now because the exclusion of postgis tables from the SchemaDumper is causing the test to fail due to expected argument mismatch (because our arguments include the excluded tables)." 3 | exclude :test_structure_dump_with_dump_schemas_string, "Skipping for now because the exclusion of postgis tables from the SchemaDumper is causing the test to fail due to expected argument mismatch (because our arguments include the excluded tables)." 4 | exclude :test_structure_dump_with_extra_flags, "Skipping for now because the exclusion of postgis tables from the SchemaDumper is causing the test to fail due to expected argument mismatch (because our arguments include the excluded tables)." 5 | exclude :test_structure_dump_with_schema_search_path, "Skipping for now because the exclusion of postgis tables from the SchemaDumper is causing the test to fail due to expected argument mismatch (because our arguments include the excluded tables)." 6 | exclude :test_structure_dump_with_schema_search_path_and_dump_schemas_all, "Skipping for now because the exclusion of postgis tables from the SchemaDumper is causing the test to fail due to expected argument mismatch (because our arguments include the excluded tables)." 7 | exclude :test_structure_dump_with_hash_extra_flags_for_a_different_driver, "Skipping for now because the exclusion of postgis tables from the SchemaDumper is causing the test to fail due to expected argument mismatch (because our arguments include the excluded tables)." 8 | exclude :test_structure_dump_with_ssl_env, "Skipping for now because the exclusion of postgis tables from the SchemaDumper is causing the test to fail due to expected argument mismatch (because our arguments include the excluded tables)." 9 | exclude :test_structure_dump_with_env, "Skipping for now because the exclusion of postgis tables from the SchemaDumper is causing the test to fail due to expected argument mismatch (because our arguments include the excluded tables)." 10 | exclude :test_structure_dump_with_hash_extra_flags_for_the_correct_driver, "Skipping for now because the exclusion of postgis tables from the SchemaDumper is causing the test to fail due to expected argument mismatch (because our arguments include the excluded tables)." 11 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/PostgresqlConnectionTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_default_client_min_messages, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_get_and_release_advisory_lock, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 3 | exclude :test_reconnection_after_actual_disconnection_with_verify, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 4 | exclude :test_reset, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 5 | exclude :test_release_non_existent_advisory_lock, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 6 | exclude :test_table_alias_length_logs_name, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 7 | exclude :test_statement_key_is_logged, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 8 | exclude :test_connection_options, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 9 | exclude :test_reset_with_transaction, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 10 | exclude :test_set_session_variable_true, "Re-implemented with a CockroachDB compatible session variable." 11 | exclude :test_set_session_variable_false, "Re-implemented with a CockroachDB compatible session variable." 12 | exclude :test_set_session_variable_nil, "Re-implemented with a CockroachDB compatible session variable." 13 | exclude :test_set_session_variable_default, "Re-implemented with a CockroachDB compatible session variable." 14 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/PostgresqlTransactionNestedTest.rb: -------------------------------------------------------------------------------- 1 | 2 | # > In CRDB SERIALIZABLE, reads block on in-progress writes for 3 | # > as long as those writes are in progress. However, PG does 4 | # > not have this "read block on write" behavior, and so rather 5 | # > than allowing the left-hand-side to execute, it must instead 6 | # > abort that transaction. Both are valid ways to implement SERIALIZABLE. 7 | # 8 | # See discussion: https://github.com/cockroachdb/activerecord-cockroachdb-adapter/pull/333 9 | message = "SERIALIZABLE transactions are different in CockroachDB." 10 | 11 | exclude :test_deadlock_raises_Deadlocked_inside_nested_SavepointTransaction, message 12 | exclude :test_unserializable_transaction_raises_SerializationFailure_inside_nested_SavepointTransaction, message 13 | exclude :test_SerializationFailure_inside_nested_SavepointTransaction_is_recoverable, message 14 | exclude :test_deadlock_inside_nested_SavepointTransaction_is_recoverable, message 15 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/PostgresqlTransactionTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_raises_LockWaitTimeout_when_lock_wait_timeout_exceeded, "The test tries to set lock_timeout, but lock_timeout is not supported by CockroachDB." 2 | exclude :test_raises_QueryCanceled_when_canceling_statement_due_to_user_request, "CockroachDB doesn't support pg_cancel_backend()." 3 | exclude :test_raises_Deadlocked_when_a_deadlock_is_encountered, "Causes CI to hand. Skip while debugging." 4 | exclude :test_raises_SerializationFailure_when_a_serialization_failure_occurs, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 5 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/RelationTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_relation_with_annotation_filters_sql_comment_delimiters, "This test is overridden for CockroachDB because this adapter adds quotes to numeric values." 2 | exclude :test_relation_with_annotation_includes_comment_in_to_sql, "This test is overridden for CockroachDB because this adapter adds quotes to numeric values." 3 | -------------------------------------------------------------------------------- /test/excludes/ActiveRecord/TooManyOrTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_too_many_or, "This test takes a very long time to run, so we are skipping until we can fix it later." 2 | -------------------------------------------------------------------------------- /test/excludes/ActiveSupportSubclassWithFixturesTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_foo, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | -------------------------------------------------------------------------------- /test/excludes/BasicsTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_column_names_are_escaped, "Rewritten for CockroachDB" 2 | -------------------------------------------------------------------------------- /test/excludes/BulkAlterTableMigrationsTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_changing_columns, "Type conversion from DATE to TIMESTAMP requires overwriting existing values which is not yet implemented. https://github.com/cockroachdb/cockroach/issues/9851" 2 | exclude :test_changing_column_null_with_default, "Type conversion from DATE to TIMESTAMP requires overwriting existing values which is not yet implemented. https://github.com/cockroachdb/cockroach/issues/9851" 3 | 4 | exclude :test_adding_indexes, "Need to reference the specific query count for CockroachDB" 5 | exclude :test_removing_index, "Need to reference the specific query count for CockroachDB" 6 | exclude :test_adding_multiple_columns, "Need to reference the specific query count for CockroachDB" 7 | exclude :test_changing_index, "Need to reference the specific query count for CockroachDB" 8 | -------------------------------------------------------------------------------- /test/excludes/CalculationsTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_group_by_with_order_by_virtual_count_attribute, "Ordering with virtual count attributes is not supported against CockroachDB." 2 | exclude :test_group_by_with_limit, "The test fails because ActiveRecord strips out the query order clause making it impossible to guarantee the results order. See bug issue https://github.com/rails/rails/issues/38936." 3 | exclude :test_group_by_with_offset, "The test fails because ActiveRecord strips out the query order clause making it impossible to guarantee the results order. See bug issue https://github.com/rails/rails/issues/38936." 4 | exclude :test_group_by_with_limit_and_offset, "The test fails because ActiveRecord strips out the query order clause making it impossible to guarantee the results order. See bug issue https://github.com/rails/rails/issues/38936." 5 | -------------------------------------------------------------------------------- /test/excludes/CommentTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_remove_comment_from_column, "The test fails because altered columns cannot change comments. We implement our own version." 2 | exclude :test_schema_dump_with_comments, "The test fails because altered columns cannot change comments. We implement our own version." 3 | -------------------------------------------------------------------------------- /test/excludes/CoreTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_pretty_print_persisted, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | -------------------------------------------------------------------------------- /test/excludes/CreateOrFindByWithinTransactions.rb: -------------------------------------------------------------------------------- 1 | ref = "See issue https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/306" 2 | exclude :test_multiple_find_or_create_by_bang_within_transactions, ref 3 | exclude :test_multiple_find_or_create_by_within_transactions, ref 4 | -------------------------------------------------------------------------------- /test/excludes/DefaultsUsingMultipleSchemasAndDomainTest.rb: -------------------------------------------------------------------------------- 1 | message = "Custom domains are not supported. See https://github.com/cockroachdb/cockroach/issues/27796" 2 | exclude :test_text_defaults_in_new_schema_when_overriding_domain, message 3 | exclude :test_string_defaults_in_new_schema_when_overriding_domain, message 4 | exclude :test_decimal_defaults_in_new_schema_when_overriding_domain, message 5 | exclude :test_bpchar_defaults_in_new_schema_when_overriding_domain, message 6 | exclude :test_text_defaults_after_updating_column_default, message 7 | exclude :test_default_containing_quote_and_colons, message 8 | -------------------------------------------------------------------------------- /test/excludes/DirtyTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_field_named_field, "Rails transactional tests are being used while making schema changes. See https://www.cockroachlabs.com/docs/stable/online-schema-changes.html#limited-support-for-schema-changes-within-transactions." 2 | exclude :test_partial_update_with_optimistic_locking, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 3 | exclude :test_virtual_attributes_are_not_written_with_partial_writes_off, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 4 | -------------------------------------------------------------------------------- /test/excludes/EachTest.rb: -------------------------------------------------------------------------------- 1 | require "support/copy_cat" 2 | 3 | # CockroachDB doesn't update schema information when adding an 4 | # index until the transaction is done. Hence impossible to delete 5 | # this index before completion of the transaction. 6 | exclude_from_transactional_tests :test_in_batches_iterating_using_custom_columns 7 | exclude_from_transactional_tests :test_in_batches_with_custom_columns_raises_when_non_unique_columns 8 | exclude_from_transactional_tests :test_in_batches_when_loaded_iterates_using_custom_column 9 | -------------------------------------------------------------------------------- /test/excludes/EagerLoadPolyAssocsTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_include_query, "The test setup doesn't properly handle random unique primary keys. This is a bug in ActiveRecord, so exclude the test until it's fixed there. See https://github.com/rails/rails/pull/38883. Note: any bug fix is unlikely to be backported to older versions of Rails." 2 | -------------------------------------------------------------------------------- /test/excludes/ExplicitlyNamedIndexMigrationTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_drop_index_by_name, "This isn't supported by CockroachDB; see https://www.cockroachlabs.com/docs/stable/online-schema-changes.html#examples-of-statements-that-fail for more information" 2 | -------------------------------------------------------------------------------- /test/excludes/FixturesResetPkSequenceTest.rb: -------------------------------------------------------------------------------- 1 | exclude "test_resets_to_min_pk_with_specified_pk_and_sequence", "This test doesn't work against CockroachDB because serial primary keys default to using unique_rowid() instead of a sequence. See https://www.cockroachlabs.com/docs/v19.2/serial.html#modes-of-operation" 2 | exclude "test_resets_to_min_pk_with_default_pk_and_sequence", "This test doesn't work against CockroachDB because serial primary keys default to using unique_rowid() instead of a sequence. See https://www.cockroachlabs.com/docs/v19.2/serial.html#modes-of-operation" 3 | exclude "test_create_fixtures_resets_sequences_when_not_cached", "This test doesn't work against CockroachDB because serial primary keys default to using unique_rowid() instead of a sequence. See https://www.cockroachlabs.com/docs/v19.2/serial.html#modes-of-operation" 4 | -------------------------------------------------------------------------------- /test/excludes/FixturesTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_bulk_insert_multiple_table_with_a_multi_statement_query, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_bulk_insert_with_a_multi_statement_query_in_a_nested_transaction, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 3 | exclude :test_clean_fixtures, "Skipping the PostgreSQL test, but reimplemented for CockroachDB in test/cases/fixtures_test.rb" 4 | exclude :test_auto_value_on_primary_key, "Skipping the PostgreSQL test, but reimplemented for CockroachDB in test/cases/fixtures_test.rb" 5 | exclude :test_create_fixtures, "Skipping the PostgreSQL test, but reimplemented for CockroachDB in test/cases/fixtures_test.rb" 6 | exclude :test_multiple_clean_fixtures, "Skipping the PostgreSQL test, but reimplemented for CockroachDB in test/cases/fixtures_test.rb" 7 | exclude :test_bulk_insert_with_a_multi_statement_query_raises_an_exception_when_any_insert_fails, "Skipping the PostgreSQL test, but reimplemented for CockroachDB in test/cases/fixtures_test.rb" 8 | exclude :test_inserts_with_pre_and_suffix, "Skipping the PostgreSQL test, but reimplemented for CockroachDB in test/cases/fixtures_test.rb" 9 | exclude :test_create_symbol_fixtures, "Skipping the PostgreSQL test, but reimplemented for CockroachDB in test/cases/fixtures_test.rb" 10 | 11 | module Replacement 12 | def test_insert_with_default_function 13 | before = Time.now.utc 14 | create_fixtures("aircrafts") 15 | after = Time.now.utc 16 | 17 | aircraft = Aircraft.find_by(name: "boeing-with-no-manufactured-at") 18 | assert before <= aircraft.manufactured_at && aircraft.manufactured_at <= after 19 | end 20 | end 21 | 22 | prepend Replacement 23 | -------------------------------------------------------------------------------- /test/excludes/FixturesWithForeignKeyViolationsTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_raises_fk_violations, 'Re-implemented our own version that does not use transactional tests.' 2 | exclude :test_does_not_raise_if_no_fk_violations, 'Re-implemented our own version that does not use transactional tests.' 3 | -------------------------------------------------------------------------------- /test/excludes/ForeignTableTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_attribute_names, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_foreign_tables, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 3 | exclude :test_table_exists, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 4 | exclude :test_attributes, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 5 | exclude :test_update_record, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 6 | exclude :test_delete_record, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 7 | exclude :test_foreign_table_exists, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 8 | exclude :test_insert_record, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 9 | exclude :test_foreign_tables_are_valid_data_sources, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 10 | exclude :test_does_not_have_a_primary_key, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 11 | -------------------------------------------------------------------------------- /test/excludes/InheritanceComputeTypeTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_inheritance_new_with_subclass_as_default, "The test fails because type information is stripped from string column default values when the default is changed in the database. Possibly caused by https://github.com/cockroachdb/cockroach/issues/47285." 2 | -------------------------------------------------------------------------------- /test/excludes/LeftOuterJoinAssociationTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_construct_finder_sql_applies_aliases_tables_on_association_conditions, "The test fails because the query result order is not guaranteed." 2 | exclude :test_does_not_override_select, "The select query fails because strings cannot be concated non-strings in CockroachDB." 3 | -------------------------------------------------------------------------------- /test/excludes/LegacyPrimaryKeyTest/V4_2.rb: -------------------------------------------------------------------------------- 1 | exclude :test_legacy_primary_key_in_create_table_should_be_integer, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_legacy_primary_key_should_be_auto_incremented, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 3 | exclude :test_legacy_integer_primary_key_should_not_be_auto_incremented, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 4 | exclude :test_add_column_with_legacy_primary_key_should_be_integer, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 5 | exclude :test_legacy_join_table_foreign_keys_should_be_integer, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 6 | exclude :test_legacy_primary_key_in_change_table_should_be_integer, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 7 | -------------------------------------------------------------------------------- /test/excludes/LegacyPrimaryKeyTest/V5_0.rb: -------------------------------------------------------------------------------- 1 | exclude :test_legacy_integer_primary_key_should_not_be_auto_incremented, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_legacy_primary_key_in_create_table_should_be_integer, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 3 | exclude :test_legacy_join_table_foreign_keys_should_be_integer, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 4 | exclude :test_legacy_primary_key_in_change_table_should_be_integer, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 5 | exclude :test_legacy_primary_key_should_be_auto_incremented, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 6 | exclude :test_add_column_with_legacy_primary_key_should_be_integer, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 7 | -------------------------------------------------------------------------------- /test/excludes/MarshalSerializationTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_deserializing_rails_6_1_marshal_basic, "This uses the adapter name to find a file. We run our own version that specifies which file to use." 2 | exclude :test_deserializing_rails_6_1_marshal_with_loaded_association_cache, "This uses the adapter name to find a file. We run our own version that specifies which file to use." 3 | exclude :test_deserializing_rails_7_1_marshal_basic, "This uses the adapter name to find a file. We run our own version that specifies which file to use." 4 | exclude :test_deserializing_rails_7_1_marshal_with_loaded_association_cache, "This uses the adapter name to find a file. We run our own version that specifies which file to use." 5 | -------------------------------------------------------------------------------- /test/excludes/MaterializedViewTest.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | 4 | # Materialized views in CRDB do not show up in `pg_class` in 5 | # the transaction they are created. Try this again to see if 6 | # it changed: 7 | # 8 | # ```sql 9 | # BEGIN; 10 | # CREATE MATERIALIZED VIEW foo AS SELECT 1; 11 | # SELECT * FROM pg_class WHERE relname = 'foo'; 12 | # ``` 13 | self.use_transactional_tests = false 14 | -------------------------------------------------------------------------------- /test/excludes/MigrationTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_add_table_with_decimals, "CockroachDB uses 64-bit signed integers, whereas the default for PG is 32-bit. The Rails test does not accommodate the 64-bit case" 2 | exclude :test_remove_column_with_if_not_exists_not_set, "We re-implement our own version. CockroachDB does not include the table name in a 'column does not exist' message." 3 | -------------------------------------------------------------------------------- /test/excludes/MultiDbMigratorTest.rb: -------------------------------------------------------------------------------- 1 | # We can't add and remove a column in the same transaction with CockroachDB 2 | exclude_from_transactional_tests :test_internal_metadata_stores_environment 3 | -------------------------------------------------------------------------------- /test/excludes/NestedRelationScopingTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_merge_options, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | -------------------------------------------------------------------------------- /test/excludes/OrTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_or_when_grouping, "This test produces a non-deterministic result. See rails/rails#38978 for fix; patch replicated in adapter test" 2 | -------------------------------------------------------------------------------- /test/excludes/PersistenceTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_model_with_no_auto_populated_fields_still_returns_primary_key_after_insert, "This test is using PL-PGSQL not compatible with CockroachDB" 2 | exclude :test_reset_column_information_resets_children, "This test fails because the column is created in the same transaction in which the test attempts to assert/operate further." 3 | exclude :test_fills_auto_populated_columns_on_creation, "See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/308" 4 | -------------------------------------------------------------------------------- /test/excludes/PessimisticLockingTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_lock_sending_custom_lock_statement, "NOWAIT lock wait policy is not supported by CockroachDB. See https://github.com/cockroachdb/cockroach/issues/40476." 2 | -------------------------------------------------------------------------------- /test/excludes/PostgreSQLExplainTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_explain_with_eager_loading, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_explain_for_one_query, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 3 | 4 | no_options = "Explain options are not yet supported by this adapter. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/301" 5 | exclude :test_explain_with_options_as_symbols, no_options 6 | exclude :test_explain_with_options_as_strings, no_options 7 | exclude :test_explain_options_with_eager_loading, no_options 8 | -------------------------------------------------------------------------------- /test/excludes/PostgreSQLGeometricLineTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_geometric_line_type, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 2 | exclude :test_alternative_format_line_type, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 3 | exclude :test_schema_dumping_for_line_type, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 4 | -------------------------------------------------------------------------------- /test/excludes/PostgreSQLGeometricTypesTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_creating_column_with_point_type, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 2 | exclude :test_creating_column_with_line_type, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 3 | exclude :test_creating_column_with_lseg_type, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 4 | exclude :test_creating_column_with_box_type, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 5 | exclude :test_creating_column_with_path_type, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 6 | exclude :test_creating_column_with_polygon_type, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 7 | exclude :test_creating_column_with_circle_type, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 8 | -------------------------------------------------------------------------------- /test/excludes/PostgreSQLPartitionsTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_partitions_table_exists, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | -------------------------------------------------------------------------------- /test/excludes/PostgreSQLReferentialIntegrityTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_only_catch_active_record_errors_others_bubble_up, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_should_reraise_invalid_foreign_key_exception_and_show_warning, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 3 | exclude :test_does_not_break_transactions, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 4 | exclude :test_does_not_break_nested_transactions, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 5 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlArrayTest.rb: -------------------------------------------------------------------------------- 1 | require "support/copy_cat" 2 | 3 | # Remove hstore from setup (both the extension and the column). 4 | CopyCat.copy_methods(self, self, :setup) do 5 | def on_send(node) 6 | if node in [:send, nil, :enable_extension!, [:str, "hstore"], *] | # enable_extension!("hstore", ...) 7 | [:send, [:lvar, :t], :hstore, *] # t.hstore(...) 8 | remove(node.location.expression) 9 | end 10 | end 11 | end 12 | 13 | exclude :test_change_column_default_with_array, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 14 | exclude :test_schema_dump_with_shorthand, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 15 | exclude :test_change_column_from_non_array_to_array, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 16 | exclude :test_with_multi_dimensional_empty_strings, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 17 | exclude :test_mutate_value_in_array, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 18 | exclude :test_change_column_with_array, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 19 | exclude :test_multi_dimensional_with_integers, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 20 | exclude :test_with_arbitrary_whitespace, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 21 | exclude :test_multi_dimensional_with_strings, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 22 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlBigSerialTest.rb: -------------------------------------------------------------------------------- 1 | # Note: all these tests fail during setup trying to create a column with a 2 | # sequence backed default because the sequence doesn't exist. The tests still 3 | # fail for different reasons after the setup is fixed. 4 | exclude :test_bigserial_column, "The test is valid but can't pass with the bad setup." 5 | exclude :test_not_bigserial_column, "The serial? assertion fails because a bigint column with a serial default function is not distinguishable from a serial column. See https://www.cockroachlabs.com/docs/v19.2/serial.html#modes-of-operation." 6 | exclude :test_schema_dump_with_shorthand, "The test is valid but can't pass with the bad setup." 7 | exclude :test_schema_dump_with_not_bigserial, "If a bigint column is created with a serial default function, it will be treated like a serial column in CockroachDB." 8 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlBitStringTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_default, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_schema_dumping, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 3 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlByteaTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_via_to_sql_with_complicating_connection, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlCitextTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_select_case_insensitive, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_column, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 3 | exclude :test_change_table_supports_json, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 4 | exclude :test_write, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 5 | exclude :test_citext_enabled, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 6 | exclude :test_schema_dump_with_shorthand, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 7 | exclude :test_case_insensitiveness, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 8 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlCollationTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_change_column_with_collation, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_schema_dump_includes_collation, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 3 | exclude :test_add_column_with_collation, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 4 | exclude :test_string_column_with_collation, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 5 | exclude :test_text_column_with_collation, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 6 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlCompositeTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_column, "Composite types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/27792" 2 | exclude :test_composite_mapping, "Composite types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/27792" 3 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlCompositeWithCustomOIDTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_column, "Composite types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/27792" 2 | exclude :test_composite_mapping, "Composite types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/27792" 3 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlDataTypeTest.rb: -------------------------------------------------------------------------------- 1 | 2 | ago_msg = "'ago' is not supported in CRDB's interval parsing. Test ignored. See #340" 3 | exclude :test_text_columns_are_limitless_the_upper_limit_is_one_GB, ago_msg 4 | exclude :test_data_type_of_oid_types, ago_msg 5 | exclude :test_update_oid, ago_msg 6 | exclude :test_data_type_of_time_types, ago_msg 7 | exclude :test_oid_values, ago_msg 8 | exclude :test_time_values, ago_msg 9 | exclude :test_update_large_time_in_seconds, ago_msg 10 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlDefaultExpressionTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_schema_dump_includes_default_expression, "The test fails because CockroachDB uses different functions than PostgreSQL for current date/timestamps. See https://www.cockroachlabs.com/docs/v19.2/functions-and-operators.html#date-and-time-functions." 2 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlDeferredConstraintsTest.rb: -------------------------------------------------------------------------------- 1 | instance_methods.grep(/\Atest_/).each do |m| 2 | exclude m, "CockroachDB doesn't support 'SET CONSTRAINTS ...'" 3 | end 4 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlDomainTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_column, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_domain_acts_like_basetype, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 3 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlExtensionMigrationTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_disable_extension_migration_ignores_prefix_and_suffix, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_enable_extension_migration_ignores_prefix_and_suffix, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 3 | exclude :test_disable_extension_drops_extension_when_cascading, ExcludeMessage::NO_HSTORE 4 | exclude :test_disable_extension_raises_when_dependent_objects_exist, ExcludeMessage::NO_HSTORE 5 | exclude :test_enable_extension_migration_with_schema, ExcludeMessage::NO_HSTORE 6 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlFullTextTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_update_tsvector, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_schema_dump_with_shorthand, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 3 | exclude :test_tsvector_column, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 4 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlGeometricTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_geometric_types, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 2 | exclude :test_alternative_format, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 3 | exclude :test_geometric_function, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 4 | exclude :test_schema_dumping, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 5 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlInfinityTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_type_casting_infinity_on_a_float_column, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_type_casting_infinity_on_a_datetime_column, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 3 | exclude :test_update_all_with_infinity_on_a_float_column, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 4 | exclude "test_assigning_'infinity'_on_a_datetime_column_with_TZ_aware_attributes", "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 5 | exclude :test_update_all_with_infinity_on_a_datetime_column, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 6 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlIntervalTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_schema_dump_with_default_value, "We implement our own tests for intervals, since CockroachDB does not support Iso8601 IntervalStyle currently." 2 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlLtreeTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_column, "CockroachDB does not currently support the 'ltree' type." 2 | exclude :test_schema_dump_with_shorthand, "CockroachDB does not currently support the 'ltree' type." 3 | exclude :test_write, "CockroachDB does not currently support the 'ltree' type." 4 | exclude :test_select, "CockroachDB does not currently support the 'ltree' type." 5 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlMoneyTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_column, "The money type is not implemented in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/41578." 2 | exclude :test_default, "The money type is not implemented in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/41578." 3 | exclude :test_money_values, "The money type is not implemented in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/41578." 4 | exclude :test_money_type_cast, "The money type is not implemented in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/41578." 5 | exclude :test_money_regex_backtracking, "The money type is not implemented in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/41578." 6 | exclude :test_schema_dumping, "The money type is not implemented in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/41578." 7 | exclude :test_create_and_update_money, "The money type is not implemented in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/41578." 8 | exclude :test_update_all_with_money_string, "The money type is not implemented in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/41578." 9 | exclude :test_update_all_with_money_big_decimal, "The money type is not implemented in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/41578." 10 | exclude :test_update_all_with_money_numeric, "The money type is not implemented in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/41578." 11 | exclude :test_sum_with_type_cast, "The money type is not implemented in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/41578." 12 | exclude :test_pluck_with_type_cast, "The money type is not implemented in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/41578." 13 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlNetworkTest.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "support/copy_cat" 4 | 5 | raise "a new setup has been added" if get_callbacks(:setup).count > 1 6 | 7 | reset_callbacks :setup 8 | 9 | setup do 10 | @connection = ActiveRecord::Base.lease_connection 11 | @connection.create_table("postgresql_network_addresses", force: true) do |t| 12 | t.inet "inet_address", default: "192.168.1.1" 13 | # Unsupported types cidr and macaddr 14 | # t.cidr "cidr_address", default: "192.168.1.0/24" 15 | # t.macaddr "mac_address", default: "ff:ff:ff:ff:ff:ff" 16 | end 17 | end 18 | 19 | exclude :test_cidr_column, "CockroachDB does not currently support the 'cidr' type." 20 | exclude :test_cidr_change_prefix, "CockroachDB does not currently support the 'cidr' type." 21 | exclude :test_macaddr_column, "CockroachDB does not currently support the 'macaddr' type." 22 | exclude :test_mac_address_change_case_does_not_mark_dirty, "CockroachDB does not currently support the 'macaddr' type." 23 | 24 | CopyCat.copy_methods(self, self, :test_schema_dump_with_shorthand) do 25 | def on_send(node) 26 | return unless node in [:send, nil, :assert_match, 27 | [:regexp, [:str, /(cidr|mac)_address/], *], 28 | * 29 | ] 30 | remove(node.location.expression) 31 | end 32 | end 33 | 34 | CopyCat.copy_methods(self, self, :test_network_types, :test_invalid_network_address) do 35 | def on_send(node) 36 | case node 37 | in [:send, [:const, nil, :PostgresqlNetworkAddress], /create|new/, [:hash, *pairs]] 38 | 39 | pairs.each_with_index do |pair, i| 40 | if pair in [:pair, [:sym, /(cidr|mac)_address/], *] 41 | expr = pair.location.expression 42 | large_expr = expr.resize(expr.size + 1) 43 | expr = large_expr if large_expr.source.end_with?(",") 44 | remove(expr) 45 | end 46 | end 47 | in [:send, [:lvar, :address], /(cidr|mac)_address/, *] 48 | remove(node.location.expression) 49 | in [:send, nil, /assert_(equal|nil)/, *list] 50 | # Recursive search for cidr or mac in test assertions. 51 | until list.empty? 52 | el = list.shift 53 | if el.respond_to?(:children) 54 | list.concat(el.children) 55 | else 56 | if el.respond_to?(:to_s) 57 | str = el.to_s.downcase 58 | if str.include?("cidr") || str.include?("mac") 59 | remove(node.location.expression) 60 | break 61 | end 62 | end 63 | end 64 | end 65 | else 66 | # Nothing 67 | end 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlNumberTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_values, "This test fails for an unknown reason on 'assert_equal ::Float::INFINITY, second.double' because Infinity is being cast to 0.0. See #77 for more details" 2 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlPointTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_column, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 2 | exclude :test_default, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 3 | exclude :test_schema_dumping, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 4 | exclude :test_roundtrip, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 5 | exclude :test_mutation, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 6 | exclude :test_array_assignment, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 7 | exclude :test_string_assignment, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 8 | exclude :test_empty_string_assignment, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 9 | exclude :test_array_of_points_round_trip, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 10 | exclude :test_legacy_column, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 11 | exclude :test_legacy_default, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 12 | exclude :test_legacy_schema_dumping, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 13 | exclude :test_legacy_roundtrip, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 14 | exclude :test_legacy_mutation, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 15 | exclude :test_hash_assignment, "Geometric types are not supported in CockroachDB. See https://github.com/cockroachdb/cockroach/issues/21286." 16 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlRangeTest.rb: -------------------------------------------------------------------------------- 1 | message = "CockroachDB doesn't support ranges. See https://github.com/cockroachdb/cockroach/issues/27791" 2 | # No test is relevant in this class. 3 | instance_methods.grep(/\Atest_/).each { exclude _1, message } 4 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlRenameTableTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_renaming_a_table_also_renames_the_primary_key_index, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_renaming_a_table_also_renames_the_primary_key_sequence, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 3 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlSerialTest.rb: -------------------------------------------------------------------------------- 1 | # Note: all these tests fail during setup trying to create a column with a 2 | # sequence backed default because the sequence doesn't exist. The tests still 3 | # fail for different reasons after the setup is fixed. 4 | exclude :test_serial_column, "The sql_type assertion fails because integer columns are bigints in CockroachDB. See https://www.cockroachlabs.com/docs/v19.2/int.html#names-and-aliases." 5 | exclude :test_not_serial_column, "The sql_type assertion fails because integer columns are bigints in CockroachDB. See https://www.cockroachlabs.com/docs/v19.2/int.html#names-and-aliases. The serial? assertion fails because an integer column with a serial default function is not distinguishable from a serial column. See https://www.cockroachlabs.com/docs/v19.2/serial.html#modes-of-operation." 6 | exclude :test_schema_dump_with_shorthand, "Serial columns are backed by integer columns, and integer columns are really bigints in CockroachDB. Therefore, the dump will include bigserial instead of serial columns. See https://www.cockroachlabs.com/docs/v19.2/serial.html#generated-values-for-mode-sql_sequence." 7 | exclude :test_schema_dump_with_not_serial, "If an integer column is created with a serial default function, it will be treated like a serial column in CockroachDB." 8 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlTimestampFixtureTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_load_infinity_and_beyond, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_bc_timestamp_leap_year, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 3 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlTimestampMigrationTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_adds_column_as_timestamp, "We implement our own version due to tests referencing the Adapter object." 2 | exclude :test_adds_column_as_timestamptz_if_datetime_type_changed, "We implement our own version due to tests referencing the Adapter object." 3 | exclude :test_adds_column_as_custom_type, "We implement our own version due to tests referencing the Adapter object." 4 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlTypeLookupTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_array_delimiters_are_looked_up_correctly, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_range_types_correctly_respect_registration_of_subtypes, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 3 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlUUIDGenerationTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_auto_create_uuid, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_id_is_uuid, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 3 | exclude :test_schema_dumper_for_uuid_primary_key_default_in_legacy_migration, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 4 | exclude :test_id_has_a_default, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 5 | exclude :test_schema_dumper_for_uuid_primary_key, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 6 | exclude :test_schema_dumper_for_uuid_primary_key_with_custom_default, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 7 | exclude :test_schema_dumper_for_uuid_primary_key_default, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 8 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlUUIDTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_change_column_default, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlVirtualColumnTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_build_fixture_sql, "Skipping because CockroachDB cannot write directly to computed columns." 2 | exclude :test_schema_dumping, "Replaced with local version" 3 | -------------------------------------------------------------------------------- /test/excludes/PostgresqlXMLTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_round_trip, "CockroachDB does not currently support the 'xml' type." 2 | exclude :test_null_xml, "CockroachDB does not currently support the 'xml' type." 3 | exclude :test_update_all, "CockroachDB does not currently support the 'xml' type." 4 | exclude :test_column, "CockroachDB does not currently support the 'xml' type." 5 | exclude :test_schema_dump_with_shorthand, "CockroachDB does not currently support the 'xml' type." 6 | -------------------------------------------------------------------------------- /test/excludes/PrimaryKeyIntegerNilDefaultTest.rb: -------------------------------------------------------------------------------- 1 | exclude "test_schema_dump_primary_key_integer_with_default_nil", "The test fails because CockroachDB's INT type translates to PostgreSQL's bigint type. Although the test table is created with an integer primary key, it will come back as BIGINT from CockroachDB. See https://www.cockroachlabs.com/docs/v19.2/int.html#names-and-aliases and https://www.postgresql.org/docs/current/datatype-numeric.htmli." 2 | -------------------------------------------------------------------------------- /test/excludes/PrimaryKeyIntegerTest.rb: -------------------------------------------------------------------------------- 1 | exclude "test_primary_key_column_type_with_serial/integer", "The last assertion in the test fails because CockroachDB's INT type translates to PostgreSQL's bigint type. See https://www.cockroachlabs.com/docs/v19.2/int.html#names-and-aliases and https://www.postgresql.org/docs/current/datatype-numeric.htmli." 2 | exclude "test_schema_dump_primary_key_with_serial/integer", "The test creates a table with a serial primary key, but the schema dump assertion fails because serial columns are bigserial columns in CockroachDB. ActiveRecord schema dumps only include serial info if the primary key is a serial column. The serial info is excluded otherwise because Active Record will create primary keys as bigserial by default. See https://www.cockroachlabs.com/docs/v19.2/serial.html#generated-values-for-mode-sql_sequence, https://www.cockroachlabs.com/docs/v19.2/int.html#names-and-aliases, and https://github.com/rails/rails/pull/26266." 3 | exclude "test_primary_key_with_serial/integer_are_automatically_numbered", "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 4 | -------------------------------------------------------------------------------- /test/excludes/PrimaryKeysTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_serial_with_quoted_sequence_name, "The serial? predicate assertion is valid, but the default_function is different in CockroachDB. See https://www.cockroachlabs.com/docs/v19.2/serial.html#modes-of-operation." 2 | exclude :test_serial_with_unquoted_sequence_name, "The serial? predicate assertion is valid, but the default_function is different in CockroachDB. See https://www.cockroachlabs.com/docs/v19.2/serial.html#modes-of-operation." 3 | -------------------------------------------------------------------------------- /test/excludes/RelationMergingTest.rb: -------------------------------------------------------------------------------- 1 | require "support/copy_cat" 2 | 3 | # Quoting integer. 4 | CopyCat.copy_methods(self, self, :test_relation_to_sql) do 5 | # From: /.?post_id.? = #{post.id}\z/i 6 | # To: /.?post_id.? = '#{post.id}'\z/i 7 | def on_regexp(node) 8 | # Sanity Check 9 | return unless node in [:regexp, [:str, /post_id/], [:begin, [:send, [:lvar, :post], :id]], *] 10 | 11 | first_str, _interpolation, last_str, _regopt = node.children 12 | insert_after(first_str.loc.expression, ?') 13 | insert_before(last_str.loc.expression, ?') 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /test/excludes/RelationTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_finding_with_sanitized_order, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_finding_with_subquery_with_eager_loading_in_from, "Overridden because test depends on ordering of results." 3 | exclude :test_finding_with_arel_sql_order, "Result is quoted in CockroachDB." 4 | -------------------------------------------------------------------------------- /test/excludes/ReservedWordsMigrationTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_drop_index_from_table_named_values, "This isn't supported by CockroachDB; see https://www.cockroachlabs.com/docs/stable/online-schema-changes.html#examples-of-statements-that-fail for more information" 2 | -------------------------------------------------------------------------------- /test/excludes/SameNameDifferentDatabaseFixturesTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_fixtures_are_properly_loaded, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | -------------------------------------------------------------------------------- /test/excludes/SanitizeTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_bind_enumerable, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_named_bind_variables, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 3 | exclude :test_sanitize_sql_array_handles_named_bind_variables, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 4 | 5 | require "support/copy_cat" 6 | 7 | # CRDB quotes ranges, like Trilogy. 8 | CopyCat.copy_methods(self, self, :test_bind_range) do 9 | def on_sym(node) 10 | return unless node in [:sym, :TrilogyAdapter] 11 | replace(node.loc.expression, ":CockroachDBAdapter") 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /test/excludes/SchemaAuthorizationTest.rb: -------------------------------------------------------------------------------- 1 | message = 'CockroachDB does not support variable session authorization. ' \ 2 | 'See https://github.com/cockroachdb/cockroach/issues/40283' 3 | exclude :test_sequence_schema_caching, message 4 | exclude :test_session_auth=, message 5 | exclude :test_schema_invisible, message 6 | exclude :test_tables_in_current_schemas, message 7 | exclude :test_auth_with_bind, message 8 | exclude :test_setting_auth_clears_stmt_cache, message 9 | -------------------------------------------------------------------------------- /test/excludes/SchemaCreateTableOptionsTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_multiple_inherited_table_options_is_dumped, "INHERITS keyword unsupported. See https://go.crdb.dev/issue-v/22456/v24.3" 2 | exclude :test_inherited_table_options_is_dumped, "INHERITS keyword unsupported. See https://go.crdb.dev/issue-v/22456/v24.3" 3 | -------------------------------------------------------------------------------- /test/excludes/SchemaDumperDefaultsTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_schema_dump_with_column_infinity_default, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | -------------------------------------------------------------------------------- /test/excludes/SchemaDumperTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_schema_dump_allows_array_of_decimal_defaults, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | exclude :test_foreign_keys_are_dumped_at_the_bottom_to_circumvent_dependency_issues, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 3 | exclude :test_schema_dump_interval_type, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 4 | exclude :test_do_not_dump_foreign_keys_for_ignored_tables, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 5 | exclude :test_schema_dump_includes_bigint_default, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 6 | exclude :test_schema_dump_with_timestamptz_datetime_format, "Re-implementing ourselves because we need CockroachDB specific methods." 7 | exclude :test_schema_dump_with_correct_timestamp_types_via_add_column_with_type_as_string, "Re-implementing ourselves because we need CockroachDB specific methods." 8 | exclude :test_timestamps_schema_dump_before_rails_7_with_timestamptz_setting, "Re-implementing ourselves because we need CockroachDB specific methods." 9 | exclude :test_schema_dump_with_correct_timestamp_types_via_add_column_before_rails_7_with_timestamptz_setting, "Re-implementing ourselves because we need CockroachDB specific methods." 10 | exclude :test_schema_dump_when_changing_datetime_type_for_an_existing_app, "Re-implementing ourselves because we need CockroachDB specific methods." 11 | exclude :test_schema_dumps_check_constraints, "Re-implementing because some constraints are now written in parenthesis" 12 | -------------------------------------------------------------------------------- /test/excludes/SchemaForeignKeyTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_dump_foreign_key_targeting_different_schema, ExcludeMessage::VALIDATE_BUG 2 | -------------------------------------------------------------------------------- /test/excludes/SchemaIndexNullsOrderTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_nulls_order_is_dumped, "NULLS FIRST/LAST are not included in the dump because they don't exist in CockroachDB. See https://www.cockroachlabs.com/docs/v19.2/null-handling.html#nulls-and-sorting." 2 | exclude :test_non_default_order_with_nulls_is_dumped, "NULLS FIRST/LAST are not included in the dump because they don't exist in CockroachDB. See https://www.cockroachlabs.com/docs/v19.2/null-handling.html#nulls-and-sorting." 3 | -------------------------------------------------------------------------------- /test/excludes/SchemaIndexOpclassTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_string_opclass_is_dumped, "Operator classes on indexes are not supported in CockroachDB." 2 | exclude :test_non_default_opclass_is_dumped, "Operator classes on indexes are not supported in CockroachDB." 3 | exclude :test_opclass_class_parsing_on_non_reserved_and_cannot_be_function_or_type_keyword, "Operator classes on indexes are not supported in CockroachDB." 4 | -------------------------------------------------------------------------------- /test/excludes/SchemaTest.rb: -------------------------------------------------------------------------------- 1 | # This hack allows us to redefine the 2 | # setup. We are using various weird 3 | # routes that might be simplified: 4 | # 1. We use `Ext` to prepend to the 5 | # current class to be sure `#setup` 6 | # is overriden. 7 | # 2. Current is a reference to self to 8 | # access it in `Ext` 9 | # 3. const_missing is used to avoid 10 | # having to rewrite every constant. 11 | Current = self 12 | module Ext 13 | def self.const_missing(const) 14 | Current.const_get(const) 15 | end 16 | 17 | def setup 18 | @connection = ActiveRecord::Base.lease_connection 19 | @connection.execute "SET default_int_size = 4" 20 | @connection.execute "SET serial_normalization = sql_sequence_cached" 21 | @connection.execute "CREATE SCHEMA #{SCHEMA_NAME}" 22 | @connection.execute "CREATE TABLE #{SCHEMA_NAME}.#{TABLE_NAME} (#{COLUMNS.join(',')})" 23 | @connection.execute "CREATE TABLE #{SCHEMA_NAME}.\"#{TABLE_NAME}.table\" (#{COLUMNS.join(',')})" 24 | @connection.execute "CREATE TABLE #{SCHEMA_NAME}.\"#{CAPITALIZED_TABLE_NAME}\" (#{COLUMNS.join(',')})" 25 | @connection.execute "CREATE SCHEMA #{SCHEMA2_NAME}" 26 | @connection.execute "CREATE TABLE #{SCHEMA2_NAME}.#{TABLE_NAME} (#{COLUMNS.join(',')})" 27 | @connection.execute "CREATE INDEX #{INDEX_A_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING btree (#{INDEX_A_COLUMN});" 28 | @connection.execute "CREATE INDEX #{INDEX_A_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING btree (#{INDEX_A_COLUMN});" 29 | @connection.execute "CREATE INDEX #{INDEX_B_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING btree (#{INDEX_B_COLUMN_S1});" 30 | @connection.execute "CREATE INDEX #{INDEX_B_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING btree (#{INDEX_B_COLUMN_S2});" 31 | @connection.execute "CREATE INDEX #{INDEX_C_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING gin (#{INDEX_C_COLUMN});" 32 | @connection.execute "CREATE INDEX #{INDEX_C_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING gin (#{INDEX_C_COLUMN});" 33 | @connection.execute "CREATE INDEX #{INDEX_D_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING btree (#{INDEX_D_COLUMN} DESC);" 34 | @connection.execute "CREATE INDEX #{INDEX_D_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING btree (#{INDEX_D_COLUMN} DESC);" 35 | @connection.execute "CREATE INDEX #{INDEX_E_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING gin (#{INDEX_E_COLUMN});" 36 | @connection.execute "CREATE INDEX #{INDEX_E_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING gin (#{INDEX_E_COLUMN});" 37 | @connection.execute "CREATE TABLE #{SCHEMA_NAME}.#{PK_TABLE_NAME} (id serial primary key)" 38 | @connection.execute "CREATE TABLE #{SCHEMA2_NAME}.#{PK_TABLE_NAME} (id serial primary key)" 39 | @connection.execute "CREATE SEQUENCE #{SCHEMA_NAME}.#{UNMATCHED_SEQUENCE_NAME}" 40 | @connection.execute "CREATE TABLE #{SCHEMA_NAME}.#{UNMATCHED_PK_TABLE_NAME} (id integer NOT NULL DEFAULT nextval('#{SCHEMA_NAME}.#{UNMATCHED_SEQUENCE_NAME}'::regclass), CONSTRAINT unmatched_pkey PRIMARY KEY (id))" 41 | end 42 | 43 | def teardown 44 | @connection.execute "SET default_int_size = DEFAULT" 45 | @connection.execute "SET serial_normalization = DEFAULT" 46 | super 47 | end 48 | end 49 | prepend Ext 50 | -------------------------------------------------------------------------------- /test/excludes/SequenceNameDetectionTestCases/CollidedSequenceNameTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_schema_dump_with_collided_sequence_name, "Serial columns are dumped as a bigserials against CockroachDB. This happens because serial columns are backed by integers, and integers are really bigints in CockroachDB. See https://www.cockroachlabs.com/docs/v19.2/serial.html#generated-values-for-mode-sql_sequence." 2 | -------------------------------------------------------------------------------- /test/excludes/SequenceNameDetectionTestCases/LongerSequenceNameDetectionTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_schema_dump_with_long_table_name, "Serial columns are dumped as a bigserials against CockroachDB. This happens because serial columns are backed by integers, and integers are really bigints in CockroachDB. See https://www.cockroachlabs.com/docs/v19.2/serial.html#generated-values-for-mode-sql_sequence." 2 | -------------------------------------------------------------------------------- /test/excludes/StrictLoadingFixturesTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_strict_loading_violations_are_ignored_on_fixtures, "This test is re-implemented with transactional tests disabled." 2 | -------------------------------------------------------------------------------- /test/excludes/TestFixturesTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_doesnt_rely_on_active_support_test_case_specific_methods, "This test is replaced with a version in our test suite." 2 | -------------------------------------------------------------------------------- /test/excludes/TransactionInstrumentationTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_transaction_instrumentation_with_restart_parent_transaction_on_rollback, "CRDB doesn't support ROLLBACK AND CHAIN" 2 | -------------------------------------------------------------------------------- /test/excludes/TransactionIsolationTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_read_uncommitted, "CockroachDB implements all isolation levels as SERIALIZABLE so this test does not work as expected." 2 | -------------------------------------------------------------------------------- /test/excludes/TypeTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_lookup_defaults_to_the_current_adapter, "Skipping until we can triage further. See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/issues/48" 2 | -------------------------------------------------------------------------------- /test/excludes/UniquenessValidationTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_validate_uniqueness_uuid, "This test is only meant to be run with a PostgreSQL adapter" 2 | exclude :test_validate_case_insensitive_uniqueness, "This tests relies on an implemented pg_cast table, see cockroach/cockroach#47498 for more details" 3 | -------------------------------------------------------------------------------- /test/excludes/UnloggedTablesTest.rb: -------------------------------------------------------------------------------- 1 | instance_methods.grep(/\Atest_\w+\z/).each do |method_name| 2 | exclude method_name, "UNLOGGED has no effect in CockroachDB." 3 | end 4 | -------------------------------------------------------------------------------- /test/excludes/UnsafeRawSqlTest.rb: -------------------------------------------------------------------------------- 1 | exclude "test_order:_allows_NULLS_FIRST_and_NULLS_LAST_too", "This functionality is not yet implemented, see https://github.com/cockroachdb/cockroach/issues/6224 for more details" 2 | exclude "test_order:_allows_valid_arguments_with_COLLATE", "Replaced for correct collation name" 3 | -------------------------------------------------------------------------------- /test/excludes/UpdateableViewTest.rb: -------------------------------------------------------------------------------- 1 | updateable_msg = "Updateable views are not currently supported, see https://github.com/cockroachdb/cockroach/issues/20948" 2 | exclude :test_update_record_to_fail_view_conditions, updateable_msg 3 | exclude :test_insert_record, updateable_msg 4 | exclude :test_insert_record_populates_primary_key, updateable_msg 5 | exclude :test_update_record, updateable_msg 6 | -------------------------------------------------------------------------------- /test/excludes/WithAnnotationsTest.rb: -------------------------------------------------------------------------------- 1 | exclude :test_has_and_belongs_to_many_with_annotation_includes_a_query_comment, "This test is overrided to fix the fixtures sequence. See test/cases/associations_test.rb" 2 | exclude :test_belongs_to_with_annotation_includes_a_query_comment, "This test is overrided to fix the fixtures sequence. See test/cases/associations_test.rb" 3 | exclude :test_has_one_with_annotation_includes_a_query_comment, "This test is overrided to fix the fixtures sequence. See test/cases/associations_test.rb" 4 | exclude :test_has_many_with_annotation_includes_a_query_comment, "This test is overrided to fix the fixtures sequence. See test/cases/associations_test.rb" 5 | exclude :test_has_many_through_with_annotation_includes_a_query_comment, "This test is overrided to fix the fixtures sequence. See test/cases/associations_test.rb" 6 | exclude :test_has_many_through_with_annotation_includes_a_query_comment_when_eager_loading, "This test is overrided to fix the fixtures sequence. See test/cases/associations_test.rb" 7 | -------------------------------------------------------------------------------- /test/models/building.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class Building < ActiveRecord::Base 4 | end 5 | -------------------------------------------------------------------------------- /test/models/spatial_model.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # This does not have an associated tabled in the cockroach_specific_schema 4 | class SpatialModel < ActiveRecord::Base 5 | end 6 | -------------------------------------------------------------------------------- /test/support/copy_cat.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "parser" 4 | require "prism" 5 | 6 | module CopyCat 7 | module NoWarnRewrite 8 | def warn(message, category: nil, **kwargs) 9 | if /method redefined; discarding old|previous definition of/.match?(message) && 10 | caller_locations.any? { _1.path["test/support/copy_cat.rb"] && _1.label["copy_methods"] } 11 | # ignore 12 | else 13 | super 14 | end 15 | end 16 | end 17 | ::Warning.singleton_class.prepend NoWarnRewrite 18 | 19 | extend self 20 | 21 | # Copy methods from The original rails class to our adapter. 22 | # While copying, we can rewrite the source code of the method using 23 | # ast. Use `debug: true` to lead you true that process. 24 | def copy_methods(new_klass, old_klass, *methods, debug: false, &block) 25 | methods.each do |met| 26 | file, _ = old_klass.instance_method(met).source_location 27 | ast = find_method(Prism::Translation::Parser.parse_file(file), met) 28 | code = 29 | if block_given? 30 | source = ast.location.expression.source 31 | buffer = Parser::Source::Buffer.new(met, source: source) 32 | # We need to recompute the ast to have correct locations. 33 | ast = Prism::Translation::Parser.parse(source) 34 | 35 | if debug 36 | puts "=" * 80 37 | puts "Rewriter doc: https://www.rubydoc.info/gems/parser/3.3.0.5/Parser/TreeRewriter" 38 | puts "Pattern matching doc: https://docs.ruby-lang.org/en/master/syntax/pattern_matching_rdoc.html" 39 | puts 40 | puts "Method: #{met}" 41 | puts 42 | puts "Source:" 43 | puts buffer.source 44 | puts 45 | puts "AST:" 46 | pp ast 47 | puts 48 | end 49 | rewriter_class = Class.new(Parser::TreeRewriter, &block) 50 | rewriter_class.new.rewrite(buffer, ast) 51 | else 52 | ast.location.expression.source 53 | end 54 | if debug and block_given? 55 | puts "Rewritten source:" 56 | puts code 57 | puts "=" * 80 58 | end 59 | location = caller_locations(3, 1).first 60 | new_klass.class_eval(code, location.absolute_path || location.path, location.lineno) 61 | end 62 | end 63 | 64 | def find_method(ast, method_name) 65 | method_name = method_name.to_sym 66 | to_search = [ast] 67 | while !to_search.empty? 68 | node = to_search.shift 69 | next unless node.is_a?(Parser::AST::Node) 70 | if node in [:def, ^method_name, *] 71 | return node 72 | end 73 | to_search += node.children 74 | end 75 | return nil 76 | end 77 | end 78 | -------------------------------------------------------------------------------- /test/support/exclude_from_transactional_tests.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Allow exclusion of tests by name using #exclude_from_transactional_tests(test_name) 4 | module ExcludeFromTransactionalTests 5 | module ClassMethods 6 | def exclude_from_transactional_tests(name) 7 | @non_transactional_list ||= [] 8 | @non_transactional_list << name.to_s 9 | end 10 | 11 | def non_transactional_list 12 | @non_transactional_list ||= [] 13 | end 14 | end 15 | 16 | def self.prepended(base) 17 | base.extend ClassMethods 18 | end 19 | 20 | def before_setup 21 | # binding.irb if self.class.non_transactional_list.include?(@NAME.to_s) 22 | @old_use_transactional_tests = self.use_transactional_tests 23 | if @old_use_transactional_tests # stay false if false 24 | self.use_transactional_tests = !self.class.non_transactional_list.include?(@NAME.to_s) 25 | end 26 | super 27 | end 28 | 29 | def after_teardown 30 | super 31 | ensure 32 | self.use_transactional_tests = @old_use_transactional_tests 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /test/support/paths_cockroachdb.rb: -------------------------------------------------------------------------------- 1 | module ARTest 2 | module CockroachDB 3 | 4 | extend self 5 | 6 | def root_cockroachdb 7 | File.expand_path File.join(File.dirname(__FILE__), '..', '..') 8 | end 9 | 10 | def test_root_cockroachdb 11 | File.join root_cockroachdb, 'test' 12 | end 13 | 14 | def root_activerecord 15 | File.join Gem.loaded_specs['rails'].full_gem_path, 'activerecord' 16 | end 17 | 18 | def root_activerecord_lib 19 | File.join root_activerecord, 'lib' 20 | end 21 | 22 | def root_activerecord_test 23 | File.join root_activerecord, 'test' 24 | end 25 | 26 | def test_load_paths 27 | ['lib', 'test', root_activerecord_lib, root_activerecord_test] 28 | end 29 | 30 | def add_to_load_paths! 31 | test_load_paths.each { |p| $LOAD_PATH.unshift(p) unless $LOAD_PATH.include?(p) } 32 | end 33 | 34 | def arconfig_file 35 | File.join test_root_cockroachdb, 'config.yml' 36 | end 37 | 38 | def arconfig_file_env! 39 | ENV['ARCONFIG'] = arconfig_file 40 | end 41 | 42 | end 43 | end 44 | 45 | ARTest::CockroachDB.add_to_load_paths! 46 | ARTest::CockroachDB.arconfig_file_env! 47 | -------------------------------------------------------------------------------- /test/support/rake_helpers.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module RakeHelpers 4 | COCKROACHDB_TEST_HELPER = 'test/cases/helper_cockroachdb.rb' 5 | 6 | module_function 7 | 8 | # Look for TEST_FILES_AR or TEST_FILES env variables 9 | # to set specific tests, otherwise load every tests 10 | # from active_record and this adapter. 11 | def test_files 12 | ar_test_files = ENV.fetch('TEST_FILES_AR', '') 13 | cr_test_files = ENV.fetch('TEST_FILES', '') 14 | 15 | return all_test_files if ar_test_files.empty? && cr_test_files.empty? 16 | 17 | ar_test_files = ar_test_files. 18 | split(','). 19 | map { |file| File.join ARTest::CockroachDB.root_activerecord, file.strip }. 20 | tap { _1.prepend(COCKROACHDB_TEST_HELPER) unless _1.empty? } 21 | 22 | cr_test_files = cr_test_files.split(',').map(&:strip) 23 | 24 | ar_test_files + cr_test_files 25 | end 26 | 27 | def all_test_files 28 | activerecord_test_files = 29 | FileList["#{ARTest::CockroachDB.root_activerecord}/test/cases/**/*_test.rb"]. 30 | reject { _1.include?("/adapters/") || _1.include?("/encryption/performance") } + 31 | FileList["#{ARTest::CockroachDB.root_activerecord}/test/cases/adapters/postgresql/**/*_test.rb"] 32 | 33 | cockroachdb_test_files = FileList['test/cases/**/*_test.rb'] 34 | 35 | FileList[COCKROACHDB_TEST_HELPER] + activerecord_test_files + cockroachdb_test_files 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /test/support/sql_logger.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module SQLLogger 4 | module_function 5 | 6 | def stdout_log 7 | ActiveRecord::Base.logger = Logger.new(STDOUT) 8 | ActiveRecord::Base.logger.level = Logger::DEBUG 9 | ActiveRecord::LogSubscriber::IGNORE_PAYLOAD_NAMES.clear 10 | ActiveRecord::Base.logger.formatter = proc { |severity, time, progname, msg| 11 | th = Thread.current[:name] 12 | th = "THREAD=#{th}" if th 13 | Logger::Formatter.new.call(severity, time, progname || th, msg) 14 | } 15 | end 16 | 17 | def summary_log 18 | ActiveRecord::TotalTimeSubscriber.attach_to :active_record 19 | Minitest.after_run { 20 | detail = ActiveRecord::TotalTimeSubscriber.hash.map { |k,v| [k, [v.sum, v.sum / v.size, v.size]]}.sort_by { |_, (_total, avg, _)| -avg }.to_h 21 | time = detail.values.sum { |(total, _, _)| total } / 1_000 22 | count = detail.values.sum { |(_, _, count)| count } 23 | puts "Total time spent in SQL: #{time}s (#{count} queries)" 24 | puts "Detail per query kind available in tmp/query_time.json (total time in ms, avg time in ms, query count). Sorted by avg time." 25 | File.write( 26 | "tmp/query_time.json", 27 | JSON.pretty_generate(detail) 28 | ) 29 | } 30 | end 31 | 32 | # Remove content between single quotes and double quotes from keys 33 | # to have a clear idea of which queries are being executed. 34 | def clean_sql(sql) 35 | sql.gsub(/".*?"/m, "\"...\"").gsub("''", "").gsub(/'.*?'/m, "'...'") 36 | end 37 | end 38 | 39 | class ActiveRecord::TotalTimeSubscriber < ActiveRecord::LogSubscriber 40 | def self.hash 41 | @@hash 42 | end 43 | 44 | def sql(event) 45 | # NOTE: If you want to debug a specific query, you can use a 'binding.irb' here with 46 | # a specific condition on 'event.payload[:sql]' content. 47 | # 48 | # binding.irb if event.payload[:sql].include?("attr.attname, nsp.nspname") 49 | # 50 | @@hash ||= {} 51 | key = SQLLogger.clean_sql(event.payload[:sql]) 52 | @@hash[key] ||= [] 53 | @@hash[key].push event.duration 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /test/support/template_creator.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'active_record' 4 | require_relative 'paths_cockroachdb' 5 | 6 | module TemplateCreator 7 | # extend self 8 | 9 | DEFAULT_CONNECTION_HASH = { 10 | adapter: 'cockroachdb', 11 | database: 'defaultdb', 12 | port: 26257, 13 | user: 'root', 14 | host: 'localhost' 15 | }.freeze 16 | 17 | BACKUP_DIR = "nodelocal://self/activerecord-crdb-adapter" 18 | 19 | module_function 20 | 21 | def ar_version 22 | ActiveRecord.version.version.gsub('.','') 23 | end 24 | 25 | def version_backup_path 26 | BACKUP_DIR + "/#{ar_version}" 27 | end 28 | 29 | def template_db_name 30 | "activerecord_unittest_template#{ar_version}" 31 | end 32 | 33 | def connect(connection_hash=nil) 34 | connection_hash = DEFAULT_CONNECTION_HASH if connection_hash.nil? 35 | ActiveRecord::Base.establish_connection(connection_hash) 36 | end 37 | 38 | def template_db_exists? 39 | ActiveRecord::Base.lease_connection.select_value("SELECT 1 FROM pg_database WHERE datname='#{template_db_name}'") == 1 40 | end 41 | 42 | def drop_template_db 43 | ActiveRecord::Base.lease_connection.execute("DROP DATABASE #{template_db_name}") 44 | end 45 | 46 | def create_template_db 47 | ActiveRecord::Base.lease_connection.execute("CREATE DATABASE #{template_db_name}") 48 | end 49 | 50 | def load_schema 51 | p 'loading schema' 52 | load ARTest::CockroachDB.root_activerecord_test + '/schema/schema.rb' 53 | load 'test/schema/cockroachdb_specific_schema.rb' 54 | end 55 | 56 | def create_test_template 57 | connect 58 | raise "#{template_db_name} already exists. If you do not have a backup created, please drop the database and run again." if template_db_exists? 59 | 60 | create_template_db 61 | 62 | # switch connection to template db 63 | conn = DEFAULT_CONNECTION_HASH.dup 64 | conn['database'] = template_db_name 65 | connect(conn) 66 | 67 | load_schema 68 | 69 | # create BACKUP to restore from 70 | ActiveRecord::Base.lease_connection.execute("BACKUP DATABASE #{template_db_name} TO '#{version_backup_path}'") 71 | end 72 | 73 | def restore_from_template 74 | connect 75 | raise "The TemplateDB does not exist. Run 'rake db:create_test_template' first." unless template_db_exists? 76 | 77 | begin 78 | ActiveRecord::Base.lease_connection.execute("DROP DATABASE activerecord_unittest") 79 | rescue ActiveRecord::StatementInvalid => e 80 | unless e.cause.class == PG::InvalidCatalogName 81 | raise e 82 | end 83 | end 84 | ActiveRecord::Base.lease_connection.execute("CREATE DATABASE activerecord_unittest") 85 | 86 | ActiveRecord::Base.lease_connection.execute("RESTORE #{template_db_name}.* FROM '#{version_backup_path}' WITH into_db = 'activerecord_unittest'") 87 | end 88 | end 89 | --------------------------------------------------------------------------------