Commit Graph

508 Commits

Author SHA1 Message Date
Jean Boussier
f7d4f674e4 Better double checked locking in load_schema 2019-09-24 18:00:05 +02:00
Eugene Kenny
2bdb58cc47 Allow inspected records to be marshaled
Since 32b03b46150b0161eba2321ccac7678511e3d58e, records which have had
`inspect` called on them can't be marshaled, because of this anonymous
`DelegateClass`. We can fix this by giving the class a concrete name.
2019-09-07 23:45:38 +01:00
Guilherme Mansur
fd3532204c Better error message for calling columns_hash
When a record does not have a table name, as in the case for a record
with `self.abstract_class = true` and no `self.table_name` set the error
message raises a cryptic:
"ActiveRecord::StatementInvalid: Could not find table ''" this patch now
raises a new `TableNotSpecified Error`

Fixes: #36274

Co-Authored-By: Eugene Kenny <elkenny@gmail.com>
2019-06-19 14:23:03 -04:00
Kasper Timm Hansen
aae270de9e
Merge pull request #35891 from Shopify/schema-cache-deduplication
Deduplicate various Active Record schema cache structures
2019-06-19 13:04:32 +02:00
eileencodes
cd881ab169 Move while_preventing_writes from conn to handler
If we put the `while_preventing_writes` on the connection then the
middleware that sends reads to the primary and ensures they can't write
will not work. The `while_preventing_writes` will only be applied to the
connection which it's called on - which in the case of the middleware is
Ar::Base.

This worked fine if you called it directly like
`OtherDbConn.connection.while_preventing_writes` but Rails didn't have a
way of knowing you wanted to call it on all the connections.

The change here moves the `while_preventing_writes` method from the
connection to the handler so that it can block writes to all queries for
that handler. This will apply to all the connections associated with
that handler.
2019-06-14 16:11:36 -04:00
Jean Boussier
17acb771d8 Deduplicate various Active Record schema cache structures
Real world database schemas contain a lot of duplicated data.
Some column names like `id`, `created_at` etc can easily be repeated
hundreds of times. Same for SqlTypeMetada, most database will contain
only a limited number of possible combinations.

This result in a lot of wasted memory.

The idea here is to make these data sctructures immutable, use a registry
to substitute similar instances with pre-existing ones.
2019-06-03 13:31:42 +02:00
Ryuta Kamizono
00310bf61a Fix const Post leakage in test/cases/base_test.rb
https://buildkite.com/rails/rails/builds/60601#81daf2ee-9259-42e5-983d-c57d66499b76/928-939
2019-04-19 19:31:20 +09:00
Ryuta Kamizono
607d77ab07 Give GeneratedRelationMethods module a name
This follows #35595.
2019-04-19 18:21:31 +09:00
Ryuta Kamizono
9972d8353d Remove duplicated test_find_last
This is completely same with `test_last`.
2019-04-05 10:02:25 +09:00
Ryuta Kamizono
4650874073 More exercise test cases for order by table name qualified column name
This covers what #34626 fixes.
2019-02-21 03:51:20 +09:00
Ryuta Kamizono
1dfd01475d Extract duplicated serialize methods into helpers
Since `serialize` is passed user input args (from `where`, schema
default, etc), a helper should provide `serialize` if the helper also
provide `cast`.

Related #32624, 34cc301, a741208.
2019-02-18 13:16:33 +09:00
Ryuta Kamizono
9379d553d8 Remove duplicated test_update_all_with_order_and_limit
This is covered by `test_update_all_with_order_and_limit_updates_subset_only`
and `test_update_all_with_order_and_limit_and_offset_updates_subset_only`.
2019-02-18 12:57:22 +09:00
Ryuta Kamizono
cdb8697b4a Revert "Merge pull request #35186 from kamipo/fix_leaking_scope_on_relation_create"
This reverts commit b67d5c6dedbf033515a96a95d24d085bf99a0d07, reversing
changes made to 2e018361c7c51e36d1d98bf770b7456d78dee68b.

Reason: #35186 may cause that silently leaking information when people
upgrade the app.

We need deprecation first before making this.
2019-02-15 12:06:45 +09:00
Ryuta Kamizono
0ee96d13de Fix pluck and select with custom attributes
Currently custom attributes are always qualified by the table name in
the generated SQL wrongly even if the table doesn't have the named
column, it would cause an invalid SQL error.

Custom attributes should only be qualified if the table has the same
named column.
2019-02-13 02:47:46 +09:00
Ryuta Kamizono
22360534ac Fix relation.create to avoid leaking scope to initialization block and callbacks
`relation.create` populates scope attributes to new record by `scoping`,
it is necessary to assign the scope attributes to the record and to find
STI subclass from the scope attributes.

But the effect of `scoping` is class global, it was caused undesired
behavior that pollute all class level querying methods in initialization
block and callbacks (`after_initialize`, `before_validation`,
`before_save`, etc), which are user provided code.

To avoid the leaking scope issue, restore the original current scope
before initialization block and callbacks are invoked.

Fixes #9894.
Fixes #17577.
Closes #31526.
2019-02-07 21:04:01 +09:00
Ryuta Kamizono
5742344024 An empty transaction does not raise the ReadOnlyError if preventing writes
BEGIN transaction would cause COMMIT or ROLLBACK, so unless COMMIT and
ROLLBACK aren't treated as write queries as well as BEGIN, the
`ReadOnlyError` would be raised.
2018-12-11 21:07:37 +09:00
Ryuta Kamizono
10457475b9 An explain query does not raise the ReadOnlyError if preventing writes 2018-12-11 07:23:00 +09:00
Ryuta Kamizono
07f0f1a8c7 Don't treat begin and rollback transactions as write queries
Otherwise `save` method would raise the `ReadOnlyError` against `BEGIN`
and `ROLLBACK` queries.
2018-12-11 06:40:38 +09:00
Eileen Uchitelle
db54afba2e Rename error that occurs when writing on a read
I originally named this `StatementInvalid` because that's what we do in
GitHub, but `@tenderlove` pointed out that this means apps can't test
for or explitly rescue this error. `StatementInvalid` is pretty broad so
I've renamed this to `ReadOnlyError`.
2018-12-07 08:53:47 -05:00
utilum
d1c2f4d0d9 Assigned but unused variable - bird
See: https://travis-ci.org/rails/rails/jobs/462233144#L1384
2018-12-03 01:36:01 +01:00
Eileen Uchitelle
f39d72d526 Add ability to prevent writes to a database
This PR adds the ability to prevent writes to a database even if the
database user is able to write (ie the database is a primary and not a
replica).

This is useful for a few reasons: 1) when converting your database from
a single db to a primary/replica setup - you can fix all the writes on
reads early on, 2) when we implement automatic database switching or
when an app is manually switching connections this feature can be used
to ensure reads are reading and writes are writing. We want to make sure
we raise if we ever try to write in read mode, regardless of database
type and 3) for local development if you don't want to set up multiple
databases but do want to support rw/ro queries.

This should be used in conjunction with `connected_to` in write mode.
For example:

```
ActiveRecord::Base.connected_to(role: :writing) do
  Dog.connection.while_preventing_writes do
    Dog.create! # will raise because we're preventing writes
  end
end

ActiveRecord::Base.connected_to(role: :reading) do
  Dog.connection.while_preventing_writes do
    Dog.first # will not raise because we're not writing
  end
end
```
2018-11-30 09:28:04 -05:00
DmitryTsepelev
d34c1fc3d6 Cached columns_hash fields should be excluded from ResultSet#column_types 2018-11-27 16:30:26 +03:00
yuuji.yaginuma
7ea546b5c6 Make test_initialize_with_invalid_attribute work correctly
Originally specified attributes were only normal values, and
`ActiveRecord::MultiparameterAssignmentErrors` did not occur.

In addition, an assertion is performed only on rescue, even if an
exception does not occur, the test passes. To avoid this use `assert_raise`.
2018-09-30 09:30:48 +09:00
kenjiszk
15e04b4ef8 add mysql and sqlite3 default test
[Gannon McGibbon + Kenji Suzuki]
2018-09-01 22:09:01 -04:00
Ryuta Kamizono
34cc301f03 Ensure casting by boolean attribute when querying
`QueryAttribute#value_for_database` calls only `type.serialize`, and
`Boolean#serialize` is a no-op unlike other attribute types.

It caused the issue #32624. Whether or not `serialize` will invoke
`cast` is undefined in our test cases, but it actually does not work
properly unless it does so for now.

Fixes #32624.
2018-05-29 05:22:31 +09:00
Takayoshi Nishida
4a3f5a68c9 Fix typo in ActiveRecord test method name 2018-05-02 00:32:27 +07:00
Daniel Colson
a1ac18671a Replace assert ! with assert_not
This autocorrects the violations after adding a custom cop in
3305c78dcd.
2018-04-19 08:11:33 -04:00
Daniel Colson
c1ceafc9d1 Autocorrect refute RuboCop violations
73e7aab behaved as expected on codeship, failing the build with
exactly these RuboCop violations. Hopefully `rubocop -a` will
have been enough to get a passing build!
2018-04-03 22:35:49 -04:00
Andreas Bühmann
d53b259a29 Properly escape column name embedded into regexp
SQLServerAdapter (gem `activerecord-sqlserver-adapter`) uses square
brackets for quoting column names (e.g. `[id]`). Those brackets must not
be misinterpreted in regular expressions.

Failure:
Expected /SELECT [developers].[id].* FROM developers/ to match "SELECT [developers].[id], [developers].[name], [developers].[salary], [developers].[firm_id], [developers].[mentor_id], [developers].[created_at], [developers].[updated_at], [developers].[created_on], [developers].[updated_on] FROM developers".
2018-02-22 14:33:32 +01:00
Daniel Colson
94333a4c31 Use assert_predicate and assert_not_predicate 2018-01-25 23:32:59 -05:00
Daniel Colson
211adb47e7 Change refute to assert_not 2018-01-25 23:32:58 -05:00
Daniel Colson
0d50cae996 Use respond_to test helpers 2018-01-25 23:32:58 -05:00
Ryuta Kamizono
9507b4f02d
Make sql_type of primary key in SQLite to comparable with an integer (#28008)
Originally I tried to add `assert_equal pk.sql_type, ref.sql_type`. But
the assert failed even though the same type due to `sql_type` of primary
key in SQLite is upper case. Prefer lower case like other types.
2017-12-26 16:00:40 +09:00
Ryuta Kamizono
de354cc357 Using table name qualified column names unless having SELECT list explicitly
Previously table name qualified `*` is used in that case. If it is not
qualified with a table name, an ambiguous column name error will occur
when using JOINs.
2017-12-18 01:52:54 +09:00
bogdanvlviv
1a411d4b7f
Convert protected_environments to an array of strings
These changes prevent ignoring environments name of which is a `Symbol`
  ```
  config.active_record.protected_environments = ['staging', :production]
  ```
2017-12-12 23:31:25 +00:00
Rafael França
a681eaf229
Merge pull request #31403 from Edouard-chin/fix-quoted-columnname
Quote colum_names when building select:
2017-12-12 12:31:35 -05:00
Ryuta Kamizono
2b35826389 Enable Layout/SpaceBeforeComma rubocop rule, and fixed more
Follow up of #31390.
2017-12-12 20:00:50 +09:00
Edouard CHIN
2d78c66cd9 Quote colum_names when building select:
- #30980 introcuded a change to not use `Arel.star` when model have ignored columns, a query used to look like `SELECT *. FROM developers` whereas now it would like `SELECT column1, column2 FROM developers`
  - If a column has the same name has a reserved database specific keyword (such as key, where ...) then the query would fail because the names aren't quoted
- Quoting almost always happen unless we use a `from` clause in the query 9965b98dc0/activerecord/lib/active_record/relation/query_methods.rb (L1052)
- This PR cast all columns name to symbols in order for the quoting logic to be picked up 9965b98dc0/activerecord/lib/active_record/relation/query_methods.rb (L1054-L1055)
- A reproduction script can be found here https://gist.github.com/Edouard-chin/f56d464a0adcb76962afc1a9134a1536
2017-12-11 17:25:54 -05:00
Ryuta Kamizono
9b823c02b6
SQLite3 valid integer value should be 8 bytes (64-bit signed integer) (#28379)
This is a regression since Rails 4.2.

SQLite3 integer is stored in 1, 2, 3, 4, 6, or 8 bytes depending on the
magnitude of the value. Assuming default valid value as 4 bytes caused
that actual valid value in INTEGER storage class cannot be stored and
existing value cannot be found.

https://www.sqlite.org/datatype3.html

We should allow valid value in INTEGER storage class in SQLite3 to fix
the regression.

Fixes #22594.
2017-12-03 15:45:40 +09:00
Yasuo Honda
ef0a3d0dfa Allow test_ignored_columns_not_included_in_SELECT column names case
insensitive

i.e. Oracle database identifier is UPPERCASE unlike other databases.

```ruby
(byebug) query = Developer.all.to_sql
"SELECT \"DEVELOPERS\".\"ID\", \"DEVELOPERS\".\"NAME\", \"DEVELOPERS\".\"SALARY\", \"DEVELOPERS\".\"FIRM_ID\", \"DEVELOPERS\".\"MENTOR_ID\", \"DEVELOPERS\".\"CREATED_AT\", \"DEVELOPERS\".\"UPDATED_AT\", \"DEVELOPERS\".\"CREATED_ON\", \"DEVELOPERS\".\"UPDATED_ON\" FROM \"DEVELOPERS\""
```
2017-11-15 17:40:58 +00:00
Jon Moss
6acde9578f
Do not use Arel.star when ignored_columns
If there are any ignored columns, we will now list out all columns we
want to be returned from the database.

Includes a regression test.
2017-11-13 17:41:28 -02:00
Altech
e9f82e76e8 Convert ignored_columns to a list of string 2017-10-20 19:42:44 +09:00
Ryuta Kamizono
207c37a1ec Test ignored_columns value is inheritable by subclasses 2017-10-19 21:07:56 +09:00
Ryuta Kamizono
a516dfd4b4 Fix CI failure due to reference type mismatch
`Firm.id` is a bigint if mysql2 adapter is used, but `firm_id` is an
integer. It will cause an out of range error.

https://travis-ci.org/rails/rails/jobs/264112814#L776
https://travis-ci.org/rails/rails/jobs/264112835#L919
2017-08-14 17:27:54 +09:00
Ryuta Kamizono
f232642879 Remove duplicated assertion in test_count_with_join
The queries both `res2` and `res3` are completely the same.
And also, `assert_nothing_raised` is covered by following assertion.
2017-07-24 13:56:02 +09:00
Kir Shatrov
831be98f9a Use frozen-string-literal in ActiveRecord 2017-07-19 22:27:07 +03:00
Matthew Draper
87b3e226d6 Revert "Merge pull request #29540 from kirs/rubocop-frozen-string"
This reverts commit 3420a14590c0e6915d8b6c242887f74adb4120f9, reversing
changes made to afb66a5a598ce4ac74ad84b125a5abf046dcf5aa.
2017-07-02 02:15:17 +09:30
Kir Shatrov
cfade1ec7e Enforce frozen string in Rubocop 2017-07-01 02:11:03 +03:00
Rafael França
908b136cf2 Merge pull request #26634 from kamipo/extract_numeric_data
Extract `NumericData` model for tests
2017-05-31 15:50:08 -04:00
Ryuta Kamizono
86e74a083a Restore fixtures :author_addresses
This change reverted in eac6f369 but it is needed for data integrity.
See #25328.
2017-04-27 15:44:25 +09:00