activerecord-cockroachdb-adapter 8.0.2 → 8.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/CONTRIBUTING.md +10 -17
- data/Gemfile +2 -1
- data/Rakefile +0 -19
- data/lib/active_record/connection_adapters/cockroachdb/column.rb +66 -24
- data/lib/active_record/connection_adapters/cockroachdb/database_statements.rb +13 -3
- data/lib/active_record/connection_adapters/cockroachdb/database_tasks.rb +1 -1
- data/lib/active_record/connection_adapters/cockroachdb/oid/spatial.rb +34 -19
- data/lib/active_record/connection_adapters/cockroachdb/quoting.rb +19 -3
- data/lib/active_record/connection_adapters/cockroachdb/referential_integrity.rb +87 -55
- data/lib/active_record/connection_adapters/cockroachdb/schema_statements.rb +181 -102
- data/lib/active_record/connection_adapters/cockroachdb_adapter.rb +42 -25
- data/lib/version.rb +1 -1
- data/test/cases/adapter_test.rb +98 -0
- data/test/cases/adapters/cockroachdb/referential_integrity_test.rb +51 -0
- data/test/cases/adapters/postgresql/active_schema_test.rb +71 -0
- data/test/cases/adapters/postgresql/change_schema_test.rb +75 -0
- data/test/cases/adapters/postgresql/connection_test.rb +46 -0
- data/test/cases/adapters/postgresql/ddl_test.rb +326 -0
- data/test/cases/adapters/postgresql/interval_test.rb +131 -0
- data/test/cases/adapters/postgresql/nested_class_test.rb +22 -0
- data/test/cases/adapters/postgresql/numeric_test.rb +28 -0
- data/test/cases/adapters/postgresql/postgis_test.rb +185 -0
- data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +115 -0
- data/test/cases/adapters/postgresql/quoting_test.rb +30 -0
- data/test/cases/adapters/postgresql/schema_statements_test.rb +29 -0
- data/test/cases/adapters/postgresql/serial_test.rb +199 -0
- data/test/cases/adapters/postgresql/spatial_queries_test.rb +118 -0
- data/test/cases/adapters/postgresql/spatial_setup_test.rb +18 -0
- data/test/cases/adapters/postgresql/spatial_type_test.rb +41 -0
- data/test/cases/adapters/postgresql/timestamp_test.rb +58 -0
- data/test/cases/adapters/postgresql/virtual_column_test.rb +39 -0
- data/test/cases/associations/eager_load_nested_include_test.rb +111 -0
- data/test/cases/associations/left_outer_join_association_test.rb +30 -0
- data/test/cases/associations_test.rb +108 -0
- data/test/cases/base_test.rb +31 -0
- data/test/cases/comment_test.rb +75 -0
- data/test/cases/connection_adapters/type_test.rb +28 -0
- data/test/cases/database_configurations/resolver_test.rb +24 -0
- data/test/cases/defaults_test.rb +45 -0
- data/test/cases/dirty_test.rb +24 -0
- data/test/cases/fixtures_test.rb +541 -0
- data/test/cases/helper_cockroachdb.rb +232 -0
- data/test/cases/inheritance_test.rb +42 -0
- data/test/cases/invertible_migration_test.rb +73 -0
- data/test/cases/marshal_serialization_test.rb +45 -0
- data/test/cases/migration/change_schema_test.rb +140 -0
- data/test/cases/migration/check_constraint_test.rb +125 -0
- data/test/cases/migration/columns_test.rb +50 -0
- data/test/cases/migration/create_join_table_test.rb +66 -0
- data/test/cases/migration/foreign_key_test.rb +390 -0
- data/test/cases/migration/hidden_column_test.rb +70 -0
- data/test/cases/migration/references_foreign_key_test.rb +124 -0
- data/test/cases/migration_test.rb +120 -0
- data/test/cases/persistence_test.rb +33 -0
- data/test/cases/primary_keys_test.rb +134 -0
- data/test/cases/relation/aost_test.rb +57 -0
- data/test/cases/relation/or_test.rb +26 -0
- data/test/cases/relation/table_hints_test.rb +124 -0
- data/test/cases/relation_test.rb +26 -0
- data/test/cases/relations_test.rb +29 -0
- data/test/cases/schema_dumper_test.rb +221 -0
- data/test/cases/show_create_test.rb +14 -0
- data/test/cases/strict_loading_test.rb +34 -0
- data/test/cases/tasks/cockroachdb_rake_test.rb +113 -0
- data/test/cases/test_fixtures_test.rb +57 -0
- data/test/cases/transactions_test.rb +51 -0
- data/test/cases/unsafe_raw_sql_test.rb +22 -0
- data/test/config.yml +23 -0
- data/test/excludes/ActiveRecord/AdapterTest.rb +3 -0
- data/test/excludes/ActiveRecord/AdapterTestWithoutTransaction.rb +25 -0
- data/test/excludes/ActiveRecord/ConnectionAdapters/PoolConfig/ResolverTest.rb +1 -0
- data/test/excludes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapter/BindParameterTest.rb +15 -0
- data/test/excludes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapter/QuotingTest.rb +22 -0
- data/test/excludes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapterPreventWritesLegacyTest.rb +1 -0
- data/test/excludes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapterPreventWritesTest.rb +1 -0
- data/test/excludes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapterTest.rb +40 -0
- data/test/excludes/ActiveRecord/ConnectionAdapters/RegistrationIsolatedTest.rb +14 -0
- data/test/excludes/ActiveRecord/Encryption/EncryptionPerformanceTest.rb +1 -0
- data/test/excludes/ActiveRecord/Encryption/EnvelopeEncryptionPerformanceTest.rb +1 -0
- data/test/excludes/ActiveRecord/Encryption/ExtendedDeterministicQueriesPerformanceTest.rb +1 -0
- data/test/excludes/ActiveRecord/Encryption/StoragePerformanceTest.rb +2 -0
- data/test/excludes/ActiveRecord/InstrumentationTest.rb +16 -0
- data/test/excludes/ActiveRecord/InvertibleMigrationTest.rb +2 -0
- data/test/excludes/ActiveRecord/Migration/ChangeSchemaTest.rb +7 -0
- data/test/excludes/ActiveRecord/Migration/CheckConstraintTest.rb +6 -0
- data/test/excludes/ActiveRecord/Migration/ColumnsTest.rb +4 -0
- data/test/excludes/ActiveRecord/Migration/CompatibilityTest.rb +50 -0
- data/test/excludes/ActiveRecord/Migration/CompositeForeignKeyTest.rb +2 -0
- data/test/excludes/ActiveRecord/Migration/CreateJoinTableTest.rb +2 -0
- data/test/excludes/ActiveRecord/Migration/ForeignKeyInCreateTest.rb +1 -0
- data/test/excludes/ActiveRecord/Migration/ForeignKeyTest.rb +35 -0
- data/test/excludes/ActiveRecord/Migration/InvalidOptionsTest.rb +14 -0
- data/test/excludes/ActiveRecord/Migration/PGChangeSchemaTest.rb +8 -0
- data/test/excludes/ActiveRecord/Migration/ReferencesForeignKeyTest.rb +7 -0
- data/test/excludes/ActiveRecord/Migration/ReferencesIndexTest.rb +7 -0
- data/test/excludes/ActiveRecord/Migration/ReferencesStatementsTest.rb +3 -0
- data/test/excludes/ActiveRecord/MysqlDBCreateWithInvalidPermissionsTest.rb +1 -0
- data/test/excludes/ActiveRecord/OrTest.rb +1 -0
- data/test/excludes/ActiveRecord/PostgreSQLStructureDumpTest.rb +10 -0
- data/test/excludes/ActiveRecord/PostgresqlConnectionTest.rb +12 -0
- data/test/excludes/ActiveRecord/PostgresqlTransactionNestedTest.rb +14 -0
- data/test/excludes/ActiveRecord/PostgresqlTransactionTest.rb +4 -0
- data/test/excludes/ActiveRecord/RelationTest.rb +2 -0
- data/test/excludes/ActiveRecord/TooManyOrTest.rb +1 -0
- data/test/excludes/ActiveSupportSubclassWithFixturesTest.rb +1 -0
- data/test/excludes/AssociationDeprecationTest/NotifyModeTest.rb +2 -0
- data/test/excludes/AssociationDeprecationTest/RaiseBacktraceModeTest.rb +2 -0
- data/test/excludes/AssociationDeprecationTest/RaiseModeTest.rb +2 -0
- data/test/excludes/AssociationDeprecationTest/WarnBacktraceModeTest.rb +2 -0
- data/test/excludes/AssociationDeprecationTest/WarnModeTest.rb +2 -0
- data/test/excludes/AssociationDeprecationTest/fix_backtrace_cleaner.rb +10 -0
- data/test/excludes/BasicsTest.rb +1 -0
- data/test/excludes/BulkAlterTableMigrationsTest.rb +7 -0
- data/test/excludes/CalculationsTest.rb +4 -0
- data/test/excludes/CommentTest.rb +2 -0
- data/test/excludes/CoreTest.rb +1 -0
- data/test/excludes/CreateOrFindByWithinTransactions.rb +3 -0
- data/test/excludes/DefaultsUsingMultipleSchemasAndDomainTest.rb +7 -0
- data/test/excludes/DirtyTest.rb +3 -0
- data/test/excludes/EachTest.rb +8 -0
- data/test/excludes/EagerLoadPolyAssocsTest.rb +1 -0
- data/test/excludes/ExplicitlyNamedIndexMigrationTest.rb +1 -0
- data/test/excludes/FixturesResetPkSequenceTest.rb +3 -0
- data/test/excludes/FixturesTest.rb +21 -0
- data/test/excludes/FixturesWithForeignKeyViolationsTest.rb +2 -0
- data/test/excludes/ForeignTableTest.rb +10 -0
- data/test/excludes/InheritanceComputeTypeTest.rb +1 -0
- data/test/excludes/LeftOuterJoinAssociationTest.rb +2 -0
- data/test/excludes/LegacyPrimaryKeyTest/V4_2.rb +6 -0
- data/test/excludes/LegacyPrimaryKeyTest/V5_0.rb +6 -0
- data/test/excludes/MarshalSerializationTest.rb +4 -0
- data/test/excludes/MaterializedViewTest.rb +13 -0
- data/test/excludes/MigrationTest.rb +2 -0
- data/test/excludes/MultiDbMigratorTest.rb +2 -0
- data/test/excludes/NestedRelationScopingTest.rb +1 -0
- data/test/excludes/OrTest.rb +1 -0
- data/test/excludes/PersistenceTest.rb +3 -0
- data/test/excludes/PessimisticLockingTest.rb +1 -0
- data/test/excludes/PostgreSQLExplainTest.rb +7 -0
- data/test/excludes/PostgreSQLGeometricLineTest.rb +3 -0
- data/test/excludes/PostgreSQLGeometricTypesTest.rb +7 -0
- data/test/excludes/PostgreSQLPartitionsTest.rb +1 -0
- data/test/excludes/PostgreSQLReferentialIntegrityTest.rb +14 -0
- data/test/excludes/PostgresqlArrayTest.rb +21 -0
- data/test/excludes/PostgresqlBigSerialTest.rb +7 -0
- data/test/excludes/PostgresqlBitStringTest.rb +2 -0
- data/test/excludes/PostgresqlByteaTest.rb +1 -0
- data/test/excludes/PostgresqlCitextTest.rb +7 -0
- data/test/excludes/PostgresqlCollationTest.rb +5 -0
- data/test/excludes/PostgresqlCompositeTest.rb +2 -0
- data/test/excludes/PostgresqlCompositeWithCustomOIDTest.rb +2 -0
- data/test/excludes/PostgresqlDataTypeTest.rb +9 -0
- data/test/excludes/PostgresqlDefaultExpressionTest.rb +1 -0
- data/test/excludes/PostgresqlDeferredConstraintsTest.rb +3 -0
- data/test/excludes/PostgresqlDomainTest.rb +2 -0
- data/test/excludes/PostgresqlExtensionMigrationTest.rb +5 -0
- data/test/excludes/PostgresqlFullTextTest.rb +3 -0
- data/test/excludes/PostgresqlGeometricTest.rb +4 -0
- data/test/excludes/PostgresqlHstoreTest.rb +45 -0
- data/test/excludes/PostgresqlInfinityTest.rb +5 -0
- data/test/excludes/PostgresqlIntervalTest.rb +1 -0
- data/test/excludes/PostgresqlJSONBTest.rb +27 -0
- data/test/excludes/PostgresqlJSONTest.rb +27 -0
- data/test/excludes/PostgresqlLtreeTest.rb +4 -0
- data/test/excludes/PostgresqlMoneyTest.rb +12 -0
- data/test/excludes/PostgresqlNetworkTest.rb +69 -0
- data/test/excludes/PostgresqlNumberTest.rb +1 -0
- data/test/excludes/PostgresqlPointTest.rb +15 -0
- data/test/excludes/PostgresqlRangeTest.rb +3 -0
- data/test/excludes/PostgresqlRenameTableTest.rb +2 -0
- data/test/excludes/PostgresqlSerialTest.rb +7 -0
- data/test/excludes/PostgresqlTimestampFixtureTest.rb +2 -0
- data/test/excludes/PostgresqlTimestampMigrationTest.rb +3 -0
- data/test/excludes/PostgresqlTypeLookupTest.rb +2 -0
- data/test/excludes/PostgresqlUUIDGenerationTest.rb +7 -0
- data/test/excludes/PostgresqlUUIDTest.rb +1 -0
- data/test/excludes/PostgresqlVirtualColumnTest.rb +17 -0
- data/test/excludes/PostgresqlXMLTest.rb +5 -0
- data/test/excludes/PrimaryKeyIntegerNilDefaultTest.rb +1 -0
- data/test/excludes/PrimaryKeyIntegerTest.rb +3 -0
- data/test/excludes/PrimaryKeysTest.rb +2 -0
- data/test/excludes/RelationMergingTest.rb +15 -0
- data/test/excludes/RelationTest.rb +3 -0
- data/test/excludes/ReservedWordsMigrationTest.rb +1 -0
- data/test/excludes/SameNameDifferentDatabaseFixturesTest.rb +1 -0
- data/test/excludes/SanitizeTest.rb +13 -0
- data/test/excludes/SchemaAuthorizationTest.rb +8 -0
- data/test/excludes/SchemaCreateTableOptionsTest.rb +2 -0
- data/test/excludes/SchemaDumperDefaultsTest.rb +1 -0
- data/test/excludes/SchemaDumperTest.rb +11 -0
- data/test/excludes/SchemaForeignKeyTest.rb +1 -0
- data/test/excludes/SchemaIndexNullsOrderTest.rb +2 -0
- data/test/excludes/SchemaIndexOpclassTest.rb +3 -0
- data/test/excludes/SchemaTest.rb +49 -0
- data/test/excludes/SequenceNameDetectionTestCases/CollidedSequenceNameTest.rb +1 -0
- data/test/excludes/SequenceNameDetectionTestCases/LongerSequenceNameDetectionTest.rb +1 -0
- data/test/excludes/StrictLoadingFixturesTest.rb +1 -0
- data/test/excludes/TestFixturesTest.rb +1 -0
- data/test/excludes/TransactionInstrumentationTest.rb +1 -0
- data/test/excludes/TransactionIsolationTest.rb +1 -0
- data/test/excludes/TypeTest.rb +1 -0
- data/test/excludes/UniquenessValidationTest.rb +2 -0
- data/test/excludes/UnloggedTablesTest.rb +3 -0
- data/test/excludes/UnsafeRawSqlTest.rb +2 -0
- data/test/excludes/UpdateableViewTest.rb +5 -0
- data/test/excludes/WithAnnotationsTest.rb +6 -0
- data/test/models/building.rb +4 -0
- data/test/models/spatial_model.rb +5 -0
- data/test/schema/cockroachdb_specific_schema.rb +218 -0
- data/test/support/copy_cat.rb +83 -0
- data/test/support/exclude_from_transactional_tests.rb +33 -0
- data/test/support/paths_cockroachdb.rb +46 -0
- data/test/support/rake_helpers.rb +37 -0
- data/test/support/sql_logger.rb +55 -0
- data/test/support/template_creator.rb +114 -0
- metadata +422 -34
- data/.editorconfig +0 -7
- data/.github/issue_template.md +0 -46
- data/.github/reproduction_scripts/migrations.rb +0 -60
- data/.github/reproduction_scripts/models_and_database.rb +0 -49
- data/.github/workflows/ci.yml +0 -96
- data/.github/workflows/docker.yml +0 -57
- data/.gitignore +0 -18
- data/.gitmodules +0 -0
- data/activerecord-cockroachdb-adapter.gemspec +0 -38
- data/bin/console +0 -36
- data/bin/console_schemas/default.rb +0 -11
- data/bin/console_schemas/schemas.rb +0 -23
- data/bin/setup +0 -8
- data/bin/start-cockroachdb +0 -33
- data/build/Dockerfile +0 -14
- data/build/config.teamcity.yml +0 -31
- data/build/local-test.sh +0 -32
- data/build/teamcity-test.sh +0 -76
- data/docker.sh +0 -35
- data/lib/active_record/connection_adapters/cockroachdb/spatial_column_info.rb +0 -60
- data/setup.sql +0 -18
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cases/helper"
|
|
4
|
+
|
|
5
|
+
module ActiveRecord
|
|
6
|
+
module CockroachDB
|
|
7
|
+
class Migration
|
|
8
|
+
class ReferencesForeignKeyTest < ActiveRecord::TestCase
|
|
9
|
+
# These tests are identical to the ones found in Rails, save for the fact
|
|
10
|
+
# that transactions are turned off for test runs. It is necessary to disable
|
|
11
|
+
# transactional tests in order to assert on schema changes due to how
|
|
12
|
+
# CockroachDB handles transactions.
|
|
13
|
+
self.use_transactional_tests = false
|
|
14
|
+
|
|
15
|
+
setup do
|
|
16
|
+
@connection = ActiveRecord::Base.lease_connection
|
|
17
|
+
@connection.create_table(:testing_parents, force: true)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
teardown do
|
|
21
|
+
@connection.drop_table "testings", if_exists: true
|
|
22
|
+
@connection.drop_table "testing_parents", if_exists: true
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
test "foreign keys can be created while changing the table" do
|
|
26
|
+
@connection.create_table :testings
|
|
27
|
+
@connection.change_table :testings do |t|
|
|
28
|
+
t.references :testing_parent, foreign_key: true
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
fk = @connection.foreign_keys("testings").first
|
|
32
|
+
assert_equal "testings", fk.from_table
|
|
33
|
+
assert_equal "testing_parents", fk.to_table
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
test "foreign keys accept options when changing the table" do
|
|
37
|
+
@connection.change_table :testing_parents do |t|
|
|
38
|
+
t.references :other, index: { unique: true }
|
|
39
|
+
end
|
|
40
|
+
@connection.create_table :testings
|
|
41
|
+
@connection.change_table :testings do |t|
|
|
42
|
+
t.references :testing_parent, foreign_key: { primary_key: :other_id }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
fk = @connection.foreign_keys("testings").find { |k| k.to_table == "testing_parents" }
|
|
46
|
+
assert_equal "other_id", fk.primary_key
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
test "foreign key column can be removed" do
|
|
50
|
+
@connection.create_table :testings do |t|
|
|
51
|
+
t.references :testing_parent, index: true, foreign_key: true
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
assert_difference "@connection.foreign_keys('testings').size", -1 do
|
|
55
|
+
@connection.remove_reference :testings, :testing_parent, foreign_key: true
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
test "removing column removes foreign key" do
|
|
60
|
+
@connection.create_table :testings do |t|
|
|
61
|
+
t.references :testing_parent, index: true, foreign_key: true
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
assert_difference "@connection.foreign_keys('testings').size", -1 do
|
|
65
|
+
@connection.remove_column :testings, :testing_parent_id
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
test "foreign key methods respect pluralize_table_names" do
|
|
70
|
+
begin
|
|
71
|
+
original_pluralize_table_names = ActiveRecord::Base.pluralize_table_names
|
|
72
|
+
ActiveRecord::Base.pluralize_table_names = false
|
|
73
|
+
@connection.create_table :testing
|
|
74
|
+
@connection.change_table :testing_parents do |t|
|
|
75
|
+
t.references :testing, foreign_key: true
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
fk = @connection.foreign_keys("testing_parents").first
|
|
79
|
+
assert_equal "testing_parents", fk.from_table
|
|
80
|
+
assert_equal "testing", fk.to_table
|
|
81
|
+
|
|
82
|
+
assert_difference "@connection.foreign_keys('testing_parents').size", -1 do
|
|
83
|
+
@connection.remove_reference :testing_parents, :testing, foreign_key: true
|
|
84
|
+
end
|
|
85
|
+
ensure
|
|
86
|
+
ActiveRecord::Base.pluralize_table_names = original_pluralize_table_names
|
|
87
|
+
@connection.drop_table "testing", if_exists: true
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
test "multiple foreign keys can be removed to the selected one" do
|
|
92
|
+
@connection.create_table :testings do |t|
|
|
93
|
+
t.references :parent1, foreign_key: { to_table: :testing_parents }
|
|
94
|
+
t.references :parent2, foreign_key: { to_table: :testing_parents }
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
assert_difference "@connection.foreign_keys('testings').size", -1 do
|
|
98
|
+
@connection.remove_reference :testings, :parent1, foreign_key: { to_table: :testing_parents }
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
fks = @connection.foreign_keys("testings").sort_by(&:column)
|
|
102
|
+
|
|
103
|
+
fk_definitions = fks.map { |fk| [fk.from_table, fk.to_table, fk.column] }
|
|
104
|
+
assert_equal([["testings", "testing_parents", "parent2_id"]], fk_definitions)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
test "multiple foreign keys can be added to the same table" do
|
|
108
|
+
@connection.create_table :testings do |t|
|
|
109
|
+
t.references :parent1, foreign_key: { to_table: :testing_parents }
|
|
110
|
+
t.references :parent2, foreign_key: { to_table: :testing_parents }
|
|
111
|
+
t.references :self_join, foreign_key: { to_table: :testings }
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
fks = @connection.foreign_keys("testings").sort_by(&:column)
|
|
115
|
+
|
|
116
|
+
fk_definitions = fks.map { |fk| [fk.from_table, fk.to_table, fk.column] }
|
|
117
|
+
assert_equal([["testings", "testing_parents", "parent1_id"],
|
|
118
|
+
["testings", "testing_parents", "parent2_id"],
|
|
119
|
+
["testings", "testings", "self_join_id"]], fk_definitions)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
require "cases/helper_cockroachdb"
|
|
2
|
+
require "models/person"
|
|
3
|
+
require "support/copy_cat"
|
|
4
|
+
|
|
5
|
+
class Reminder < ActiveRecord::Base; end unless Object.const_defined?(:Reminder)
|
|
6
|
+
class Thing < ActiveRecord::Base; end unless Object.const_defined?(:Thing)
|
|
7
|
+
module CockroachDB
|
|
8
|
+
class MigrationTest < ActiveRecord::TestCase
|
|
9
|
+
self.use_transactional_tests = false
|
|
10
|
+
|
|
11
|
+
fixtures :people
|
|
12
|
+
|
|
13
|
+
CopyCat.copy_methods(self, ::MigrationTest, :setup)
|
|
14
|
+
|
|
15
|
+
teardown do
|
|
16
|
+
ActiveRecord::Base.table_name_prefix = ""
|
|
17
|
+
ActiveRecord::Base.table_name_suffix = ""
|
|
18
|
+
|
|
19
|
+
@schema_migration.create_table
|
|
20
|
+
@schema_migration.delete_all_versions
|
|
21
|
+
|
|
22
|
+
%w(things awesome_things prefix_things_suffix p_awesome_things_s).each do |table|
|
|
23
|
+
Thing.lease_connection.drop_table(table, if_exists: true)
|
|
24
|
+
end
|
|
25
|
+
Thing.reset_column_information
|
|
26
|
+
|
|
27
|
+
%w(reminders people_reminders prefix_reminders_suffix).each do |table|
|
|
28
|
+
Reminder.lease_connection.drop_table(table, if_exists: true)
|
|
29
|
+
end
|
|
30
|
+
Reminder.reset_table_name
|
|
31
|
+
Reminder.reset_column_information
|
|
32
|
+
|
|
33
|
+
%w(last_name key bio age height wealth birthday favorite_day
|
|
34
|
+
moment_of_truth male administrator funny).each do |column|
|
|
35
|
+
Person.lease_connection.remove_column("people", column, if_exists: true)
|
|
36
|
+
end
|
|
37
|
+
Person.lease_connection.remove_column("people", "first_name", if_exists: true)
|
|
38
|
+
Person.lease_connection.remove_column("people", "middle_name", if_exists: true)
|
|
39
|
+
Person.lease_connection.add_column("people", "first_name", :string)
|
|
40
|
+
Person.reset_column_information
|
|
41
|
+
|
|
42
|
+
ActiveRecord::Migration.verbose = @verbose_was
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def test_remove_column_with_if_not_exists_not_set
|
|
46
|
+
migration_a = Class.new(ActiveRecord::Migration::Current) {
|
|
47
|
+
def version; 100 end
|
|
48
|
+
def migrate(x)
|
|
49
|
+
add_column "people", "last_name", :string
|
|
50
|
+
end
|
|
51
|
+
}.new
|
|
52
|
+
|
|
53
|
+
migration_b = Class.new(ActiveRecord::Migration::Current) {
|
|
54
|
+
def version; 101 end
|
|
55
|
+
def migrate(x)
|
|
56
|
+
remove_column "people", "last_name"
|
|
57
|
+
end
|
|
58
|
+
}.new
|
|
59
|
+
|
|
60
|
+
migration_c = Class.new(ActiveRecord::Migration::Current) {
|
|
61
|
+
def version; 102 end
|
|
62
|
+
def migrate(x)
|
|
63
|
+
remove_column "people", "last_name"
|
|
64
|
+
end
|
|
65
|
+
}.new
|
|
66
|
+
|
|
67
|
+
ActiveRecord::Migrator.new(:up, [migration_a], @schema_migration, @internal_metadata, 100).migrate
|
|
68
|
+
assert_column Person, :last_name, "migration_a should have added the last_name column on people"
|
|
69
|
+
|
|
70
|
+
ActiveRecord::Migrator.new(:up, [migration_b], @schema_migration, @internal_metadata, 101).migrate
|
|
71
|
+
assert_no_column Person, :last_name, "migration_b should have dropped the last_name column on people"
|
|
72
|
+
migrator = ActiveRecord::Migrator.new(:up, [migration_c], @schema_migration, @internal_metadata, 102)
|
|
73
|
+
|
|
74
|
+
error = assert_raises do
|
|
75
|
+
migrator.migrate
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
assert_match(/column \"last_name\" does not exist/, error.message)
|
|
79
|
+
ensure
|
|
80
|
+
Person.reset_column_information
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
class BulkAlterTableMigrationsTest < ActiveRecord::TestCase
|
|
85
|
+
def setup
|
|
86
|
+
@connection = Person.lease_connection
|
|
87
|
+
@connection.create_table(:delete_me, force: true) { |t| }
|
|
88
|
+
Person.reset_column_information
|
|
89
|
+
Person.reset_sequence_name
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
teardown do
|
|
93
|
+
Person.lease_connection.drop_table(:delete_me, if_exists: true)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Change expected query count from PostgreSQLAdapter to CockroachDBAdapter.
|
|
97
|
+
CopyCat.copy_methods(self, ::BulkAlterTableMigrationsTest,
|
|
98
|
+
:test_adding_indexes,
|
|
99
|
+
:test_removing_index,
|
|
100
|
+
:test_adding_multiple_columns,
|
|
101
|
+
:test_changing_index
|
|
102
|
+
) do
|
|
103
|
+
def on_str(node)
|
|
104
|
+
return unless node in [:str, "PostgreSQLAdapter"]
|
|
105
|
+
|
|
106
|
+
replace(node.loc.expression, '"CockroachDBAdapter"')
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
private
|
|
111
|
+
|
|
112
|
+
CopyCat.copy_methods(self, ::BulkAlterTableMigrationsTest,
|
|
113
|
+
:with_bulk_change_table,
|
|
114
|
+
:column,
|
|
115
|
+
:columns,
|
|
116
|
+
:index,
|
|
117
|
+
:indexes
|
|
118
|
+
)
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
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
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
require "cases/helper_cockroachdb"
|
|
2
|
+
|
|
3
|
+
# Load dependencies from ActiveRecord test suite
|
|
4
|
+
require "support/schema_dumping_helper"
|
|
5
|
+
require "models/topic"
|
|
6
|
+
require "models/mixed_case_monkey"
|
|
7
|
+
|
|
8
|
+
module CockroachDB
|
|
9
|
+
class PrimaryKeysTest < ActiveRecord::TestCase
|
|
10
|
+
fixtures :mixed_case_monkeys, :topics
|
|
11
|
+
|
|
12
|
+
# This replaces the same test that's been excluded from PrimaryKeysTest. We
|
|
13
|
+
# run it here without an assertion on column.default_function because it
|
|
14
|
+
# will always be unique_rowid() in CockroachDB.
|
|
15
|
+
# See test/excludes/PrimaryKeysTest.rb
|
|
16
|
+
def test_serial_with_quoted_sequence_name
|
|
17
|
+
column = MixedCaseMonkey.columns_hash[MixedCaseMonkey.primary_key]
|
|
18
|
+
assert_predicate column, :serial?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# This replaces the same test that's been excluded from PrimaryKeysTest. We
|
|
22
|
+
# run it here without an assertion on column.default_function because it
|
|
23
|
+
# will always be unique_rowid() in CockroachDB.
|
|
24
|
+
# See test/excludes/PrimaryKeysTest.rb
|
|
25
|
+
def test_serial_with_unquoted_sequence_name
|
|
26
|
+
column = Topic.columns_hash[Topic.primary_key]
|
|
27
|
+
assert_predicate column, :serial?
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class PrimaryKeyIntegerTest < ActiveRecord::TestCase
|
|
32
|
+
include SchemaDumpingHelper
|
|
33
|
+
|
|
34
|
+
self.use_transactional_tests = false
|
|
35
|
+
|
|
36
|
+
class Widget < ActiveRecord::Base
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
setup do
|
|
40
|
+
@connection = ActiveRecord::Base.lease_connection
|
|
41
|
+
@pk_type = :serial
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
teardown do
|
|
45
|
+
@connection.drop_table :widgets, if_exists: true
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# This replaces the same test that's been excluded from
|
|
49
|
+
# PrimaryKeyIntegerTest. In PostgreSQL, serial columns are backed by integer
|
|
50
|
+
# columns. They're also backed by integer columns in CockroachDB, but
|
|
51
|
+
# integer columns are the same size as PostgreSQL's bigints. Therefore, we
|
|
52
|
+
# change the final assertion to verify the serial column is a bigint.
|
|
53
|
+
# See test/excludes/PrimaryKeyIntegerTest.rb
|
|
54
|
+
test "primary key column type with serial/integer" do
|
|
55
|
+
@connection.create_table(:widgets, id: @pk_type, force: true)
|
|
56
|
+
column = @connection.columns(:widgets).find { |c| c.name == "id" }
|
|
57
|
+
assert_equal :integer, column.type
|
|
58
|
+
assert_predicate column, :bigint?
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# This replaces the same test that's been excluded from
|
|
62
|
+
# PrimaryKeyIntegerTest. Although the widgets table is created with a serial
|
|
63
|
+
# primary key, that info will not be included in the schema dump.
|
|
64
|
+
# CockroachDB serial and bigserial columns are really bigserial columns, and
|
|
65
|
+
# ActiveRecord defaults to bigserial primary keys. Therefore, nothing about
|
|
66
|
+
# the id primary key will be in the widgets schema dump.
|
|
67
|
+
# See test/excludes/PrimaryKeyIntegerTest.rb
|
|
68
|
+
test "schema dump primary key with serial/integer" do
|
|
69
|
+
@connection.create_table(:widgets, id: @pk_type, force: true)
|
|
70
|
+
schema = dump_table_schema "widgets"
|
|
71
|
+
assert_match %r{create_table "widgets", }, schema
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
class PrimaryKeyIntegerNilDefaultTest < ActiveRecord::TestCase
|
|
76
|
+
include SchemaDumpingHelper
|
|
77
|
+
|
|
78
|
+
self.use_transactional_tests = false
|
|
79
|
+
|
|
80
|
+
def setup
|
|
81
|
+
@connection = ActiveRecord::Base.lease_connection
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def teardown
|
|
85
|
+
@connection.drop_table :int_defaults, if_exists: true
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# This replaces the same test that's been excluded from
|
|
89
|
+
# PrimaryKeyIntegerNilDefaultTest. int_defaults is created with an integer
|
|
90
|
+
# primary key, and integer columns are bigints in CockroachDB. Therefore,
|
|
91
|
+
# the schema dump will include the primary key as :bigint.
|
|
92
|
+
# See test/excludes/PrimaryKeyIntegerNilDefaultTest.rb
|
|
93
|
+
def test_schema_dump_primary_key_integer_with_default_nil
|
|
94
|
+
skip if current_adapter?(:SQLite3Adapter)
|
|
95
|
+
@connection.create_table(:int_defaults, id: :integer, default: nil, force: true)
|
|
96
|
+
schema = dump_table_schema "int_defaults"
|
|
97
|
+
assert_match %r{create_table "int_defaults", id: :bigint, default: nil}, schema
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
class PrimaryKeyHiddenColumnTest < ActiveRecord::TestCase
|
|
102
|
+
class Rocket < ActiveRecord::Base
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def setup
|
|
106
|
+
connection = ActiveRecord::Base.lease_connection
|
|
107
|
+
connection.execute <<-SQL
|
|
108
|
+
CREATE TABLE rockets(
|
|
109
|
+
id SERIAL PRIMARY KEY USING HASH WITH (bucket_count=4)
|
|
110
|
+
)
|
|
111
|
+
SQL
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def teardown
|
|
115
|
+
ActiveRecord::Base.connection.drop_table :rockets
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def test_to_key_with_hidden_primary_key_part
|
|
119
|
+
rocket = Rocket.new
|
|
120
|
+
assert_nil rocket.to_key
|
|
121
|
+
rocket.save
|
|
122
|
+
assert_equal rocket.to_key, [rocket.id]
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def test_read_attribute_with_hidden_primary_key_part
|
|
126
|
+
rocket = Rocket.create!
|
|
127
|
+
id = assert_not_deprecated(ActiveRecord.deprecator) do
|
|
128
|
+
rocket.read_attribute(:id)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
assert_equal rocket.id, id
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
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
|
|
@@ -0,0 +1,26 @@
|
|
|
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
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "cases/helper_cockroachdb"
|
|
4
|
+
require "models/post"
|
|
5
|
+
|
|
6
|
+
module CockroachDB
|
|
7
|
+
class TableHintsTest < ActiveRecord::TestCase
|
|
8
|
+
fixtures :posts
|
|
9
|
+
|
|
10
|
+
def test_add_hint
|
|
11
|
+
force_index = ->(q) { q.force_index("index_posts_on_author_id") }
|
|
12
|
+
index_hint = ->(q) { q.index_hint("NO_FULL_SCAN") }
|
|
13
|
+
|
|
14
|
+
assert_queries_match(/"posts"@\{FORCE_INDEX=index_posts_on_author_id\}/) do
|
|
15
|
+
Post.then(&force_index).take
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
assert_queries_match(/"posts"@\{NO_FULL_SCAN\}/) do
|
|
19
|
+
Post.then(&index_hint).take
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
[force_index, index_hint].permutation do |procs|
|
|
23
|
+
assert_queries_match(/"posts"@\{NO_FULL_SCAN,FORCE_INDEX=index_posts_on_author_id\}/) do
|
|
24
|
+
Post.then(&procs.reduce(:<<)).take
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_choose_index_order
|
|
30
|
+
idx = "index_posts_on_author_id"
|
|
31
|
+
assert_queries_match(/"posts"@\{FORCE_INDEX=#{idx},ASC\}/) do
|
|
32
|
+
Post.force_index(idx, direction: "ASC").take
|
|
33
|
+
end
|
|
34
|
+
assert_queries_match(/"posts"@\{FORCE_INDEX=#{idx},DESC\}/) do
|
|
35
|
+
Post.force_index(idx, direction: "DESC").take
|
|
36
|
+
end
|
|
37
|
+
assert_queries_match(/"posts"@\{NO_FULL_SCAN,FORCE_INDEX=#{idx},DESC\}/) do
|
|
38
|
+
Post.force_index(idx, direction: "DESC").index_hint("NO_FULL_SCAN").take
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def test_use_other_table
|
|
43
|
+
force_index = ->(q) { q.force_index("index_subscribers_on_nick") }
|
|
44
|
+
index_hint = ->(q) { q.index_hint("NO_FULL_SCAN") }
|
|
45
|
+
post_from = Post.select(:id).from("subscribers")
|
|
46
|
+
|
|
47
|
+
assert_queries_match(/subscribers@\{FORCE_INDEX=index_subscribers_on_nick\}/) do
|
|
48
|
+
post_from.then(&force_index).take
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
assert_queries_match(/subscribers@\{NO_FULL_SCAN\}/) do
|
|
52
|
+
post_from.then(&index_hint).take
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
[force_index, index_hint].permutation do |procs|
|
|
56
|
+
assert_queries_match(/subscribers@\{NO_FULL_SCAN,FORCE_INDEX=index_subscribers_on_nick\}/) do
|
|
57
|
+
post_from.then(&procs.reduce(:<<)).take
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def test_from_with_space
|
|
63
|
+
["foo\t", "foo "].each do
|
|
64
|
+
assert_match(/FROM foo@\{H\}/, Post.from(_1).index_hint("H").to_sql)
|
|
65
|
+
assert_match(
|
|
66
|
+
/FROM foo@\{H,FORCE_INDEX=i\}/,
|
|
67
|
+
Post.from(_1).index_hint("H").force_index("i").to_sql
|
|
68
|
+
)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def test_reset_with_from
|
|
73
|
+
force_index = ->(q) { q.force_index("type") }
|
|
74
|
+
index_hint = ->(q) { q.index_hint("NO_FULL_SCAN") }
|
|
75
|
+
|
|
76
|
+
[force_index, index_hint].permutation do
|
|
77
|
+
assert_match(
|
|
78
|
+
/FROM age\z/,
|
|
79
|
+
Post.then(&_1).then(&_2).from("age").to_sql
|
|
80
|
+
)
|
|
81
|
+
end
|
|
82
|
+
[force_index, index_hint].each do
|
|
83
|
+
assert_match(/FROM age\z/, Post.then(&_1).from("age").to_sql)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def test_ignore_from_multiple_tables
|
|
89
|
+
tables = "ta, tb"
|
|
90
|
+
from = ->(q) { q.from(tables) }
|
|
91
|
+
force_index = ->(q) { q.force_index("type") }
|
|
92
|
+
index_hint = ->(q) { q.index_hint("NO_FULL_SCAN") }
|
|
93
|
+
|
|
94
|
+
(
|
|
95
|
+
[from, force_index, index_hint].permutation +
|
|
96
|
+
[from, force_index].permutation +
|
|
97
|
+
[from, index_hint].permutation
|
|
98
|
+
).each do |procs|
|
|
99
|
+
assert_match(
|
|
100
|
+
/FROM #{tables}\z/,
|
|
101
|
+
Post.then(&procs.reduce(:<<)).to_sql
|
|
102
|
+
)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def test_ignore_from_subquery
|
|
107
|
+
subquery = Post.where("created_at < ?", 1.year.ago)
|
|
108
|
+
from = ->(q) { q.from(subquery) }
|
|
109
|
+
force_index = ->(q) { q.force_index("safeword") }
|
|
110
|
+
index_hint = ->(q) { q.index_hint("NO_FULL_SCAN") }
|
|
111
|
+
|
|
112
|
+
(
|
|
113
|
+
[from, force_index, index_hint].permutation +
|
|
114
|
+
[from, force_index].permutation +
|
|
115
|
+
[from, index_hint].permutation
|
|
116
|
+
).each do |procs|
|
|
117
|
+
refute_match(
|
|
118
|
+
/safeword|NO_FULL_SCAN|@/,
|
|
119
|
+
Post.then(&procs.reduce(:<<)).to_sql
|
|
120
|
+
)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
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
|
|
@@ -0,0 +1,29 @@
|
|
|
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
|