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.
Files changed (239) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/CONTRIBUTING.md +10 -17
  4. data/Gemfile +2 -1
  5. data/Rakefile +0 -19
  6. data/lib/active_record/connection_adapters/cockroachdb/column.rb +66 -24
  7. data/lib/active_record/connection_adapters/cockroachdb/database_statements.rb +13 -3
  8. data/lib/active_record/connection_adapters/cockroachdb/database_tasks.rb +1 -1
  9. data/lib/active_record/connection_adapters/cockroachdb/oid/spatial.rb +34 -19
  10. data/lib/active_record/connection_adapters/cockroachdb/quoting.rb +19 -3
  11. data/lib/active_record/connection_adapters/cockroachdb/referential_integrity.rb +87 -55
  12. data/lib/active_record/connection_adapters/cockroachdb/schema_statements.rb +181 -102
  13. data/lib/active_record/connection_adapters/cockroachdb_adapter.rb +42 -25
  14. data/lib/version.rb +1 -1
  15. data/test/cases/adapter_test.rb +98 -0
  16. data/test/cases/adapters/cockroachdb/referential_integrity_test.rb +51 -0
  17. data/test/cases/adapters/postgresql/active_schema_test.rb +71 -0
  18. data/test/cases/adapters/postgresql/change_schema_test.rb +75 -0
  19. data/test/cases/adapters/postgresql/connection_test.rb +46 -0
  20. data/test/cases/adapters/postgresql/ddl_test.rb +326 -0
  21. data/test/cases/adapters/postgresql/interval_test.rb +131 -0
  22. data/test/cases/adapters/postgresql/nested_class_test.rb +22 -0
  23. data/test/cases/adapters/postgresql/numeric_test.rb +28 -0
  24. data/test/cases/adapters/postgresql/postgis_test.rb +185 -0
  25. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +115 -0
  26. data/test/cases/adapters/postgresql/quoting_test.rb +30 -0
  27. data/test/cases/adapters/postgresql/schema_statements_test.rb +29 -0
  28. data/test/cases/adapters/postgresql/serial_test.rb +199 -0
  29. data/test/cases/adapters/postgresql/spatial_queries_test.rb +118 -0
  30. data/test/cases/adapters/postgresql/spatial_setup_test.rb +18 -0
  31. data/test/cases/adapters/postgresql/spatial_type_test.rb +41 -0
  32. data/test/cases/adapters/postgresql/timestamp_test.rb +58 -0
  33. data/test/cases/adapters/postgresql/virtual_column_test.rb +39 -0
  34. data/test/cases/associations/eager_load_nested_include_test.rb +111 -0
  35. data/test/cases/associations/left_outer_join_association_test.rb +30 -0
  36. data/test/cases/associations_test.rb +108 -0
  37. data/test/cases/base_test.rb +31 -0
  38. data/test/cases/comment_test.rb +75 -0
  39. data/test/cases/connection_adapters/type_test.rb +28 -0
  40. data/test/cases/database_configurations/resolver_test.rb +24 -0
  41. data/test/cases/defaults_test.rb +45 -0
  42. data/test/cases/dirty_test.rb +24 -0
  43. data/test/cases/fixtures_test.rb +541 -0
  44. data/test/cases/helper_cockroachdb.rb +232 -0
  45. data/test/cases/inheritance_test.rb +42 -0
  46. data/test/cases/invertible_migration_test.rb +73 -0
  47. data/test/cases/marshal_serialization_test.rb +45 -0
  48. data/test/cases/migration/change_schema_test.rb +140 -0
  49. data/test/cases/migration/check_constraint_test.rb +125 -0
  50. data/test/cases/migration/columns_test.rb +50 -0
  51. data/test/cases/migration/create_join_table_test.rb +66 -0
  52. data/test/cases/migration/foreign_key_test.rb +390 -0
  53. data/test/cases/migration/hidden_column_test.rb +70 -0
  54. data/test/cases/migration/references_foreign_key_test.rb +124 -0
  55. data/test/cases/migration_test.rb +120 -0
  56. data/test/cases/persistence_test.rb +33 -0
  57. data/test/cases/primary_keys_test.rb +134 -0
  58. data/test/cases/relation/aost_test.rb +57 -0
  59. data/test/cases/relation/or_test.rb +26 -0
  60. data/test/cases/relation/table_hints_test.rb +124 -0
  61. data/test/cases/relation_test.rb +26 -0
  62. data/test/cases/relations_test.rb +29 -0
  63. data/test/cases/schema_dumper_test.rb +221 -0
  64. data/test/cases/show_create_test.rb +14 -0
  65. data/test/cases/strict_loading_test.rb +34 -0
  66. data/test/cases/tasks/cockroachdb_rake_test.rb +113 -0
  67. data/test/cases/test_fixtures_test.rb +57 -0
  68. data/test/cases/transactions_test.rb +51 -0
  69. data/test/cases/unsafe_raw_sql_test.rb +22 -0
  70. data/test/config.yml +23 -0
  71. data/test/excludes/ActiveRecord/AdapterTest.rb +3 -0
  72. data/test/excludes/ActiveRecord/AdapterTestWithoutTransaction.rb +25 -0
  73. data/test/excludes/ActiveRecord/ConnectionAdapters/PoolConfig/ResolverTest.rb +1 -0
  74. data/test/excludes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapter/BindParameterTest.rb +15 -0
  75. data/test/excludes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapter/QuotingTest.rb +22 -0
  76. data/test/excludes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapterPreventWritesLegacyTest.rb +1 -0
  77. data/test/excludes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapterPreventWritesTest.rb +1 -0
  78. data/test/excludes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapterTest.rb +40 -0
  79. data/test/excludes/ActiveRecord/ConnectionAdapters/RegistrationIsolatedTest.rb +14 -0
  80. data/test/excludes/ActiveRecord/Encryption/EncryptionPerformanceTest.rb +1 -0
  81. data/test/excludes/ActiveRecord/Encryption/EnvelopeEncryptionPerformanceTest.rb +1 -0
  82. data/test/excludes/ActiveRecord/Encryption/ExtendedDeterministicQueriesPerformanceTest.rb +1 -0
  83. data/test/excludes/ActiveRecord/Encryption/StoragePerformanceTest.rb +2 -0
  84. data/test/excludes/ActiveRecord/InstrumentationTest.rb +16 -0
  85. data/test/excludes/ActiveRecord/InvertibleMigrationTest.rb +2 -0
  86. data/test/excludes/ActiveRecord/Migration/ChangeSchemaTest.rb +7 -0
  87. data/test/excludes/ActiveRecord/Migration/CheckConstraintTest.rb +6 -0
  88. data/test/excludes/ActiveRecord/Migration/ColumnsTest.rb +4 -0
  89. data/test/excludes/ActiveRecord/Migration/CompatibilityTest.rb +50 -0
  90. data/test/excludes/ActiveRecord/Migration/CompositeForeignKeyTest.rb +2 -0
  91. data/test/excludes/ActiveRecord/Migration/CreateJoinTableTest.rb +2 -0
  92. data/test/excludes/ActiveRecord/Migration/ForeignKeyInCreateTest.rb +1 -0
  93. data/test/excludes/ActiveRecord/Migration/ForeignKeyTest.rb +35 -0
  94. data/test/excludes/ActiveRecord/Migration/InvalidOptionsTest.rb +14 -0
  95. data/test/excludes/ActiveRecord/Migration/PGChangeSchemaTest.rb +8 -0
  96. data/test/excludes/ActiveRecord/Migration/ReferencesForeignKeyTest.rb +7 -0
  97. data/test/excludes/ActiveRecord/Migration/ReferencesIndexTest.rb +7 -0
  98. data/test/excludes/ActiveRecord/Migration/ReferencesStatementsTest.rb +3 -0
  99. data/test/excludes/ActiveRecord/MysqlDBCreateWithInvalidPermissionsTest.rb +1 -0
  100. data/test/excludes/ActiveRecord/OrTest.rb +1 -0
  101. data/test/excludes/ActiveRecord/PostgreSQLStructureDumpTest.rb +10 -0
  102. data/test/excludes/ActiveRecord/PostgresqlConnectionTest.rb +12 -0
  103. data/test/excludes/ActiveRecord/PostgresqlTransactionNestedTest.rb +14 -0
  104. data/test/excludes/ActiveRecord/PostgresqlTransactionTest.rb +4 -0
  105. data/test/excludes/ActiveRecord/RelationTest.rb +2 -0
  106. data/test/excludes/ActiveRecord/TooManyOrTest.rb +1 -0
  107. data/test/excludes/ActiveSupportSubclassWithFixturesTest.rb +1 -0
  108. data/test/excludes/AssociationDeprecationTest/NotifyModeTest.rb +2 -0
  109. data/test/excludes/AssociationDeprecationTest/RaiseBacktraceModeTest.rb +2 -0
  110. data/test/excludes/AssociationDeprecationTest/RaiseModeTest.rb +2 -0
  111. data/test/excludes/AssociationDeprecationTest/WarnBacktraceModeTest.rb +2 -0
  112. data/test/excludes/AssociationDeprecationTest/WarnModeTest.rb +2 -0
  113. data/test/excludes/AssociationDeprecationTest/fix_backtrace_cleaner.rb +10 -0
  114. data/test/excludes/BasicsTest.rb +1 -0
  115. data/test/excludes/BulkAlterTableMigrationsTest.rb +7 -0
  116. data/test/excludes/CalculationsTest.rb +4 -0
  117. data/test/excludes/CommentTest.rb +2 -0
  118. data/test/excludes/CoreTest.rb +1 -0
  119. data/test/excludes/CreateOrFindByWithinTransactions.rb +3 -0
  120. data/test/excludes/DefaultsUsingMultipleSchemasAndDomainTest.rb +7 -0
  121. data/test/excludes/DirtyTest.rb +3 -0
  122. data/test/excludes/EachTest.rb +8 -0
  123. data/test/excludes/EagerLoadPolyAssocsTest.rb +1 -0
  124. data/test/excludes/ExplicitlyNamedIndexMigrationTest.rb +1 -0
  125. data/test/excludes/FixturesResetPkSequenceTest.rb +3 -0
  126. data/test/excludes/FixturesTest.rb +21 -0
  127. data/test/excludes/FixturesWithForeignKeyViolationsTest.rb +2 -0
  128. data/test/excludes/ForeignTableTest.rb +10 -0
  129. data/test/excludes/InheritanceComputeTypeTest.rb +1 -0
  130. data/test/excludes/LeftOuterJoinAssociationTest.rb +2 -0
  131. data/test/excludes/LegacyPrimaryKeyTest/V4_2.rb +6 -0
  132. data/test/excludes/LegacyPrimaryKeyTest/V5_0.rb +6 -0
  133. data/test/excludes/MarshalSerializationTest.rb +4 -0
  134. data/test/excludes/MaterializedViewTest.rb +13 -0
  135. data/test/excludes/MigrationTest.rb +2 -0
  136. data/test/excludes/MultiDbMigratorTest.rb +2 -0
  137. data/test/excludes/NestedRelationScopingTest.rb +1 -0
  138. data/test/excludes/OrTest.rb +1 -0
  139. data/test/excludes/PersistenceTest.rb +3 -0
  140. data/test/excludes/PessimisticLockingTest.rb +1 -0
  141. data/test/excludes/PostgreSQLExplainTest.rb +7 -0
  142. data/test/excludes/PostgreSQLGeometricLineTest.rb +3 -0
  143. data/test/excludes/PostgreSQLGeometricTypesTest.rb +7 -0
  144. data/test/excludes/PostgreSQLPartitionsTest.rb +1 -0
  145. data/test/excludes/PostgreSQLReferentialIntegrityTest.rb +14 -0
  146. data/test/excludes/PostgresqlArrayTest.rb +21 -0
  147. data/test/excludes/PostgresqlBigSerialTest.rb +7 -0
  148. data/test/excludes/PostgresqlBitStringTest.rb +2 -0
  149. data/test/excludes/PostgresqlByteaTest.rb +1 -0
  150. data/test/excludes/PostgresqlCitextTest.rb +7 -0
  151. data/test/excludes/PostgresqlCollationTest.rb +5 -0
  152. data/test/excludes/PostgresqlCompositeTest.rb +2 -0
  153. data/test/excludes/PostgresqlCompositeWithCustomOIDTest.rb +2 -0
  154. data/test/excludes/PostgresqlDataTypeTest.rb +9 -0
  155. data/test/excludes/PostgresqlDefaultExpressionTest.rb +1 -0
  156. data/test/excludes/PostgresqlDeferredConstraintsTest.rb +3 -0
  157. data/test/excludes/PostgresqlDomainTest.rb +2 -0
  158. data/test/excludes/PostgresqlExtensionMigrationTest.rb +5 -0
  159. data/test/excludes/PostgresqlFullTextTest.rb +3 -0
  160. data/test/excludes/PostgresqlGeometricTest.rb +4 -0
  161. data/test/excludes/PostgresqlHstoreTest.rb +45 -0
  162. data/test/excludes/PostgresqlInfinityTest.rb +5 -0
  163. data/test/excludes/PostgresqlIntervalTest.rb +1 -0
  164. data/test/excludes/PostgresqlJSONBTest.rb +27 -0
  165. data/test/excludes/PostgresqlJSONTest.rb +27 -0
  166. data/test/excludes/PostgresqlLtreeTest.rb +4 -0
  167. data/test/excludes/PostgresqlMoneyTest.rb +12 -0
  168. data/test/excludes/PostgresqlNetworkTest.rb +69 -0
  169. data/test/excludes/PostgresqlNumberTest.rb +1 -0
  170. data/test/excludes/PostgresqlPointTest.rb +15 -0
  171. data/test/excludes/PostgresqlRangeTest.rb +3 -0
  172. data/test/excludes/PostgresqlRenameTableTest.rb +2 -0
  173. data/test/excludes/PostgresqlSerialTest.rb +7 -0
  174. data/test/excludes/PostgresqlTimestampFixtureTest.rb +2 -0
  175. data/test/excludes/PostgresqlTimestampMigrationTest.rb +3 -0
  176. data/test/excludes/PostgresqlTypeLookupTest.rb +2 -0
  177. data/test/excludes/PostgresqlUUIDGenerationTest.rb +7 -0
  178. data/test/excludes/PostgresqlUUIDTest.rb +1 -0
  179. data/test/excludes/PostgresqlVirtualColumnTest.rb +17 -0
  180. data/test/excludes/PostgresqlXMLTest.rb +5 -0
  181. data/test/excludes/PrimaryKeyIntegerNilDefaultTest.rb +1 -0
  182. data/test/excludes/PrimaryKeyIntegerTest.rb +3 -0
  183. data/test/excludes/PrimaryKeysTest.rb +2 -0
  184. data/test/excludes/RelationMergingTest.rb +15 -0
  185. data/test/excludes/RelationTest.rb +3 -0
  186. data/test/excludes/ReservedWordsMigrationTest.rb +1 -0
  187. data/test/excludes/SameNameDifferentDatabaseFixturesTest.rb +1 -0
  188. data/test/excludes/SanitizeTest.rb +13 -0
  189. data/test/excludes/SchemaAuthorizationTest.rb +8 -0
  190. data/test/excludes/SchemaCreateTableOptionsTest.rb +2 -0
  191. data/test/excludes/SchemaDumperDefaultsTest.rb +1 -0
  192. data/test/excludes/SchemaDumperTest.rb +11 -0
  193. data/test/excludes/SchemaForeignKeyTest.rb +1 -0
  194. data/test/excludes/SchemaIndexNullsOrderTest.rb +2 -0
  195. data/test/excludes/SchemaIndexOpclassTest.rb +3 -0
  196. data/test/excludes/SchemaTest.rb +49 -0
  197. data/test/excludes/SequenceNameDetectionTestCases/CollidedSequenceNameTest.rb +1 -0
  198. data/test/excludes/SequenceNameDetectionTestCases/LongerSequenceNameDetectionTest.rb +1 -0
  199. data/test/excludes/StrictLoadingFixturesTest.rb +1 -0
  200. data/test/excludes/TestFixturesTest.rb +1 -0
  201. data/test/excludes/TransactionInstrumentationTest.rb +1 -0
  202. data/test/excludes/TransactionIsolationTest.rb +1 -0
  203. data/test/excludes/TypeTest.rb +1 -0
  204. data/test/excludes/UniquenessValidationTest.rb +2 -0
  205. data/test/excludes/UnloggedTablesTest.rb +3 -0
  206. data/test/excludes/UnsafeRawSqlTest.rb +2 -0
  207. data/test/excludes/UpdateableViewTest.rb +5 -0
  208. data/test/excludes/WithAnnotationsTest.rb +6 -0
  209. data/test/models/building.rb +4 -0
  210. data/test/models/spatial_model.rb +5 -0
  211. data/test/schema/cockroachdb_specific_schema.rb +218 -0
  212. data/test/support/copy_cat.rb +83 -0
  213. data/test/support/exclude_from_transactional_tests.rb +33 -0
  214. data/test/support/paths_cockroachdb.rb +46 -0
  215. data/test/support/rake_helpers.rb +37 -0
  216. data/test/support/sql_logger.rb +55 -0
  217. data/test/support/template_creator.rb +114 -0
  218. metadata +422 -34
  219. data/.editorconfig +0 -7
  220. data/.github/issue_template.md +0 -46
  221. data/.github/reproduction_scripts/migrations.rb +0 -60
  222. data/.github/reproduction_scripts/models_and_database.rb +0 -49
  223. data/.github/workflows/ci.yml +0 -96
  224. data/.github/workflows/docker.yml +0 -57
  225. data/.gitignore +0 -18
  226. data/.gitmodules +0 -0
  227. data/activerecord-cockroachdb-adapter.gemspec +0 -38
  228. data/bin/console +0 -36
  229. data/bin/console_schemas/default.rb +0 -11
  230. data/bin/console_schemas/schemas.rb +0 -23
  231. data/bin/setup +0 -8
  232. data/bin/start-cockroachdb +0 -33
  233. data/build/Dockerfile +0 -14
  234. data/build/config.teamcity.yml +0 -31
  235. data/build/local-test.sh +0 -32
  236. data/build/teamcity-test.sh +0 -76
  237. data/docker.sh +0 -35
  238. data/lib/active_record/connection_adapters/cockroachdb/spatial_column_info.rb +0 -60
  239. data/setup.sql +0 -18
@@ -0,0 +1,199 @@
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 PostgresqlSerialTest < ActiveRecord::PostgreSQLTestCase
8
+ include SchemaDumpingHelper
9
+
10
+ class PostgresqlSerial < ActiveRecord::Base; end
11
+
12
+ setup do
13
+ @connection = ActiveRecord::Base.lease_connection
14
+ @connection.create_table "postgresql_serials", force: true do |t|
15
+ t.serial :seq
16
+
17
+ # Instead of creating this column with a sequence default, we'll create
18
+ # it with a unique_rowid() default. This better matches the behavior in
19
+ # CockroachDB.
20
+ t.integer :serials_id, default: -> { "unique_rowid()" }
21
+ end
22
+ end
23
+
24
+ teardown do
25
+ @connection.drop_table "postgresql_serials", if_exists: true
26
+ end
27
+
28
+ # This replaces the same test that's been excluded from
29
+ # PostgresqlSerialTest. The column's type is integer, but it's sql_type is
30
+ # bigint because CockroachDB's integers are bigints.
31
+ # See test/excludes/PostgresqlSerialTest.rb
32
+ def test_serial_column
33
+ column = PostgresqlSerial.columns_hash["seq"]
34
+ assert_equal :integer, column.type
35
+ assert_equal "bigint", column.sql_type
36
+ assert_predicate column, :serial?
37
+ end
38
+
39
+ # This replaces the same test that's been excluded from
40
+ # PostgresqlSerialTest. The column's type is integer, but it's sql_type is
41
+ # bigint because CockroachDB's integers are bigints. The column is also
42
+ # serial? because it uses the same default function that serial columns use.
43
+ # See test/excludes/PostgresqlSerialTest.rb
44
+ def test_not_serial_column
45
+ column = PostgresqlSerial.columns_hash["serials_id"]
46
+ assert_equal :integer, column.type
47
+ assert_equal "bigint", column.sql_type
48
+ assert_predicate column, :serial?
49
+ end
50
+
51
+ # This replaces the same test that's been excluded from
52
+ # PostgresqlSerialTest. Although the seq column was created as a serial
53
+ # column, the dump will include it as a bigserial column. That's because
54
+ # serial columns are backed by integer columns, and integer columns are
55
+ # bigints in CockroachDB.
56
+ # See test/excludes/PostgresqlSerialTest.rb
57
+ def test_schema_dump_with_shorthand
58
+ output = dump_table_schema "postgresql_serials"
59
+ assert_match %r{t\.bigserial\s+"seq",\s+null: false$}, output
60
+ end
61
+
62
+ # This replaces the same test that's been excluded from
63
+ # PostgresqlSerialTest. The serials_id column wasn't created as a serial
64
+ # column, but the dump will include it as such because it has the same
65
+ # default function has a serial column.
66
+ # See test/excludes/PostgresqlSerialTest.rb
67
+ def test_schema_dump_with_not_serial
68
+ output = dump_table_schema "postgresql_serials"
69
+ assert_match %r{t\.bigserial\s+"serials_id"$}, output
70
+ end
71
+ end
72
+
73
+ class PostgresqlBigSerialTest < ActiveRecord::PostgreSQLTestCase
74
+ include SchemaDumpingHelper
75
+
76
+ class PostgresqlBigSerial < ActiveRecord::Base; end
77
+
78
+ setup do
79
+ @connection = ActiveRecord::Base.lease_connection
80
+ @connection.create_table "postgresql_big_serials", force: true do |t|
81
+ t.bigserial :seq
82
+
83
+ # Instead of creating this column with a sequence default, we'll create
84
+ # it with a unique_rowid() default. This better matches the behavior in
85
+ # CockroachDB.
86
+ t.bigint :serials_id, default: -> { "unique_rowid()" }
87
+ end
88
+ end
89
+
90
+ teardown do
91
+ @connection.drop_table "postgresql_big_serials", if_exists: true
92
+ end
93
+
94
+ # This replaces the same test that's been excluded from
95
+ # PostgresqlBigSerialTest. We can run it here because the setup has been
96
+ # fixed.
97
+ # See test/excluded/PostgresqlBigSerialTest.rb
98
+ def test_bigserial_column
99
+ column = PostgresqlBigSerial.columns_hash["seq"]
100
+ assert_equal :integer, column.type
101
+ assert_equal "bigint", column.sql_type
102
+ assert_predicate column, :serial?
103
+ end
104
+
105
+ # This replaces the same test that's been excluded from
106
+ # PostgresqlBigSerialTest. The column is serial? because it uses the same
107
+ # default function that serial columns use.
108
+ # See test/excludes/PostgresqlBigSerialTest.rb
109
+ def test_not_bigserial_column
110
+ column = PostgresqlBigSerial.columns_hash["serials_id"]
111
+ assert_equal :integer, column.type
112
+ assert_equal "bigint", column.sql_type
113
+ assert_predicate column, :serial?
114
+ end
115
+
116
+ # This replaces the same test that's been excluded from
117
+ # PostgresqlBigSerialTest. We can run it here because the setup has been
118
+ # fixed.
119
+ # See test/excluded/PostgresqlBigSerialTest.rb
120
+ def test_schema_dump_with_shorthand
121
+ output = dump_table_schema "postgresql_big_serials"
122
+ assert_match %r{t\.bigserial\s+"seq",\s+null: false$}, output
123
+ end
124
+
125
+ # This replaces the same test that's been excluded from
126
+ # PostgresqlBigSerialTest. The serials_id column wasn't created as a serial
127
+ # column, but the dump will include it as such because it has the same
128
+ # default function has a serial column.
129
+ # See test/excluded/PostgresqlBigSerialTest.rb
130
+ def test_schema_dump_with_not_bigserial
131
+ output = dump_table_schema "postgresql_big_serials"
132
+ assert_match %r{t\.bigserial\s+"serials_id"$}, output
133
+ end
134
+ end
135
+
136
+ module SequenceNameDetectionTestCases
137
+ class CollidedSequenceNameTest < ActiveRecord::PostgreSQLTestCase
138
+ include SchemaDumpingHelper
139
+
140
+ def setup
141
+ @connection = ActiveRecord::Base.lease_connection
142
+ @connection.create_table :foo_bar, force: true do |t|
143
+ t.serial :baz_id
144
+ end
145
+ @connection.create_table :foo, force: true do |t|
146
+ t.serial :bar_id
147
+ t.bigserial :bar_baz_id
148
+ end
149
+ end
150
+
151
+ def teardown
152
+ @connection.drop_table :foo_bar, if_exists: true
153
+ @connection.drop_table :foo, if_exists: true
154
+ end
155
+
156
+ # This replaces the same test that's been excluded from
157
+ # SequenceNameDetectionTestCases::CollidedSequenceNameTest. Although
158
+ # bar_id was created as a serial column, it will get dumped as a bigserial
159
+ # column. Serial columns are backed by integer columns, and integer
160
+ # columns are bigints in CockroachDB.
161
+ # See test/excludes/SequenceNameDetectionTestCases/CollidedSequenceNameTest.rb
162
+ def test_schema_dump_with_collided_sequence_name
163
+ output = dump_table_schema "foo"
164
+ assert_match %r{t\.bigserial\s+"bar_id",\s+null: false$}, output
165
+ assert_match %r{t\.bigserial\s+"bar_baz_id",\s+null: false$}, output
166
+ end
167
+ end
168
+
169
+ class LongerSequenceNameDetectionTest < ActiveRecord::PostgreSQLTestCase
170
+ include SchemaDumpingHelper
171
+
172
+ def setup
173
+ @table_name = "long_table_name_to_test_sequence_name_detection_for_serial_cols"
174
+ @connection = ActiveRecord::Base.lease_connection
175
+ @connection.create_table @table_name, force: true do |t|
176
+ t.serial :seq
177
+ t.bigserial :bigseq
178
+ end
179
+ end
180
+
181
+ def teardown
182
+ @connection.drop_table @table_name, if_exists: true
183
+ end
184
+
185
+ # This replaces the same test that's been excluded from
186
+ # SequenceNameDetectionTestCases::LongerSequenceNameDetectionTest.
187
+ # Although seq was created as a serial column, it will get dumped as a bigserial
188
+ # column. Serial columns are backed by integer columns, and integer
189
+ # columns are bigints in CockroachDB.
190
+ # See test/excludes/SequenceNameDetectionTestCases/LongerSequenceNameDetectionTest.rb
191
+ def test_schema_dump_with_long_table_name
192
+ output = dump_table_schema @table_name
193
+ assert_match %r{create_table "#{@table_name}", force: :cascade}, output
194
+ assert_match %r{t\.bigserial\s+"seq",\s+null: false$}, output
195
+ assert_match %r{t\.bigserial\s+"bigseq",\s+null: false$}, output
196
+ end
197
+ end
198
+ end
199
+ end
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cases/helper_cockroachdb'
4
+ require 'models/building'
5
+
6
+ class SpatialQueriesTest < ActiveSupport::TestCase
7
+ def setup
8
+ Building.delete_all
9
+ end
10
+
11
+ def test_query_point
12
+ obj = Building.create!(coordinates: factory.point(1, 2))
13
+ id = obj.id
14
+ assert_empty Building.where(coordinates: factory.point(2, 2))
15
+ obj1 = Building.find_by(coordinates: factory.point(1, 2))
16
+ refute_nil(obj1)
17
+ assert_equal id, obj1.id
18
+ end
19
+
20
+ def test_query_multi_point
21
+ obj = Building.create!(points: factory.multi_point([factory.point(1, 2)]))
22
+ id = obj.id
23
+ obj2 = Building.find_by(points: factory.multi_point([factory.point(1, 2)]))
24
+ refute_nil(obj2)
25
+ assert_equal(id, obj2.id)
26
+ end
27
+
28
+ def test_query_point_wkt
29
+ obj = Building.create!(coordinates: factory.point(1, 2))
30
+ id = obj.id
31
+ obj2 = Building.find_by(coordinates: 'SRID=3857;POINT(1 2)')
32
+ refute_nil(obj2)
33
+ assert_equal(id, obj2.id)
34
+ obj3 = Building.find_by(coordinates: 'SRID=3857;POINT(2 2)')
35
+ assert_nil(obj3)
36
+ end
37
+
38
+ def test_query_st_distance
39
+ obj = Building.create!(coordinates: factory.point(1, 2))
40
+ id = obj.id
41
+ obj2 = Building.find_by(Building.arel_table[:coordinates].st_distance('SRID=3857;POINT(2 3)').lt(2))
42
+ refute_nil(obj2)
43
+ assert_equal(id, obj2.id)
44
+ obj3 = Building.find_by(Building.arel_table[:coordinates].st_distance('SRID=3857;POINT(2 3)').gt(2))
45
+ assert_nil(obj3)
46
+ end
47
+
48
+ def test_query_st_distance_from_constant
49
+ obj = Building.create!(coordinates: factory.point(1, 2))
50
+ id = obj.id
51
+
52
+ query_point = parser.parse('SRID=3857;POINT(2 3)')
53
+ obj2 = Building.find_by(Arel.spatial(query_point).st_distance(Building.arel_table[:coordinates]).lt(2))
54
+ refute_nil(obj2)
55
+ assert_equal(id, obj2.id)
56
+ obj3 = Building.find_by(Arel.spatial(query_point).st_distance(Building.arel_table[:coordinates]).gt(2))
57
+ assert_nil(obj3)
58
+ end
59
+
60
+ def test_query_st_length
61
+ obj = Building.new
62
+ obj.path = factory.line(factory.point(1.0, 2.0), factory.point(3.0, 2.0))
63
+ obj.save!
64
+ id = obj.id
65
+ obj2 = Building.find_by(Building.arel_table[:path].st_length.eq(2))
66
+ refute_nil(obj2)
67
+ assert_equal(id, obj2.id)
68
+ obj3 = Building.find_by(Building.arel_table[:path].st_length.gt(3))
69
+ assert_nil(obj3)
70
+ end
71
+
72
+ def test_query_rgeo_feature_node
73
+ obj = Building.new
74
+ obj.path = factory.line_string([factory.point(1.0, 2.0),
75
+ factory.point(2.0, 2.0), factory.point(3.0, 2.0)])
76
+ obj.save!
77
+ id = obj.id
78
+
79
+ query_point = factory.point(2.0, 2.0)
80
+ obj2 = Building.find_by(Building.arel_table[:path].st_contains(query_point))
81
+ assert_equal(id, obj2.id)
82
+
83
+ query_point = factory.point(0.0, 2.0)
84
+ obj3 = Building.find_by(Building.arel_table[:path].st_contains(query_point))
85
+ assert_nil(obj3)
86
+ end
87
+
88
+ def test_query_rgeo_bbox_node
89
+ obj = Building.new
90
+ obj.coordinates = factory.point(1, 2)
91
+ obj.save!
92
+ id = obj.id
93
+
94
+ pt1 = factory.point(-1, -1)
95
+ pt2 = factory.point(4, 4)
96
+ bbox = RGeo::Cartesian::BoundingBox.create_from_points(pt1, pt2)
97
+ obj2 = Building.find_by(Building.arel_table[:coordinates].st_within(bbox))
98
+ assert_equal(id, obj2.id)
99
+ end
100
+
101
+ def test_ewkt_parser_query
102
+ obj = Building.create!(coordinates: factory.point(1, 2))
103
+ id = obj.id
104
+
105
+ query_point = parser.parse('SRID=3857;POINT(2 3)')
106
+ obj2 = Building.find_by(Arel.spatial(query_point).st_distance(Building.arel_table[:coordinates]).lt(2))
107
+ refute_nil(obj2)
108
+ assert_equal(id, obj2.id)
109
+ obj3 = Building.find_by(Arel.spatial(query_point).st_distance(Building.arel_table[:coordinates]).gt(2))
110
+ assert_nil(obj3)
111
+ end
112
+
113
+ private
114
+
115
+ def parser
116
+ RGeo::WKRep::WKTParser.new(nil, support_ewkt: true)
117
+ end
118
+ end
@@ -0,0 +1,18 @@
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
@@ -0,0 +1,41 @@
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
@@ -0,0 +1,58 @@
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
@@ -0,0 +1,39 @@
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
@@ -0,0 +1,111 @@
1
+ # This test has been copied to fix a bug in the test setup. It can be removed
2
+ # once the bug has been fixed and released in Rails.
3
+ # See test/excludes/EagerLoadPolyAssocsTest.rb
4
+
5
+ require "cases/helper_cockroachdb"
6
+
7
+ # Load dependencies from ActiveRecord test suite
8
+ require "models/post"
9
+ require "models/tag"
10
+ require "models/author"
11
+ require "models/comment"
12
+ require "models/category"
13
+ require "models/categorization"
14
+ require "models/tagging"
15
+
16
+ module CockroachDB
17
+ module Remembered
18
+ extend ActiveSupport::Concern
19
+
20
+ included do
21
+ after_create :remember
22
+ private
23
+ def remember; self.class.remembered << self; end
24
+ end
25
+
26
+ module ClassMethods
27
+ # The test setup bug is fixed here. @@remembered was being shared by every
28
+ # class that included the Remembered module. Instead, we can use
29
+ # @remembered which will be unique to each included class.
30
+ def remembered; @remembered ||= []; end
31
+ def sample; remembered.sample; end
32
+ end
33
+ end
34
+
35
+ class ShapeExpression < ActiveRecord::Base
36
+ belongs_to :shape, polymorphic: true
37
+ belongs_to :paint, polymorphic: true
38
+ end
39
+
40
+ class Circle < ActiveRecord::Base
41
+ has_many :shape_expressions, as: :shape
42
+ include Remembered
43
+ end
44
+ class Square < ActiveRecord::Base
45
+ has_many :shape_expressions, as: :shape
46
+ include Remembered
47
+ end
48
+ class Triangle < ActiveRecord::Base
49
+ has_many :shape_expressions, as: :shape
50
+ include Remembered
51
+ end
52
+ class PaintColor < ActiveRecord::Base
53
+ has_many :shape_expressions, as: :paint
54
+ belongs_to :non_poly, foreign_key: "non_poly_one_id", class_name: "NonPolyOne"
55
+ include Remembered
56
+ end
57
+ class PaintTexture < ActiveRecord::Base
58
+ has_many :shape_expressions, as: :paint
59
+ belongs_to :non_poly, foreign_key: "non_poly_two_id", class_name: "NonPolyTwo"
60
+ include Remembered
61
+ end
62
+ class NonPolyOne < ActiveRecord::Base
63
+ has_many :paint_colors
64
+ include Remembered
65
+ end
66
+ class NonPolyTwo < ActiveRecord::Base
67
+ has_many :paint_textures
68
+ include Remembered
69
+ end
70
+
71
+ class EagerLoadPolyAssocsTest < ActiveRecord::TestCase
72
+ NUM_SIMPLE_OBJS = 50
73
+ NUM_SHAPE_EXPRESSIONS = 100
74
+
75
+ def setup
76
+ generate_test_object_graphs
77
+ end
78
+
79
+ teardown do
80
+ [Circle, Square, Triangle, PaintColor, PaintTexture,
81
+ ShapeExpression, NonPolyOne, NonPolyTwo].each(&:delete_all)
82
+ end
83
+
84
+ def generate_test_object_graphs
85
+ 1.upto(NUM_SIMPLE_OBJS) do
86
+ [Circle, Square, Triangle, NonPolyOne, NonPolyTwo].map(&:create!)
87
+ end
88
+ 1.upto(NUM_SIMPLE_OBJS) do
89
+ PaintColor.create!(non_poly_one_id: NonPolyOne.sample.id)
90
+ PaintTexture.create!(non_poly_two_id: NonPolyTwo.sample.id)
91
+ end
92
+ 1.upto(NUM_SHAPE_EXPRESSIONS) do
93
+ shape_type = [Circle, Square, Triangle].sample
94
+ paint_type = [PaintColor, PaintTexture].sample
95
+ ShapeExpression.create!(shape_type: shape_type.to_s, shape_id: shape_type.sample.id,
96
+ paint_type: paint_type.to_s, paint_id: paint_type.sample.id)
97
+ end
98
+ end
99
+
100
+ def test_include_query
101
+ res = ShapeExpression.all.merge!(includes: [ :shape, { paint: :non_poly } ]).to_a
102
+ assert_equal NUM_SHAPE_EXPRESSIONS, res.size
103
+ assert_queries_count(0) do
104
+ res.each do |se|
105
+ assert_not_nil se.paint.non_poly, "this is the association that was loading incorrectly before the change"
106
+ assert_not_nil se.shape, "just making sure other associations still work"
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,30 @@
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