Commit Graph

9593 Commits

Author SHA1 Message Date
Ryuta Kamizono
d05f1f036f Merge pull request #37103 from giraffate/add_tests_for_no_or_blank_like_arguments_to_query_methods
Add tests for no or blank like arguments to query methods
2019-09-02 10:49:58 +09:00
Takayuki Nakata
2f308e7071 Add tests for no or blank like arguments to query methods
The methods with tests added here is for the query methods that uses
`check_if_method_has_arguments!` in `ActiveRecord::QueryMethods`.
However, some of these query methods had no tests.
2019-09-02 09:39:41 +09:00
bogdanvlviv
39c6986ffc
Extend test_can_write_while_reading_from_replicas_if_explicit
- Ensure that explicit method call `connected_to` with `prevent_writes: false`
  turns off 'preventing writes' in the passed block.
- Ensure that after explicit call method call `connected_to` with `prevent_writes: false`
  'preventing writes' is retained

Related to https://github.com/rails/rails/pull/37065
2019-08-30 17:46:21 +03:00
eileencodes
66bc2ff6b3 Call while_preventing_writes from connected_to
If a user is using the middleware for swapping database connections and
manually calling `connected_to` in a controller/model/etc without
calling `while_preventing_writes(false)` there is potential for a race
condition where writes will be blocked.

While the user could _just_ call `while_preventing_writes` in the same
place they call `connected_to` this would mean that all cases need to
call two methods.

This PR changes `connected_to` to call `while_preventing_writes`
directly. By default we'll assume you don't want to prevent writes, but
if called with `connected_to(role: :writing, prevent_writes: true)` or
from the middleware (which calls `connected_to` this way) the writes
will be blocked.

For replicas, apps should use readonly users to enforce not writing
rather than `while_preventing_writes` directly.

Should fix the remaining issues in
https://github.com/rails/rails/issues/36830
2019-08-28 13:44:51 -04:00
Takayuki Nakata
37b4a3c4f0 Fix docs to replace http with https in activerecord [ci skip] 2019-08-26 22:34:33 +09:00
Guo Xiang Tan
97fe59990c Fix ConnectionPool::Reaper reaping parent connection pools after fork.
After forking, the connection handler will discard any connection pools that belongs to the parent process. However, it will continue to hold a reference to the connection pools of the parent process which is used for retrieval of the connection pool in the child process. Therefore, the `weakref_alive?` check in the connection pool reaper is insufficient since the connection pools of the parent process is never GCed.
2019-08-24 14:26:50 +08:00
Guo Xiang Tan
755da80063 Move tests that does not rely on forking out of fork conditional. 2019-08-21 15:27:41 +08:00
John Hawthorn
95cf3d9a57
Merge pull request #36999 from rails/reaper_fork2
Fix error on reap/flush for closed connection pool
2019-08-20 14:00:36 -07:00
John Hawthorn
3a8eeacf63 Fix error on reap/flush for closed connection pool 2019-08-20 13:20:56 -07:00
Eileen M. Uchitelle
d06dbe9432
Merge pull request #36930 from eugeneius/active_record_base_connection_specification_name
Fix setting connection_specification_name on ActiveRecord::Base
2019-08-20 15:15:37 -04:00
John Hawthorn
c72b77bc54 Ensure reaper threads respawn in forks
This broke in 3e2e8ee where it switched to one reaper thread per
process. However, the implementation will only spawn the reaping thread
if the reaping frequency has not been seen.  Since the reaping
frequencies are stored in a class instance variable, that variable is
copied when the process is forked. As such, a forked process will not
spawn a new reaping thread since the class instance variable would have
contain the reaping frequency that was seen in the parent process.

This commit tracks threads separately and checks that they both have
been spawned and are currently alive.

This adds a failing test to reaper_test.rb, based on the previous test
without forking. It also improves the test to return an failure instead
of hanging forever if the reaper is not started.

Co-authored-by: Guo Xiang Tan <tgx_world@hotmail.com>
2019-08-20 10:42:48 -07:00
Anmol Arora
2a65310890 Clear ActiveRecord object memoized by take 2019-08-20 00:54:03 +05:30
Jon Zeppieri
d553213cfb Make prepared statement status thread and instance-specific
This fixes a race condition in system tests where prepared
statements can be incorrectly parameterized when multiple
threads observe the mutation of the @prepared_statements
instance variable on the connection.

Fixes #36763
2019-08-16 02:11:19 -04:00
Kir Shatrov
c99c572d37 Improve detection of ActiveRecord::StatementTimeout with mysql2 adapter
in the edge case when the query is terminated by MySQL server during filesort.
See https://bugs.mysql.com/bug.php?id=96537 for more details.
2019-08-15 21:00:07 +01:00
Eugene Kenny
92d31b1f81 Fix setting connection_specification_name on ActiveRecord::Base
Since 2f8b397258b66581409b0e6537f98ea9b56e9f19, `ActiveRecord::Base` and
`ApplicationRecord` use the same default `connection_specification_name`
so that database connections configured on `ApplicationRecord` also
apply to `ActiveRecord::Base`.

However, when resolving the connection for `ApplicationRecord` we should
continue to fall back to `ActiveRecord::Base` when there's no connection
explicitly configured, so that setting `connection_specification_name`
on `ActiveRecord::Base` affects `ApplicationRecord` and its descendants
in this case as it did in previous versions.
2019-08-14 02:54:13 +01:00
Gannon McGibbon
9899697794 Stop trying to read yaml file fixtures when loading Active Record fixtures 2019-08-09 14:24:59 -04:00
Ryuta Kamizono
eec562dbcf Deprecate .reorder(nil) with .first / .first! taking non-deterministic result
To continue taking non-deterministic result, use `.take` / `.take!`
instead.
2019-08-08 19:14:24 +09:00
Ryuta Kamizono
49b617f68c Restore an ability that reorder with first taking non-deterministic result
Actually, `first` taking non-deterministic result is considered a bug to
me. But changing the behavior should not be happened in rc2.

I've restored the behavior for 6.0, and then will deprecate that in 6.1.

Fixes #36802.
2019-08-08 18:34:10 +09:00
John Hawthorn
ec2dcddf79
Merge pull request #36848 from jhawthorn/type_error_on_resolve_connection
Raise TypeError instead of infinite loop in resolve_connection
2019-08-07 14:51:26 -07:00
Gannon McGibbon
dacfa5b792
Merge pull request #36847 from gmcgibbon/fix_custom_pk_through_reflect
Ensure custom PK types are casted in through reflection queries
2019-08-07 16:48:21 -04:00
Gannon McGibbon
5ec2f35f27 Ensure custom PK types are casted in through reflection queries
Make sure primary keys with non-integer types can be correctly type
casted in through reflections.
2019-08-07 16:27:33 -04:00
Carlos Antonio da Silva
683e1c7d18 Fix typo in test name 2019-08-07 13:46:15 -03:00
Ryuta Kamizono
e62195e259 Fix GROUP BY aggregation alias to not duplicate "_" chars
c9e4c848 has one performance optimization for `aggregate_alias` to early
returning by `aggregate_alias.match?(/\A\w+\z/)`, but it is caused a
regression that failing deduplication for non word chars #36867.

I've quited the optimization and add a test to prevent a future
regression.

Fixes #36867.
2019-08-07 23:05:23 +09:00
eileencodes
ff70c1764d Fix thread safety of prevent_writes
As demonstrated in the test added and in #36830 the code that prevents
writes wasn't thread safe. If one thread does a read, then another does
a write, and then another does a read the second read will cause the
first write to be unwriteable.

This change removes the instance variable and instead uses a
getter/setter on Thread.current[:prevent_writes] for the connection
handler to set whether writes are allowed.

Fixes #36830
2019-08-06 13:07:19 -04:00
Lachlan Sylvester
1af44e4aee
handle passing in primary key to unique_by, and handle primary keys missing indexes 2019-08-05 02:39:52 +02:00
Yasuo Honda
20772f6c53 Address DEPRECATED: Use assert_nil if expecting nil
```ruby
$ cd activerecord
$ bin/test test/cases/dirty_test.rb:494
... snip ...
DEPRECATED: Use assert_nil if expecting nil from /home/yahonda/git/rails/activerecord/test/cases/dirty_test.rb:494. This will fail in Minitest 6.
DEPRECATED: Use assert_nil if expecting nil from /home/yahonda/git/rails/activerecord/test/cases/dirty_test.rb:511. This will fail in Minitest 6.
.

Finished in 0.061593s, 16.2356 runs/s, 795.5428 assertions/s.
1 runs, 49 assertions, 0 failures, 0 errors, 0 skips
$
```

Refer seattlerb/minitest#666 rails/rails#27712
2019-08-03 02:27:56 +00:00
John Hawthorn
d0e95f45f3 Raise TypeError instead of infinite looping 2019-08-02 15:58:42 -07:00
eileencodes
f2de448106 Add ability to unset preventing writes
Previously if an app attempts to do a write inside a read request it will be
impossilbe to switch back to writing to the primary. This PR adds an
argument to the `while_preventing_writes` so that we can make sure to
turn it off if we're doing a write on a primary.

Fixes #36830

Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2019-08-02 12:10:32 -04:00
Eileen M. Uchitelle
f3c68c59ed
Merge pull request #36814 from eileencodes/introduce-invalid-configuration-error
Introduce InvalidConfigurationError
2019-08-02 08:50:27 -04:00
Rafael Mendonça França
967beb7229
Revert "MethodCallAssertions is a regular player of the team ActiveSupport::TestCase now"
This reverts commit 98d0f7ebd34b858f12a12dcf37ae54fdbb5cab64.
2019-08-02 00:24:21 -04:00
David Heinemeier Hansson
a0bb19fbfa
Add *_previously_was attribute methods when dirty tracking (#36836) 2019-08-01 15:38:03 -07:00
Ryuta Kamizono
89399ed88c
Merge pull request #36821 from rails/virtual-attribute-type
Add tests for selecting aggregrates
2019-08-02 05:54:01 +09:00
Akira Matsuda
98d0f7ebd3 MethodCallAssertions is a regular player of the team ActiveSupport::TestCase now
It's used everywhere, clean and mature enough
2019-08-02 05:36:15 +09:00
eileencodes
dde03a9234 Introduce InvalidConfigurationError
In our app at work we had a faked config like this:

```
{ "foo" => :bar, "bar" => { "adapter" => "memory" } }
```

This config is invalid. You can't say for foo env just have a symbol,
nor would this work if you had fa foo env with just a string. A
configuration must be a url or an adapter or a database. Otherwise it's
invalid and we can't parse it.

When this was just yaml turned into hashes you could get away with
passing whatever. It wouldn't work but it wouldn't blow up either.

Now that we're using objects we were returning `nil` for these but that
just means we either blow up on `for_current_env` or compact the
`nil`'s.

I think it's a better user experience to not build the configs and raise
an appropriate error.

This is also an invalid config because if you do pass a string here it
should be a URL.

```
{ "foo" => "bar", "bar" => { "adapter" => "memory" } }
```
2019-08-01 16:33:58 -04:00
Ryuta Kamizono
e6f953fc39 Deduplicate joins values
#36805 have one possible regression that failing deduplication if
`joins_values` have complex order (e.g. `joins_values = [join_node_a,
:comments, :tags, join_node_a]`).

This fixes the deduplication to take it in the first phase before
grouping.
2019-08-02 03:35:44 +09:00
Godfrey Chan
05300be635 Add tests for selecting aggregates
These tests verifies that aggregates like `AVG` can be selected as
"virtual attributes" on Active Record models and have the correct
column type.
2019-08-01 10:56:10 -07:00
Akira Matsuda
af2129b4c7 Use try only when we're unsure if the receiver would respond_to the method 2019-08-01 17:58:00 +09:00
Kasper Timm Hansen
40fc31c103
Merge pull request #36708 from rails/has-one-polymorphic-touch-dont-cache-association-result-inside-create-transaction
Polymorphic has_one touch: Don't cache association result inside crea…
2019-07-31 06:31:50 +02:00
yamato-payforward
b8309e85b9 fix a typo 2019-07-31 13:17:32 +09:00
Kasper Timm Hansen
cea392eb96
Polymorphic has_one touch: Reset association cache result after create transaction
In case of a polymorphic association there's no automatic inverse_of to assign the
inverse record. So to get the record there needs to be a query executed,
however, if the query fires within the transaction that's trying to create
the associated record, no record can be found. And worse, the nil result is cached
on the association so after the transaction commits the record can't be found.

That's what happens if touch is enabled on a polymorphic has_one association.

Consider a Comment with a commentable association that needs to be touched.

For `Comment.create(commentable: Post.new)`, the existing code essentially
does `commentable.send(:comment)` within the create transaction for the comment
and thus not finding the comment.

Now we're purposefully clearing the cache in case we've tried accessing
the association within the transaction and found no object.

Before:

```
kaspth-imac 2.6.3 ~/code/rails/activerecord master *= ARCONN=postgresql bin/test test/cases/associations/has_one_associations_test.rb -n /commit/
Using postgresql
Run options: -n /commit/ --seed 46022

D, [2019-07-19T03:30:37.864537 #96022] DEBUG -- :   Chef Load (0.2ms)  SELECT "chefs".* FROM "chefs" WHERE "chefs"."employable_id" = $1 AND "chefs"."employable_type" = $2 LIMIT $3  [["employable_id", 1], ["employable_type", "DrinkDesignerWithPolymorphicTouchChef"], ["LIMIT", 1]]
D, [2019-07-19T03:30:37.865013 #96022] DEBUG -- :   Chef Create (0.2ms)  INSERT INTO "chefs" ("employable_id", "employable_type") VALUES ($1, $2) RETURNING "id"  [["employable_id", 1], ["employable_type", "DrinkDesignerWithPolymorphicTouchChef"]]
D, [2019-07-19T03:30:37.865201 #96022] DEBUG -- :   TRANSACTION (0.1ms)  RELEASE SAVEPOINT active_record_1
D, [2019-07-19T03:30:37.874136 #96022] DEBUG -- :   TRANSACTION (0.1ms)  ROLLBACK
D, [2019-07-19T03:30:37.874323 #96022] DEBUG -- :   TRANSACTION (0.1ms)  ROLLBACK
F

Failure:
HasOneAssociationsTest#test_polymorphic_has_one_with_touch_option_on_create_wont_cache_assocation_so_fetching_after_transaction_commit_works [/Users/kaspth/code/rails/activerecord/test/cases/associations/has_one_associations_test.rb:716]:
--- expected
+++ actual
@@ -1 +1 @@
-#<Chef id: 1, employable_id: 1, employable_type: "DrinkDesignerWithPolymorphicTouchChef", department_id: nil, employable_list_type: nil, employable_list_id: nil>
+nil
```

After:

```
kaspth-imac 2.6.3 ~/code/rails/activerecord master *= ARCONN=postgresql bin/test test/cases/associations/has_one_associations_test.rb -n /commit/
Using postgresql
Run options: -n /commit/ --seed 46022

D, [2019-07-19T03:30:22.479387 #95973] DEBUG -- :   Chef Create (0.3ms)  INSERT INTO "chefs" ("employable_id", "employable_type") VALUES ($1, $2) RETURNING "id"  [["employable_id", 1], ["employable_type", "DrinkDesignerWithPolymorphicTouchChef"]]
D, [2019-07-19T03:30:22.479574 #95973] DEBUG -- :   TRANSACTION (0.1ms)  RELEASE SAVEPOINT active_record_1
D, [2019-07-19T03:30:22.482051 #95973] DEBUG -- :   Chef Load (0.1ms)  SELECT "chefs".* FROM "chefs" WHERE "chefs"."employable_id" = $1 AND "chefs"."employable_type" = $2 LIMIT $3  [["employable_id", 1], ["employable_type", "DrinkDesignerWithPolymorphicTouchChef"], ["LIMIT", 1]]
D, [2019-07-19T03:30:22.482317 #95973] DEBUG -- :   TRANSACTION (0.1ms)  ROLLBACK
D, [2019-07-19T03:30:22.482437 #95973] DEBUG -- :   TRANSACTION (0.1ms)  ROLLBACK
.

Finished in 0.088498s, 11.2997 runs/s, 22.5994 assertions/s.
1 runs, 2 assertions, 0 failures, 0 errors, 0 skips
```

Notice the select now fires after the commit.
2019-07-31 05:59:23 +02:00
Ryuta Kamizono
1e5c0a7836
Merge pull request #36805 from kamipo/user_supplied_joins_order_should_be_preserved
Preserve user supplied joins order as much as possible
2019-07-30 12:39:50 +09:00
Ryuta Kamizono
fff120c752 Add silence_warnings for defining 'not_' prefix enum elements
To suppress the following warnings in tests.

```
~/rails/activerecord/lib/active_record/scoping/named.rb:190: warning: method redefined; discarding old not_sent
~/rails/activerecord/lib/active_record/scoping/named.rb:190: warning: previous definition of not_sent was here
```
2019-07-30 04:54:55 +09:00
Ryuta Kamizono
b4478ae8bc Preserve user supplied joins order as much as possible
Currently, string joins are always applied as last joins part, and Arel
join nodes are always applied as leading joins part (since #36304), it
makes people struggled to preserve user supplied joins order.

To mitigate this problem, preserve the order of string joins and Arel
join nodes either before or after of association joins.

Fixes #36761.
Fixes #34328.
Fixes #24281.
Fixes #12953.
2019-07-30 04:02:58 +09:00
John Hawthorn
69700c9ee7 Move DatabaseAlreadyExists detection to DB adapter
Previously it was the responsibility of the database tasks to translate
the invalid statement from creating a duplicate database into an
ActiveRecord::Tasks::DatabaseAlreadyExists error.

It's actually easier for us to do this detection inside of the adapter,
where we already do a case statement on the return code to translate the
error.

This commit introduces ActiveRecord::DatabaseAlreadyExists, a subclass
of StatementInvalid, and updates both AbstractMysqlAdapter and
PostgresqlAdapter to return this more specific exception in that case.

Because this is a subclass of the old exception, StatementInvalid, it
should be backwards compatible with any code expecting that from
create_database.

This works for both create_database and exectute("CREATE DATABASE")
2019-07-29 08:40:57 -07:00
James Pearson
92c265b3ad Enabled matches_regex for MySql
Previously matches_regex was only availble on PostgreSql, this will enable it for MySql

Usage example:

    users = User.arel_table;
    users = User.arel_table; User.where(users[:email].matches_regexp('(.*)\@gmail.com'))

Update activerecord/test/cases/arel/visitors/mysql_test.rb

Co-Authored-By: Ryuta Kamizono <kamipo@gmail.com>
2019-07-29 15:53:29 +01:00
Akira Matsuda
0196551e60 Use match? where we don't need MatchData 2019-07-29 14:23:10 +09:00
Ryuta Kamizono
715dad107b
Merge pull request #36787 from st0012/refactor-sql-tests
Use capture_sql helper method in tests
2019-07-28 16:34:24 +09:00
st0012
6fbf52d580 Use capture_sql helper method in tests 2019-07-28 14:47:57 +08:00
Rafael França
481714dd06
Merge pull request #36303 from gaotongfei/feature/ignore-specified-fixtures
Allow specifying fixtures to be ignored in "_fixture" section
2019-07-27 21:12:06 -04:00
Tongfei Gao
c09a4fd23d Allow specify fixtures to be ignored
Allow specifying what fixtures can be ignored by setting
`ignore` in fixtures YAML file:

    # users.yml
    _fixture:
      ignore:
        - base

    base: &base
      admin: false
      introduction: "This is a default description"

    admin:
      <<: *base
      admin: true

    visitor:
      <<: *base

In the above example, "base" fixture will be ignored when creating
users fixture. This is helpful when you want to inherit attributes
and it makes your fixtures more "DRY".
2019-07-27 16:40:16 +08:00