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.
- checksums.yaml +4 -4
- data/ext/Makefile +13 -9
- data/ext/extconf.rb +176 -110
- data/ext/ibm_db.c +60 -0
- data/ext/ibm_db.o +0 -0
- data/ext/ibm_db.so +0 -0
- data/ext/mkmf.log +6 -6
- data/ext/ruby_ibm_db_cli.c +14 -10
- data/ext/ruby_ibm_db_cli.h +4 -0
- data/ext/ruby_ibm_db_cli.o +0 -0
- data/lib/IBM_DB.rb +2 -2
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +1254 -277
- data/test/active_record/connection_adapters/fake_legacy_adapter.rb +17 -0
- data/test/active_record/connection_adapters/fake_misleading_legacy_adapter.rb +8 -0
- data/test/activejob/destroy_association_async_job_test.rb +62 -0
- data/test/activejob/destroy_association_async_test.rb +147 -11
- data/test/activejob/job_runtime_test.rb +41 -0
- data/test/activejob/unloadable_base_job.rb +3 -0
- data/test/cases/active_record_schema_test.rb +196 -0
- data/test/cases/active_record_test.rb +21 -0
- data/test/cases/adapter_prevent_writes_test.rb +26 -202
- data/test/cases/adapter_test.rb +592 -82
- data/test/cases/adapters/abstract_mysql_adapter/active_schema_test.rb +210 -0
- data/test/cases/adapters/abstract_mysql_adapter/adapter_prevent_writes_test.rb +111 -0
- data/test/cases/adapters/abstract_mysql_adapter/auto_increment_test.rb +48 -0
- data/test/cases/adapters/abstract_mysql_adapter/bind_parameter_test.rb +91 -0
- data/test/cases/adapters/abstract_mysql_adapter/case_sensitivity_test.rb +65 -0
- data/test/cases/adapters/abstract_mysql_adapter/charset_collation_test.rb +85 -0
- data/test/cases/adapters/abstract_mysql_adapter/connection_test.rb +267 -0
- data/test/cases/adapters/abstract_mysql_adapter/count_deleted_rows_with_lock_test.rb +29 -0
- data/test/cases/adapters/abstract_mysql_adapter/json_test.rb +24 -0
- data/test/cases/adapters/abstract_mysql_adapter/mysql_boolean_test.rb +102 -0
- data/test/cases/adapters/abstract_mysql_adapter/mysql_enum_test.rb +47 -0
- data/test/cases/adapters/abstract_mysql_adapter/mysql_explain_test.rb +71 -0
- data/test/cases/adapters/abstract_mysql_adapter/nested_deadlock_test.rb +191 -0
- data/test/cases/adapters/abstract_mysql_adapter/optimizer_hints_test.rb +69 -0
- data/test/cases/adapters/abstract_mysql_adapter/quoting_test.rb +49 -0
- data/test/cases/adapters/abstract_mysql_adapter/schema_migrations_test.rb +68 -0
- data/test/cases/adapters/abstract_mysql_adapter/schema_test.rb +130 -0
- data/test/cases/adapters/abstract_mysql_adapter/set_test.rb +32 -0
- data/test/cases/adapters/abstract_mysql_adapter/sp_test.rb +39 -0
- data/test/cases/adapters/abstract_mysql_adapter/sql_types_test.rb +16 -0
- data/test/cases/adapters/abstract_mysql_adapter/table_options_test.rb +125 -0
- data/test/cases/adapters/abstract_mysql_adapter/transaction_test.rb +204 -0
- data/test/cases/adapters/abstract_mysql_adapter/unsigned_type_test.rb +77 -0
- data/test/cases/adapters/abstract_mysql_adapter/virtual_column_test.rb +69 -0
- data/test/cases/adapters/abstract_mysql_adapter/warnings_test.rb +109 -0
- data/test/cases/adapters/mysql2/check_constraint_quoting_test.rb +35 -0
- data/test/cases/adapters/mysql2/dbconsole_test.rb +87 -0
- data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +136 -10
- data/test/cases/adapters/mysql2/mysql2_rake_test.rb +433 -0
- data/test/cases/adapters/postgresql/active_schema_test.rb +8 -4
- data/test/cases/adapters/postgresql/array_test.rb +6 -6
- data/test/cases/adapters/postgresql/bind_parameter_test.rb +52 -0
- data/test/cases/adapters/postgresql/bit_string_test.rb +2 -2
- data/test/cases/adapters/postgresql/bytea_test.rb +3 -3
- data/test/cases/adapters/postgresql/case_insensitive_test.rb +1 -1
- data/test/cases/adapters/postgresql/change_schema_test.rb +32 -1
- data/test/cases/adapters/postgresql/cidr_test.rb +17 -0
- data/test/cases/adapters/postgresql/citext_test.rb +7 -1
- data/test/cases/adapters/postgresql/collation_test.rb +1 -1
- data/test/cases/adapters/postgresql/composite_test.rb +1 -1
- data/test/cases/adapters/postgresql/connection_test.rb +43 -36
- data/test/cases/adapters/postgresql/create_unlogged_tables_test.rb +3 -2
- data/test/cases/adapters/postgresql/datatype_test.rb +9 -4
- data/test/cases/adapters/postgresql/date_test.rb +2 -2
- data/test/cases/adapters/postgresql/dbconsole_test.rb +109 -0
- data/test/cases/adapters/postgresql/deferred_constraints_test.rb +55 -0
- data/test/cases/adapters/postgresql/domain_test.rb +1 -1
- data/test/cases/adapters/postgresql/enum_test.rb +208 -8
- data/test/cases/adapters/postgresql/explain_test.rb +25 -6
- data/test/cases/adapters/postgresql/extension_migration_test.rb +51 -9
- data/test/cases/adapters/postgresql/foreign_table_test.rb +3 -3
- data/test/cases/adapters/postgresql/full_text_test.rb +1 -1
- data/test/cases/adapters/postgresql/geometric_test.rb +13 -6
- data/test/cases/adapters/postgresql/hstore_test.rb +22 -32
- data/test/cases/adapters/postgresql/infinity_test.rb +13 -2
- data/test/cases/adapters/postgresql/integer_test.rb +1 -1
- data/test/cases/adapters/postgresql/interval_test.rb +9 -17
- data/test/cases/adapters/postgresql/invertible_migration_test.rb +139 -0
- data/test/cases/adapters/postgresql/json_test.rb +5 -0
- data/test/cases/adapters/postgresql/ltree_test.rb +1 -1
- data/test/cases/adapters/postgresql/money_test.rb +17 -9
- data/test/cases/adapters/postgresql/network_test.rb +13 -1
- data/test/cases/adapters/postgresql/numbers_test.rb +18 -2
- data/test/cases/adapters/postgresql/optimizer_hints_test.rb +9 -9
- data/test/cases/adapters/postgresql/partitions_test.rb +5 -2
- data/test/cases/adapters/postgresql/postgresql_adapter_prevent_writes_test.rb +7 -110
- data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +403 -20
- data/test/cases/adapters/postgresql/postgresql_rake_test.rb +637 -0
- data/test/cases/adapters/postgresql/prepared_statements_disabled_test.rb +1 -1
- data/test/cases/adapters/postgresql/quoting_test.rb +60 -1
- data/test/cases/adapters/postgresql/range_test.rb +185 -21
- data/test/cases/adapters/postgresql/referential_integrity_test.rb +29 -5
- data/test/cases/adapters/postgresql/rename_table_test.rb +35 -8
- data/test/cases/adapters/postgresql/schema_authorization_test.rb +2 -2
- data/test/cases/adapters/postgresql/schema_test.rb +270 -20
- data/test/cases/adapters/postgresql/serial_test.rb +5 -5
- data/test/cases/adapters/postgresql/statement_pool_test.rb +6 -2
- data/test/cases/adapters/postgresql/timestamp_test.rb +122 -5
- data/test/cases/adapters/postgresql/transaction_nested_test.rb +130 -6
- data/test/cases/adapters/postgresql/transaction_test.rb +37 -11
- data/test/cases/adapters/postgresql/type_lookup_test.rb +1 -1
- data/test/cases/adapters/postgresql/uuid_test.rb +77 -9
- data/test/cases/adapters/postgresql/virtual_column_test.rb +114 -0
- data/test/cases/adapters/postgresql/xml_test.rb +1 -1
- data/test/cases/adapters/sqlite3/bind_parameter_test.rb +52 -0
- data/test/cases/adapters/sqlite3/collation_test.rb +1 -1
- data/test/cases/adapters/sqlite3/copy_table_test.rb +28 -7
- data/test/cases/adapters/sqlite3/dbconsole_test.rb +81 -0
- data/test/cases/adapters/sqlite3/explain_test.rb +3 -3
- data/test/cases/adapters/sqlite3/quoting_test.rb +34 -3
- data/test/cases/adapters/sqlite3/sqlite3_adapter_prevent_writes_test.rb +9 -102
- data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +727 -72
- data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +6 -3
- data/test/cases/adapters/sqlite3/sqlite_rake_test.rb +264 -0
- data/test/cases/adapters/sqlite3/statement_pool_test.rb +1 -1
- data/test/cases/adapters/sqlite3/transaction_test.rb +6 -3
- data/test/cases/adapters/sqlite3/virtual_column_test.rb +138 -0
- data/test/cases/adapters/sqlite3/virtual_table_test.rb +51 -0
- data/test/cases/adapters/trilogy/dbconsole_test.rb +76 -0
- data/test/cases/adapters/trilogy/trilogy_adapter_test.rb +473 -0
- data/test/cases/adapters/trilogy/trilogy_rake_test.rb +433 -0
- data/test/cases/aggregations_test.rb +16 -0
- data/test/cases/annotate_test.rb +14 -12
- data/test/cases/arel/attributes/attribute_test.rb +86 -47
- data/test/cases/arel/collectors/bind_test.rb +1 -1
- data/test/cases/arel/collectors/composite_test.rb +11 -1
- data/test/cases/arel/collectors/sql_string_test.rb +1 -1
- data/test/cases/arel/collectors/substitute_bind_collector_test.rb +1 -1
- data/test/cases/arel/delete_manager_test.rb +0 -6
- data/test/cases/arel/factory_methods_test.rb +45 -0
- data/test/cases/arel/insert_manager_test.rb +1 -7
- data/test/cases/arel/nodes/as_test.rb +12 -0
- data/test/cases/arel/nodes/ascending_test.rb +1 -1
- data/test/cases/arel/nodes/bin_test.rb +1 -1
- data/test/cases/arel/nodes/bound_sql_literal_test.rb +31 -0
- data/test/cases/arel/nodes/cte_test.rb +46 -0
- data/test/cases/arel/nodes/descending_test.rb +1 -1
- data/test/cases/arel/nodes/equality_test.rb +3 -3
- data/test/cases/arel/nodes/filter_test.rb +37 -0
- data/test/cases/arel/nodes/fragments_test.rb +38 -0
- data/test/cases/arel/nodes/homogeneous_in_test.rb +52 -0
- data/test/cases/arel/nodes/infix_operation_test.rb +1 -1
- data/test/cases/arel/nodes/node_test.rb +1 -1
- data/test/cases/arel/nodes/or_test.rb +2 -2
- data/test/cases/arel/nodes/sql_literal_test.rb +18 -1
- data/test/cases/arel/nodes/table_alias_test.rb +12 -0
- data/test/cases/arel/nodes/unary_operation_test.rb +1 -1
- data/test/cases/arel/nodes/update_statement_test.rb +4 -0
- data/test/cases/arel/nodes_test.rb +3 -2
- data/test/cases/arel/select_manager_test.rb +12 -12
- data/test/cases/arel/support/fake_record.rb +22 -17
- data/test/cases/arel/table_test.rb +15 -25
- data/test/cases/arel/update_manager_test.rb +51 -6
- data/test/cases/arel/visitors/dispatch_contamination_test.rb +1 -1
- data/test/cases/arel/visitors/dot_test.rb +177 -2
- data/test/cases/arel/visitors/mysql_test.rb +49 -1
- data/test/cases/arel/visitors/postgres_test.rb +1 -31
- data/test/cases/arel/visitors/sqlite_test.rb +1 -1
- data/test/cases/arel/visitors/to_sql_test.rb +330 -20
- data/test/cases/assertions/query_assertions_test.rb +136 -0
- data/test/cases/associations/belongs_to_associations_test.rb +502 -41
- data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +1 -1
- data/test/cases/associations/cascaded_eager_loading_test.rb +26 -15
- data/test/cases/associations/eager_load_nested_include_test.rb +1 -1
- data/test/cases/associations/eager_singularization_test.rb +1 -1
- data/test/cases/associations/eager_test.rb +255 -93
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +25 -53
- data/test/cases/associations/has_many_associations_test.rb +282 -72
- data/test/cases/associations/has_many_through_associations_test.rb +172 -45
- data/test/cases/associations/has_many_through_disable_joins_associations_test.rb +197 -0
- data/test/cases/associations/has_one_associations_test.rb +160 -29
- data/test/cases/associations/has_one_through_associations_test.rb +64 -15
- data/test/cases/associations/has_one_through_disable_joins_associations_test.rb +82 -0
- data/test/cases/associations/inner_join_association_test.rb +36 -6
- data/test/cases/associations/inverse_associations_test.rb +177 -40
- data/test/cases/associations/join_model_test.rb +17 -12
- data/test/cases/associations/left_outer_join_association_test.rb +14 -3
- data/test/cases/associations/nested_error_test.rb +116 -0
- data/test/cases/associations/nested_through_associations_test.rb +54 -19
- data/test/cases/associations/required_test.rb +1 -1
- data/test/cases/associations_test.rb +1278 -21
- data/test/cases/asynchronous_queries_test.rb +310 -0
- data/test/cases/attribute_methods/read_test.rb +6 -0
- data/test/cases/attribute_methods/time_zone_converter_test.rb +21 -0
- data/test/cases/attribute_methods_test.rb +565 -46
- data/test/cases/attributes_test.rb +42 -1
- data/test/cases/autosave_association_test.rb +645 -92
- data/test/cases/base_prevent_writes_test.rb +28 -159
- data/test/cases/base_test.rb +434 -209
- data/test/cases/batches_test.rb +441 -57
- data/test/cases/binary_test.rb +31 -0
- data/test/cases/bind_parameter_test.rb +107 -16
- data/test/cases/cache_key_test.rb +7 -7
- data/test/cases/calculations_test.rb +541 -110
- data/test/cases/callbacks_test.rb +0 -1
- data/test/cases/clone_test.rb +5 -4
- data/test/cases/coders/yaml_column_test.rb +97 -2
- data/test/cases/collection_cache_key_test.rb +24 -16
- data/test/cases/column_alias_test.rb +2 -8
- data/test/cases/column_definition_test.rb +12 -3
- data/test/cases/comment_test.rb +23 -26
- data/test/cases/connection_adapters/adapter_leasing_test.rb +9 -9
- data/test/cases/connection_adapters/connection_handler_test.rb +145 -99
- data/test/cases/connection_adapters/connection_handlers_multi_db_test.rb +79 -55
- data/test/cases/connection_adapters/connection_handlers_multi_pool_config_test.rb +17 -20
- data/test/cases/connection_adapters/connection_handlers_sharding_db_test.rb +146 -55
- data/test/cases/connection_adapters/connection_swapping_nested_test.rb +136 -23
- data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +96 -27
- data/test/cases/connection_adapters/mysql_type_lookup_test.rb +5 -5
- data/test/cases/connection_adapters/registration_test.rb +98 -0
- data/test/cases/connection_adapters/schema_cache_test.rb +288 -135
- data/test/cases/connection_adapters/standalone_connection_test.rb +38 -0
- data/test/cases/connection_adapters/statement_pool_test.rb +29 -0
- data/test/cases/connection_adapters/type_lookup_test.rb +12 -24
- data/test/cases/connection_handling_test.rb +210 -0
- data/test/cases/connection_management_test.rb +44 -7
- data/test/cases/connection_pool_test.rb +466 -99
- data/test/cases/core_test.rb +167 -9
- data/test/cases/counter_cache_test.rb +129 -2
- data/test/cases/custom_locking_test.rb +3 -3
- data/test/cases/database_configurations/hash_config_test.rb +149 -13
- data/test/cases/database_configurations/resolver_test.rb +14 -10
- data/test/cases/database_configurations/url_config_test.rb +53 -0
- data/test/cases/database_configurations_test.rb +86 -43
- data/test/cases/database_selector_test.rb +30 -8
- data/test/cases/database_statements_test.rb +10 -14
- data/test/cases/date_time_precision_test.rb +141 -11
- data/test/cases/date_time_test.rb +19 -1
- data/test/cases/defaults_test.rb +107 -41
- data/test/cases/delegated_type_test.rb +69 -9
- data/test/cases/dirty_test.rb +82 -25
- data/test/cases/disconnected_test.rb +10 -9
- data/test/cases/dup_test.rb +26 -6
- data/test/cases/encryption/cipher/aes256_gcm_test.rb +50 -0
- data/test/cases/encryption/cipher_test.rb +65 -0
- data/test/cases/encryption/concurrency_test.rb +27 -0
- data/test/cases/encryption/config_test.rb +21 -0
- data/test/cases/encryption/configurable_test.rb +93 -0
- data/test/cases/encryption/contexts_test.rb +105 -0
- data/test/cases/encryption/derived_secret_key_provider_test.rb +31 -0
- data/test/cases/encryption/deterministic_key_provider_test.rb +11 -0
- data/test/cases/encryption/encryptable_record_api_test.rb +175 -0
- data/test/cases/encryption/encryptable_record_message_pack_serialized_test.rb +42 -0
- data/test/cases/encryption/encryptable_record_test.rb +470 -0
- data/test/cases/encryption/encrypted_fixtures_test.rb +22 -0
- data/test/cases/encryption/encrypting_only_encryptor_test.rb +20 -0
- data/test/cases/encryption/encryption_schemes_test.rb +240 -0
- data/test/cases/encryption/encryptor_test.rb +113 -0
- data/test/cases/encryption/envelope_encryption_key_provider_test.rb +49 -0
- data/test/cases/encryption/extended_deterministic_queries_test.rb +81 -0
- data/test/cases/encryption/helper.rb +152 -0
- data/test/cases/encryption/key_generator_test.rb +55 -0
- data/test/cases/encryption/key_provider_test.rb +57 -0
- data/test/cases/encryption/key_test.rb +17 -0
- data/test/cases/encryption/message_pack_message_serializer_test.rb +70 -0
- data/test/cases/encryption/message_serializer_test.rb +82 -0
- data/test/cases/encryption/message_test.rb +43 -0
- data/test/cases/encryption/null_encryptor_test.rb +21 -0
- data/test/cases/encryption/properties_test.rb +69 -0
- data/test/cases/encryption/read_only_null_encryptor_test.rb +19 -0
- data/test/cases/encryption/scheme_test.rb +58 -0
- data/test/cases/encryption/unencrypted_attributes_test.rb +27 -0
- data/test/cases/encryption/uniqueness_validations_test.rb +65 -0
- data/test/cases/enum_test.rb +374 -72
- data/test/cases/errors_test.rb +7 -4
- data/test/cases/excluding_test.rb +116 -0
- data/test/cases/explain_subscriber_test.rb +6 -1
- data/test/cases/explain_test.rb +119 -10
- data/test/cases/filter_attributes_test.rb +7 -14
- data/test/cases/finder_respond_to_test.rb +3 -3
- data/test/cases/finder_test.rb +357 -72
- data/test/cases/fixture_set/file_test.rb +9 -0
- data/test/cases/fixtures_test.rb +426 -190
- data/test/cases/helper.rb +66 -192
- data/test/cases/hot_compatibility_test.rb +10 -10
- data/test/cases/inheritance_test.rb +51 -61
- data/test/cases/inherited_test.rb +40 -0
- data/test/cases/insert_all_test.rb +419 -9
- data/test/cases/instrumentation_test.rb +202 -30
- data/test/cases/integration_test.rb +25 -7
- data/test/cases/invalid_connection_test.rb +5 -5
- data/test/cases/invertible_migration_test.rb +108 -24
- data/test/cases/json_attribute_test.rb +1 -0
- data/test/cases/json_serialization_test.rb +5 -5
- data/test/cases/json_shared_test_cases.rb +5 -9
- data/test/cases/locking_test.rb +67 -31
- data/test/cases/log_subscriber_test.rb +17 -15
- data/test/cases/marshal_serialization_test.rb +78 -5
- data/test/cases/message_pack_test.rb +91 -0
- data/test/cases/migration/change_schema_test.rb +77 -46
- data/test/cases/migration/change_table_test.rb +129 -114
- data/test/cases/migration/check_constraint_test.rb +192 -10
- data/test/cases/migration/column_attributes_test.rb +4 -9
- data/test/cases/migration/column_positioning_test.rb +2 -2
- data/test/cases/migration/columns_test.rb +118 -4
- data/test/cases/migration/command_recorder_test.rb +181 -14
- data/test/cases/migration/compatibility_test.rb +883 -196
- data/test/cases/migration/create_join_table_test.rb +8 -1
- data/test/cases/migration/exclusion_constraint_test.rb +192 -0
- data/test/cases/migration/foreign_key_test.rb +356 -14
- data/test/cases/migration/helper.rb +4 -1
- data/test/cases/migration/index_test.rb +67 -2
- data/test/cases/migration/invalid_options_test.rb +129 -0
- data/test/cases/migration/logger_test.rb +7 -4
- data/test/cases/migration/pending_migrations_test.rb +103 -60
- data/test/cases/migration/references_foreign_key_test.rb +73 -4
- data/test/cases/migration/references_index_test.rb +25 -27
- data/test/cases/migration/references_statements_test.rb +27 -3
- data/test/cases/migration/rename_table_test.rb +39 -54
- data/test/cases/migration/schema_definitions_test.rb +109 -0
- data/test/cases/migration/unique_constraint_test.rb +248 -0
- data/test/cases/migration_test.rb +677 -220
- data/test/cases/migrator_test.rb +102 -75
- data/test/cases/multi_db_migrator_test.rb +55 -34
- data/test/cases/multiparameter_attributes_test.rb +26 -29
- data/test/cases/multiple_db_test.rb +42 -19
- data/test/cases/nested_attributes_test.rb +124 -6
- data/test/cases/nested_attributes_with_callbacks_test.rb +2 -2
- data/test/cases/normalized_attribute_test.rb +117 -0
- data/test/cases/null_relation_test.rb +35 -2
- data/test/cases/persistence/reload_association_cache_test.rb +20 -0
- data/test/cases/persistence_test.rb +629 -22
- data/test/cases/pooled_connections_test.rb +57 -56
- data/test/cases/prepared_statement_status_test.rb +8 -3
- data/test/cases/primary_class_test.rb +134 -0
- data/test/cases/primary_keys_test.rb +171 -55
- data/test/cases/query_cache_test.rb +558 -263
- data/test/cases/query_logs_test.rb +293 -0
- data/test/cases/quoting_test.rb +39 -72
- data/test/cases/readonly_test.rb +50 -12
- data/test/cases/reaper_test.rb +22 -6
- data/test/cases/reflection_test.rb +207 -9
- data/test/cases/relation/and_test.rb +43 -0
- data/test/cases/relation/delegation_test.rb +32 -5
- data/test/cases/relation/delete_all_test.rb +27 -6
- data/test/cases/relation/field_ordered_values_test.rb +128 -0
- data/test/cases/relation/load_async_test.rb +650 -0
- data/test/cases/relation/merging_test.rb +80 -109
- data/test/cases/relation/mutation_test.rb +12 -7
- data/test/cases/relation/or_test.rb +11 -8
- data/test/cases/relation/order_test.rb +90 -0
- data/test/cases/relation/predicate_builder_test.rb +21 -6
- data/test/cases/relation/select_test.rb +162 -3
- data/test/cases/relation/structural_compatibility_test.rb +38 -0
- data/test/cases/relation/update_all_test.rb +81 -27
- data/test/cases/relation/where_chain_test.rb +190 -3
- data/test/cases/relation/where_clause_test.rb +43 -1
- data/test/cases/relation/where_test.rb +95 -7
- data/test/cases/relation/with_test.rb +165 -0
- data/test/cases/relation_test.rb +42 -37
- data/test/cases/relations_test.rb +436 -138
- data/test/cases/reload_models_test.rb +18 -14
- data/test/cases/reserved_word_test.rb +2 -1
- data/test/cases/result_test.rb +14 -22
- data/test/cases/sanitize_test.rb +89 -27
- data/test/cases/schema_dumper_test.rb +535 -62
- data/test/cases/scoping/default_scoping_test.rb +219 -35
- data/test/cases/scoping/named_scoping_test.rb +25 -46
- data/test/cases/scoping/relation_scoping_test.rb +112 -4
- data/test/cases/secure_password_test.rb +108 -0
- data/test/cases/secure_token_test.rb +72 -0
- data/test/cases/serialization_test.rb +1 -1
- data/test/cases/serialized_attribute_test.rb +305 -60
- data/test/cases/shard_keys_test.rb +125 -0
- data/test/cases/shard_selector_test.rb +45 -0
- data/test/cases/signed_id_test.rb +57 -5
- data/test/cases/statement_cache_test.rb +31 -30
- data/test/cases/statement_invalid_test.rb +8 -4
- data/test/cases/store_test.rb +73 -9
- data/test/cases/strict_loading_test.rb +327 -13
- data/test/cases/table_metadata_test.rb +16 -0
- data/test/cases/tasks/database_tasks_test.rb +517 -244
- data/test/cases/test_case.rb +254 -60
- data/test/cases/test_case_test.rb +69 -0
- data/test/cases/test_databases_test.rb +7 -3
- data/test/cases/test_fixtures_test.rb +19 -40
- data/test/cases/time_precision_test.rb +17 -5
- data/test/cases/timestamp_test.rb +124 -16
- data/test/cases/token_for_test.rb +165 -0
- data/test/cases/touch_later_test.rb +43 -1
- data/test/cases/transaction_callbacks_test.rb +325 -8
- data/test/cases/transaction_instrumentation_test.rb +453 -0
- data/test/cases/transaction_isolation_test.rb +12 -8
- data/test/cases/transactions_test.rb +629 -112
- data/test/cases/type/date_time_test.rb +7 -1
- data/test/cases/type/time_test.rb +9 -0
- data/test/cases/type/type_map_test.rb +108 -73
- data/test/cases/type/unsigned_integer_test.rb +12 -0
- data/test/cases/type_caster/connection_test.rb +19 -0
- data/test/cases/type_test.rb +1 -1
- data/test/cases/unconnected_test.rb +7 -7
- data/test/cases/unsafe_raw_sql_test.rb +39 -8
- data/test/cases/validations/absence_validation_test.rb +1 -1
- data/test/cases/validations/association_validation_test.rb +25 -3
- data/test/cases/validations/numericality_validation_test.rb +3 -9
- data/test/cases/validations/presence_validation_test.rb +1 -1
- data/test/cases/validations/uniqueness_validation_test.rb +280 -40
- data/test/cases/validations_test.rb +2 -2
- data/test/cases/view_test.rb +33 -22
- data/test/cases/yaml_serialization_test.rb +23 -17
- data/test/config.example.yml +58 -56
- data/test/config.rb +1 -0
- data/test/fixtures/1_need_quoting.yml +2 -0
- data/test/fixtures/accounts.yml +5 -0
- data/test/fixtures/aircrafts.yml +7 -0
- data/test/fixtures/book_identifiers.yml +11 -0
- data/test/fixtures/books.yml +5 -4
- data/test/fixtures/cake_designers.yml +5 -0
- data/test/fixtures/cars.yml +6 -0
- data/test/fixtures/chefs.yml +5 -0
- data/test/fixtures/clothing_items.yml +23 -0
- data/test/fixtures/clubs.yml +1 -1
- data/test/fixtures/comments.yml +2 -1
- data/test/fixtures/cpk_authors.yml +8 -0
- data/test/fixtures/cpk_books.yml +21 -0
- data/test/fixtures/cpk_order_agreements.yml +13 -0
- data/test/fixtures/cpk_order_tags.yml +15 -0
- data/test/fixtures/cpk_orders.yml +11 -0
- data/test/fixtures/cpk_posts.yml +12 -0
- data/test/fixtures/cpk_reviews.yml +13 -0
- data/test/fixtures/cpk_tags.yml +11 -0
- data/test/fixtures/drink_designers.yml +5 -0
- data/test/fixtures/encrypted_book_that_ignores_cases.yml +4 -0
- data/test/fixtures/encrypted_books.yml +4 -0
- data/test/fixtures/fk_object_to_point_to.yml +2 -0
- data/test/fixtures/memberships.yml +15 -15
- data/test/fixtures/paragraphs.yml +5 -0
- data/test/fixtures/parrots.yml +4 -0
- data/test/fixtures/people.yml +2 -0
- data/test/fixtures/pirates.yml +2 -2
- data/test/fixtures/primary_key_error/primary_key_error.yml +6 -0
- data/test/fixtures/references.yml +3 -3
- data/test/fixtures/sharded_blog_posts.yml +14 -0
- data/test/fixtures/sharded_blog_posts_tags.yml +27 -0
- data/test/fixtures/sharded_blogs.yml +8 -0
- data/test/fixtures/sharded_comments.yml +22 -0
- data/test/fixtures/sharded_tags.yml +34 -0
- data/test/fixtures/sponsors.yml +2 -2
- data/test/fixtures/topics.yml +1 -0
- data/test/fixtures/treasures.yml +4 -0
- data/test/fixtures/virtual_columns.yml +5 -0
- data/test/fixtures/warehouse_things.yml +1 -1
- data/test/migrations/old_and_new_versions/20210716122844_add_people_description.rb +5 -0
- data/test/migrations/old_and_new_versions/20210716123013_add_people_number_of_legs.rb +5 -0
- data/test/migrations/old_and_new_versions/230_add_people_hobby.rb +5 -0
- data/test/migrations/old_and_new_versions/231_add_people_last_name.rb +5 -0
- data/test/migrations/scope/1_unscoped.rb +7 -0
- data/test/migrations/scope/2_mysql_only.mysql.rb +7 -0
- data/test/models/admin/user.rb +2 -0
- data/test/models/admin/user_json.rb +48 -0
- data/test/models/attachment.rb +7 -0
- data/test/models/author.rb +70 -3
- data/test/models/author_encrypted.rb +16 -0
- data/test/models/bird.rb +1 -1
- data/test/models/book.rb +18 -11
- data/test/models/book_destroy_async.rb +1 -1
- data/test/models/book_encrypted.rb +106 -0
- data/test/models/book_identifier.rb +5 -0
- data/test/models/branch.rb +11 -0
- data/test/models/bulb.rb +1 -1
- data/test/models/car.rb +8 -1
- data/test/models/cat.rb +1 -1
- data/test/models/category.rb +3 -1
- data/test/models/chat_message.rb +8 -0
- data/test/models/chef.rb +52 -0
- data/test/models/clothing_item.rb +12 -0
- data/test/models/club.rb +4 -1
- data/test/models/comment.rb +7 -4
- data/test/models/comment_overlapping_counter_cache.rb +15 -0
- data/test/models/company.rb +16 -2
- data/test/models/computer.rb +1 -0
- data/test/models/contact.rb +3 -3
- data/test/models/contract.rb +5 -1
- data/test/models/cpk/author.rb +9 -0
- data/test/models/cpk/book.rb +55 -0
- data/test/models/cpk/book_destroy_async.rb +9 -0
- data/test/models/cpk/car.rb +9 -0
- data/test/models/cpk/car_review.rb +9 -0
- data/test/models/cpk/chapter.rb +16 -0
- data/test/models/cpk/chapter_destroy_async.rb +10 -0
- data/test/models/cpk/comment.rb +9 -0
- data/test/models/cpk/order.rb +55 -0
- data/test/models/cpk/order_agreement.rb +10 -0
- data/test/models/cpk/order_tag.rb +10 -0
- data/test/models/cpk/post.rb +10 -0
- data/test/models/cpk/posts_tag.rb +10 -0
- data/test/models/cpk/review.rb +9 -0
- data/test/models/cpk/tag.rb +10 -0
- data/test/models/cpk.rb +15 -0
- data/test/models/customer.rb +3 -1
- data/test/models/destroy_async_parent.rb +1 -1
- data/test/models/developer.rb +44 -3
- data/test/models/discount.rb +4 -0
- data/test/models/drink_designer.rb +1 -0
- data/test/models/editor.rb +8 -0
- data/test/models/editorship.rb +6 -0
- data/test/models/entry.rb +5 -0
- data/test/models/essay.rb +6 -1
- data/test/models/essay_destroy_async.rb +1 -0
- data/test/models/eye.rb +87 -21
- data/test/models/face.rb +1 -1
- data/test/models/friendship.rb +3 -0
- data/test/models/hardback.rb +7 -0
- data/test/models/hotel.rb +2 -0
- data/test/models/human.rb +2 -2
- data/test/models/invoice.rb +2 -1
- data/test/models/invokes_an_undefined_method.rb +5 -0
- data/test/models/line_item.rb +6 -0
- data/test/models/member.rb +9 -4
- data/test/models/membership.rb +2 -2
- data/test/models/message.rb +2 -1
- data/test/models/need_quoting.rb +5 -0
- data/test/models/paragraph.rb +5 -0
- data/test/models/parrot.rb +6 -3
- data/test/models/person.rb +7 -4
- data/test/models/pirate.rb +4 -1
- data/test/models/pk_autopopulated_by_a_trigger_record.rb +5 -0
- data/test/models/post.rb +65 -2
- data/test/models/post_encrypted.rb +15 -0
- data/test/models/post_with_prefetched_pk.rb +15 -0
- data/test/models/project.rb +1 -0
- data/test/models/publication.rb +16 -0
- data/test/models/raises_argument_error.rb +5 -0
- data/test/models/raises_no_method_error.rb +5 -0
- data/test/models/recipient.rb +5 -0
- data/test/models/reference.rb +1 -1
- data/test/models/reply.rb +1 -1
- data/test/models/room.rb +3 -0
- data/test/models/sharded/blog.rb +12 -0
- data/test/models/sharded/blog_post.rb +17 -0
- data/test/models/sharded/blog_post_destroy_async.rb +14 -0
- data/test/models/sharded/blog_post_tag.rb +11 -0
- data/test/models/sharded/blog_post_with_revision.rb +11 -0
- data/test/models/sharded/comment.rb +12 -0
- data/test/models/sharded/comment_destroy_async.rb +12 -0
- data/test/models/sharded/tag.rb +11 -0
- data/test/models/sharded.rb +8 -0
- data/test/models/ship.rb +1 -1
- data/test/models/shipping_line.rb +11 -0
- data/test/models/subscriber.rb +1 -0
- data/test/models/subscription.rb +3 -1
- data/test/models/too_long_table_name.rb +5 -0
- data/test/models/topic.rb +3 -1
- data/test/models/traffic_light.rb +2 -2
- data/test/models/traffic_light_encrypted.rb +21 -0
- data/test/models/translation.rb +9 -0
- data/test/models/treasure.rb +1 -1
- data/test/models/tyre.rb +1 -1
- data/test/models/user.rb +16 -0
- data/test/models/user_with_invalid_relation.rb +28 -0
- data/test/models/uuid_comment.rb +5 -0
- data/test/models/uuid_entry.rb +5 -0
- data/test/models/uuid_message.rb +5 -0
- data/test/models/zine.rb +2 -1
- data/test/schema/mysql2_specific_schema.rb +26 -12
- data/test/schema/postgresql_specific_schema.rb +121 -13
- data/test/schema/schema.rb +361 -103
- data/test/schema/sqlite_specific_schema.rb +17 -6
- data/test/schema/trilogy_specific_schema.rb +96 -0
- data/test/support/adapter_helper.rb +104 -0
- data/test/support/async_helper.rb +15 -0
- data/test/support/config.rb +1 -1
- data/test/support/connection.rb +14 -2
- data/test/support/ddl_helper.rb +1 -1
- data/test/support/fake_adapter.rb +42 -0
- data/test/support/load_schema_helper.rb +22 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/IBM_DB/rails_7_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Mysql2/rails_7_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/PostgreSQL/rails_7_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLite/rails_7_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Trilogy/rails_6_1_topic_associations.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/Trilogy/rails_7_1_topic_associations.dump +0 -0
- data/test/support/schema_dumping_helper.rb +15 -9
- data/test/support/tools.rb +37 -0
- data/test/support/yaml_compatibility_fixtures/rails_4_1_no_symbol.yml +22 -0
- metadata +247 -15
|
@@ -4,6 +4,8 @@ require "cases/helper"
|
|
|
4
4
|
require "support/ddl_helper"
|
|
5
5
|
require "support/connection_helper"
|
|
6
6
|
|
|
7
|
+
require "active_support/error_reporter/test_helper"
|
|
8
|
+
|
|
7
9
|
module ActiveRecord
|
|
8
10
|
module ConnectionAdapters
|
|
9
11
|
class PostgreSQLAdapterTest < ActiveRecord::PostgreSQLTestCase
|
|
@@ -12,14 +14,15 @@ module ActiveRecord
|
|
|
12
14
|
include ConnectionHelper
|
|
13
15
|
|
|
14
16
|
def setup
|
|
15
|
-
@connection = ActiveRecord::Base.
|
|
16
|
-
@
|
|
17
|
+
@connection = ActiveRecord::Base.lease_connection
|
|
18
|
+
@original_db_warnings_action = :ignore
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
def test_connection_error
|
|
20
|
-
assert_raises ActiveRecord::ConnectionNotEstablished do
|
|
21
|
-
ActiveRecord::
|
|
22
|
+
error = assert_raises ActiveRecord::ConnectionNotEstablished do
|
|
23
|
+
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.new(host: File::NULL).connect!
|
|
22
24
|
end
|
|
25
|
+
assert_kind_of ActiveRecord::ConnectionAdapters::NullPool, error.connection_pool
|
|
23
26
|
end
|
|
24
27
|
|
|
25
28
|
def test_reconnection_error
|
|
@@ -38,8 +41,12 @@ module ActiveRecord
|
|
|
38
41
|
{}
|
|
39
42
|
end
|
|
40
43
|
|
|
44
|
+
def escape(query)
|
|
45
|
+
PG::Connection.escape(query)
|
|
46
|
+
end
|
|
47
|
+
|
|
41
48
|
def reset
|
|
42
|
-
raise PG::ConnectionBad
|
|
49
|
+
raise PG::ConnectionBad, "I'll be rescued by the reconnect method"
|
|
43
50
|
end
|
|
44
51
|
|
|
45
52
|
def close
|
|
@@ -53,8 +60,14 @@ module ActiveRecord
|
|
|
53
60
|
{ host: File::NULL }
|
|
54
61
|
)
|
|
55
62
|
|
|
56
|
-
|
|
57
|
-
|
|
63
|
+
connect_raises_error = proc { |**_conn_params| raise(PG::ConnectionBad, "actual bad connection error") }
|
|
64
|
+
PG.stub(:connect, connect_raises_error) do
|
|
65
|
+
error = assert_raises ActiveRecord::ConnectionNotEstablished do
|
|
66
|
+
@conn.reconnect!
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
assert_equal("actual bad connection error", error.message)
|
|
70
|
+
assert_equal @conn.pool, error.connection_pool
|
|
58
71
|
end
|
|
59
72
|
end
|
|
60
73
|
|
|
@@ -62,11 +75,103 @@ module ActiveRecord
|
|
|
62
75
|
assert_raise ActiveRecord::NoDatabaseError do
|
|
63
76
|
db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
|
|
64
77
|
configuration = db_config.configuration_hash.merge(database: "should_not_exist-cinco-dog-db")
|
|
65
|
-
connection = ActiveRecord::
|
|
78
|
+
connection = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.new(configuration)
|
|
66
79
|
connection.exec_query("SELECT 1")
|
|
67
80
|
end
|
|
68
81
|
end
|
|
69
82
|
|
|
83
|
+
def test_bad_connection_to_postgres_database
|
|
84
|
+
connect_raises_error = proc { |**_conn_params| raise(PG::ConnectionBad, 'FATAL: database "postgres" does not exist') }
|
|
85
|
+
PG.stub(:connect, connect_raises_error) do
|
|
86
|
+
connection = nil
|
|
87
|
+
error = assert_raises ActiveRecord::ConnectionNotEstablished do
|
|
88
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
|
|
89
|
+
configuration = db_config.configuration_hash.merge(database: "postgres")
|
|
90
|
+
connection = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.new(configuration)
|
|
91
|
+
connection.exec_query("SELECT 1")
|
|
92
|
+
end
|
|
93
|
+
assert_not_nil connection
|
|
94
|
+
assert_equal connection.pool, error.connection_pool
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def test_reconnect_after_bad_connection_on_check_version
|
|
99
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
|
|
100
|
+
connection = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.new(db_config.configuration_hash.merge(connection_retries: 0))
|
|
101
|
+
connection.connect!
|
|
102
|
+
|
|
103
|
+
# mimic a connection that hasn't checked and cached the server version yet i.e. without a raw_connection
|
|
104
|
+
connection.pool.instance_variable_set(:@server_version, nil)
|
|
105
|
+
connection.raw_connection.stub(:server_version, 0) do
|
|
106
|
+
error = assert_raises ActiveRecord::ConnectionFailed do
|
|
107
|
+
connection.reconnect!
|
|
108
|
+
end
|
|
109
|
+
assert_equal "Could not determine PostgreSQL version", error.message
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# can reconnect after a bad connection
|
|
113
|
+
assert_nothing_raised do
|
|
114
|
+
connection.reconnect!
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def test_reconnect_after_bad_connection_on_check_version_with_native_exception
|
|
119
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
|
|
120
|
+
connection = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.new(db_config.configuration_hash.merge(connection_retries: 0))
|
|
121
|
+
connection.connect!
|
|
122
|
+
|
|
123
|
+
# mimic a connection that hasn't checked and cached the server version yet i.e. without a raw_connection
|
|
124
|
+
connection.pool.instance_variable_set(:@server_version, nil)
|
|
125
|
+
# https://github.com/ged/ruby-pg/commit/a565e153d4d05955342ad24d4845378eee956935
|
|
126
|
+
connection.raw_connection.stub(:server_version, -> { raise PG::ConnectionBad, "PQserverVersion() can't get server version" }) do
|
|
127
|
+
error = assert_raises ActiveRecord::ConnectionNotEstablished do
|
|
128
|
+
connection.reconnect!
|
|
129
|
+
end
|
|
130
|
+
assert_equal "PQserverVersion() can't get server version", error.message
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# can reconnect after a bad connection
|
|
134
|
+
assert_nothing_raised do
|
|
135
|
+
connection.reconnect!
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def test_schema_search_path_is_reapplied_after_reconnect
|
|
140
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
|
|
141
|
+
|
|
142
|
+
connection = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.new(
|
|
143
|
+
db_config.configuration_hash.merge(schema_search_path: "public,foo")
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
connection.connect!
|
|
147
|
+
|
|
148
|
+
assert_equal "public, foo", connection.select_value("SHOW search_path")
|
|
149
|
+
|
|
150
|
+
connection.reconnect!
|
|
151
|
+
|
|
152
|
+
assert_equal "public, foo", connection.select_value("SHOW search_path")
|
|
153
|
+
ensure
|
|
154
|
+
connection&.disconnect!
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def test_schema_search_path_is_reapplied_after_reset
|
|
158
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
|
|
159
|
+
|
|
160
|
+
connection = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.new(
|
|
161
|
+
db_config.configuration_hash.merge(schema_search_path: "public,foo")
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
connection.connect!
|
|
165
|
+
|
|
166
|
+
assert_equal "public, foo", connection.select_value("SHOW search_path")
|
|
167
|
+
|
|
168
|
+
connection.reset!
|
|
169
|
+
|
|
170
|
+
assert_equal "public, foo", connection.select_value("SHOW search_path")
|
|
171
|
+
ensure
|
|
172
|
+
connection&.disconnect!
|
|
173
|
+
end
|
|
174
|
+
|
|
70
175
|
def test_database_exists_returns_false_when_the_database_does_not_exist
|
|
71
176
|
config = { database: "non_extant_database", adapter: "postgresql" }
|
|
72
177
|
assert_not ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.database_exists?(config),
|
|
@@ -133,9 +238,11 @@ module ActiveRecord
|
|
|
133
238
|
assert_equal "public.accounts_id_seq",
|
|
134
239
|
@connection.serial_sequence("accounts", "id")
|
|
135
240
|
|
|
136
|
-
assert_raises(ActiveRecord::StatementInvalid) do
|
|
241
|
+
error = assert_raises(ActiveRecord::StatementInvalid) do
|
|
137
242
|
@connection.serial_sequence("zomg", "id")
|
|
138
243
|
end
|
|
244
|
+
|
|
245
|
+
assert_equal @connection.pool, error.connection_pool
|
|
139
246
|
end
|
|
140
247
|
|
|
141
248
|
def test_default_sequence_name
|
|
@@ -292,6 +399,48 @@ module ActiveRecord
|
|
|
292
399
|
end
|
|
293
400
|
end
|
|
294
401
|
|
|
402
|
+
def test_partial_index_on_column_named_like_keyword
|
|
403
|
+
with_example_table('id serial primary key, number integer, "primary" boolean') do
|
|
404
|
+
@connection.add_index "ex", "id", name: "partial", where: "primary" # "primary" is a keyword
|
|
405
|
+
index = @connection.indexes("ex").find { |idx| idx.name == "partial" }
|
|
406
|
+
assert_equal '"primary"', index.where
|
|
407
|
+
end
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
if supports_index_include?
|
|
411
|
+
def test_include_index
|
|
412
|
+
with_example_table do
|
|
413
|
+
@connection.add_index "ex", %w{ id }, name: "include", include: :number
|
|
414
|
+
index = @connection.indexes("ex").find { |idx| idx.name == "include" }
|
|
415
|
+
assert_equal ["number"], index.include
|
|
416
|
+
end
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
def test_include_multiple_columns_index
|
|
420
|
+
with_example_table do
|
|
421
|
+
@connection.add_index "ex", %w{ id }, name: "include", include: [:number, :data]
|
|
422
|
+
index = @connection.indexes("ex").find { |idx| idx.name == "include" }
|
|
423
|
+
assert_equal ["number", "data"], index.include
|
|
424
|
+
end
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
def test_include_keyword_column_name
|
|
428
|
+
with_example_table("id integer, timestamp integer") do
|
|
429
|
+
@connection.add_index "ex", :id, name: "include", include: [:timestamp]
|
|
430
|
+
index = @connection.indexes("ex").find { |idx| idx.name == "include" }
|
|
431
|
+
assert_equal ["timestamp"], index.include
|
|
432
|
+
end
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
def test_include_escaped_quotes_column_name
|
|
436
|
+
with_example_table(%{id integer, "I""like""quotes" integer}) do
|
|
437
|
+
@connection.add_index "ex", :id, name: "include", include: [:"I\"like\"quotes"]
|
|
438
|
+
index = @connection.indexes("ex").find { |idx| idx.name == "include" }
|
|
439
|
+
assert_equal ["I\"like\"quotes"], index.include
|
|
440
|
+
end
|
|
441
|
+
end
|
|
442
|
+
end
|
|
443
|
+
|
|
295
444
|
def test_expression_index
|
|
296
445
|
with_example_table do
|
|
297
446
|
expr = "mod(id, 10), abs(number)"
|
|
@@ -313,6 +462,35 @@ module ActiveRecord
|
|
|
313
462
|
end
|
|
314
463
|
end
|
|
315
464
|
|
|
465
|
+
def test_invalid_index
|
|
466
|
+
with_example_table do
|
|
467
|
+
@connection.exec_query("INSERT INTO ex (number) VALUES (1), (1)")
|
|
468
|
+
error = assert_raises(ActiveRecord::RecordNotUnique) do
|
|
469
|
+
@connection.add_index(:ex, :number, unique: true, algorithm: :concurrently, name: :invalid_index)
|
|
470
|
+
end
|
|
471
|
+
assert_match(/could not create unique index/, error.message)
|
|
472
|
+
assert_equal @connection.pool, error.connection_pool
|
|
473
|
+
|
|
474
|
+
assert @connection.index_exists?(:ex, :number, name: :invalid_index)
|
|
475
|
+
assert_not @connection.index_exists?(:ex, :number, name: :invalid_index, valid: true)
|
|
476
|
+
assert @connection.index_exists?(:ex, :number, name: :invalid_index, valid: false)
|
|
477
|
+
end
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
def test_index_with_not_distinct_nulls
|
|
481
|
+
skip("current adapter doesn't support nulls not distinct") unless supports_nulls_not_distinct?
|
|
482
|
+
|
|
483
|
+
with_example_table do
|
|
484
|
+
@connection.execute(<<~SQL)
|
|
485
|
+
CREATE UNIQUE INDEX index_ex_on_data ON ex (data) NULLS NOT DISTINCT WHERE number > 0
|
|
486
|
+
SQL
|
|
487
|
+
|
|
488
|
+
index = @connection.indexes(:ex).first
|
|
489
|
+
assert_equal true, index.unique
|
|
490
|
+
assert_match("number", index.where)
|
|
491
|
+
end
|
|
492
|
+
end
|
|
493
|
+
|
|
316
494
|
def test_columns_for_distinct_zero_orders
|
|
317
495
|
assert_equal "posts.id",
|
|
318
496
|
@connection.columns_for_distinct("posts.id", [])
|
|
@@ -373,28 +551,53 @@ module ActiveRecord
|
|
|
373
551
|
end
|
|
374
552
|
end
|
|
375
553
|
|
|
554
|
+
def test_translate_no_connection_exception_to_not_established
|
|
555
|
+
pid = @connection.execute("SELECT pg_backend_pid()").to_a[0]["pg_backend_pid"]
|
|
556
|
+
@connection.pool.checkout.execute("SELECT pg_terminate_backend(#{pid})")
|
|
557
|
+
# If you run `@connection.execute` after the backend process has been terminated,
|
|
558
|
+
# you will get the "server closed the connection unexpectedly" rather than "no connection to the server".
|
|
559
|
+
# Because what we want to test here is an error that occurs during `send_query`,
|
|
560
|
+
# which is called internally by `@connection.execute`, we will call it explicitly.
|
|
561
|
+
# The `send_query` changes the internal `PG::Connection#status` to `CONNECTION_BAD`,
|
|
562
|
+
# so any subsequent queries will get the "no connection to the server" error.
|
|
563
|
+
# https://github.com/postgres/postgres/blob/REL_17_0/src/interfaces/libpq/fe-exec.c#L1686-L1691
|
|
564
|
+
@connection.instance_variable_get(:@raw_connection).send_query("SELECT 1")
|
|
565
|
+
|
|
566
|
+
assert_raise ActiveRecord::ConnectionNotEstablished do
|
|
567
|
+
@connection.execute("SELECT 1")
|
|
568
|
+
end
|
|
569
|
+
end
|
|
570
|
+
|
|
376
571
|
def test_reload_type_map_for_newly_defined_types
|
|
377
|
-
@connection.
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
572
|
+
@connection.create_enum "feeling", ["good", "bad"]
|
|
573
|
+
|
|
574
|
+
# Runs only SELECT, no type map reloading.
|
|
575
|
+
assert_queries_count(1, include_schema: true) do
|
|
576
|
+
result = @connection.select_all "SELECT 'good'::feeling"
|
|
577
|
+
assert_instance_of(PostgreSQLAdapter::OID::Enum,
|
|
578
|
+
result.column_types["feeling"])
|
|
579
|
+
end
|
|
381
580
|
ensure
|
|
382
|
-
|
|
581
|
+
# Reloads type map.
|
|
582
|
+
assert_queries_match(/from pg_type/i, include_schema: true) do
|
|
583
|
+
@connection.drop_enum "feeling", if_exists: true
|
|
584
|
+
end
|
|
383
585
|
reset_connection
|
|
384
586
|
end
|
|
385
587
|
|
|
386
588
|
def test_only_reload_type_map_once_for_every_unrecognized_type
|
|
387
589
|
reset_connection
|
|
388
|
-
connection = ActiveRecord::Base.
|
|
590
|
+
connection = ActiveRecord::Base.lease_connection
|
|
591
|
+
connection.select_all "SELECT 1" # eagerly initialize the connection
|
|
389
592
|
|
|
390
593
|
silence_warnings do
|
|
391
|
-
|
|
594
|
+
assert_queries_count(2, include_schema: true) do
|
|
392
595
|
connection.select_all "select 'pg_catalog.pg_class'::regclass"
|
|
393
596
|
end
|
|
394
|
-
|
|
597
|
+
assert_queries_count(1, include_schema: true) do
|
|
395
598
|
connection.select_all "select 'pg_catalog.pg_class'::regclass"
|
|
396
599
|
end
|
|
397
|
-
|
|
600
|
+
assert_queries_count(2, include_schema: true) do
|
|
398
601
|
connection.select_all "SELECT NULL::anyarray"
|
|
399
602
|
end
|
|
400
603
|
end
|
|
@@ -404,7 +607,7 @@ module ActiveRecord
|
|
|
404
607
|
|
|
405
608
|
def test_only_warn_on_first_encounter_of_unrecognized_oid
|
|
406
609
|
reset_connection
|
|
407
|
-
connection = ActiveRecord::Base.
|
|
610
|
+
connection = ActiveRecord::Base.lease_connection
|
|
408
611
|
|
|
409
612
|
warning = capture(:stderr) {
|
|
410
613
|
connection.select_all "select 'pg_catalog.pg_class'::regclass"
|
|
@@ -433,14 +636,194 @@ module ActiveRecord
|
|
|
433
636
|
end
|
|
434
637
|
end
|
|
435
638
|
|
|
639
|
+
def test_only_check_for_insensitive_comparison_capability_once
|
|
640
|
+
@connection.execute("CREATE DOMAIN example_type AS integer")
|
|
641
|
+
|
|
642
|
+
with_example_table "id SERIAL PRIMARY KEY, number example_type" do
|
|
643
|
+
number_klass = Class.new(ActiveRecord::Base) do
|
|
644
|
+
self.table_name = "ex"
|
|
645
|
+
end
|
|
646
|
+
attribute = number_klass.arel_table[:number]
|
|
647
|
+
assert_queries_count(include_schema: true) do
|
|
648
|
+
@connection.case_insensitive_comparison(attribute, "foo")
|
|
649
|
+
end
|
|
650
|
+
assert_no_queries do
|
|
651
|
+
@connection.case_insensitive_comparison(attribute, "foo")
|
|
652
|
+
end
|
|
653
|
+
end
|
|
654
|
+
ensure
|
|
655
|
+
@connection.execute("DROP DOMAIN example_type")
|
|
656
|
+
end
|
|
657
|
+
|
|
658
|
+
def test_extensions_omits_current_schema_name
|
|
659
|
+
@connection.execute("DROP EXTENSION IF EXISTS hstore")
|
|
660
|
+
@connection.execute("CREATE SCHEMA customschema")
|
|
661
|
+
@connection.execute("CREATE EXTENSION hstore SCHEMA customschema")
|
|
662
|
+
assert_includes @connection.extensions, "customschema.hstore"
|
|
663
|
+
ensure
|
|
664
|
+
@connection.execute("DROP SCHEMA IF EXISTS customschema CASCADE")
|
|
665
|
+
@connection.execute("DROP EXTENSION IF EXISTS hstore")
|
|
666
|
+
end
|
|
667
|
+
|
|
668
|
+
def test_extensions_includes_non_current_schema_name
|
|
669
|
+
@connection.execute("DROP EXTENSION IF EXISTS hstore")
|
|
670
|
+
@connection.execute("CREATE EXTENSION hstore")
|
|
671
|
+
assert_includes @connection.extensions, "hstore"
|
|
672
|
+
ensure
|
|
673
|
+
@connection.execute("DROP EXTENSION IF EXISTS hstore")
|
|
674
|
+
end
|
|
675
|
+
|
|
676
|
+
def test_ignores_warnings_when_behaviour_ignore
|
|
677
|
+
with_db_warnings_action(:ignore) do
|
|
678
|
+
# libpq prints a warning to stderr from C, so we need to stub
|
|
679
|
+
# the whole file descriptors, not just Ruby's $stdout/$stderr.
|
|
680
|
+
_out, err = capture_subprocess_io do
|
|
681
|
+
result = @connection.execute("do $$ BEGIN RAISE WARNING 'foo'; END; $$")
|
|
682
|
+
assert_equal [], result.to_a
|
|
683
|
+
end
|
|
684
|
+
assert_match(/WARNING: foo/, err)
|
|
685
|
+
end
|
|
686
|
+
end
|
|
687
|
+
|
|
688
|
+
def test_logs_warnings_when_behaviour_log
|
|
689
|
+
with_db_warnings_action(:log) do
|
|
690
|
+
sql_warning = "[ActiveRecord::SQLWarning] PostgreSQL SQL warning (01000)"
|
|
691
|
+
|
|
692
|
+
assert_called_with(ActiveRecord::Base.logger, :warn, [sql_warning]) do
|
|
693
|
+
@connection.execute("do $$ BEGIN RAISE WARNING 'PostgreSQL SQL warning'; END; $$")
|
|
694
|
+
end
|
|
695
|
+
end
|
|
696
|
+
end
|
|
697
|
+
|
|
698
|
+
def test_raises_warnings_when_behaviour_raise
|
|
699
|
+
with_db_warnings_action(:raise) do
|
|
700
|
+
error = assert_raises(ActiveRecord::SQLWarning) do
|
|
701
|
+
@connection.execute("do $$ BEGIN RAISE WARNING 'PostgreSQL SQL warning'; END; $$")
|
|
702
|
+
end
|
|
703
|
+
assert_equal @connection.pool, error.connection_pool
|
|
704
|
+
end
|
|
705
|
+
end
|
|
706
|
+
|
|
707
|
+
def test_reports_when_behaviour_report
|
|
708
|
+
with_db_warnings_action(:report) do
|
|
709
|
+
error_reporter = ActiveSupport::ErrorReporter.new
|
|
710
|
+
subscriber = ActiveSupport::ErrorReporter::TestHelper::ErrorSubscriber.new
|
|
711
|
+
|
|
712
|
+
Rails.define_singleton_method(:error) { error_reporter }
|
|
713
|
+
Rails.error.subscribe(subscriber)
|
|
714
|
+
|
|
715
|
+
@connection.execute("do $$ BEGIN RAISE WARNING 'PostgreSQL SQL warning'; END; $$")
|
|
716
|
+
warning_event, * = subscriber.events.first
|
|
717
|
+
|
|
718
|
+
assert_kind_of ActiveRecord::SQLWarning, warning_event
|
|
719
|
+
assert_equal "PostgreSQL SQL warning", warning_event.message
|
|
720
|
+
end
|
|
721
|
+
end
|
|
722
|
+
|
|
723
|
+
def test_warnings_behaviour_can_be_customized_with_a_proc
|
|
724
|
+
warning_message = nil
|
|
725
|
+
warning_level = nil
|
|
726
|
+
warning_action = ->(warning) do
|
|
727
|
+
warning_message = warning.message
|
|
728
|
+
warning_level = warning.level
|
|
729
|
+
end
|
|
730
|
+
|
|
731
|
+
with_db_warnings_action(warning_action) do
|
|
732
|
+
@connection.execute("do $$ BEGIN RAISE WARNING 'PostgreSQL SQL warning'; END; $$")
|
|
733
|
+
|
|
734
|
+
assert_equal "PostgreSQL SQL warning", warning_message
|
|
735
|
+
assert_equal "WARNING", warning_level
|
|
736
|
+
end
|
|
737
|
+
end
|
|
738
|
+
|
|
739
|
+
def test_allowlist_of_warnings_to_ignore
|
|
740
|
+
with_db_warnings_action(:raise, [/PostgreSQL SQL warning/]) do
|
|
741
|
+
result = @connection.execute("do $$ BEGIN RAISE WARNING 'PostgreSQL SQL warning'; END; $$")
|
|
742
|
+
|
|
743
|
+
assert_equal [], result.to_a
|
|
744
|
+
end
|
|
745
|
+
end
|
|
746
|
+
|
|
747
|
+
def test_allowlist_of_warning_codes_to_ignore
|
|
748
|
+
with_example_table do
|
|
749
|
+
with_db_warnings_action(:raise, ["01000"]) do
|
|
750
|
+
result = @connection.execute("do $$ BEGIN RAISE WARNING 'PostgreSQL SQL warning'; END; $$")
|
|
751
|
+
assert_equal [], result.to_a
|
|
752
|
+
end
|
|
753
|
+
end
|
|
754
|
+
end
|
|
755
|
+
|
|
756
|
+
def test_does_not_raise_notice_level_warnings
|
|
757
|
+
with_db_warnings_action(:raise, [/PostgreSQL SQL warning/]) do
|
|
758
|
+
result = @connection.execute("DROP TABLE IF EXISTS non_existent_table")
|
|
759
|
+
|
|
760
|
+
assert_equal [], result.to_a
|
|
761
|
+
end
|
|
762
|
+
end
|
|
763
|
+
|
|
764
|
+
def test_date_decoding_enabled
|
|
765
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
|
|
766
|
+
connection = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.new(db_config.configuration_hash)
|
|
767
|
+
|
|
768
|
+
with_postgresql_apdater_decode_dates do
|
|
769
|
+
date = connection.select_value("select '2024-01-01'::date")
|
|
770
|
+
assert_equal Date.new(2024, 01, 01), date
|
|
771
|
+
assert_equal Date, date.class
|
|
772
|
+
end
|
|
773
|
+
end
|
|
774
|
+
|
|
775
|
+
def test_date_decoding_disabled
|
|
776
|
+
db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
|
|
777
|
+
connection = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.new(db_config.configuration_hash)
|
|
778
|
+
|
|
779
|
+
date = connection.select_value("select '2024-01-01'::date")
|
|
780
|
+
assert_equal "2024-01-01", date
|
|
781
|
+
assert_equal String, date.class
|
|
782
|
+
end
|
|
783
|
+
|
|
784
|
+
def test_disable_extension_with_schema
|
|
785
|
+
@connection.execute("CREATE SCHEMA custom_schema")
|
|
786
|
+
@connection.execute("DROP EXTENSION IF EXISTS hstore")
|
|
787
|
+
@connection.execute("CREATE EXTENSION hstore SCHEMA custom_schema")
|
|
788
|
+
result = @connection.query("SELECT extname FROM pg_extension WHERE extnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'custom_schema')")
|
|
789
|
+
assert_equal [["hstore"]], result.to_a
|
|
790
|
+
|
|
791
|
+
@connection.disable_extension "custom_schema.hstore"
|
|
792
|
+
result = @connection.query("SELECT extname FROM pg_extension WHERE extnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'custom_schema')")
|
|
793
|
+
assert_equal [], result.to_a
|
|
794
|
+
ensure
|
|
795
|
+
@connection.execute("DROP EXTENSION IF EXISTS hstore")
|
|
796
|
+
@connection.execute("DROP SCHEMA IF EXISTS custom_schema CASCADE")
|
|
797
|
+
end
|
|
798
|
+
|
|
799
|
+
def test_disable_extension_without_schema
|
|
800
|
+
@connection.execute("DROP EXTENSION IF EXISTS hstore")
|
|
801
|
+
@connection.execute("CREATE EXTENSION hstore")
|
|
802
|
+
result = @connection.query("SELECT extname FROM pg_extension")
|
|
803
|
+
assert_includes result.to_a, ["hstore"]
|
|
804
|
+
|
|
805
|
+
@connection.disable_extension "hstore"
|
|
806
|
+
result = @connection.query("SELECT extname FROM pg_extension")
|
|
807
|
+
assert_not_includes result.to_a, ["hstore"]
|
|
808
|
+
ensure
|
|
809
|
+
@connection.execute("DROP EXTENSION IF EXISTS hstore")
|
|
810
|
+
end
|
|
811
|
+
|
|
436
812
|
private
|
|
813
|
+
def with_postgresql_apdater_decode_dates
|
|
814
|
+
PostgreSQLAdapter.decode_dates = true
|
|
815
|
+
yield
|
|
816
|
+
ensure
|
|
817
|
+
PostgreSQLAdapter.decode_dates = false
|
|
818
|
+
end
|
|
819
|
+
|
|
437
820
|
def with_example_table(definition = "id serial primary key, number integer, data character varying(255)", &block)
|
|
438
821
|
super(@connection, "ex", definition, &block)
|
|
439
822
|
end
|
|
440
823
|
|
|
441
824
|
def connection_without_insert_returning
|
|
442
825
|
db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
|
|
443
|
-
ActiveRecord::
|
|
826
|
+
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.new(db_config.configuration_hash.merge(insert_returning: false))
|
|
444
827
|
end
|
|
445
828
|
end
|
|
446
829
|
end
|