activerecord 6.0.0 → 7.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +996 -594
- data/MIT-LICENSE +1 -1
- data/README.rdoc +34 -34
- data/examples/performance.rb +2 -2
- data/lib/active_record/aggregations.rb +22 -20
- data/lib/active_record/association_relation.rb +22 -12
- data/lib/active_record/associations/alias_tracker.rb +41 -30
- data/lib/active_record/associations/association.rb +106 -41
- data/lib/active_record/associations/association_scope.rb +30 -21
- data/lib/active_record/associations/belongs_to_association.rb +69 -14
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +20 -6
- data/lib/active_record/associations/builder/association.rb +39 -6
- data/lib/active_record/associations/builder/belongs_to.rb +47 -17
- data/lib/active_record/associations/builder/collection_association.rb +14 -6
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -10
- data/lib/active_record/associations/builder/has_many.rb +7 -3
- data/lib/active_record/associations/builder/has_one.rb +13 -16
- data/lib/active_record/associations/builder/singular_association.rb +7 -3
- data/lib/active_record/associations/collection_association.rb +90 -53
- data/lib/active_record/associations/collection_proxy.rb +54 -19
- data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
- data/lib/active_record/associations/errors.rb +265 -0
- data/lib/active_record/associations/foreign_association.rb +21 -1
- data/lib/active_record/associations/has_many_association.rb +41 -10
- data/lib/active_record/associations/has_many_through_association.rb +29 -12
- data/lib/active_record/associations/has_one_association.rb +33 -9
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +41 -17
- data/lib/active_record/associations/join_dependency/join_part.rb +3 -3
- data/lib/active_record/associations/join_dependency.rb +97 -54
- data/lib/active_record/associations/nested_error.rb +47 -0
- data/lib/active_record/associations/preloader/association.rb +237 -54
- data/lib/active_record/associations/preloader/batch.rb +48 -0
- data/lib/active_record/associations/preloader/branch.rb +153 -0
- data/lib/active_record/associations/preloader/through_association.rb +51 -17
- data/lib/active_record/associations/preloader.rb +55 -121
- data/lib/active_record/associations/singular_association.rb +16 -4
- data/lib/active_record/associations/through_association.rb +26 -15
- data/lib/active_record/associations.rb +454 -440
- data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
- data/lib/active_record/attribute_assignment.rb +11 -14
- data/lib/active_record/attribute_methods/before_type_cast.rb +36 -11
- data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
- data/lib/active_record/attribute_methods/dirty.rb +75 -34
- data/lib/active_record/attribute_methods/primary_key.rb +53 -31
- data/lib/active_record/attribute_methods/query.rb +31 -22
- data/lib/active_record/attribute_methods/read.rb +16 -17
- data/lib/active_record/attribute_methods/serialization.rb +177 -35
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +18 -15
- data/lib/active_record/attribute_methods/write.rb +16 -28
- data/lib/active_record/attribute_methods.rb +227 -100
- data/lib/active_record/attributes.rb +94 -56
- data/lib/active_record/autosave_association.rb +119 -73
- data/lib/active_record/base.rb +31 -21
- data/lib/active_record/callbacks.rb +168 -55
- data/lib/active_record/coders/column_serializer.rb +61 -0
- data/lib/active_record/coders/json.rb +1 -1
- data/lib/active_record/coders/yaml_column.rb +70 -25
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +284 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +211 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +79 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +367 -565
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +3 -57
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +277 -89
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +241 -69
- data/lib/active_record/connection_adapters/abstract/quoting.rb +122 -134
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -116
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +324 -72
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +17 -4
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +611 -211
- data/lib/active_record/connection_adapters/abstract/transaction.rb +425 -82
- data/lib/active_record/connection_adapters/abstract_adapter.rb +698 -211
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +464 -239
- data/lib/active_record/connection_adapters/column.rb +28 -1
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +32 -137
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
- data/lib/active_record/connection_adapters/mysql/quoting.rb +90 -43
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +41 -7
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +18 -1
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +13 -4
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +53 -15
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +152 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +127 -63
- data/lib/active_record/connection_adapters/pool_config.rb +83 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +57 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +54 -2
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +127 -100
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +9 -5
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +10 -2
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +15 -2
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -15
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +5 -4
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +35 -8
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +23 -4
- data/lib/active_record/connection_adapters/postgresql/oid.rb +4 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +139 -106
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +30 -2
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +98 -4
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +176 -4
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +78 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +462 -118
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -11
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +585 -295
- data/lib/active_record/connection_adapters/schema_cache.rb +399 -60
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +8 -0
- data/lib/active_record/connection_adapters/sqlite3/column.rb +62 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +99 -48
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +80 -54
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +27 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +20 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +102 -24
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +425 -174
- data/lib/active_record/connection_adapters/statement_pool.rb +7 -1
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +229 -0
- data/lib/active_record/connection_adapters.rb +176 -0
- data/lib/active_record/connection_handling.rb +243 -115
- data/lib/active_record/core.rb +481 -199
- data/lib/active_record/counter_cache.rb +69 -32
- data/lib/active_record/database_configurations/connection_url_resolver.rb +107 -0
- data/lib/active_record/database_configurations/database_config.rb +77 -10
- data/lib/active_record/database_configurations/hash_config.rb +148 -26
- data/lib/active_record/database_configurations/url_config.rb +44 -45
- data/lib/active_record/database_configurations.rb +190 -114
- data/lib/active_record/delegated_type.rb +279 -0
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +38 -0
- data/lib/active_record/disable_joins_association_relation.rb +39 -0
- data/lib/active_record/dynamic_matchers.rb +5 -6
- data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
- data/lib/active_record/encryption/cipher.rb +53 -0
- data/lib/active_record/encryption/config.rb +68 -0
- data/lib/active_record/encryption/configurable.rb +60 -0
- data/lib/active_record/encryption/context.rb +42 -0
- data/lib/active_record/encryption/contexts.rb +76 -0
- data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
- data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
- data/lib/active_record/encryption/encryptable_record.rb +230 -0
- data/lib/active_record/encryption/encrypted_attribute_type.rb +175 -0
- data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
- data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
- data/lib/active_record/encryption/encryptor.rb +171 -0
- data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
- data/lib/active_record/encryption/errors.rb +15 -0
- data/lib/active_record/encryption/extended_deterministic_queries.rb +157 -0
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
- data/lib/active_record/encryption/key.rb +28 -0
- data/lib/active_record/encryption/key_generator.rb +53 -0
- data/lib/active_record/encryption/key_provider.rb +46 -0
- data/lib/active_record/encryption/message.rb +33 -0
- data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
- data/lib/active_record/encryption/message_serializer.rb +96 -0
- data/lib/active_record/encryption/null_encryptor.rb +25 -0
- data/lib/active_record/encryption/properties.rb +76 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +28 -0
- data/lib/active_record/encryption/scheme.rb +100 -0
- data/lib/active_record/encryption.rb +58 -0
- data/lib/active_record/enum.rb +224 -73
- data/lib/active_record/errors.rb +254 -36
- data/lib/active_record/explain.rb +30 -17
- data/lib/active_record/explain_registry.rb +11 -6
- data/lib/active_record/explain_subscriber.rb +2 -2
- data/lib/active_record/fixture_set/file.rb +22 -15
- data/lib/active_record/fixture_set/model_metadata.rb +15 -6
- data/lib/active_record/fixture_set/render_context.rb +3 -1
- data/lib/active_record/fixture_set/table_row.rb +88 -16
- data/lib/active_record/fixture_set/table_rows.rb +4 -5
- data/lib/active_record/fixtures.rb +229 -116
- data/lib/active_record/future_result.rb +178 -0
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +121 -48
- data/lib/active_record/insert_all.rb +178 -29
- data/lib/active_record/integration.rb +16 -14
- data/lib/active_record/internal_metadata.rb +132 -21
- data/lib/active_record/legacy_yaml_adapter.rb +3 -36
- data/lib/active_record/locking/optimistic.rb +64 -33
- data/lib/active_record/locking/pessimistic.rb +21 -8
- data/lib/active_record/log_subscriber.rb +61 -30
- data/lib/active_record/marshalling.rb +59 -0
- data/lib/active_record/message_pack.rb +124 -0
- data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +19 -19
- data/lib/active_record/middleware/database_selector.rb +25 -13
- data/lib/active_record/middleware/shard_selector.rb +62 -0
- data/lib/active_record/migration/command_recorder.rb +160 -55
- data/lib/active_record/migration/compatibility.rb +286 -43
- data/lib/active_record/migration/default_strategy.rb +22 -0
- data/lib/active_record/migration/execution_strategy.rb +19 -0
- data/lib/active_record/migration/join_table.rb +1 -2
- data/lib/active_record/migration/pending_migration_connection.rb +21 -0
- data/lib/active_record/migration.rb +421 -193
- data/lib/active_record/model_schema.rb +217 -125
- data/lib/active_record/nested_attributes.rb +62 -27
- data/lib/active_record/no_touching.rb +4 -4
- data/lib/active_record/normalization.rb +163 -0
- data/lib/active_record/persistence.rb +322 -319
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +18 -15
- data/lib/active_record/query_logs.rb +193 -0
- data/lib/active_record/query_logs_formatter.rb +41 -0
- data/lib/active_record/querying.rb +54 -14
- data/lib/active_record/railtie.rb +250 -72
- data/lib/active_record/railties/console_sandbox.rb +2 -4
- data/lib/active_record/railties/controller_runtime.rb +25 -11
- data/lib/active_record/railties/databases.rake +312 -197
- data/lib/active_record/railties/job_runtime.rb +23 -0
- data/lib/active_record/readonly_attributes.rb +45 -3
- data/lib/active_record/reflection.rb +389 -146
- data/lib/active_record/relation/batches/batch_enumerator.rb +61 -16
- data/lib/active_record/relation/batches.rb +214 -73
- data/lib/active_record/relation/calculations.rb +379 -124
- data/lib/active_record/relation/delegation.rb +36 -23
- data/lib/active_record/relation/finder_methods.rb +159 -49
- data/lib/active_record/relation/from_clause.rb +5 -1
- data/lib/active_record/relation/merger.rb +41 -33
- data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -11
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -7
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +20 -13
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
- data/lib/active_record/relation/predicate_builder.rb +79 -53
- data/lib/active_record/relation/query_attribute.rb +30 -12
- data/lib/active_record/relation/query_methods.rb +1156 -279
- data/lib/active_record/relation/record_fetch_warning.rb +12 -11
- data/lib/active_record/relation/spawn_methods.rb +10 -9
- data/lib/active_record/relation/where_clause.rb +100 -66
- data/lib/active_record/relation.rb +829 -194
- data/lib/active_record/result.rb +76 -56
- data/lib/active_record/runtime_registry.rb +71 -13
- data/lib/active_record/sanitization.rb +86 -47
- data/lib/active_record/schema.rb +39 -23
- data/lib/active_record/schema_dumper.rb +140 -33
- data/lib/active_record/schema_migration.rb +74 -29
- data/lib/active_record/scoping/default.rb +73 -19
- data/lib/active_record/scoping/named.rb +10 -28
- data/lib/active_record/scoping.rb +65 -35
- data/lib/active_record/secure_password.rb +60 -0
- data/lib/active_record/secure_token.rb +34 -8
- data/lib/active_record/serialization.rb +11 -4
- data/lib/active_record/signed_id.rb +138 -0
- data/lib/active_record/statement_cache.rb +26 -10
- data/lib/active_record/store.rb +19 -14
- data/lib/active_record/suppressor.rb +15 -17
- data/lib/active_record/table_metadata.rb +46 -36
- data/lib/active_record/tasks/database_tasks.rb +371 -205
- data/lib/active_record/tasks/mysql_database_tasks.rb +43 -36
- data/lib/active_record/tasks/postgresql_database_tasks.rb +54 -41
- data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -13
- data/lib/active_record/test_databases.rb +5 -4
- data/lib/active_record/test_fixtures.rb +189 -104
- data/lib/active_record/testing/query_assertions.rb +121 -0
- data/lib/active_record/timestamp.rb +35 -25
- data/lib/active_record/token_for.rb +123 -0
- data/lib/active_record/touch_later.rb +31 -27
- data/lib/active_record/transaction.rb +132 -0
- data/lib/active_record/transactions.rb +131 -99
- data/lib/active_record/translation.rb +3 -5
- data/lib/active_record/type/adapter_specific_registry.rb +33 -18
- data/lib/active_record/type/hash_lookup_type_map.rb +34 -2
- data/lib/active_record/type/internal/timezone.rb +7 -2
- data/lib/active_record/type/serialized.rb +11 -6
- data/lib/active_record/type/time.rb +14 -0
- data/lib/active_record/type/type_map.rb +17 -21
- data/lib/active_record/type/unsigned_integer.rb +0 -1
- data/lib/active_record/type.rb +7 -2
- data/lib/active_record/type_caster/connection.rb +4 -5
- data/lib/active_record/type_caster/map.rb +8 -5
- data/lib/active_record/validations/absence.rb +1 -1
- data/lib/active_record/validations/associated.rb +13 -8
- data/lib/active_record/validations/numericality.rb +36 -0
- data/lib/active_record/validations/presence.rb +5 -28
- data/lib/active_record/validations/uniqueness.rb +88 -18
- data/lib/active_record/validations.rb +15 -8
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +446 -40
- data/lib/arel/alias_predication.rb +1 -1
- data/lib/arel/attributes/attribute.rb +4 -8
- data/lib/arel/collectors/bind.rb +8 -1
- data/lib/arel/collectors/composite.rb +15 -0
- data/lib/arel/collectors/sql_string.rb +7 -0
- data/lib/arel/collectors/substitute_binds.rb +7 -0
- data/lib/arel/crud.rb +30 -22
- data/lib/arel/delete_manager.rb +23 -4
- data/lib/arel/errors.rb +10 -0
- data/lib/arel/factory_methods.rb +4 -0
- data/lib/arel/filter_predications.rb +9 -0
- data/lib/arel/insert_manager.rb +2 -3
- data/lib/arel/nodes/binary.rb +82 -9
- data/lib/arel/nodes/bind_param.rb +8 -0
- data/lib/arel/nodes/bound_sql_literal.rb +65 -0
- data/lib/arel/nodes/casted.rb +22 -10
- data/lib/arel/nodes/cte.rb +36 -0
- data/lib/arel/nodes/delete_statement.rb +14 -13
- data/lib/arel/nodes/equality.rb +6 -9
- data/lib/arel/nodes/filter.rb +10 -0
- data/lib/arel/nodes/fragments.rb +35 -0
- data/lib/arel/nodes/function.rb +1 -0
- data/lib/arel/nodes/grouping.rb +3 -0
- data/lib/arel/nodes/homogeneous_in.rb +68 -0
- data/lib/arel/nodes/in.rb +8 -1
- data/lib/arel/nodes/infix_operation.rb +13 -1
- data/lib/arel/nodes/insert_statement.rb +2 -2
- data/lib/arel/nodes/join_source.rb +1 -1
- data/lib/arel/nodes/leading_join.rb +8 -0
- data/lib/arel/nodes/{and.rb → nary.rb} +9 -2
- data/lib/arel/nodes/node.rb +122 -11
- data/lib/arel/nodes/ordering.rb +27 -0
- data/lib/arel/nodes/select_core.rb +2 -2
- data/lib/arel/nodes/select_statement.rb +2 -2
- data/lib/arel/nodes/sql_literal.rb +16 -0
- data/lib/arel/nodes/table_alias.rb +11 -3
- data/lib/arel/nodes/unary.rb +0 -1
- data/lib/arel/nodes/update_statement.rb +11 -4
- data/lib/arel/nodes.rb +10 -3
- data/lib/arel/predications.rb +31 -28
- data/lib/arel/select_manager.rb +18 -9
- data/lib/arel/table.rb +21 -10
- data/lib/arel/tree_manager.rb +8 -15
- data/lib/arel/update_manager.rb +25 -5
- data/lib/arel/visitors/dot.rb +94 -90
- data/lib/arel/visitors/mysql.rb +34 -6
- data/lib/arel/visitors/postgresql.rb +5 -16
- data/lib/arel/visitors/sqlite.rb +25 -1
- data/lib/arel/visitors/to_sql.rb +227 -81
- data/lib/arel/visitors/visitor.rb +2 -3
- data/lib/arel/visitors.rb +0 -7
- data/lib/arel.rb +37 -15
- data/lib/rails/generators/active_record/application_record/USAGE +8 -0
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
- data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +6 -1
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -4
- data/lib/rails/generators/active_record/migration.rb +9 -3
- data/lib/rails/generators/active_record/model/USAGE +113 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +49 -4
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
- data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
- data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
- metadata +117 -30
- data/lib/active_record/attribute_decorators.rb +0 -90
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -297
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
- data/lib/active_record/define_callbacks.rb +0 -22
- data/lib/active_record/null_relation.rb +0 -68
- data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
- data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
- data/lib/active_record/relation/where_clause_factory.rb +0 -33
- data/lib/arel/attributes.rb +0 -22
- data/lib/arel/visitors/depth_first.rb +0 -204
- data/lib/arel/visitors/ibm_db.rb +0 -34
- data/lib/arel/visitors/informix.rb +0 -62
- data/lib/arel/visitors/mssql.rb +0 -157
- data/lib/arel/visitors/oracle.rb +0 -159
- data/lib/arel/visitors/oracle12.rb +0 -66
- data/lib/arel/visitors/where_sql.rb +0 -23
data/lib/arel/visitors/to_sql.rb
CHANGED
|
@@ -19,8 +19,8 @@ module Arel # :nodoc: all
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
private
|
|
22
|
-
|
|
23
22
|
def visit_Arel_Nodes_DeleteStatement(o, collector)
|
|
23
|
+
collector.retryable = false
|
|
24
24
|
o = prepare_delete_statement(o)
|
|
25
25
|
|
|
26
26
|
if has_join_sources?(o)
|
|
@@ -35,9 +35,11 @@ module Arel # :nodoc: all
|
|
|
35
35
|
collect_nodes_for o.wheres, collector, " WHERE ", " AND "
|
|
36
36
|
collect_nodes_for o.orders, collector, " ORDER BY "
|
|
37
37
|
maybe_visit o.limit, collector
|
|
38
|
+
maybe_visit o.comment, collector
|
|
38
39
|
end
|
|
39
40
|
|
|
40
41
|
def visit_Arel_Nodes_UpdateStatement(o, collector)
|
|
42
|
+
collector.retryable = false
|
|
41
43
|
o = prepare_update_statement(o)
|
|
42
44
|
|
|
43
45
|
collector << "UPDATE "
|
|
@@ -47,9 +49,11 @@ module Arel # :nodoc: all
|
|
|
47
49
|
collect_nodes_for o.wheres, collector, " WHERE ", " AND "
|
|
48
50
|
collect_nodes_for o.orders, collector, " ORDER BY "
|
|
49
51
|
maybe_visit o.limit, collector
|
|
52
|
+
maybe_visit o.comment, collector
|
|
50
53
|
end
|
|
51
54
|
|
|
52
55
|
def visit_Arel_Nodes_InsertStatement(o, collector)
|
|
56
|
+
collector.retryable = false
|
|
53
57
|
collector << "INSERT INTO "
|
|
54
58
|
collector = visit o.relation, collector
|
|
55
59
|
|
|
@@ -83,12 +87,9 @@ module Arel # :nodoc: all
|
|
|
83
87
|
end
|
|
84
88
|
|
|
85
89
|
def visit_Arel_Nodes_Casted(o, collector)
|
|
86
|
-
collector <<
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def visit_Arel_Nodes_Quoted(o, collector)
|
|
90
|
-
collector << quoted(o.expr, nil).to_s
|
|
90
|
+
collector << quote(o.value_for_database).to_s
|
|
91
91
|
end
|
|
92
|
+
alias :visit_Arel_Nodes_Quoted :visit_Arel_Nodes_Casted
|
|
92
93
|
|
|
93
94
|
def visit_Arel_Nodes_True(o, collector)
|
|
94
95
|
collector << "TRUE"
|
|
@@ -107,7 +108,7 @@ module Arel # :nodoc: all
|
|
|
107
108
|
row.each_with_index do |value, k|
|
|
108
109
|
collector << ", " unless k == 0
|
|
109
110
|
case value
|
|
110
|
-
when Nodes::SqlLiteral, Nodes::BindParam
|
|
111
|
+
when Nodes::SqlLiteral, Nodes::BindParam, ActiveModel::Attribute
|
|
111
112
|
collector = visit(value, collector)
|
|
112
113
|
else
|
|
113
114
|
collector << quote(value).to_s
|
|
@@ -139,6 +140,8 @@ module Arel # :nodoc: all
|
|
|
139
140
|
visit_Arel_Nodes_SelectOptions(o, collector)
|
|
140
141
|
end
|
|
141
142
|
|
|
143
|
+
# The Oracle enhanced adapter uses this private method,
|
|
144
|
+
# see https://github.com/rsim/oracle-enhanced/issues/2186
|
|
142
145
|
def visit_Arel_Nodes_SelectOptions(o, collector)
|
|
143
146
|
collector = maybe_visit o.limit, collector
|
|
144
147
|
collector = maybe_visit o.offset, collector
|
|
@@ -196,12 +199,12 @@ module Arel # :nodoc: all
|
|
|
196
199
|
|
|
197
200
|
def visit_Arel_Nodes_With(o, collector)
|
|
198
201
|
collector << "WITH "
|
|
199
|
-
|
|
202
|
+
collect_ctes(o.children, collector)
|
|
200
203
|
end
|
|
201
204
|
|
|
202
205
|
def visit_Arel_Nodes_WithRecursive(o, collector)
|
|
203
206
|
collector << "WITH RECURSIVE "
|
|
204
|
-
|
|
207
|
+
collect_ctes(o.children, collector)
|
|
205
208
|
end
|
|
206
209
|
|
|
207
210
|
def visit_Arel_Nodes_Union(o, collector)
|
|
@@ -247,6 +250,13 @@ module Arel # :nodoc: all
|
|
|
247
250
|
collector << ")"
|
|
248
251
|
end
|
|
249
252
|
|
|
253
|
+
def visit_Arel_Nodes_Filter(o, collector)
|
|
254
|
+
visit o.left, collector
|
|
255
|
+
collector << " FILTER (WHERE "
|
|
256
|
+
visit o.right, collector
|
|
257
|
+
collector << ")"
|
|
258
|
+
end
|
|
259
|
+
|
|
250
260
|
def visit_Arel_Nodes_Rows(o, collector)
|
|
251
261
|
if o.expr
|
|
252
262
|
collector << "ROWS "
|
|
@@ -325,6 +335,28 @@ module Arel # :nodoc: all
|
|
|
325
335
|
end
|
|
326
336
|
end
|
|
327
337
|
|
|
338
|
+
def visit_Arel_Nodes_HomogeneousIn(o, collector)
|
|
339
|
+
collector.preparable = false
|
|
340
|
+
|
|
341
|
+
visit o.left, collector
|
|
342
|
+
|
|
343
|
+
if o.type == :in
|
|
344
|
+
collector << " IN ("
|
|
345
|
+
else
|
|
346
|
+
collector << " NOT IN ("
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
values = o.casted_values
|
|
350
|
+
|
|
351
|
+
if values.empty?
|
|
352
|
+
collector << @connection.quote(nil)
|
|
353
|
+
else
|
|
354
|
+
collector.add_binds(values, o.proc_for_binds, &bind_block)
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
collector << ")"
|
|
358
|
+
end
|
|
359
|
+
|
|
328
360
|
def visit_Arel_SelectManager(o, collector)
|
|
329
361
|
collector << "("
|
|
330
362
|
visit(o.ast, collector) << ")"
|
|
@@ -338,11 +370,23 @@ module Arel # :nodoc: all
|
|
|
338
370
|
visit(o.expr, collector) << " DESC"
|
|
339
371
|
end
|
|
340
372
|
|
|
373
|
+
# NullsFirst is available on all but MySQL, where it is redefined.
|
|
374
|
+
def visit_Arel_Nodes_NullsFirst(o, collector)
|
|
375
|
+
visit o.expr, collector
|
|
376
|
+
collector << " NULLS FIRST"
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
def visit_Arel_Nodes_NullsLast(o, collector)
|
|
380
|
+
visit o.expr, collector
|
|
381
|
+
collector << " NULLS LAST"
|
|
382
|
+
end
|
|
383
|
+
|
|
341
384
|
def visit_Arel_Nodes_Group(o, collector)
|
|
342
385
|
visit o.expr, collector
|
|
343
386
|
end
|
|
344
387
|
|
|
345
388
|
def visit_Arel_Nodes_NamedFunction(o, collector)
|
|
389
|
+
collector.retryable = false
|
|
346
390
|
collector << o.name
|
|
347
391
|
collector << "("
|
|
348
392
|
collector << "DISTINCT " if o.distinct
|
|
@@ -393,24 +437,48 @@ module Arel # :nodoc: all
|
|
|
393
437
|
end
|
|
394
438
|
|
|
395
439
|
def visit_Arel_Nodes_GreaterThanOrEqual(o, collector)
|
|
440
|
+
case unboundable?(o.right)
|
|
441
|
+
when 1
|
|
442
|
+
return collector << "1=0"
|
|
443
|
+
when -1
|
|
444
|
+
return collector << "1=1"
|
|
445
|
+
end
|
|
396
446
|
collector = visit o.left, collector
|
|
397
447
|
collector << " >= "
|
|
398
448
|
visit o.right, collector
|
|
399
449
|
end
|
|
400
450
|
|
|
401
451
|
def visit_Arel_Nodes_GreaterThan(o, collector)
|
|
452
|
+
case unboundable?(o.right)
|
|
453
|
+
when 1
|
|
454
|
+
return collector << "1=0"
|
|
455
|
+
when -1
|
|
456
|
+
return collector << "1=1"
|
|
457
|
+
end
|
|
402
458
|
collector = visit o.left, collector
|
|
403
459
|
collector << " > "
|
|
404
460
|
visit o.right, collector
|
|
405
461
|
end
|
|
406
462
|
|
|
407
463
|
def visit_Arel_Nodes_LessThanOrEqual(o, collector)
|
|
464
|
+
case unboundable?(o.right)
|
|
465
|
+
when 1
|
|
466
|
+
return collector << "1=1"
|
|
467
|
+
when -1
|
|
468
|
+
return collector << "1=0"
|
|
469
|
+
end
|
|
408
470
|
collector = visit o.left, collector
|
|
409
471
|
collector << " <= "
|
|
410
472
|
visit o.right, collector
|
|
411
473
|
end
|
|
412
474
|
|
|
413
475
|
def visit_Arel_Nodes_LessThan(o, collector)
|
|
476
|
+
case unboundable?(o.right)
|
|
477
|
+
when 1
|
|
478
|
+
return collector << "1=1"
|
|
479
|
+
when -1
|
|
480
|
+
return collector << "1=0"
|
|
481
|
+
end
|
|
414
482
|
collector = visit o.left, collector
|
|
415
483
|
collector << " < "
|
|
416
484
|
visit o.right, collector
|
|
@@ -506,72 +574,51 @@ module Arel # :nodoc: all
|
|
|
506
574
|
end
|
|
507
575
|
|
|
508
576
|
def visit_Arel_Table(o, collector)
|
|
509
|
-
if o.
|
|
510
|
-
|
|
577
|
+
if Arel::Nodes::Node === o.name
|
|
578
|
+
visit o.name, collector
|
|
511
579
|
else
|
|
512
580
|
collector << quote_table_name(o.name)
|
|
513
581
|
end
|
|
514
|
-
end
|
|
515
582
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
return collect_in_clause(o.left, o.right, collector)
|
|
583
|
+
if o.table_alias
|
|
584
|
+
collector << " " << quote_table_name(o.table_alias)
|
|
519
585
|
end
|
|
520
586
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
end
|
|
587
|
+
collector
|
|
588
|
+
end
|
|
524
589
|
|
|
525
|
-
|
|
590
|
+
def visit_Arel_Nodes_In(o, collector)
|
|
591
|
+
attr, values = o.left, o.right
|
|
526
592
|
|
|
527
|
-
|
|
593
|
+
if Array === values
|
|
594
|
+
collector.preparable = false
|
|
528
595
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
else
|
|
532
|
-
collector << "("
|
|
533
|
-
o.right.each_slice(in_clause_length).each_with_index do |right, i|
|
|
534
|
-
collector << " OR " unless i == 0
|
|
535
|
-
collect_in_clause(o.left, right, collector)
|
|
596
|
+
unless values.empty?
|
|
597
|
+
values.delete_if { |value| unboundable?(value) }
|
|
536
598
|
end
|
|
537
|
-
|
|
599
|
+
|
|
600
|
+
return collector << "1=0" if values.empty?
|
|
538
601
|
end
|
|
539
|
-
end
|
|
540
602
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
collector << " IN ("
|
|
544
|
-
visit(right, collector) << ")"
|
|
603
|
+
visit(attr, collector) << " IN ("
|
|
604
|
+
visit(values, collector) << ")"
|
|
545
605
|
end
|
|
546
606
|
|
|
547
607
|
def visit_Arel_Nodes_NotIn(o, collector)
|
|
548
|
-
|
|
549
|
-
return collect_not_in_clause(o.left, o.right, collector)
|
|
550
|
-
end
|
|
608
|
+
attr, values = o.left, o.right
|
|
551
609
|
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
end
|
|
555
|
-
|
|
556
|
-
return collector << "1=1" if o.right.empty?
|
|
557
|
-
|
|
558
|
-
in_clause_length = @connection.in_clause_length
|
|
610
|
+
if Array === values
|
|
611
|
+
collector.preparable = false
|
|
559
612
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
else
|
|
563
|
-
o.right.each_slice(in_clause_length).each_with_index do |right, i|
|
|
564
|
-
collector << " AND " unless i == 0
|
|
565
|
-
collect_not_in_clause(o.left, right, collector)
|
|
613
|
+
unless values.empty?
|
|
614
|
+
values.delete_if { |value| unboundable?(value) }
|
|
566
615
|
end
|
|
567
|
-
|
|
616
|
+
|
|
617
|
+
return collector << "1=1" if values.empty?
|
|
568
618
|
end
|
|
569
|
-
end
|
|
570
619
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
collector << " NOT IN ("
|
|
574
|
-
visit(right, collector) << ")"
|
|
620
|
+
visit(attr, collector) << " NOT IN ("
|
|
621
|
+
visit(values, collector) << ")"
|
|
575
622
|
end
|
|
576
623
|
|
|
577
624
|
def visit_Arel_Nodes_And(o, collector)
|
|
@@ -579,14 +626,12 @@ module Arel # :nodoc: all
|
|
|
579
626
|
end
|
|
580
627
|
|
|
581
628
|
def visit_Arel_Nodes_Or(o, collector)
|
|
582
|
-
|
|
583
|
-
collector << " OR "
|
|
584
|
-
visit o.right, collector
|
|
629
|
+
inject_join o.children, collector, " OR "
|
|
585
630
|
end
|
|
586
631
|
|
|
587
632
|
def visit_Arel_Nodes_Assignment(o, collector)
|
|
588
633
|
case o.right
|
|
589
|
-
when Arel::Nodes::Node, Arel::Attributes::Attribute
|
|
634
|
+
when Arel::Nodes::Node, Arel::Attributes::Attribute, ActiveModel::Attribute
|
|
590
635
|
collector = visit o.left, collector
|
|
591
636
|
collector << " = "
|
|
592
637
|
visit o.right, collector
|
|
@@ -686,32 +731,100 @@ module Arel # :nodoc: all
|
|
|
686
731
|
collector << quote_column_name(o.name)
|
|
687
732
|
end
|
|
688
733
|
|
|
734
|
+
def visit_Arel_Nodes_Cte(o, collector)
|
|
735
|
+
collector << quote_table_name(o.name)
|
|
736
|
+
collector << " AS "
|
|
737
|
+
|
|
738
|
+
case o.materialized
|
|
739
|
+
when true
|
|
740
|
+
collector << "MATERIALIZED "
|
|
741
|
+
when false
|
|
742
|
+
collector << "NOT MATERIALIZED "
|
|
743
|
+
end
|
|
744
|
+
|
|
745
|
+
visit o.relation, collector
|
|
746
|
+
end
|
|
747
|
+
|
|
689
748
|
def visit_Arel_Attributes_Attribute(o, collector)
|
|
690
749
|
join_name = o.relation.table_alias || o.relation.name
|
|
691
750
|
collector << quote_table_name(join_name) << "." << quote_column_name(o.name)
|
|
692
751
|
end
|
|
693
|
-
alias :visit_Arel_Attributes_Integer :visit_Arel_Attributes_Attribute
|
|
694
|
-
alias :visit_Arel_Attributes_Float :visit_Arel_Attributes_Attribute
|
|
695
|
-
alias :visit_Arel_Attributes_Decimal :visit_Arel_Attributes_Attribute
|
|
696
|
-
alias :visit_Arel_Attributes_String :visit_Arel_Attributes_Attribute
|
|
697
|
-
alias :visit_Arel_Attributes_Time :visit_Arel_Attributes_Attribute
|
|
698
|
-
alias :visit_Arel_Attributes_Boolean :visit_Arel_Attributes_Attribute
|
|
699
752
|
|
|
700
|
-
|
|
753
|
+
BIND_BLOCK = proc { "?" }
|
|
754
|
+
private_constant :BIND_BLOCK
|
|
755
|
+
|
|
756
|
+
def bind_block; BIND_BLOCK; end
|
|
757
|
+
|
|
758
|
+
def visit_ActiveModel_Attribute(o, collector)
|
|
759
|
+
collector.add_bind(o, &bind_block)
|
|
760
|
+
end
|
|
701
761
|
|
|
702
762
|
def visit_Arel_Nodes_BindParam(o, collector)
|
|
703
|
-
collector.add_bind(o.value)
|
|
763
|
+
collector.add_bind(o.value, &bind_block)
|
|
704
764
|
end
|
|
705
765
|
|
|
706
|
-
|
|
707
|
-
|
|
766
|
+
def visit_Arel_Nodes_SqlLiteral(o, collector)
|
|
767
|
+
collector.preparable = false
|
|
768
|
+
collector.retryable &&= o.retryable
|
|
769
|
+
collector << o.to_s
|
|
770
|
+
end
|
|
771
|
+
|
|
772
|
+
def visit_Arel_Nodes_BoundSqlLiteral(o, collector)
|
|
773
|
+
collector.retryable = false
|
|
774
|
+
bind_index = 0
|
|
775
|
+
|
|
776
|
+
new_bind = lambda do |value|
|
|
777
|
+
if Arel.arel_node?(value)
|
|
778
|
+
visit value, collector
|
|
779
|
+
elsif value.is_a?(Array)
|
|
780
|
+
if value.empty?
|
|
781
|
+
collector << @connection.quote(nil)
|
|
782
|
+
else
|
|
783
|
+
if value.none? { |v| Arel.arel_node?(v) }
|
|
784
|
+
collector.add_binds(value.map { |v| @connection.cast_bound_value(v) }, &bind_block)
|
|
785
|
+
else
|
|
786
|
+
value.each_with_index do |v, i|
|
|
787
|
+
collector << ", " unless i == 0
|
|
788
|
+
if Arel.arel_node?(v)
|
|
789
|
+
visit v, collector
|
|
790
|
+
else
|
|
791
|
+
collector.add_bind(@connection.cast_bound_value(v), &bind_block)
|
|
792
|
+
end
|
|
793
|
+
end
|
|
794
|
+
end
|
|
795
|
+
end
|
|
796
|
+
else
|
|
797
|
+
collector.add_bind(@connection.cast_bound_value(value), &bind_block)
|
|
798
|
+
end
|
|
799
|
+
end
|
|
708
800
|
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
801
|
+
if o.positional_binds
|
|
802
|
+
o.sql_with_placeholders.scan(/\?|([^?]+)/) do
|
|
803
|
+
if $1
|
|
804
|
+
collector << $1
|
|
805
|
+
else
|
|
806
|
+
value = o.positional_binds[bind_index]
|
|
807
|
+
bind_index += 1
|
|
808
|
+
|
|
809
|
+
new_bind.call(value)
|
|
810
|
+
end
|
|
811
|
+
end
|
|
712
812
|
else
|
|
713
|
-
|
|
813
|
+
o.sql_with_placeholders.scan(/:(?<!::)([a-zA-Z]\w*)|([^:]+|.)/) do
|
|
814
|
+
if $2
|
|
815
|
+
collector << $2
|
|
816
|
+
else
|
|
817
|
+
value = o.named_binds[$1.to_sym]
|
|
818
|
+
new_bind.call(value)
|
|
819
|
+
end
|
|
820
|
+
end
|
|
714
821
|
end
|
|
822
|
+
|
|
823
|
+
collector
|
|
824
|
+
end
|
|
825
|
+
|
|
826
|
+
def visit_Integer(o, collector)
|
|
827
|
+
collector << o.to_s
|
|
715
828
|
end
|
|
716
829
|
|
|
717
830
|
def unsupported(o, collector)
|
|
@@ -739,11 +852,6 @@ module Arel # :nodoc: all
|
|
|
739
852
|
visit o.right, collector
|
|
740
853
|
end
|
|
741
854
|
|
|
742
|
-
alias :visit_Arel_Nodes_Addition :visit_Arel_Nodes_InfixOperation
|
|
743
|
-
alias :visit_Arel_Nodes_Subtraction :visit_Arel_Nodes_InfixOperation
|
|
744
|
-
alias :visit_Arel_Nodes_Multiplication :visit_Arel_Nodes_InfixOperation
|
|
745
|
-
alias :visit_Arel_Nodes_Division :visit_Arel_Nodes_InfixOperation
|
|
746
|
-
|
|
747
855
|
def visit_Arel_Nodes_UnaryOperation(o, collector)
|
|
748
856
|
collector << " #{o.operator} "
|
|
749
857
|
visit o.expr, collector
|
|
@@ -754,6 +862,10 @@ module Arel # :nodoc: all
|
|
|
754
862
|
end
|
|
755
863
|
alias :visit_Set :visit_Array
|
|
756
864
|
|
|
865
|
+
def visit_Arel_Nodes_Fragments(o, collector)
|
|
866
|
+
inject_join o.values, collector, " "
|
|
867
|
+
end
|
|
868
|
+
|
|
757
869
|
def quote(value)
|
|
758
870
|
return value if Arel::Nodes::SqlLiteral === value
|
|
759
871
|
@connection.quote value
|
|
@@ -804,6 +916,10 @@ module Arel # :nodoc: all
|
|
|
804
916
|
o.limit || o.offset || !o.orders.empty?
|
|
805
917
|
end
|
|
806
918
|
|
|
919
|
+
def has_group_by_and_having?(o)
|
|
920
|
+
!o.groups.empty? && !o.havings.empty?
|
|
921
|
+
end
|
|
922
|
+
|
|
807
923
|
# The default strategy for an UPDATE with joins is to use a subquery. This doesn't work
|
|
808
924
|
# on MySQL (even when aliasing the tables), but MySQL allows using JOIN directly in
|
|
809
925
|
# an UPDATE statement, so in the MySQL visitor we redefine this to do that.
|
|
@@ -813,8 +929,11 @@ module Arel # :nodoc: all
|
|
|
813
929
|
stmt.limit = nil
|
|
814
930
|
stmt.offset = nil
|
|
815
931
|
stmt.orders = []
|
|
816
|
-
|
|
932
|
+
columns = Arel::Nodes::Grouping.new(o.key)
|
|
933
|
+
stmt.wheres = [Nodes::In.new(columns, [build_subselect(o.key, o)])]
|
|
817
934
|
stmt.relation = o.relation.left if has_join_sources?(o)
|
|
935
|
+
stmt.groups = o.groups unless o.groups.empty?
|
|
936
|
+
stmt.havings = o.havings unless o.havings.empty?
|
|
818
937
|
stmt
|
|
819
938
|
else
|
|
820
939
|
o
|
|
@@ -829,6 +948,8 @@ module Arel # :nodoc: all
|
|
|
829
948
|
core.froms = o.relation
|
|
830
949
|
core.wheres = o.wheres
|
|
831
950
|
core.projections = [key]
|
|
951
|
+
core.groups = o.groups unless o.groups.empty?
|
|
952
|
+
core.havings = o.havings unless o.havings.empty?
|
|
832
953
|
stmt.limit = o.limit
|
|
833
954
|
stmt.offset = o.offset
|
|
834
955
|
stmt.orders = o.orders
|
|
@@ -846,18 +967,34 @@ module Arel # :nodoc: all
|
|
|
846
967
|
collector = if o.left.class == o.class
|
|
847
968
|
infix_value_with_paren(o.left, collector, value, true)
|
|
848
969
|
else
|
|
849
|
-
|
|
970
|
+
grouping_parentheses o.left, collector, false
|
|
850
971
|
end
|
|
851
972
|
collector << value
|
|
852
973
|
collector = if o.right.class == o.class
|
|
853
974
|
infix_value_with_paren(o.right, collector, value, true)
|
|
854
975
|
else
|
|
855
|
-
|
|
976
|
+
grouping_parentheses o.right, collector, false
|
|
856
977
|
end
|
|
857
978
|
collector << " )" unless suppress_parens
|
|
858
979
|
collector
|
|
859
980
|
end
|
|
860
981
|
|
|
982
|
+
# Used by some visitors to enclose select queries in parentheses
|
|
983
|
+
def grouping_parentheses(o, collector, always_wrap_selects = true)
|
|
984
|
+
if o.is_a?(Nodes::SelectStatement) && (always_wrap_selects || require_parentheses?(o))
|
|
985
|
+
collector << "("
|
|
986
|
+
visit o, collector
|
|
987
|
+
collector << ")"
|
|
988
|
+
collector
|
|
989
|
+
else
|
|
990
|
+
visit o, collector
|
|
991
|
+
end
|
|
992
|
+
end
|
|
993
|
+
|
|
994
|
+
def require_parentheses?(o)
|
|
995
|
+
!o.orders.empty? || o.limit || o.offset
|
|
996
|
+
end
|
|
997
|
+
|
|
861
998
|
def aggregate(name, o, collector)
|
|
862
999
|
collector << "#{name}("
|
|
863
1000
|
if o.distinct
|
|
@@ -884,6 +1021,15 @@ module Arel # :nodoc: all
|
|
|
884
1021
|
collector << " IS NULL)"
|
|
885
1022
|
collector << " THEN 0 ELSE 1 END"
|
|
886
1023
|
end
|
|
1024
|
+
|
|
1025
|
+
def collect_ctes(children, collector)
|
|
1026
|
+
children.each_with_index do |child, i|
|
|
1027
|
+
collector << ", " unless i == 0
|
|
1028
|
+
visit child.to_cte, collector
|
|
1029
|
+
end
|
|
1030
|
+
|
|
1031
|
+
collector
|
|
1032
|
+
end
|
|
887
1033
|
end
|
|
888
1034
|
end
|
|
889
1035
|
end
|
|
@@ -12,13 +12,12 @@ module Arel # :nodoc: all
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
private
|
|
15
|
-
|
|
16
15
|
attr_reader :dispatch
|
|
17
16
|
|
|
18
17
|
def self.dispatch_cache
|
|
19
18
|
@dispatch_cache ||= Hash.new do |hash, klass|
|
|
20
|
-
hash[klass] = "visit_#{(klass.name ||
|
|
21
|
-
end
|
|
19
|
+
hash[klass] = :"visit_#{(klass.name || "").gsub("::", "_")}"
|
|
20
|
+
end.compare_by_identity
|
|
22
21
|
end
|
|
23
22
|
|
|
24
23
|
def get_dispatch_cache
|
data/lib/arel/visitors.rb
CHANGED
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "arel/visitors/visitor"
|
|
4
|
-
require "arel/visitors/depth_first"
|
|
5
4
|
require "arel/visitors/to_sql"
|
|
6
5
|
require "arel/visitors/sqlite"
|
|
7
6
|
require "arel/visitors/postgresql"
|
|
8
7
|
require "arel/visitors/mysql"
|
|
9
|
-
require "arel/visitors/mssql"
|
|
10
|
-
require "arel/visitors/oracle"
|
|
11
|
-
require "arel/visitors/oracle12"
|
|
12
|
-
require "arel/visitors/where_sql"
|
|
13
8
|
require "arel/visitors/dot"
|
|
14
|
-
require "arel/visitors/ibm_db"
|
|
15
|
-
require "arel/visitors/informix"
|
|
16
9
|
|
|
17
10
|
module Arel # :nodoc: all
|
|
18
11
|
module Visitors
|
data/lib/arel.rb
CHANGED
|
@@ -7,12 +7,13 @@ require "arel/factory_methods"
|
|
|
7
7
|
|
|
8
8
|
require "arel/expressions"
|
|
9
9
|
require "arel/predications"
|
|
10
|
+
require "arel/filter_predications"
|
|
10
11
|
require "arel/window_predications"
|
|
11
12
|
require "arel/math"
|
|
12
13
|
require "arel/alias_predication"
|
|
13
14
|
require "arel/order_predications"
|
|
14
15
|
require "arel/table"
|
|
15
|
-
require "arel/attributes"
|
|
16
|
+
require "arel/attributes/attribute"
|
|
16
17
|
|
|
17
18
|
require "arel/visitors"
|
|
18
19
|
require "arel/collectors/sql_string"
|
|
@@ -24,28 +25,49 @@ require "arel/update_manager"
|
|
|
24
25
|
require "arel/delete_manager"
|
|
25
26
|
require "arel/nodes"
|
|
26
27
|
|
|
27
|
-
module Arel
|
|
28
|
+
module Arel
|
|
28
29
|
VERSION = "10.0.0"
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
# Wrap a known-safe SQL string for passing to query methods, e.g.
|
|
32
|
+
#
|
|
33
|
+
# Post.order(Arel.sql("REPLACE(title, 'misc', 'zzzz') asc")).pluck(:id)
|
|
34
|
+
#
|
|
35
|
+
# Great caution should be taken to avoid SQL injection vulnerabilities.
|
|
36
|
+
# This method should not be used with unsafe values such as request
|
|
37
|
+
# parameters or model attributes.
|
|
38
|
+
#
|
|
39
|
+
# Take a look at the {security guide}[https://guides.rubyonrails.org/security.html#sql-injection]
|
|
40
|
+
# for more information.
|
|
41
|
+
#
|
|
42
|
+
# To construct a more complex query fragment, including the possible
|
|
43
|
+
# use of user-provided values, the +sql_string+ may contain <tt>?</tt> and
|
|
44
|
+
# +:key+ placeholders, corresponding to the additional arguments. Note
|
|
45
|
+
# that this behavior only applies when bind value parameters are
|
|
46
|
+
# supplied in the call; without them, the placeholder tokens have no
|
|
47
|
+
# special meaning, and will be passed through to the query as-is.
|
|
48
|
+
#
|
|
49
|
+
# The +:retryable+ option can be used to mark the SQL as safe to retry.
|
|
50
|
+
# Use this option only if the SQL is idempotent, as it could be executed
|
|
51
|
+
# more than once.
|
|
52
|
+
def self.sql(sql_string, *positional_binds, retryable: false, **named_binds)
|
|
53
|
+
if positional_binds.empty? && named_binds.empty?
|
|
54
|
+
Arel::Nodes::SqlLiteral.new(sql_string, retryable: retryable)
|
|
55
|
+
else
|
|
56
|
+
Arel::Nodes::BoundSqlLiteral.new sql_string, positional_binds, named_binds
|
|
57
|
+
end
|
|
32
58
|
end
|
|
33
59
|
|
|
34
|
-
def self.star
|
|
35
|
-
sql
|
|
60
|
+
def self.star # :nodoc:
|
|
61
|
+
sql("*", retryable: true)
|
|
36
62
|
end
|
|
37
63
|
|
|
38
|
-
def self.arel_node?(value)
|
|
39
|
-
value.is_a?(Arel::Node) || value.is_a?(Arel::Attribute) || value.is_a?(Arel::Nodes::SqlLiteral)
|
|
64
|
+
def self.arel_node?(value) # :nodoc:
|
|
65
|
+
value.is_a?(Arel::Nodes::Node) || value.is_a?(Arel::Attribute) || value.is_a?(Arel::Nodes::SqlLiteral)
|
|
40
66
|
end
|
|
41
67
|
|
|
42
|
-
def self.fetch_attribute(value)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
yield value.left.is_a?(Arel::Attributes::Attribute) ? value.left : value.right
|
|
68
|
+
def self.fetch_attribute(value, &block) # :nodoc:
|
|
69
|
+
unless String === value
|
|
70
|
+
value.fetch_attribute(&block)
|
|
46
71
|
end
|
|
47
72
|
end
|
|
48
|
-
|
|
49
|
-
## Convenience Alias
|
|
50
|
-
Node = Arel::Nodes::Node
|
|
51
73
|
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Description:
|
|
2
|
+
Generates an `ApplicationRecord` base class for other models to inherit from.
|
|
3
|
+
|
|
4
|
+
Example:
|
|
5
|
+
`bin/rails generate application_record`
|
|
6
|
+
|
|
7
|
+
This generates the base class. A test is not generated because no
|
|
8
|
+
behaviour is included in `ApplicationRecord` by default.
|
|
@@ -7,6 +7,7 @@ module ActiveRecord
|
|
|
7
7
|
class MigrationGenerator < Base # :nodoc:
|
|
8
8
|
argument :attributes, type: :array, default: [], banner: "field[:type][:index] field[:type][:index]"
|
|
9
9
|
|
|
10
|
+
class_option :timestamps, type: :boolean
|
|
10
11
|
class_option :primary_key_type, type: :string, desc: "The type for primary key"
|
|
11
12
|
class_option :database, type: :string, aliases: %i(--db), desc: "The database for your migration. By default, the current environment's primary database is used."
|
|
12
13
|
|