| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|\
| |
| |
| |
| | |
eileencodes/fix-query-cache-for-database-switching
Invalidate all query caches for current thread
|
| |
| |
| |
| |
| |
| | |
This change ensures that all query cahces are cleared across all
connections per handler for the current thread so if you write on one
connection the read will have the query cache cleared.
|
|\ \
| | |
| | | |
Hint at advanced options for foreign_key
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
We sometimes display simple examples of additional parameters that can be
supplied to table-wise methods like these and I found it particularly difficult
to figure out which options `t.foreign_key` accepts without drilling very deep
into the specific SchemaStatements docs.
Since it's relatively common to create foreign keys with custom column names or
primary keys, it seems like this should help quite a few people.
[ci skip]
|
|\ \ \
| |_|/
|/| | |
Eagerly materialize the fixtures transaction
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The transaction used to restore fixtures is an implementation detail
that should be abstracted away. Idealy a test should behave the same
wether or not transactional fixtures are enabled.
However since transactions have been made lazy, the fixture
transaction started leaking into tests case. e.g. consider the
following (oversimplified) test:
```ruby
class SQLSubscriber
attr_accessor :sql
def initialize
@sql = []
end
def call(*, event)
sql << event[:sql]
end
end
subscriber = SQLSubscriber.new
ActiveSupport::Notifications.subscribe("sql.active_record", subscriber)
User.connection.execute('SELECT 1', 'Generic name')
assert_equal ['SELECT 1'], subscriber.sql
```
On Rails 6 it starts to break because the `sql` array will be `['BEGIN', 'SELECT 1']`.
Several things are wrong here:
- That transaction is not generated by the tested code, so it shouldn't be visible.
- The transaction is not even closed yet, which again doesn't reflect the reality.
|
|/ /
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
I deprecated two unused attr_writers `visitor` and `indexes` at 8056fe0
and f4bc364 conservatively, since those are accidentaly exposed in the
docs.
https://api.rubyonrails.org/v5.2/classes/ActiveRecord/ConnectionAdapters/AbstractAdapter.html
https://api.rubyonrails.org/v5.2/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html
But I've found that `view_renderer` attr_writer is removed without
deprecation at #35093, that is also exposed in the doc.
https://api.rubyonrails.org/v5.2/classes/ActionView/Base.html
I'd like to also remove the deprecated attr_writers since I think that
removing `visitor` and `indexes` attr_writers is as safe as removing
`view_renderer` attr_writer.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
In MySQL, the text column size is 65,535 bytes by default (1 GiB in
PostgreSQL). It is sometimes too short when people want to use a text
column, so they sometimes change the text size to mediumtext (16 MiB) or
longtext (4 GiB) by giving the `limit` option.
Unlike MySQL, PostgreSQL doesn't allow the `limit` option for a text
column (raises ERROR: type modifier is not allowed for type "text").
So `limit: 4294967295` (longtext) couldn't be used in Action Text.
I've allowed changing text and blob size without giving the `limit`
option, it prevents that migration failure on PostgreSQL.
|
| |
| |
| |
| |
| | |
This improves performance of timestamp conversion and avoids
additional string allocations.
|
| | |
|
| | |
|
| | |
|
|/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
While working on another feature for multiple databases (auto-switching)
I observed that in development the first request won't autoload the
application record connection for the primary database and may not yet
know about the replica connection.
In my test application this caused the application to thrown an error if
I tried to send the first request to the replica before the replica was
connected. This wouldn't be an issue in production because the
application is preloaded.
In order to fix this I decided to leave the original error message and
delete the new error message. I updated the original error message to
include the `role` to make it a bit clearer that the connection isn't
established for that particular role.
The error now reads:
```
No connection pool with 'primary' found for the 'reading' role.
```
A single database application will continue uisng the original error
message:
```
No connection pool with 'primary' found.
```
|
|
|
|
|
|
|
|
|
|
|
| |
Currently `conn.column_exists?("testings", "created_at", "datetime")`
returns false even if the table has the `created_at` column.
That reason is that `column.type` is a symbol but passed `type` is not
normalized to symbol unlike `column_name`, it is surprising behavior to
me.
I've improved that to normalize a value before comparison.
|
|
|
|
|
|
|
|
|
|
|
|
| |
https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-14.html
> Error messages relating to creating and dropping foreign keys
> were improved to be more specific and informative. (Bug #28526309, Bug #92087)
https://dev.mysql.com/doc/refman/8.0/en/server-error-reference.html
> Error number: 3780; Symbol: ER_FK_INCOMPATIBLE_COLUMNS; SQLSTATE: HY000
> Message: Referencing column '%s' and referenced column '%s' in foreign key constraint '%s' are incompatible.
> ER_FK_INCOMPATIBLE_COLUMNS was added in 8.0.14.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Since #31230, `change_column` is executed as a bulk statement.
That caused incorrect type casting column default by looking up the
before changed type, not the after changed type.
In a bulk statement, we can't use `change_column_default_for_alter` if
the statement changes the column type.
This fixes the type casting to use the constructed target sql_type.
Fixes #34938.
|
|\
| |
| | |
Fix error message when adapter is not specified
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
When we added support for multiple databases through a 3-tiered config
and configuration objects this error message got a bit convoluted.
Previously if you had an application with a missing configuation and
multiple databases the error message would look like this:
```
'doesnexist' database is not configured. Available: development,
development, test, test, production, production
(ActiveRecord::AdapterNotSpecified)
```
That's not very descriptive since it duplicates the environments
(because there are multiple databases per environment for this
application).
To fix this I've constructed a bit more readable error message which now
reads like this if you have a multi db app:
```
The `doesntexist` database is not configured for the `production`
environment. (ActiveRecord::AdapterNotSpecified)
Available databases configurations are:
development: primary, primary_readonly
test: primary, primary_readonly
production: primary, primary_readonly
```
And like this if you have a single db app:
```
The `doesntexist` database is not configured for the `production`
environment. (ActiveRecord::AdapterNotSpecified)
Available databases configurations are:
development
test
```
This makes the error message more readable and presents the user all
available options for the database connections.
|
| | |
|
| | |
|
| | |
|
| |
| |
| |
| | |
`ActiveRecord::ConnectionAdapters::SQLite3Adapter#valid_alter_table_type?`
|
|/ |
|
|
|
|
|
|
| |
The `@prevent_writes` should be updated only in the
`while_preventing_writes`, it is not necessary to expose the attr
writer.
|
|
|
|
|
|
|
|
|
| |
This attr writer was introduced at 7db90aa, but the usage is already
removed at bd2f5c0 before v3.2.0.rc1 is released.
If we'd like to customize the visitor in the connection, `arel_visitor`
which is implemented in all adapters (mysql2, postgresql, sqlite3,
oracle-enhanced, sqlserver) could be used for the purpose #23515.
|
|
|
|
| |
Since #26002, `id_value` is no longer passed to `sql_for_insert`.
|
|
|
|
| |
predicate construction
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Enable `Lint/UselessAssignment` cop to avoid unused variable warnings
Since we've addressed the warning "assigned but unused variable"
frequently.
370537de05092aeea552146b42042833212a1acc
3040446cece8e7a6d9e29219e636e13f180a1e03
5ed618e192e9788094bd92c51255dda1c4fd0eae
76ebafe594fc23abc3764acc7a3758ca473799e5
And also, I've found the unused args in c1b14ad which raises no warnings
by the cop, it shows the value of the cop.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
`nil`, `Numeric`, and `String` are most basic objects which are passed
to `type_cast`. But now each `when *types_which_need_no_typecasting`
evaluation allocates extra two arrays, it makes `type_cast` slower.
The `types_which_need_no_typecasting` was introduced at #15351, but the
method isn't useful (never used any adapters) since all adapters
(sqlite3, mysql2, postgresql, oracle-enhanced, sqlserver) still
overrides the `_type_cast`.
Just expanding the method would make the `type_cast` 2x faster.
```ruby
module ActiveRecord
module TypeCastFast
def type_cast_fast(value, column = nil)
value = id_value_for_database(value) if value.is_a?(Base)
if column
value = type_cast_from_column(column, value)
end
_type_cast_fast(value)
rescue TypeError
to_type = column ? " to #{column.type}" : ""
raise TypeError, "can't cast #{value.class}#{to_type}"
end
private
def _type_cast_fast(value)
case value
when Symbol, ActiveSupport::Multibyte::Chars, Type::Binary::Data
value.to_s
when true then unquoted_true
when false then unquoted_false
# BigDecimals need to be put in a non-normalized form and quoted.
when BigDecimal then value.to_s("F")
when nil, Numeric, String then value
when Type::Time::Value then quoted_time(value)
when Date, Time then quoted_date(value)
else raise TypeError
end
end
end
end
conn = ActiveRecord::Base.connection
conn.extend ActiveRecord::TypeCastFast
Benchmark.ips do |x|
x.report("type_cast") { conn.type_cast("foo") }
x.report("type_cast_fast") { conn.type_cast_fast("foo") }
x.compare!
end
```
```
Warming up --------------------------------------
type_cast 58.733k i/100ms
type_cast_fast 101.364k i/100ms
Calculating -------------------------------------
type_cast 708.066k (± 5.9%) i/s - 3.583M in 5.080866s
type_cast_fast 1.424M (± 2.3%) i/s - 7.197M in 5.055860s
Comparison:
type_cast_fast: 1424240.0 i/s
type_cast: 708066.0 i/s - 2.01x slower
```
|
|\
| |
| | |
Only define attribute methods from schema cache
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
To define the attribute methods for a model, Active Record needs to know
the schema of the underlying table, which is usually achieved by making
a request to the database. This is undesirable behaviour while the app
is booting, for two reasons: it makes the boot process dependent on the
availability of the database, and it means every new process will make
one query for each table, which can cause issues for large applications.
However, if the application is using the schema cache dump feature, then
the schema cache already contains the necessary information, and we can
define the attribute methods without causing any extra database queries.
|
| |
| |
| |
| | |
Since we already bumped the minimum version of MySQL to 5.5.8 at #33853.
|
| |
| |
| |
| | |
Since the `preventing_writes?` is public API.
|
| |
| |
| |
| |
| |
| |
| |
| | |
directly
Since `migration_context` has `migrations_paths` itself and provides
methods which returning values from parsed migration files, so there is
no reason to use the `parse_migration_filename` low level API directly.
|
| |
| |
| |
| |
| |
| |
| | |
`connection.assume_migrated_upto_version`
Since #31727, `migrations_paths` in `assume_migrated_upto_version` is no
longer used.
|
|\ \
| | |
| | | |
MySQL: `ROW_FORMAT=DYNAMIC` create table option by default
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Since MySQL 5.7.9, the `innodb_default_row_format` option defines the
default row format for InnoDB tables. The default setting is `DYNAMIC`.
The row format is required for indexing on `varchar(255)` with `utf8mb4`
columns.
As long as using MySQL 5.6, CI won't be passed even if MySQL server
setting is properly configured the same as MySQL 5.7
(`innodb_file_per_table = 1`, `innodb_file_format = 'Barracuda'`, and
`innodb_large_prefix = 1`) since InnoDB table is created as the row
format `COMPACT` by default on MySQL 5.6, therefore indexing on string
with `utf8mb4` columns aren't succeeded.
Making `ROW_FORMAT=DYNAMIC` create table option by default for legacy
MySQL version would mitigate the indexing issue on the user side, and it
makes CI would be passed on MySQL 5.6 which is configured properly.
|
|/ /
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Currently we sometimes find a redundant begin block in code review
(e.g. https://github.com/rails/rails/pull/33604#discussion_r209784205).
I'd like to enable `Style/RedundantBegin` cop to avoid that, since
rescue/else/ensure are allowed inside do/end blocks in Ruby 2.5
(https://bugs.ruby-lang.org/issues/12906), so we'd probably meets with
that situation than before.
|
| |
| |
| |
| | |
The indexing issue on `utf8mb4` columns is resolved since MySQL 5.7.9.
|
| |
| |
| |
| | |
consistently
|
| |
| |
| |
| |
| |
| | |
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.
|
| | |
|
| |
| |
| |
| |
| | |
Otherwise `save` method would raise the `ReadOnlyError` against `BEGIN`
and `ROLLBACK` queries.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Without this change, mysql2 adapter with prepared statements won't pass
`base_test.rb`.
```
% ARCONN=mysql2 be ruby -w -Itest test/cases/base_test.rb
Using mysql2
Run options: --seed 27614
# Running:
....S..............................F
Failure:
BasicsTest#test_creating_a_record_raises_if_preventing_writes [test/cases/base_test.rb:1493]:
ActiveRecord::ReadOnlyError expected but nothing was raised.
rails test test/cases/base_test.rb:1492
...F
Failure:
BasicsTest#test_deleting_a_record_raises_if_preventing_writes [test/cases/base_test.rb:1513]:
ActiveRecord::ReadOnlyError expected but nothing was raised.
rails test test/cases/base_test.rb:1510
............................................................................................................F
Failure:
BasicsTest#test_updating_a_record_raises_if_preventing_writes [test/cases/base_test.rb:1503]:
ActiveRecord::ReadOnlyError expected but nothing was raised.
rails test test/cases/base_test.rb:1500
..........
Finished in 2.534490s, 62.7345 runs/s, 149.5370 assertions/s.
159 runs, 379 assertions, 3 failures, 0 errors, 1 skips
```
|
| |
| |
| |
| | |
Follow up #34505.
|
| |
| |
| |
| |
| |
| |
| | |
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`.
|
| | |
|