| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|/ / /
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
`Truncate Tables posts` will also reset the `AUTOINCREMENT` this causes
a situation where if a test suite that uses the `taggings` fixtures runs
and subsequently the `test_truncate_tables` run, newly created posts
would reference the `tagging` in the database. This commit resest the
state of the posts table after the `connection.truncate` call in the
`test_truncate_tables`, as well as all other tests that call `trucate`
This ensures the associations and db state remain consistent after the
tests.
Fixes: https://github.com/rails/rails/issues/35941
|
|\ \ \
| | | |
| | | |
| | | |
| | | | |
kamipo/lazy_sync_with_transaction_state_on_destroy
Lazy sync with transaction state on destroy
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
This reverts commit 58410b3d566e6b93c7b71c0eec0fc11ec906b68e.
If we have any implicit commit/rollback callbacks, it is necessary to
add record to transaction explicitly like `:touch_deferred_attributes`.
https://github.com/rails/rails/blob/5f261d04d6f857d49c75124df809adfbd6cd5b5e/activerecord/lib/active_record/touch_later.rb#L9
https://github.com/rails/rails/blob/5f261d04d6f857d49c75124df809adfbd6cd5b5e/activerecord/lib/active_record/touch_later.rb#L25
But I can't find any other implicit commit/rollback callbacks in our
code base at least now.
I think the `self.class.connection.add_transaction_record(self)` line
doesn't cover any behavior.
|
|\ \ \ \
| | | | |
| | | | |
| | | | |
| | | | | |
kamipo/dont_call_commit_callbacks_for_invalid_record
Don't call after_commit callbacks despite a record isn't saved
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Regardless of a record isn't saved (e.g. validation is failed),
`after_commit` / `after_rollback` callbacks are invoked for now.
To fix the issue, this adds a record to the current transaction only
when a record is actually saved.
Fixes #29747.
Closes #29833.
|
|\ \ \ \ \
| | | | | |
| | | | | | |
Fix `automatic_inverse_of` not to be disabled if extension block is given
|
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
If an association has a scope, `automatic_inverse_of` is to be disabled.
But extension block is obviously not a scope. It should not be regarded
as a scope.
Fixes #28806.
|
|/ / / / /
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
* remove useless `@type_metadata` and `@array`
* move the compatibility code (for array) into column
* etc.
|
|\ \ \ \ \
| | | | | |
| | | | | | |
Address `ORA-01795: maximum number of expressions in a list is 1000`
|
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
* To address this error, this commit splits expressions by slices of 1000 elements.
* "Oracle Database Error Messages 18c"
https://docs.oracle.com/en/database/oracle/oracle-database/18/errmg/
```
ORA-01795: maximum number of expressions in a list is 1000
Cause: Number of expressions in the query exceeded than 1000. Note that unused column/expressions are also counted Maximum number of expressions that are allowed are 1000.
```
* This commit addresses this ORA-01795 error
Note: Actually addressing this error raises another "ORA-00913: too many values"
Number of values Oracle database allows is 65535 regardless bind values or literal values.
```ruby
$ ARCONN=oracle bin/test test/cases/bind_parameter_test.rb -n test_too_many_binds
... snip ...
Error:
ActiveRecord::BindParameterTest#test_too_many_binds:
ActiveRecord::StatementInvalid: OCIError: ORA-01795: maximum number of expressions in a list is 1000
stmt.c:267:in oci8lib_260.so
/home/yahonda/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/ruby-oci8-2.2.7/lib/oci8/cursor.rb:131:in `exec'
/home/yahonda/git/oracle-enhanced/lib/active_record/connection_adapters/oracle_enhanced/oci_connection.rb:142:in `exec'
/home/yahonda/git/oracle-enhanced/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb:41:in `block in exec_query'
/home/yahonda/git/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb:676:in `block (2 levels) in log'
/home/yahonda/.rbenv/versions/2.6.2/lib/ruby/2.6.0/monitor.rb:230:in `mon_synchronize'
/home/yahonda/git/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb:675:in `block in log'
/home/yahonda/git/rails/activesupport/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
/home/yahonda/git/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb:666:in `log'
/home/yahonda/git/oracle-enhanced/lib/active_record/connection_adapters/oracle_enhanced/dbms_output.rb:36:in `log'
/home/yahonda/git/oracle-enhanced/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb:24:in `exec_query'
/home/yahonda/git/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:484:in `select'
/home/yahonda/git/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:70:in `select_all'
/home/yahonda/git/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:106:in `select_all'
/home/yahonda/git/rails/activerecord/lib/active_record/relation/calculations.rb:299:in `block in execute_simple_calculation'
/home/yahonda/git/rails/activerecord/lib/active_record/relation.rb:755:in `skip_query_cache_if_necessary'
/home/yahonda/git/rails/activerecord/lib/active_record/relation/calculations.rb:299:in `execute_simple_calculation'
/home/yahonda/git/rails/activerecord/lib/active_record/relation/calculations.rb:251:in `perform_calculation'
/home/yahonda/git/rails/activerecord/lib/active_record/relation/calculations.rb:141:in `calculate'
/home/yahonda/git/rails/activerecord/lib/active_record/relation/calculations.rb:49:in `count'
/home/yahonda/git/rails/activerecord/test/cases/bind_parameter_test.rb:113:in `test_too_many_binds'
bin/test test/cases/bind_parameter_test.rb:109
.............................F
```
|
|\ \ \ \ \ \
| | | | | | |
| | | | | | | |
Deduplicate Active Record reflection names
|
| | | | | | | |
|
|\ \ \ \ \ \ \
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | | |
michaelglass/move-sqlite-3-database-statements-into-database-statements
make SQLite3 `last_inserted_id` private and organize DatabaseStatement methods
|
| | |_|_|/ / /
| |/| | | | |
| | | | | | |
| | | | | | | |
Sqlite3::DatabaseStatements and make those that are private in Abstract::DatabaseStatements private for sqlite3
|
|\ \ \ \ \ \ \
| |_|_|_|_|_|/
|/| | | | | | |
PERF: 2x ~ 30x faster dirty tracking
|
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | | |
Currently, although using both dirty tracking (ivar backed and
attributes backed) on one model is not supported (doesn't fully work at
least), both dirty tracking are being performed, that is very slow.
As long as attributes backed dirty tracking is used, ivar backed dirty
tracking should not need to be performed.
I've refactored to extract new `ForcedMutationTracker` which only tracks
`force_change` to be performed for ivar backed dirty tracking, that
makes dirty tracking on Active Record 2x ~ 30x faster.
https://gist.github.com/kamipo/971dfe0891f0fe1ec7db8ab31f016435
Before:
```
Warming up --------------------------------------
changed? 4.467k i/100ms
changed 5.134k i/100ms
changes 3.023k i/100ms
changed_attributes 4.358k i/100ms
title_change 3.185k i/100ms
title_was 3.381k i/100ms
Calculating -------------------------------------
changed? 42.197k (±28.5%) i/s - 187.614k in 5.050446s
changed 50.481k (±16.0%) i/s - 246.432k in 5.045759s
changes 30.799k (± 7.2%) i/s - 154.173k in 5.030765s
changed_attributes 51.530k (±14.2%) i/s - 252.764k in 5.041106s
title_change 44.667k (± 9.0%) i/s - 222.950k in 5.040646s
title_was 44.635k (±16.6%) i/s - 216.384k in 5.051098s
```
After:
```
Warming up --------------------------------------
changed? 24.130k i/100ms
changed 13.503k i/100ms
changes 6.511k i/100ms
changed_attributes 9.226k i/100ms
title_change 48.221k i/100ms
title_was 96.060k i/100ms
Calculating -------------------------------------
changed? 245.478k (±16.1%) i/s - 1.182M in 5.015837s
changed 157.641k (± 4.9%) i/s - 796.677k in 5.066734s
changes 70.633k (± 5.7%) i/s - 358.105k in 5.086553s
changed_attributes 95.155k (±13.6%) i/s - 470.526k in 5.082841s
title_change 566.481k (± 3.5%) i/s - 2.845M in 5.028852s
title_was 1.487M (± 3.9%) i/s - 7.493M in 5.046774s
```
|
|/ / / / / / |
|
|/ / / / /
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
* Adding type option example to the documentation [ci skip]
It was hard for me looking https://api.rubyonrails.org/ to find that there was a type option.
Adding this to the doc would be helpful especially for application with old tables where the references are still an integer not bigint
* Update activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
Co-Authored-By: robertomiranda <rjmaltamar@gmail.com>
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
This reverts commit b33ccaa6c335e2ce482c9de1aa05e4a612aa84bc.
That isn't hit by `git grep`, but actually used in meta-programming...
https://github.com/rails/rails/blob/b33ccaa6c335e2ce482c9de1aa05e4a612aa84bc/activerecord/test/cases/transactions_test.rb#L1020-L1028
|
| |_|/ /
|/| | | |
|
|\ \ \ \
| | | | |
| | | | |
| | | | | |
Fix "autosave: true" on belongs_to of join model causes invalid records to be saved
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Use a variable local to the `save_collection_association` method in
`activerecord/lib/active_record/autosave_association.rb`, instead of an
instance variable.
Prior to this PR, when there was a circular series of `autosave: true`
associations, the callback for a `has_many` association was run while
another instance of the same callback on the same association hadn't
finished running. When control returned to the first instance of the
callback, the instance variable had changed, and subsequent associated
records weren't saved correctly. Specifically, the ID field for the
`belongs_to` corresponding to the `has_many` was `nil`.
Remove unnecessary test and comments.
Fixes #28080.
|
| | | | |
| | | | |
| | | | |
| | | | | |
Refer #35875.
|
| | | | | |
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
All adapters (sqlite3, mysql2, postgresql, oracle-enhanced, sqlserver)
doesn't use `sequence_name` in `sql_for_insert`.
https://github.com/rsim/oracle-enhanced/blob/4e0db270a93859c9713fd079dbb315b9fe550e57/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb#L79-L85
https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/959fe8f49744460b876bc205c73259f8d4f37629/lib/active_record/connection_adapters/sqlserver/database_statements.rb#L226-L249
It can be handled in `exec_insert` like postgresql adapter if we want.
|
| | | | | |
|
|\ \ \ \ \
| | | | | |
| | | | | | |
Improve == and hash methods on various schema cache structs to be allocation free.
|
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
free.
The previous implementation would allocate 2 arrays per comparisons.
I tried relying on Struct, but they do allocate one Hash inside `Struct#hash`.
|
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
The default log messages for Model.exists?, when called from .save
on an object which uses scoped uniqueness validation like:
class Example < ApplicationRecord
validates :field, uniqueness: {scope: parent_id}
end
can result in slightly misleading logs.
An example case:
↳ app/controllers/example_controller.rb:23
(0.2ms) begin transaction
↳ app/controllers/example_controller.rb:39
Example Exists (0.2ms) SELECT 1 AS one FROM "examples" WHERE "examples"."field" IS NULL AND "examples"."parent_id" = ? LIMIT ? [["parent_id", 123], ["LIMIT", 1]]
↳ app/controllers/example_controller.rb:39
(0.1ms) rollback transaction
To me, a Rails newbie, this parsed as the following:
- started the transaction to create a thing
- found that your object exists already!
- so we rolled back the transaction
(even though the actual cause of the transaction is something that happens
after the Exists check.)
All this does is add a question mark to the message, to make it clear in the
log that this is a check, not a confirmation.
This may be kind of silly, but it may save some future goofs by newbs like me.
|
|\ \ \ \ \ \
| | | | | | |
| | | | | | | |
Bring back postgresql_version as an alias.
|
| |/ / / / / |
|
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
This is also resolved in `arel_column`.
|
|/ / / / / |
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Because this method only updates or inserts a single record
like `insert` method.
|
|\ \ \ \ \
| | | | | |
| | | | | | |
Wrap Mysql count of deleted rows in lock block to avoid conflict in test
|
| | | | | | |
|
|\ \ \ \ \ \
| | | | | | |
| | | | | | | |
Raise `ArgumentError` for invalid `:limit` and `:precision` like as other options
|
| | |_|_|/ /
| |/| | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
options
When I've added new `:size` option in #35071, I've found that invalid
`:limit` and `:precision` raises `ActiveRecordError` unlike other
invalid options.
I think that is hard to distinguish argument errors and statement
invalid errors since the `StatementInvalid` is a subclass of the
`ActiveRecordError`.
https://github.com/rails/rails/blob/c9e4c848eeeb8999b778fa1ae52185ca5537fffe/activerecord/lib/active_record/errors.rb#L103
```ruby
begin
# execute any migration
rescue ActiveRecord::StatementInvalid
# statement invalid
rescue ActiveRecord::ActiveRecordError, ArgumentError
# `ActiveRecordError` except `StatementInvalid` is maybe an argument error
end
```
I'd say this is the inconsistency worth fixing.
Before:
```ruby
add_column :items, :attr1, :binary, size: 10 # => ArgumentError
add_column :items, :attr2, :decimal, scale: 10 # => ArgumentError
add_column :items, :attr3, :integer, limit: 10 # => ActiveRecordError
add_column :items, :attr4, :datetime, precision: 10 # => ActiveRecordError
```
After:
```ruby
add_column :items, :attr1, :binary, size: 10 # => ArgumentError
add_column :items, :attr2, :decimal, scale: 10 # => ArgumentError
add_column :items, :attr3, :integer, limit: 10 # => ArgumentError
add_column :items, :attr4, :datetime, precision: 10 # => ArgumentError
```
|
|\ \ \ \ \ \
| |_|_|_|_|/
|/| | | | | |
Except `table_name` from column objects
|
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
The `table_name` was added at #23677 to detect whether serial column or
not correctly.
We can do that detection before initialize column object, it makes
column object size smaller, and it probably helps column object
de-duplication.
|
|\ \ \ \ \ \
| | | | | | |
| | | | | | | |
Improve log messages for #insert_all` / `#upsert_all` etc. methods
|
| | |/ / / /
| |/| | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
etc. methods
In #35077, `#insert_all` / `#upsert_all` / `#insert` / `#upsert` etc. methods are added. But Active Record logs only “Bulk Insert” log messages when they are invoked.
This commit improves the log messages to use collect words for how invoked them.
|
| |/ / / /
|/| | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
not specified
If `id` is an `AUTONUMBER` column, then my former strategy here of assigning `no_op_column` to an arbitrary column would fail in this specific scenario:
1. `model.columns.first` is an AUTONUMBER column
2. `model.columns.first` is not assigned in the insert attributes
I added three tests: the first test covers the actual error; the second test documents that this _isn't_ a problem when a value is given for the AUTONUMBER column and the third test ensures that this no-op strategy isn't secretly doing an UPSERT.
|
|/ / / /
| | | |
| | | |
| | | | |
Follow up of c9e4c848eeeb8999b778fa1ae52185ca5537fffe.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
This refactors `execute_grouped_calculation` and slightly changes
generated GROUP BY queries, since I'd not prefer to repeat same
expression in SELECT and GROUP BY clauses.
Before:
```
SELECT COUNT(*) AS count_all, "topics"."author_name" AS topics_author_name, COALESCE(type, title) AS coalesce_type_title FROM "topics" GROUP BY "topics"."author_name", COALESCE(type, title)
```
After:
```
SELECT COUNT(*) AS count_all, "topics"."author_name" AS topics_author_name, COALESCE(type, title) AS coalesce_type_title FROM "topics" GROUP BY topics_author_name, coalesce_type_title
```
Although we generally don't guarantee to support Arel node constructed
by user itself, this also fixes #24207.
|
| | | |
| | | |
| | | |
| | | | |
`values[:extending]` includes `NullRelation` if `null_relation?`.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Follow up of #35868.
Closes #19349.
|
|\ \ \ \
| | | | |
| | | | |
| | | | |
| | | | | |
kamipo/association_isnt_to_be_affected_by_scoping_consistently
Association loading isn't to be affected by scoping consistently
|
| |/ / /
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
Follow-up of 5c71000, #29834, and #30271.
Currently, preloading and eager loading are not to be affected by
scoping, with the exception of `unscoped`.
But non eager loaded association access is still affected by scoping.
Although this is a breaking change, the association loading will work
consistently whether preloaded / eager loaded or not.
Before:
```ruby
Post.where("1=0").scoping do
Comment.find(1).post # => nil
Comment.preload(:post).find(1).post # => #<Post id: 1, ...>
Comment.eager_load(:post).find(1).post # => #<Post id: 1, ...>
end
```
After:
```ruby
Post.where("1=0").scoping do
Comment.find(1).post # => #<Post id: 1, ...>
Comment.preload(:post).find(1).post # => #<Post id: 1, ...>
Comment.eager_load(:post).find(1).post # => #<Post id: 1, ...>
end
```
Fixes #34638.
Fixes #35398.
|
| |_|/
|/| | |
|