ibm_db 5.6.1 → 5.7.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 (592) hide show
  1. checksums.yaml +4 -4
  2. data/ext/Makefile +13 -9
  3. data/ext/extconf.rb +176 -110
  4. data/ext/ibm_db.c +60 -0
  5. data/ext/ibm_db.o +0 -0
  6. data/ext/ibm_db.so +0 -0
  7. data/ext/mkmf.log +6 -6
  8. data/ext/ruby_ibm_db_cli.c +14 -10
  9. data/ext/ruby_ibm_db_cli.h +4 -0
  10. data/ext/ruby_ibm_db_cli.o +0 -0
  11. data/lib/IBM_DB.rb +2 -2
  12. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1254 -277
  13. data/test/active_record/connection_adapters/fake_legacy_adapter.rb +17 -0
  14. data/test/active_record/connection_adapters/fake_misleading_legacy_adapter.rb +8 -0
  15. data/test/activejob/destroy_association_async_job_test.rb +62 -0
  16. data/test/activejob/destroy_association_async_test.rb +147 -11
  17. data/test/activejob/job_runtime_test.rb +41 -0
  18. data/test/activejob/unloadable_base_job.rb +3 -0
  19. data/test/cases/active_record_schema_test.rb +196 -0
  20. data/test/cases/active_record_test.rb +21 -0
  21. data/test/cases/adapter_prevent_writes_test.rb +26 -202
  22. data/test/cases/adapter_test.rb +592 -82
  23. data/test/cases/adapters/abstract_mysql_adapter/active_schema_test.rb +210 -0
  24. data/test/cases/adapters/abstract_mysql_adapter/adapter_prevent_writes_test.rb +111 -0
  25. data/test/cases/adapters/abstract_mysql_adapter/auto_increment_test.rb +48 -0
  26. data/test/cases/adapters/abstract_mysql_adapter/bind_parameter_test.rb +91 -0
  27. data/test/cases/adapters/abstract_mysql_adapter/case_sensitivity_test.rb +65 -0
  28. data/test/cases/adapters/abstract_mysql_adapter/charset_collation_test.rb +85 -0
  29. data/test/cases/adapters/abstract_mysql_adapter/connection_test.rb +267 -0
  30. data/test/cases/adapters/abstract_mysql_adapter/count_deleted_rows_with_lock_test.rb +29 -0
  31. data/test/cases/adapters/abstract_mysql_adapter/json_test.rb +24 -0
  32. data/test/cases/adapters/abstract_mysql_adapter/mysql_boolean_test.rb +102 -0
  33. data/test/cases/adapters/abstract_mysql_adapter/mysql_enum_test.rb +47 -0
  34. data/test/cases/adapters/abstract_mysql_adapter/mysql_explain_test.rb +71 -0
  35. data/test/cases/adapters/abstract_mysql_adapter/nested_deadlock_test.rb +191 -0
  36. data/test/cases/adapters/abstract_mysql_adapter/optimizer_hints_test.rb +69 -0
  37. data/test/cases/adapters/abstract_mysql_adapter/quoting_test.rb +49 -0
  38. data/test/cases/adapters/abstract_mysql_adapter/schema_migrations_test.rb +68 -0
  39. data/test/cases/adapters/abstract_mysql_adapter/schema_test.rb +130 -0
  40. data/test/cases/adapters/abstract_mysql_adapter/set_test.rb +32 -0
  41. data/test/cases/adapters/abstract_mysql_adapter/sp_test.rb +39 -0
  42. data/test/cases/adapters/abstract_mysql_adapter/sql_types_test.rb +16 -0
  43. data/test/cases/adapters/abstract_mysql_adapter/table_options_test.rb +125 -0
  44. data/test/cases/adapters/abstract_mysql_adapter/transaction_test.rb +204 -0
  45. data/test/cases/adapters/abstract_mysql_adapter/unsigned_type_test.rb +77 -0
  46. data/test/cases/adapters/abstract_mysql_adapter/virtual_column_test.rb +69 -0
  47. data/test/cases/adapters/abstract_mysql_adapter/warnings_test.rb +109 -0
  48. data/test/cases/adapters/mysql2/check_constraint_quoting_test.rb +35 -0
  49. data/test/cases/adapters/mysql2/dbconsole_test.rb +87 -0
  50. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +136 -10
  51. data/test/cases/adapters/mysql2/mysql2_rake_test.rb +433 -0
  52. data/test/cases/adapters/postgresql/active_schema_test.rb +8 -4
  53. data/test/cases/adapters/postgresql/array_test.rb +6 -6
  54. data/test/cases/adapters/postgresql/bind_parameter_test.rb +52 -0
  55. data/test/cases/adapters/postgresql/bit_string_test.rb +2 -2
  56. data/test/cases/adapters/postgresql/bytea_test.rb +3 -3
  57. data/test/cases/adapters/postgresql/case_insensitive_test.rb +1 -1
  58. data/test/cases/adapters/postgresql/change_schema_test.rb +32 -1
  59. data/test/cases/adapters/postgresql/cidr_test.rb +17 -0
  60. data/test/cases/adapters/postgresql/citext_test.rb +7 -1
  61. data/test/cases/adapters/postgresql/collation_test.rb +1 -1
  62. data/test/cases/adapters/postgresql/composite_test.rb +1 -1
  63. data/test/cases/adapters/postgresql/connection_test.rb +43 -36
  64. data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +3 -2
  65. data/test/cases/adapters/postgresql/datatype_test.rb +9 -4
  66. data/test/cases/adapters/postgresql/date_test.rb +2 -2
  67. data/test/cases/adapters/postgresql/dbconsole_test.rb +109 -0
  68. data/test/cases/adapters/postgresql/deferred_constraints_test.rb +55 -0
  69. data/test/cases/adapters/postgresql/domain_test.rb +1 -1
  70. data/test/cases/adapters/postgresql/enum_test.rb +208 -8
  71. data/test/cases/adapters/postgresql/explain_test.rb +25 -6
  72. data/test/cases/adapters/postgresql/extension_migration_test.rb +51 -9
  73. data/test/cases/adapters/postgresql/foreign_table_test.rb +3 -3
  74. data/test/cases/adapters/postgresql/full_text_test.rb +1 -1
  75. data/test/cases/adapters/postgresql/geometric_test.rb +13 -6
  76. data/test/cases/adapters/postgresql/hstore_test.rb +22 -32
  77. data/test/cases/adapters/postgresql/infinity_test.rb +13 -2
  78. data/test/cases/adapters/postgresql/integer_test.rb +1 -1
  79. data/test/cases/adapters/postgresql/interval_test.rb +9 -17
  80. data/test/cases/adapters/postgresql/invertible_migration_test.rb +139 -0
  81. data/test/cases/adapters/postgresql/json_test.rb +5 -0
  82. data/test/cases/adapters/postgresql/ltree_test.rb +1 -1
  83. data/test/cases/adapters/postgresql/money_test.rb +17 -9
  84. data/test/cases/adapters/postgresql/network_test.rb +13 -1
  85. data/test/cases/adapters/postgresql/numbers_test.rb +18 -2
  86. data/test/cases/adapters/postgresql/optimizer_hints_test.rb +9 -9
  87. data/test/cases/adapters/postgresql/partitions_test.rb +5 -2
  88. data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +7 -110
  89. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +403 -20
  90. data/test/cases/adapters/postgresql/postgresql_rake_test.rb +637 -0
  91. data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +1 -1
  92. data/test/cases/adapters/postgresql/quoting_test.rb +60 -1
  93. data/test/cases/adapters/postgresql/range_test.rb +185 -21
  94. data/test/cases/adapters/postgresql/referential_integrity_test.rb +29 -5
  95. data/test/cases/adapters/postgresql/rename_table_test.rb +35 -8
  96. data/test/cases/adapters/postgresql/schema_authorization_test.rb +2 -2
  97. data/test/cases/adapters/postgresql/schema_test.rb +270 -20
  98. data/test/cases/adapters/postgresql/serial_test.rb +5 -5
  99. data/test/cases/adapters/postgresql/statement_pool_test.rb +6 -2
  100. data/test/cases/adapters/postgresql/timestamp_test.rb +122 -5
  101. data/test/cases/adapters/postgresql/transaction_nested_test.rb +130 -6
  102. data/test/cases/adapters/postgresql/transaction_test.rb +37 -11
  103. data/test/cases/adapters/postgresql/type_lookup_test.rb +1 -1
  104. data/test/cases/adapters/postgresql/uuid_test.rb +77 -9
  105. data/test/cases/adapters/postgresql/virtual_column_test.rb +114 -0
  106. data/test/cases/adapters/postgresql/xml_test.rb +1 -1
  107. data/test/cases/adapters/sqlite3/bind_parameter_test.rb +52 -0
  108. data/test/cases/adapters/sqlite3/collation_test.rb +1 -1
  109. data/test/cases/adapters/sqlite3/copy_table_test.rb +28 -7
  110. data/test/cases/adapters/sqlite3/dbconsole_test.rb +81 -0
  111. data/test/cases/adapters/sqlite3/explain_test.rb +3 -3
  112. data/test/cases/adapters/sqlite3/quoting_test.rb +34 -3
  113. data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +9 -102
  114. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +727 -72
  115. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +6 -3
  116. data/test/cases/adapters/sqlite3/sqlite_rake_test.rb +264 -0
  117. data/test/cases/adapters/sqlite3/statement_pool_test.rb +1 -1
  118. data/test/cases/adapters/sqlite3/transaction_test.rb +6 -3
  119. data/test/cases/adapters/sqlite3/virtual_column_test.rb +138 -0
  120. data/test/cases/adapters/sqlite3/virtual_table_test.rb +51 -0
  121. data/test/cases/adapters/trilogy/dbconsole_test.rb +76 -0
  122. data/test/cases/adapters/trilogy/trilogy_adapter_test.rb +473 -0
  123. data/test/cases/adapters/trilogy/trilogy_rake_test.rb +433 -0
  124. data/test/cases/aggregations_test.rb +16 -0
  125. data/test/cases/annotate_test.rb +14 -12
  126. data/test/cases/arel/attributes/attribute_test.rb +86 -47
  127. data/test/cases/arel/collectors/bind_test.rb +1 -1
  128. data/test/cases/arel/collectors/composite_test.rb +11 -1
  129. data/test/cases/arel/collectors/sql_string_test.rb +1 -1
  130. data/test/cases/arel/collectors/substitute_bind_collector_test.rb +1 -1
  131. data/test/cases/arel/delete_manager_test.rb +0 -6
  132. data/test/cases/arel/factory_methods_test.rb +45 -0
  133. data/test/cases/arel/insert_manager_test.rb +1 -7
  134. data/test/cases/arel/nodes/as_test.rb +12 -0
  135. data/test/cases/arel/nodes/ascending_test.rb +1 -1
  136. data/test/cases/arel/nodes/bin_test.rb +1 -1
  137. data/test/cases/arel/nodes/bound_sql_literal_test.rb +31 -0
  138. data/test/cases/arel/nodes/cte_test.rb +46 -0
  139. data/test/cases/arel/nodes/descending_test.rb +1 -1
  140. data/test/cases/arel/nodes/equality_test.rb +3 -3
  141. data/test/cases/arel/nodes/filter_test.rb +37 -0
  142. data/test/cases/arel/nodes/fragments_test.rb +38 -0
  143. data/test/cases/arel/nodes/homogeneous_in_test.rb +52 -0
  144. data/test/cases/arel/nodes/infix_operation_test.rb +1 -1
  145. data/test/cases/arel/nodes/node_test.rb +1 -1
  146. data/test/cases/arel/nodes/or_test.rb +2 -2
  147. data/test/cases/arel/nodes/sql_literal_test.rb +18 -1
  148. data/test/cases/arel/nodes/table_alias_test.rb +12 -0
  149. data/test/cases/arel/nodes/unary_operation_test.rb +1 -1
  150. data/test/cases/arel/nodes/update_statement_test.rb +4 -0
  151. data/test/cases/arel/nodes_test.rb +3 -2
  152. data/test/cases/arel/select_manager_test.rb +12 -12
  153. data/test/cases/arel/support/fake_record.rb +22 -17
  154. data/test/cases/arel/table_test.rb +15 -25
  155. data/test/cases/arel/update_manager_test.rb +51 -6
  156. data/test/cases/arel/visitors/dispatch_contamination_test.rb +1 -1
  157. data/test/cases/arel/visitors/dot_test.rb +177 -2
  158. data/test/cases/arel/visitors/mysql_test.rb +49 -1
  159. data/test/cases/arel/visitors/postgres_test.rb +1 -31
  160. data/test/cases/arel/visitors/sqlite_test.rb +1 -1
  161. data/test/cases/arel/visitors/to_sql_test.rb +330 -20
  162. data/test/cases/assertions/query_assertions_test.rb +136 -0
  163. data/test/cases/associations/belongs_to_associations_test.rb +502 -41
  164. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +1 -1
  165. data/test/cases/associations/cascaded_eager_loading_test.rb +26 -15
  166. data/test/cases/associations/eager_load_nested_include_test.rb +1 -1
  167. data/test/cases/associations/eager_singularization_test.rb +1 -1
  168. data/test/cases/associations/eager_test.rb +255 -93
  169. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +25 -53
  170. data/test/cases/associations/has_many_associations_test.rb +282 -72
  171. data/test/cases/associations/has_many_through_associations_test.rb +172 -45
  172. data/test/cases/associations/has_many_through_disable_joins_associations_test.rb +197 -0
  173. data/test/cases/associations/has_one_associations_test.rb +160 -29
  174. data/test/cases/associations/has_one_through_associations_test.rb +64 -15
  175. data/test/cases/associations/has_one_through_disable_joins_associations_test.rb +82 -0
  176. data/test/cases/associations/inner_join_association_test.rb +36 -6
  177. data/test/cases/associations/inverse_associations_test.rb +177 -40
  178. data/test/cases/associations/join_model_test.rb +17 -12
  179. data/test/cases/associations/left_outer_join_association_test.rb +14 -3
  180. data/test/cases/associations/nested_error_test.rb +116 -0
  181. data/test/cases/associations/nested_through_associations_test.rb +54 -19
  182. data/test/cases/associations/required_test.rb +1 -1
  183. data/test/cases/associations_test.rb +1278 -21
  184. data/test/cases/asynchronous_queries_test.rb +310 -0
  185. data/test/cases/attribute_methods/read_test.rb +6 -0
  186. data/test/cases/attribute_methods/time_zone_converter_test.rb +21 -0
  187. data/test/cases/attribute_methods_test.rb +565 -46
  188. data/test/cases/attributes_test.rb +42 -1
  189. data/test/cases/autosave_association_test.rb +645 -92
  190. data/test/cases/base_prevent_writes_test.rb +28 -159
  191. data/test/cases/base_test.rb +434 -209
  192. data/test/cases/batches_test.rb +441 -57
  193. data/test/cases/binary_test.rb +31 -0
  194. data/test/cases/bind_parameter_test.rb +107 -16
  195. data/test/cases/cache_key_test.rb +7 -7
  196. data/test/cases/calculations_test.rb +541 -110
  197. data/test/cases/callbacks_test.rb +0 -1
  198. data/test/cases/clone_test.rb +5 -4
  199. data/test/cases/coders/yaml_column_test.rb +97 -2
  200. data/test/cases/collection_cache_key_test.rb +24 -16
  201. data/test/cases/column_alias_test.rb +2 -8
  202. data/test/cases/column_definition_test.rb +12 -3
  203. data/test/cases/comment_test.rb +23 -26
  204. data/test/cases/connection_adapters/adapter_leasing_test.rb +9 -9
  205. data/test/cases/connection_adapters/connection_handler_test.rb +145 -99
  206. data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +79 -55
  207. data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +17 -20
  208. data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +146 -55
  209. data/test/cases/connection_adapters/connection_swapping_nested_test.rb +136 -23
  210. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +96 -27
  211. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +5 -5
  212. data/test/cases/connection_adapters/registration_test.rb +98 -0
  213. data/test/cases/connection_adapters/schema_cache_test.rb +288 -135
  214. data/test/cases/connection_adapters/standalone_connection_test.rb +38 -0
  215. data/test/cases/connection_adapters/statement_pool_test.rb +29 -0
  216. data/test/cases/connection_adapters/type_lookup_test.rb +12 -24
  217. data/test/cases/connection_handling_test.rb +210 -0
  218. data/test/cases/connection_management_test.rb +44 -7
  219. data/test/cases/connection_pool_test.rb +466 -99
  220. data/test/cases/core_test.rb +167 -9
  221. data/test/cases/counter_cache_test.rb +129 -2
  222. data/test/cases/custom_locking_test.rb +3 -3
  223. data/test/cases/database_configurations/hash_config_test.rb +149 -13
  224. data/test/cases/database_configurations/resolver_test.rb +14 -10
  225. data/test/cases/database_configurations/url_config_test.rb +53 -0
  226. data/test/cases/database_configurations_test.rb +86 -43
  227. data/test/cases/database_selector_test.rb +30 -8
  228. data/test/cases/database_statements_test.rb +10 -14
  229. data/test/cases/date_time_precision_test.rb +141 -11
  230. data/test/cases/date_time_test.rb +19 -1
  231. data/test/cases/defaults_test.rb +107 -41
  232. data/test/cases/delegated_type_test.rb +69 -9
  233. data/test/cases/dirty_test.rb +82 -25
  234. data/test/cases/disconnected_test.rb +10 -9
  235. data/test/cases/dup_test.rb +26 -6
  236. data/test/cases/encryption/cipher/aes256_gcm_test.rb +50 -0
  237. data/test/cases/encryption/cipher_test.rb +65 -0
  238. data/test/cases/encryption/concurrency_test.rb +27 -0
  239. data/test/cases/encryption/config_test.rb +21 -0
  240. data/test/cases/encryption/configurable_test.rb +93 -0
  241. data/test/cases/encryption/contexts_test.rb +105 -0
  242. data/test/cases/encryption/derived_secret_key_provider_test.rb +31 -0
  243. data/test/cases/encryption/deterministic_key_provider_test.rb +11 -0
  244. data/test/cases/encryption/encryptable_record_api_test.rb +175 -0
  245. data/test/cases/encryption/encryptable_record_message_pack_serialized_test.rb +42 -0
  246. data/test/cases/encryption/encryptable_record_test.rb +470 -0
  247. data/test/cases/encryption/encrypted_fixtures_test.rb +22 -0
  248. data/test/cases/encryption/encrypting_only_encryptor_test.rb +20 -0
  249. data/test/cases/encryption/encryption_schemes_test.rb +240 -0
  250. data/test/cases/encryption/encryptor_test.rb +113 -0
  251. data/test/cases/encryption/envelope_encryption_key_provider_test.rb +49 -0
  252. data/test/cases/encryption/extended_deterministic_queries_test.rb +81 -0
  253. data/test/cases/encryption/helper.rb +152 -0
  254. data/test/cases/encryption/key_generator_test.rb +55 -0
  255. data/test/cases/encryption/key_provider_test.rb +57 -0
  256. data/test/cases/encryption/key_test.rb +17 -0
  257. data/test/cases/encryption/message_pack_message_serializer_test.rb +70 -0
  258. data/test/cases/encryption/message_serializer_test.rb +82 -0
  259. data/test/cases/encryption/message_test.rb +43 -0
  260. data/test/cases/encryption/null_encryptor_test.rb +21 -0
  261. data/test/cases/encryption/properties_test.rb +69 -0
  262. data/test/cases/encryption/read_only_null_encryptor_test.rb +19 -0
  263. data/test/cases/encryption/scheme_test.rb +58 -0
  264. data/test/cases/encryption/unencrypted_attributes_test.rb +27 -0
  265. data/test/cases/encryption/uniqueness_validations_test.rb +65 -0
  266. data/test/cases/enum_test.rb +374 -72
  267. data/test/cases/errors_test.rb +7 -4
  268. data/test/cases/excluding_test.rb +116 -0
  269. data/test/cases/explain_subscriber_test.rb +6 -1
  270. data/test/cases/explain_test.rb +119 -10
  271. data/test/cases/filter_attributes_test.rb +7 -14
  272. data/test/cases/finder_respond_to_test.rb +3 -3
  273. data/test/cases/finder_test.rb +357 -72
  274. data/test/cases/fixture_set/file_test.rb +9 -0
  275. data/test/cases/fixtures_test.rb +426 -190
  276. data/test/cases/helper.rb +66 -192
  277. data/test/cases/hot_compatibility_test.rb +10 -10
  278. data/test/cases/inheritance_test.rb +51 -61
  279. data/test/cases/inherited_test.rb +40 -0
  280. data/test/cases/insert_all_test.rb +419 -9
  281. data/test/cases/instrumentation_test.rb +202 -30
  282. data/test/cases/integration_test.rb +25 -7
  283. data/test/cases/invalid_connection_test.rb +5 -5
  284. data/test/cases/invertible_migration_test.rb +108 -24
  285. data/test/cases/json_attribute_test.rb +1 -0
  286. data/test/cases/json_serialization_test.rb +5 -5
  287. data/test/cases/json_shared_test_cases.rb +5 -9
  288. data/test/cases/locking_test.rb +67 -31
  289. data/test/cases/log_subscriber_test.rb +17 -15
  290. data/test/cases/marshal_serialization_test.rb +78 -5
  291. data/test/cases/message_pack_test.rb +91 -0
  292. data/test/cases/migration/change_schema_test.rb +77 -46
  293. data/test/cases/migration/change_table_test.rb +129 -114
  294. data/test/cases/migration/check_constraint_test.rb +192 -10
  295. data/test/cases/migration/column_attributes_test.rb +4 -9
  296. data/test/cases/migration/column_positioning_test.rb +2 -2
  297. data/test/cases/migration/columns_test.rb +118 -4
  298. data/test/cases/migration/command_recorder_test.rb +181 -14
  299. data/test/cases/migration/compatibility_test.rb +883 -196
  300. data/test/cases/migration/create_join_table_test.rb +8 -1
  301. data/test/cases/migration/exclusion_constraint_test.rb +192 -0
  302. data/test/cases/migration/foreign_key_test.rb +356 -14
  303. data/test/cases/migration/helper.rb +4 -1
  304. data/test/cases/migration/index_test.rb +67 -2
  305. data/test/cases/migration/invalid_options_test.rb +129 -0
  306. data/test/cases/migration/logger_test.rb +7 -4
  307. data/test/cases/migration/pending_migrations_test.rb +103 -60
  308. data/test/cases/migration/references_foreign_key_test.rb +73 -4
  309. data/test/cases/migration/references_index_test.rb +25 -27
  310. data/test/cases/migration/references_statements_test.rb +27 -3
  311. data/test/cases/migration/rename_table_test.rb +39 -54
  312. data/test/cases/migration/schema_definitions_test.rb +109 -0
  313. data/test/cases/migration/unique_constraint_test.rb +248 -0
  314. data/test/cases/migration_test.rb +677 -220
  315. data/test/cases/migrator_test.rb +102 -75
  316. data/test/cases/multi_db_migrator_test.rb +55 -34
  317. data/test/cases/multiparameter_attributes_test.rb +26 -29
  318. data/test/cases/multiple_db_test.rb +42 -19
  319. data/test/cases/nested_attributes_test.rb +124 -6
  320. data/test/cases/nested_attributes_with_callbacks_test.rb +2 -2
  321. data/test/cases/normalized_attribute_test.rb +117 -0
  322. data/test/cases/null_relation_test.rb +35 -2
  323. data/test/cases/persistence/reload_association_cache_test.rb +20 -0
  324. data/test/cases/persistence_test.rb +629 -22
  325. data/test/cases/pooled_connections_test.rb +57 -56
  326. data/test/cases/prepared_statement_status_test.rb +8 -3
  327. data/test/cases/primary_class_test.rb +134 -0
  328. data/test/cases/primary_keys_test.rb +171 -55
  329. data/test/cases/query_cache_test.rb +558 -263
  330. data/test/cases/query_logs_test.rb +293 -0
  331. data/test/cases/quoting_test.rb +39 -72
  332. data/test/cases/readonly_test.rb +50 -12
  333. data/test/cases/reaper_test.rb +22 -6
  334. data/test/cases/reflection_test.rb +207 -9
  335. data/test/cases/relation/and_test.rb +43 -0
  336. data/test/cases/relation/delegation_test.rb +32 -5
  337. data/test/cases/relation/delete_all_test.rb +27 -6
  338. data/test/cases/relation/field_ordered_values_test.rb +128 -0
  339. data/test/cases/relation/load_async_test.rb +650 -0
  340. data/test/cases/relation/merging_test.rb +80 -109
  341. data/test/cases/relation/mutation_test.rb +12 -7
  342. data/test/cases/relation/or_test.rb +11 -8
  343. data/test/cases/relation/order_test.rb +90 -0
  344. data/test/cases/relation/predicate_builder_test.rb +21 -6
  345. data/test/cases/relation/select_test.rb +162 -3
  346. data/test/cases/relation/structural_compatibility_test.rb +38 -0
  347. data/test/cases/relation/update_all_test.rb +81 -27
  348. data/test/cases/relation/where_chain_test.rb +190 -3
  349. data/test/cases/relation/where_clause_test.rb +43 -1
  350. data/test/cases/relation/where_test.rb +95 -7
  351. data/test/cases/relation/with_test.rb +165 -0
  352. data/test/cases/relation_test.rb +42 -37
  353. data/test/cases/relations_test.rb +436 -138
  354. data/test/cases/reload_models_test.rb +18 -14
  355. data/test/cases/reserved_word_test.rb +2 -1
  356. data/test/cases/result_test.rb +14 -22
  357. data/test/cases/sanitize_test.rb +89 -27
  358. data/test/cases/schema_dumper_test.rb +535 -62
  359. data/test/cases/scoping/default_scoping_test.rb +219 -35
  360. data/test/cases/scoping/named_scoping_test.rb +25 -46
  361. data/test/cases/scoping/relation_scoping_test.rb +112 -4
  362. data/test/cases/secure_password_test.rb +108 -0
  363. data/test/cases/secure_token_test.rb +72 -0
  364. data/test/cases/serialization_test.rb +1 -1
  365. data/test/cases/serialized_attribute_test.rb +305 -60
  366. data/test/cases/shard_keys_test.rb +125 -0
  367. data/test/cases/shard_selector_test.rb +45 -0
  368. data/test/cases/signed_id_test.rb +57 -5
  369. data/test/cases/statement_cache_test.rb +31 -30
  370. data/test/cases/statement_invalid_test.rb +8 -4
  371. data/test/cases/store_test.rb +73 -9
  372. data/test/cases/strict_loading_test.rb +327 -13
  373. data/test/cases/table_metadata_test.rb +16 -0
  374. data/test/cases/tasks/database_tasks_test.rb +517 -244
  375. data/test/cases/test_case.rb +254 -60
  376. data/test/cases/test_case_test.rb +69 -0
  377. data/test/cases/test_databases_test.rb +7 -3
  378. data/test/cases/test_fixtures_test.rb +19 -40
  379. data/test/cases/time_precision_test.rb +17 -5
  380. data/test/cases/timestamp_test.rb +124 -16
  381. data/test/cases/token_for_test.rb +165 -0
  382. data/test/cases/touch_later_test.rb +43 -1
  383. data/test/cases/transaction_callbacks_test.rb +325 -8
  384. data/test/cases/transaction_instrumentation_test.rb +453 -0
  385. data/test/cases/transaction_isolation_test.rb +12 -8
  386. data/test/cases/transactions_test.rb +629 -112
  387. data/test/cases/type/date_time_test.rb +7 -1
  388. data/test/cases/type/time_test.rb +9 -0
  389. data/test/cases/type/type_map_test.rb +108 -73
  390. data/test/cases/type/unsigned_integer_test.rb +12 -0
  391. data/test/cases/type_caster/connection_test.rb +19 -0
  392. data/test/cases/type_test.rb +1 -1
  393. data/test/cases/unconnected_test.rb +7 -7
  394. data/test/cases/unsafe_raw_sql_test.rb +39 -8
  395. data/test/cases/validations/absence_validation_test.rb +1 -1
  396. data/test/cases/validations/association_validation_test.rb +25 -3
  397. data/test/cases/validations/numericality_validation_test.rb +3 -9
  398. data/test/cases/validations/presence_validation_test.rb +1 -1
  399. data/test/cases/validations/uniqueness_validation_test.rb +280 -40
  400. data/test/cases/validations_test.rb +2 -2
  401. data/test/cases/view_test.rb +33 -22
  402. data/test/cases/yaml_serialization_test.rb +23 -17
  403. data/test/config.example.yml +58 -56
  404. data/test/config.rb +1 -0
  405. data/test/fixtures/1_need_quoting.yml +2 -0
  406. data/test/fixtures/accounts.yml +5 -0
  407. data/test/fixtures/aircrafts.yml +7 -0
  408. data/test/fixtures/book_identifiers.yml +11 -0
  409. data/test/fixtures/books.yml +5 -4
  410. data/test/fixtures/cake_designers.yml +5 -0
  411. data/test/fixtures/cars.yml +6 -0
  412. data/test/fixtures/chefs.yml +5 -0
  413. data/test/fixtures/clothing_items.yml +23 -0
  414. data/test/fixtures/clubs.yml +1 -1
  415. data/test/fixtures/comments.yml +2 -1
  416. data/test/fixtures/cpk_authors.yml +8 -0
  417. data/test/fixtures/cpk_books.yml +21 -0
  418. data/test/fixtures/cpk_order_agreements.yml +13 -0
  419. data/test/fixtures/cpk_order_tags.yml +15 -0
  420. data/test/fixtures/cpk_orders.yml +11 -0
  421. data/test/fixtures/cpk_posts.yml +12 -0
  422. data/test/fixtures/cpk_reviews.yml +13 -0
  423. data/test/fixtures/cpk_tags.yml +11 -0
  424. data/test/fixtures/drink_designers.yml +5 -0
  425. data/test/fixtures/encrypted_book_that_ignores_cases.yml +4 -0
  426. data/test/fixtures/encrypted_books.yml +4 -0
  427. data/test/fixtures/fk_object_to_point_to.yml +2 -0
  428. data/test/fixtures/memberships.yml +15 -15
  429. data/test/fixtures/paragraphs.yml +5 -0
  430. data/test/fixtures/parrots.yml +4 -0
  431. data/test/fixtures/people.yml +2 -0
  432. data/test/fixtures/pirates.yml +2 -2
  433. data/test/fixtures/primary_key_error/primary_key_error.yml +6 -0
  434. data/test/fixtures/references.yml +3 -3
  435. data/test/fixtures/sharded_blog_posts.yml +14 -0
  436. data/test/fixtures/sharded_blog_posts_tags.yml +27 -0
  437. data/test/fixtures/sharded_blogs.yml +8 -0
  438. data/test/fixtures/sharded_comments.yml +22 -0
  439. data/test/fixtures/sharded_tags.yml +34 -0
  440. data/test/fixtures/sponsors.yml +2 -2
  441. data/test/fixtures/topics.yml +1 -0
  442. data/test/fixtures/treasures.yml +4 -0
  443. data/test/fixtures/virtual_columns.yml +5 -0
  444. data/test/fixtures/warehouse_things.yml +1 -1
  445. data/test/migrations/old_and_new_versions/20210716122844_add_people_description.rb +5 -0
  446. data/test/migrations/old_and_new_versions/20210716123013_add_people_number_of_legs.rb +5 -0
  447. data/test/migrations/old_and_new_versions/230_add_people_hobby.rb +5 -0
  448. data/test/migrations/old_and_new_versions/231_add_people_last_name.rb +5 -0
  449. data/test/migrations/scope/1_unscoped.rb +7 -0
  450. data/test/migrations/scope/2_mysql_only.mysql.rb +7 -0
  451. data/test/models/admin/user.rb +2 -0
  452. data/test/models/admin/user_json.rb +48 -0
  453. data/test/models/attachment.rb +7 -0
  454. data/test/models/author.rb +70 -3
  455. data/test/models/author_encrypted.rb +16 -0
  456. data/test/models/bird.rb +1 -1
  457. data/test/models/book.rb +18 -11
  458. data/test/models/book_destroy_async.rb +1 -1
  459. data/test/models/book_encrypted.rb +106 -0
  460. data/test/models/book_identifier.rb +5 -0
  461. data/test/models/branch.rb +11 -0
  462. data/test/models/bulb.rb +1 -1
  463. data/test/models/car.rb +8 -1
  464. data/test/models/cat.rb +1 -1
  465. data/test/models/category.rb +3 -1
  466. data/test/models/chat_message.rb +8 -0
  467. data/test/models/chef.rb +52 -0
  468. data/test/models/clothing_item.rb +12 -0
  469. data/test/models/club.rb +4 -1
  470. data/test/models/comment.rb +7 -4
  471. data/test/models/comment_overlapping_counter_cache.rb +15 -0
  472. data/test/models/company.rb +16 -2
  473. data/test/models/computer.rb +1 -0
  474. data/test/models/contact.rb +3 -3
  475. data/test/models/contract.rb +5 -1
  476. data/test/models/cpk/author.rb +9 -0
  477. data/test/models/cpk/book.rb +55 -0
  478. data/test/models/cpk/book_destroy_async.rb +9 -0
  479. data/test/models/cpk/car.rb +9 -0
  480. data/test/models/cpk/car_review.rb +9 -0
  481. data/test/models/cpk/chapter.rb +16 -0
  482. data/test/models/cpk/chapter_destroy_async.rb +10 -0
  483. data/test/models/cpk/comment.rb +9 -0
  484. data/test/models/cpk/order.rb +55 -0
  485. data/test/models/cpk/order_agreement.rb +10 -0
  486. data/test/models/cpk/order_tag.rb +10 -0
  487. data/test/models/cpk/post.rb +10 -0
  488. data/test/models/cpk/posts_tag.rb +10 -0
  489. data/test/models/cpk/review.rb +9 -0
  490. data/test/models/cpk/tag.rb +10 -0
  491. data/test/models/cpk.rb +15 -0
  492. data/test/models/customer.rb +3 -1
  493. data/test/models/destroy_async_parent.rb +1 -1
  494. data/test/models/developer.rb +44 -3
  495. data/test/models/discount.rb +4 -0
  496. data/test/models/drink_designer.rb +1 -0
  497. data/test/models/editor.rb +8 -0
  498. data/test/models/editorship.rb +6 -0
  499. data/test/models/entry.rb +5 -0
  500. data/test/models/essay.rb +6 -1
  501. data/test/models/essay_destroy_async.rb +1 -0
  502. data/test/models/eye.rb +87 -21
  503. data/test/models/face.rb +1 -1
  504. data/test/models/friendship.rb +3 -0
  505. data/test/models/hardback.rb +7 -0
  506. data/test/models/hotel.rb +2 -0
  507. data/test/models/human.rb +2 -2
  508. data/test/models/invoice.rb +2 -1
  509. data/test/models/invokes_an_undefined_method.rb +5 -0
  510. data/test/models/line_item.rb +6 -0
  511. data/test/models/member.rb +9 -4
  512. data/test/models/membership.rb +2 -2
  513. data/test/models/message.rb +2 -1
  514. data/test/models/need_quoting.rb +5 -0
  515. data/test/models/paragraph.rb +5 -0
  516. data/test/models/parrot.rb +6 -3
  517. data/test/models/person.rb +7 -4
  518. data/test/models/pirate.rb +4 -1
  519. data/test/models/pk_autopopulated_by_a_trigger_record.rb +5 -0
  520. data/test/models/post.rb +65 -2
  521. data/test/models/post_encrypted.rb +15 -0
  522. data/test/models/post_with_prefetched_pk.rb +15 -0
  523. data/test/models/project.rb +1 -0
  524. data/test/models/publication.rb +16 -0
  525. data/test/models/raises_argument_error.rb +5 -0
  526. data/test/models/raises_no_method_error.rb +5 -0
  527. data/test/models/recipient.rb +5 -0
  528. data/test/models/reference.rb +1 -1
  529. data/test/models/reply.rb +1 -1
  530. data/test/models/room.rb +3 -0
  531. data/test/models/sharded/blog.rb +12 -0
  532. data/test/models/sharded/blog_post.rb +17 -0
  533. data/test/models/sharded/blog_post_destroy_async.rb +14 -0
  534. data/test/models/sharded/blog_post_tag.rb +11 -0
  535. data/test/models/sharded/blog_post_with_revision.rb +11 -0
  536. data/test/models/sharded/comment.rb +12 -0
  537. data/test/models/sharded/comment_destroy_async.rb +12 -0
  538. data/test/models/sharded/tag.rb +11 -0
  539. data/test/models/sharded.rb +8 -0
  540. data/test/models/ship.rb +1 -1
  541. data/test/models/shipping_line.rb +11 -0
  542. data/test/models/subscriber.rb +1 -0
  543. data/test/models/subscription.rb +3 -1
  544. data/test/models/too_long_table_name.rb +5 -0
  545. data/test/models/topic.rb +3 -1
  546. data/test/models/traffic_light.rb +2 -2
  547. data/test/models/traffic_light_encrypted.rb +21 -0
  548. data/test/models/translation.rb +9 -0
  549. data/test/models/treasure.rb +1 -1
  550. data/test/models/tyre.rb +1 -1
  551. data/test/models/user.rb +16 -0
  552. data/test/models/user_with_invalid_relation.rb +28 -0
  553. data/test/models/uuid_comment.rb +5 -0
  554. data/test/models/uuid_entry.rb +5 -0
  555. data/test/models/uuid_message.rb +5 -0
  556. data/test/models/zine.rb +2 -1
  557. data/test/schema/mysql2_specific_schema.rb +26 -12
  558. data/test/schema/postgresql_specific_schema.rb +121 -13
  559. data/test/schema/schema.rb +361 -103
  560. data/test/schema/sqlite_specific_schema.rb +17 -6
  561. data/test/schema/trilogy_specific_schema.rb +96 -0
  562. data/test/support/adapter_helper.rb +104 -0
  563. data/test/support/async_helper.rb +15 -0
  564. data/test/support/config.rb +1 -1
  565. data/test/support/connection.rb +14 -2
  566. data/test/support/ddl_helper.rb +1 -1
  567. data/test/support/fake_adapter.rb +42 -0
  568. data/test/support/load_schema_helper.rb +22 -0
  569. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic.dump +0 -0
  570. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic_associations.dump +0 -0
  571. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic.dump +0 -0
  572. data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic_associations.dump +0 -0
  573. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic.dump +0 -0
  574. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic_associations.dump +0 -0
  575. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic.dump +0 -0
  576. data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic_associations.dump +0 -0
  577. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic.dump +0 -0
  578. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic_associations.dump +0 -0
  579. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic.dump +0 -0
  580. data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic_associations.dump +0 -0
  581. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic.dump +0 -0
  582. data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic_associations.dump +0 -0
  583. data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic.dump +0 -0
  584. data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic_associations.dump +0 -0
  585. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic.dump +0 -0
  586. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic_associations.dump +0 -0
  587. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic.dump +0 -0
  588. data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic_associations.dump +0 -0
  589. data/test/support/schema_dumping_helper.rb +15 -9
  590. data/test/support/tools.rb +37 -0
  591. data/test/support/yaml_compatibility_fixtures/rails_4_1_no_symbol.yml +22 -0
  592. metadata +247 -15
@@ -6,7 +6,7 @@ module Arel
6
6
  module Visitors
7
7
  class MysqlTest < Arel::Spec
8
8
  before do
9
- @visitor = MySQL.new Table.engine.connection
9
+ @visitor = MySQL.new Table.engine.lease_connection
10
10
  end
11
11
 
12
12
  def compile(node)
@@ -152,6 +152,54 @@ module Arel
152
152
  }
153
153
  end
154
154
  end
155
+
156
+ describe "Nodes::Ordering" do
157
+ it "should handle nulls first" do
158
+ test = Table.new(:users)[:first_name].asc.nulls_first
159
+ _(compile(test)).must_be_like %{
160
+ "users"."first_name" IS NOT NULL, "users"."first_name" ASC
161
+ }
162
+ end
163
+
164
+ it "should handle nulls last" do
165
+ test = Table.new(:users)[:first_name].asc.nulls_last
166
+ _(compile(test)).must_be_like %{
167
+ "users"."first_name" IS NULL, "users"."first_name" ASC
168
+ }
169
+ end
170
+
171
+ it "should handle nulls first reversed" do
172
+ test = Table.new(:users)[:first_name].asc.nulls_first.reverse
173
+ _(compile(test)).must_be_like %{
174
+ "users"."first_name" IS NULL, "users"."first_name" DESC
175
+ }
176
+ end
177
+
178
+ it "should handle nulls last reversed" do
179
+ test = Table.new(:users)[:first_name].asc.nulls_last.reverse
180
+ _(compile(test)).must_be_like %{
181
+ "users"."first_name" IS NOT NULL, "users"."first_name" DESC
182
+ }
183
+ end
184
+ end
185
+
186
+ describe "Nodes::Cte" do
187
+ it "ignores MATERIALIZED modifiers" do
188
+ cte = Nodes::Cte.new("foo", Table.new(:bar).project(Arel.star), materialized: true)
189
+
190
+ _(compile(cte)).must_be_like %{
191
+ "foo" AS (SELECT * FROM "bar")
192
+ }
193
+ end
194
+
195
+ it "ignores NOT MATERIALIZED modifiers" do
196
+ cte = Nodes::Cte.new("foo", Table.new(:bar).project(Arel.star), materialized: false)
197
+
198
+ _(compile(cte)).must_be_like %{
199
+ "foo" AS (SELECT * FROM "bar")
200
+ }
201
+ end
202
+ end
155
203
  end
156
204
  end
157
205
  end
@@ -6,7 +6,7 @@ module Arel
6
6
  module Visitors
7
7
  class PostgresTest < Arel::Spec
8
8
  before do
9
- @visitor = PostgreSQL.new Table.engine.connection
9
+ @visitor = PostgreSQL.new Table.engine.lease_connection
10
10
  @table = Table.new(:users)
11
11
  @attr = @table[:id]
12
12
  end
@@ -316,36 +316,6 @@ module Arel
316
316
  end
317
317
  end
318
318
 
319
- describe "Nodes::Ordering" do
320
- it "should handle nulls first" do
321
- test = Table.new(:users)[:first_name].desc.nulls_first
322
- _(compile(test)).must_be_like %{
323
- "users"."first_name" DESC NULLS FIRST
324
- }
325
- end
326
-
327
- it "should handle nulls last" do
328
- test = Table.new(:users)[:first_name].desc.nulls_last
329
- _(compile(test)).must_be_like %{
330
- "users"."first_name" DESC NULLS LAST
331
- }
332
- end
333
-
334
- it "should handle nulls first reversed" do
335
- test = Table.new(:users)[:first_name].desc.nulls_first.reverse
336
- _(compile(test)).must_be_like %{
337
- "users"."first_name" ASC NULLS LAST
338
- }
339
- end
340
-
341
- it "should handle nulls last reversed" do
342
- test = Table.new(:users)[:first_name].desc.nulls_last.reverse
343
- _(compile(test)).must_be_like %{
344
- "users"."first_name" ASC NULLS FIRST
345
- }
346
- end
347
- end
348
-
349
319
  describe "Nodes::InfixOperation" do
350
320
  it "should handle Contains" do
351
321
  inner = Nodes.build_quoted('{"foo":"bar"}')
@@ -6,7 +6,7 @@ module Arel
6
6
  module Visitors
7
7
  class SqliteTest < Arel::Spec
8
8
  before do
9
- @visitor = SQLite.new Table.engine.connection
9
+ @visitor = SQLite.new Table.engine.lease_connection
10
10
  end
11
11
 
12
12
  def compile(node)
@@ -8,7 +8,7 @@ module Arel
8
8
  describe "the to_sql visitor" do
9
9
  before do
10
10
  @conn = FakeRecord::Base.new
11
- @visitor = ToSql.new @conn.connection
11
+ @visitor = ToSql.new @conn.lease_connection
12
12
  @table = Table.new(:users)
13
13
  @attr = @table[:id]
14
14
  end
@@ -69,6 +69,81 @@ module Arel
69
69
  _(sql).must_be_like %{ omg(*) IS NULL }
70
70
  end
71
71
 
72
+ it "should mark collector as non-retryable when visiting named function" do
73
+ function = Nodes::NamedFunction.new("ABS", [@table])
74
+ collector = Collectors::SQLString.new
75
+ collector.retryable = true
76
+ @visitor.accept(function, collector)
77
+
78
+ assert_equal false, collector.retryable
79
+ end
80
+
81
+ it "should mark collector as non-retryable when visiting SQL literal" do
82
+ node = Nodes::SqlLiteral.new("COUNT(*)")
83
+ collector = Collectors::SQLString.new
84
+ collector.retryable = true
85
+ @visitor.accept(node, collector)
86
+
87
+ assert_equal false, collector.retryable
88
+ end
89
+
90
+ it "should not change retryable if SQL literal is marked as retryable" do
91
+ node = Nodes::SqlLiteral.new("COUNT(*)", retryable: true)
92
+ collector = Collectors::SQLString.new
93
+ collector.retryable = true
94
+ @visitor.accept(node, collector)
95
+
96
+ assert_predicate collector, :retryable
97
+ end
98
+
99
+ it "should mark collector as non-retryable if SQL literal is not retryable" do
100
+ node = Nodes::As.new(
101
+ Nodes::SqlLiteral.new("`product.id`"),
102
+ Nodes::SqlLiteral.new("`product.id`", retryable: true)
103
+ )
104
+ collector = Collectors::SQLString.new
105
+ collector.retryable = true
106
+ @visitor.accept(node, collector)
107
+
108
+ assert_equal false, collector.retryable
109
+ end
110
+
111
+ it "should mark collector as non-retryable when visiting bound SQL literal" do
112
+ node = Nodes::BoundSqlLiteral.new("id IN (?)", [[1, 2, 3]], {})
113
+ collector = Collectors::SQLString.new
114
+ collector.retryable = true
115
+ @visitor.accept(node, collector)
116
+
117
+ assert_equal false, collector.retryable
118
+ end
119
+
120
+ it "should mark collector as non-retryable when visiting insert statement node" do
121
+ statement = Arel::Nodes::InsertStatement.new(@table)
122
+ collector = Collectors::SQLString.new
123
+ collector.retryable = true
124
+ @visitor.accept(statement, collector)
125
+
126
+ assert_equal false, collector.retryable
127
+ end
128
+
129
+ it "should mark collector as non-retryable when visiting update statement node" do
130
+ statement = Arel::Nodes::UpdateStatement.new(@table)
131
+ collector = Collectors::SQLString.new
132
+ collector.retryable = true
133
+ @visitor.accept(statement, collector)
134
+
135
+ assert_equal false, collector.retryable
136
+ end
137
+
138
+ it "should mark collector as non-retryable when visiting delete statement node" do
139
+ statement = Arel::Nodes::DeleteStatement.new(@table)
140
+ collector = Collectors::SQLString.new
141
+ collector.retryable = true
142
+ @visitor.accept(statement, collector)
143
+
144
+ assert_equal false, collector.retryable
145
+ end
146
+
72
147
  it "should visit built-in functions" do
73
148
  function = Nodes::Count.new([Arel.star])
74
149
  assert_equal "COUNT(*)", compile(function)
@@ -305,7 +380,7 @@ module Arel
305
380
  end
306
381
 
307
382
  it "should visit_Arel_Nodes_Or" do
308
- node = Nodes::Or.new @attr.eq(10), @attr.eq(11)
383
+ node = Nodes::Or.new [@attr.eq(10), @attr.eq(11)]
309
384
  _(compile(node)).must_be_like %{
310
385
  "users"."id" = 10 OR "users"."id" = 11
311
386
  }
@@ -322,11 +397,6 @@ module Arel
322
397
  }
323
398
  end
324
399
 
325
- it "should visit visit_Arel_Attributes_Time" do
326
- attr = Attributes::Time.new(@attr.relation, @attr.name)
327
- compile attr
328
- end
329
-
330
400
  it "should visit_TrueClass" do
331
401
  test = Table.new(:users)[:bool].eq(true)
332
402
  _(compile(test)).must_be_like %{ "users"."bool" = 't' }
@@ -387,6 +457,34 @@ module Arel
387
457
  "users"."id" DESC
388
458
  }
389
459
  end
460
+
461
+ it "should handle nulls first" do
462
+ node = @attr.desc.nulls_first
463
+ _(compile(node)).must_be_like %{
464
+ "users"."id" DESC NULLS FIRST
465
+ }
466
+ end
467
+
468
+ it "should handle nulls last" do
469
+ node = @attr.desc.nulls_last
470
+ _(compile(node)).must_be_like %{
471
+ "users"."id" DESC NULLS LAST
472
+ }
473
+ end
474
+
475
+ it "should handle nulls first reversed" do
476
+ node = @attr.desc.nulls_first.reverse
477
+ _(compile(node)).must_be_like %{
478
+ "users"."id" ASC NULLS LAST
479
+ }
480
+ end
481
+
482
+ it "should handle nulls last reversed" do
483
+ node = @attr.desc.nulls_last.reverse
484
+ _(compile(node)).must_be_like %{
485
+ "users"."id" ASC NULLS FIRST
486
+ }
487
+ end
390
488
  end
391
489
 
392
490
  describe "Nodes::In" do
@@ -441,26 +539,44 @@ module Arel
441
539
  "users"."id" IN (SELECT id FROM "users" WHERE "users"."name" = 'Aaron')
442
540
  }
443
541
  end
542
+
543
+ it "is not preparable when an array" do
544
+ node = @attr.in [1, 2, 3]
545
+
546
+ collector = Collectors::SQLString.new.tap { |c| c.preparable = true }
547
+ @visitor.accept(node, collector)
548
+ _(collector.preparable).must_equal false
549
+ end
550
+
551
+ it "is preparable when a subselect" do
552
+ table = Table.new(:users)
553
+ subquery = table.project(table[:id]).where(table[:name].eq("Aaron"))
554
+ node = @attr.in subquery
555
+
556
+ collector = Collectors::SQLString.new.tap { |c| c.preparable = true }
557
+ @visitor.accept(node, collector)
558
+ _(collector.preparable).must_equal true
559
+ end
444
560
  end
445
561
 
446
562
  describe "Nodes::InfixOperation" do
447
563
  it "should handle Multiplication" do
448
- node = Arel::Attributes::Decimal.new(Table.new(:products), :price) * Arel::Attributes::Decimal.new(Table.new(:currency_rates), :rate)
564
+ node = Arel::Attribute.new(Table.new(:products), :price) * Arel::Attribute.new(Table.new(:currency_rates), :rate)
449
565
  _(compile(node)).must_equal %("products"."price" * "currency_rates"."rate")
450
566
  end
451
567
 
452
568
  it "should handle Division" do
453
- node = Arel::Attributes::Decimal.new(Table.new(:products), :price) / 5
569
+ node = Arel::Attribute.new(Table.new(:products), :price) / 5
454
570
  _(compile(node)).must_equal %("products"."price" / 5)
455
571
  end
456
572
 
457
573
  it "should handle Addition" do
458
- node = Arel::Attributes::Decimal.new(Table.new(:products), :price) + 6
574
+ node = Arel::Attribute.new(Table.new(:products), :price) + 6
459
575
  _(compile(node)).must_equal %(("products"."price" + 6))
460
576
  end
461
577
 
462
578
  it "should handle Subtraction" do
463
- node = Arel::Attributes::Decimal.new(Table.new(:products), :price) - 7
579
+ node = Arel::Attribute.new(Table.new(:products), :price) - 7
464
580
  _(compile(node)).must_equal %(("products"."price" - 7))
465
581
  end
466
582
 
@@ -483,35 +599,35 @@ module Arel
483
599
  end
484
600
 
485
601
  it "should handle BitwiseAnd" do
486
- node = Arel::Attributes::Integer.new(Table.new(:products), :bitmap) & 16
602
+ node = Arel::Attribute.new(Table.new(:products), :bitmap) & 16
487
603
  _(compile(node)).must_equal %(("products"."bitmap" & 16))
488
604
  end
489
605
 
490
606
  it "should handle BitwiseOr" do
491
- node = Arel::Attributes::Integer.new(Table.new(:products), :bitmap) | 16
607
+ node = Arel::Attribute.new(Table.new(:products), :bitmap) | 16
492
608
  _(compile(node)).must_equal %(("products"."bitmap" | 16))
493
609
  end
494
610
 
495
611
  it "should handle BitwiseXor" do
496
- node = Arel::Attributes::Integer.new(Table.new(:products), :bitmap) ^ 16
612
+ node = Arel::Attribute.new(Table.new(:products), :bitmap) ^ 16
497
613
  _(compile(node)).must_equal %(("products"."bitmap" ^ 16))
498
614
  end
499
615
 
500
616
  it "should handle BitwiseShiftLeft" do
501
- node = Arel::Attributes::Integer.new(Table.new(:products), :bitmap) << 4
617
+ node = Arel::Attribute.new(Table.new(:products), :bitmap) << 4
502
618
  _(compile(node)).must_equal %(("products"."bitmap" << 4))
503
619
  end
504
620
 
505
621
  it "should handle BitwiseShiftRight" do
506
- node = Arel::Attributes::Integer.new(Table.new(:products), :bitmap) >> 4
622
+ node = Arel::Attribute.new(Table.new(:products), :bitmap) >> 4
507
623
  _(compile(node)).must_equal %(("products"."bitmap" >> 4))
508
624
  end
509
625
 
510
626
  it "should handle arbitrary operators" do
511
627
  node = Arel::Nodes::InfixOperation.new(
512
628
  "&&",
513
- Arel::Attributes::String.new(Table.new(:products), :name),
514
- Arel::Attributes::String.new(Table.new(:products), :name)
629
+ Arel::Attribute.new(Table.new(:products), :name),
630
+ Arel::Attribute.new(Table.new(:products), :name)
515
631
  )
516
632
  _(compile(node)).must_equal %("products"."name" && "products"."name")
517
633
  end
@@ -519,12 +635,12 @@ module Arel
519
635
 
520
636
  describe "Nodes::UnaryOperation" do
521
637
  it "should handle BitwiseNot" do
522
- node = ~ Arel::Attributes::Integer.new(Table.new(:products), :bitmap)
638
+ node = ~ Arel::Attribute.new(Table.new(:products), :bitmap)
523
639
  _(compile(node)).must_equal %( ~ "products"."bitmap")
524
640
  end
525
641
 
526
642
  it "should handle arbitrary operators" do
527
- node = Arel::Nodes::UnaryOperation.new("!", Arel::Attributes::String.new(Table.new(:products), :active))
643
+ node = Arel::Nodes::UnaryOperation.new("!", Arel::Attribute.new(Table.new(:products), :active))
528
644
  _(compile(node)).must_equal %( ! "products"."active")
529
645
  end
530
646
  end
@@ -538,6 +654,14 @@ module Arel
538
654
  node = Nodes::Union.new Arel.sql("topleft"), subnode
539
655
  assert_equal("( topleft UNION left UNION right )", compile(node))
540
656
  end
657
+
658
+ it "encloses SELECT statements with parentheses" do
659
+ table = Table.new(:users)
660
+ left = table.where(table[:name].eq(0)).take(1).ast
661
+ right = table.where(table[:name].eq(1)).take(1).ast
662
+ node = Nodes::Union.new left, right
663
+ assert_match(/LIMIT 1\) UNION \(/, compile(node))
664
+ end
541
665
  end
542
666
 
543
667
  describe "Nodes::UnionAll" do
@@ -549,6 +673,14 @@ module Arel
549
673
  node = Nodes::UnionAll.new Arel.sql("topleft"), subnode
550
674
  assert_equal("( topleft UNION ALL left UNION ALL right )", compile(node))
551
675
  end
676
+
677
+ it "encloses SELECT statements with parentheses" do
678
+ table = Table.new(:users)
679
+ left = table.where(table[:name].eq(0)).take(1).ast
680
+ right = table.where(table[:name].eq(1)).take(1).ast
681
+ node = Nodes::UnionAll.new left, right
682
+ assert_match(/LIMIT 1\) UNION ALL \(/, compile(node))
683
+ end
552
684
  end
553
685
 
554
686
  describe "Nodes::NotIn" do
@@ -603,6 +735,24 @@ module Arel
603
735
  "users"."id" NOT IN (SELECT id FROM "users" WHERE "users"."name" = 'Aaron')
604
736
  }
605
737
  end
738
+
739
+ it "is not preparable when an array" do
740
+ node = @attr.not_in [1, 2, 3]
741
+
742
+ collector = Collectors::SQLString.new.tap { |c| c.preparable = true }
743
+ @visitor.accept(node, collector)
744
+ _(collector.preparable).must_equal false
745
+ end
746
+
747
+ it "is preparable when a subselect" do
748
+ table = Table.new(:users)
749
+ subquery = table.project(table[:id]).where(table[:name].eq("Aaron"))
750
+ node = @attr.not_in subquery
751
+
752
+ collector = Collectors::SQLString.new.tap { |c| c.preparable = true }
753
+ @visitor.accept(node, collector)
754
+ _(collector.preparable).must_equal true
755
+ end
606
756
  end
607
757
 
608
758
  describe "Constants" do
@@ -621,6 +771,113 @@ module Arel
621
771
  end
622
772
  end
623
773
 
774
+ describe "Nodes::BoundSqlLiteral" do
775
+ it "works with positional binds" do
776
+ node = Nodes::BoundSqlLiteral.new("id = ?", [1], {})
777
+ _(compile(node)).must_be_like %{
778
+ id = ?
779
+ }
780
+ end
781
+
782
+ it "works with named binds" do
783
+ node = Nodes::BoundSqlLiteral.new("id = :id", [], { id: 1 })
784
+ _(compile(node)).must_be_like %{
785
+ id = ?
786
+ }
787
+ end
788
+
789
+ it "will only consider named binds starting with a letter" do
790
+ node = Nodes::BoundSqlLiteral.new("id = :0abc", [], { "0abc": 1 })
791
+ _(compile(node)).must_be_like %{
792
+ id = :0abc
793
+ }
794
+ end
795
+
796
+ it "works with array values" do
797
+ node = Nodes::BoundSqlLiteral.new("id IN (?)", [[1, 2, 3]], {})
798
+ _(compile(node)).must_be_like %{
799
+ id IN (?, ?, ?)
800
+ }
801
+ end
802
+
803
+ it "refuses mixed binds" do
804
+ assert_raises(Arel::BindError) do
805
+ Nodes::BoundSqlLiteral.new("id = ? AND name = :name", [1], { name: "Aaron" })
806
+ end
807
+ end
808
+
809
+ it "requires positional binds to match the placeholders" do
810
+ assert_raises(Arel::BindError) do
811
+ Nodes::BoundSqlLiteral.new("id IN (?, ?, ?)", [1, 2], {})
812
+ end
813
+
814
+ assert_raises(Arel::BindError) do
815
+ Nodes::BoundSqlLiteral.new("id IN (?, ?, ?)", [1, 2, 3, 4], {})
816
+ end
817
+ end
818
+
819
+ it "requires all named bind params to be supplied" do
820
+ assert_raises(Arel::BindError) do
821
+ Nodes::BoundSqlLiteral.new("id IN (:foo, :bar)", [], { foo: 1 })
822
+ end
823
+ end
824
+
825
+ it "ignores excess named parameters" do
826
+ node = Nodes::BoundSqlLiteral.new("id = :id", [], { foo: 2, id: 1, bar: 3 })
827
+ _(compile(node)).must_be_like %{
828
+ id = ?
829
+ }
830
+ end
831
+
832
+ it "quotes nested arrays" do
833
+ # Two cases to exercise all branches.
834
+ # For real adapters, quoting arrays may fail in adapter-specific ways.
835
+
836
+ inner_literal = Nodes::BoundSqlLiteral.new("? * 2", [4], {})
837
+ node = Nodes::BoundSqlLiteral.new("id IN (?)", [[1, [2, 3], inner_literal]], {})
838
+ _(compile(node)).must_be_like %{
839
+ id IN (?, ?, ? * 2)
840
+ }
841
+
842
+ node = Nodes::BoundSqlLiteral.new("id IN (?)", [[1, [2, 3]]], {})
843
+ _(compile(node)).must_be_like %{
844
+ id IN (?, ?)
845
+ }
846
+ end
847
+
848
+ it "supports other bound literals as binds" do
849
+ node = Arel.sql("?", [1, 2, Arel.sql("?", 3)])
850
+ _(compile(node)).must_be_like %{
851
+ ?, ?, ?
852
+ }
853
+ end
854
+ end
855
+
856
+ describe "Table" do
857
+ it "should compile node names" do
858
+ test = Table.new(:users).alias("zomgusers")[:id].eq "3"
859
+ _(compile(test)).must_be_like %{
860
+ "zomgusers"."id" = '3'
861
+ }
862
+ end
863
+
864
+ it "should compile literal SQL" do
865
+ test = Table.new Arel.sql("generate_series(4, 2)")
866
+ _(compile(test)).must_be_like %{ generate_series(4, 2) }
867
+ end
868
+
869
+ it "should compile Arel nodes" do
870
+ test = Arel::Nodes::NamedFunction.new("generate_series", [4, 2])
871
+ _(compile(test)).must_be_like %{ generate_series(4, 2) }
872
+ end
873
+
874
+ it "should compile nodes with bind params" do
875
+ bp = Nodes::BindParam.new(1)
876
+ test = Arel::Nodes::NamedFunction.new("generate_series", [4, bp])
877
+ _(compile(test)).must_be_like %{ generate_series(4, ?) }
878
+ end
879
+ end
880
+
624
881
  describe "TableAlias" do
625
882
  it "should use the underlying table for checking columns" do
626
883
  test = Table.new(:users).alias("zomgusers")[:id].eq "3"
@@ -732,6 +989,19 @@ module Arel
732
989
  WITH expr1 AS (SELECT * FROM "bar"), expr2 AS (SELECT * FROM "baz") SELECT * FROM expr2
733
990
  }
734
991
  end
992
+
993
+ it "handles Cte nodes" do
994
+ cte = Arel::Nodes::Cte.new("expr1", Table.new(:bar).project(Arel.star))
995
+ manager = Table.new(:foo).
996
+ project(Arel.star).
997
+ with(cte).
998
+ from(cte.to_table).
999
+ where(cte.to_table[:score].gt(5))
1000
+
1001
+ _(compile(manager.ast)).must_be_like %{
1002
+ WITH "expr1" AS (SELECT * FROM "bar") SELECT * FROM "expr1" WHERE "expr1"."score" > 5
1003
+ }
1004
+ end
735
1005
  end
736
1006
 
737
1007
  describe "Nodes::WithRecursive" do
@@ -745,6 +1015,46 @@ module Arel
745
1015
  }
746
1016
  end
747
1017
  end
1018
+
1019
+ describe "Nodes::Cte" do
1020
+ it "handles CTEs with no MATERIALIZED modifier" do
1021
+ cte = Nodes::Cte.new("foo", Table.new(:bar).project(Arel.star))
1022
+
1023
+ _(compile(cte)).must_be_like %{
1024
+ "foo" AS (SELECT * FROM "bar")
1025
+ }
1026
+ end
1027
+
1028
+ it "handles CTEs with a MATERIALIZED modifier" do
1029
+ cte = Nodes::Cte.new("foo", Table.new(:bar).project(Arel.star), materialized: true)
1030
+
1031
+ _(compile(cte)).must_be_like %{
1032
+ "foo" AS MATERIALIZED (SELECT * FROM "bar")
1033
+ }
1034
+ end
1035
+
1036
+ it "handles CTEs with a NOT MATERIALIZED modifier" do
1037
+ cte = Nodes::Cte.new("foo", Table.new(:bar).project(Arel.star), materialized: false)
1038
+
1039
+ _(compile(cte)).must_be_like %{
1040
+ "foo" AS NOT MATERIALIZED (SELECT * FROM "bar")
1041
+ }
1042
+ end
1043
+ end
1044
+
1045
+ describe "Nodes::Fragments" do
1046
+ it "joins subexpressions" do
1047
+ sql = Arel.sql("SELECT foo, bar") + Arel.sql(" FROM customers")
1048
+ _(compile(sql)).must_be_like "SELECT foo, bar FROM customers"
1049
+ end
1050
+
1051
+ it "can be built by adding SQL fragments one at a time" do
1052
+ sql = Arel.sql("SELECT foo, bar")
1053
+ sql += Arel.sql("FROM customers")
1054
+ sql += Arel.sql("GROUP BY foo")
1055
+ _(compile(sql)).must_be_like "SELECT foo, bar FROM customers GROUP BY foo"
1056
+ end
1057
+ end
748
1058
  end
749
1059
  end
750
1060
  end