| Commit message (Collapse) | Author | Age | Files | Lines |
|\
| |
| |
| | |
Disallow raw SQL in dangerous AR methods
|
| | |
|
| | |
|
| | |
|
| |
| |
| |
| | |
with Arel SQL literator which overrides #concat
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
|\ \
| | |
| | | |
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.
|
| |
| |
| |
| | |
Fixes #21577.
|
|/
|
|
|
| |
Use these to back the attributes API. Stop automatically including
ActiveModel::Dirty in ActiveModel::Attributes, and make it optional.
|
|
|
|
|
|
|
|
| |
It should be shared the count of alias tracking in both INNER/LEFT JOINs
to avoid duplicate aliases.
Fixes #30504.
Closes #30410.
|
|
|
|
| |
This basically reverts 9d4f79d3d394edb74fa2192e5d9ad7b09ce50c6d
|
|
|
|
|
|
|
|
|
| |
parent relation's aliases
Building association scope in join dependency should respect the parent
relation's aliases to avoid using the same alias name more than once.
Fixes #30681.
|
|
|
|
|
| |
This is preparation to respect parent relation's alias tracking for
fixing #30681.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Before
```
> Article.left_joins
ArgumentError: The method .left_outer_joins() must contain arguments.
```
After
```
> Article.left_joins
ArgumentError: The method .left_joins() must contain arguments.
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
```ruby
require 'active_record'
require 'benchmark/ips'
ActiveRecord::Base.establish_connection(ENV.fetch('DATABASE_URL'))
ActiveRecord::Migration.verbose = false
ActiveRecord::Schema.define do
create_table :users, force: true do |t|
t.string :name, :email
t.timestamps null: false
end
end
attributes = {
name: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
email: 'foobar@email.com'
}
class User < ActiveRecord::Base; end
1000.times do
User.create!(attributes)
end
Benchmark.ips do |x|
x.config(time: 10, warmup: 2)
x.report('pluck 1 column') do
User.pluck(:id)
end
x.report('pluck 2 columns') do
User.pluck(:id, :email)
end
x.report('pluck 1 column with scope') do
User.where(id: 1000).pluck(:id)
end
x.report('pluck 2 columns with scope') do
User.where(id: 1000).pluck(:id, :email)
end
end
```
```
Calculating -------------------------------------
pluck 1 column 122.000 i/100ms
pluck 2 columns 74.000 i/100ms
pluck 1 column with scope
615.000 i/100ms
pluck 2 columns with scope
515.000 i/100ms
-------------------------------------------------
pluck 1 column 1.272k (± 3.9%) i/s - 12.810k
pluck 2 columns 750.096 (± 3.3%) i/s - 7.548k
pluck 1 column with scope
6.074k (± 4.1%) i/s - 60.885k
pluck 2 columns with scope
5.158k (± 2.7%) i/s - 52.015k
```
```
Calculating -------------------------------------
pluck 1 column 126.000 i/100ms
pluck 2 columns 78.000 i/100ms
pluck 1 column with scope
457.000 i/100ms
pluck 2 columns with scope
434.000 i/100ms
-------------------------------------------------
pluck 1 column 1.266k (± 2.1%) i/s - 12.726k
pluck 2 columns 795.061 (± 3.0%) i/s - 7.956k
pluck 1 column with scope
4.660k (± 2.1%) i/s - 46.614k
pluck 2 columns with scope
4.355k (± 2.3%) i/s - 43.834k
```
```
Calculating -------------------------------------
pluck 1 column 126.000 i/100ms
pluck 2 columns 78.000 i/100ms
pluck 1 column with scope
539.000 i/100ms
pluck 2 columns with scope
481.000 i/100ms
-------------------------------------------------
pluck 1 column 1.308k (± 3.4%) i/s - 13.104k
pluck 2 columns 798.604 (± 2.8%) i/s - 8.034k
pluck 1 column with scope
5.530k (± 3.4%) i/s - 55.517k
pluck 2 columns with scope
4.914k (± 2.7%) i/s - 49.543k
```
```
Calculating -------------------------------------
pluck 1 column 139.000 i/100ms
pluck 2 columns 79.000 i/100ms
pluck 1 column with scope
580.000 i/100ms
pluck 2 columns with scope
526.000 i/100ms
-------------------------------------------------
pluck 1 column 1.337k (± 3.0%) i/s - 13.483k
pluck 2 columns 806.776 (± 2.7%) i/s - 8.137k
pluck 1 column with scope
5.924k (± 4.1%) i/s - 59.160k
pluck 2 columns with scope
5.276k (± 3.1%) i/s - 53.126k
```
|
|\
| |
| |
| |
| | |
kamipo/relation_merger_should_not_fill_empty_values
`Relation::Merger` should not fill `values` with empty values
|
| | |
|
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Note that the two relations must still have the same `includes` values
(which is the only time `references` actually does anything). It makes
sense for us to allow this, as `references` is called implicitly when
passing a hash to `where`.
Fixes #29411
|
|/
|
|
|
| |
Since 213796f removed `binds`, `JoinInformation` only contain `joins`.
So it is enough to return `joins` simply.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A common source of bugs and code bloat within Active Record has been the
need for us to maintain the list of bind values separately from the AST
they're associated with. This makes any sort of AST manipulation
incredibly difficult, as any time we want to potentially insert or
remove an AST node, we need to traverse the entire tree to find where
the associated bind parameters are.
With this change, the bind parameters now live on the AST directly.
Active Record does not need to know or care about them until the final
AST traversal for SQL construction. Rather than returning just the SQL,
the Arel collector will now return both the SQL and the bind parameters.
At this point the connection adapter will have all the values that it
had before.
A bit of this code is janky and something I'd like to refactor later. In
particular, I don't like how we're handling associations in the
predicate builder, the special casing of `StatementCache::Substitute` in
`QueryAttribute`, or generally how we're handling bind value replacement
in the statement cache when prepared statements are disabled.
This also mostly reverts #26378, as it moved all the code into a
location that I wanted to delete.
/cc @metaskills @yahonda, this change will affect the adapters
Fixes #29766.
Fixes #29804.
Fixes #26541.
Close #28539.
Close #24769.
Close #26468.
Close #26202.
There are probably other issues/PRs that can be closed because of this
commit, but that's all I could find on the first few pages.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Without this fix, `JoinDependency` doesn't use a custom table alias:
```
% ARCONN=sqlite3 be ruby -w -Itest test/cases/relations_test.rb -n test_using_a_custom_table_with_joins_affects_the_wheres
Using sqlite3
Run options: -n test_using_a_custom_table_with_joins_affects_the_wheres --seed 14531
E
Error:RelationTest#test_using_a_custom_table_with_joins_affects_the_wheres:
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: posts.author_id: SELECT "omg_posts".* FROM "posts" "omg_posts" INNER JOIN "authors" ON "authors"."id" = "posts"."author_id" WHERE "omg_posts"."title" = ? LIMIT ?
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Without this fix, SELECT clause doesn't use a custom table alias name:
```
% ARCONN=sqlite3 be ruby -w -Itest test/cases/relations_test.rb -n test_using_a_custom_table_affects_the_wheres
Using sqlite3
Run options: -n test_using_a_custom_table_affects_the_wheres --seed 31818
E
Error:
RelationTest#test_using_a_custom_table_affects_the_wheres:
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such table: posts: SELECT "posts".* FROM "posts" "omg_posts" WHERE "omg_posts"."title" = ? LIMIT ?
```
|
|
|
|
| |
[ci skip]
|
|
|
|
|
|
|
| |
This is related with #27680.
Since `where_values_hash` keys constructed by `where` are string, so we
need `stringify_keys` to `create_with_value` before merging it.
|
|
|
|
|
|
|
|
|
|
|
| |
The `find_each`, `find_in_batches` and `in_batches` APIs usually operate
on large numbers of records, where it's preferable not to load them all
into memory at once.
If the query cache is enabled, it will hold onto the query results until
the end of the execution context (request/job), which means the memory
used is still proportional to the total number of records. These queries
are typically not repeated, so the query cache isn't desirable here.
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
```ruby
require "benchmark/ips"
require "set"
array = [:asc, :desc, :ASC, :DESC, "asc", "desc", "ASC", "DESC"]
set = array.to_set
item = "DESC"
Benchmark.ips do |x|
x.report "array" do
array.include?(item)
end
x.report "set" do
set.include?(item)
end
end
```
```
% ruby array_vs_set.rb
Warming up --------------------------------------
array 188.441k i/100ms
set 229.531k i/100ms
Calculating -------------------------------------
array 3.508M (± 9.0%) i/s - 17.525M in 5.043058s
set 5.134M (± 7.6%) i/s - 25.707M in 5.038921s
```
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When `order` is given a hash, the keys are currently assumed to be
attribute names and are quoted as such in the query, which makes it
impossible to pass an expression instead:
Post.order("LENGTH(title)" => :asc).last
# SELECT `posts`.* FROM `posts` ORDER BY `posts`.`LENGTH(title)` DESC LIMIT 1
If the key is an `Arel::Nodes::SqlLiteral`, we now use it directly in
the query. This provides a way to build a relation with a complex order
clause that can still be reversed with `reverse_order` or `last`.
|
|
|
|
| |
Actually, private methods cannot be called with `self.`, so it's not just redundant, it's a bad habit in Ruby
|
| |
|
| |
|
|
|
|
| |
provided.
|
| |
|
|
|
|
| |
All query methods calls `spawn` and bang method, but only `none` is not.
|
|
|
|
|
|
| |
Regexp#match? should be considered to be part of the Ruby core library. We are
emulating it for < 2.4, but not having to require the extension is part of the
illusion of the emulation.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- CollectionAssociation#select was removed in
https://github.com/rails/rails/pull/25989 in favor of
QueryMethods#select but it caused a regression when passing arguments
to select and a block.
- This used to work earlier in Rails 4.2 and Rails 5. See gist
https://gist.github.com/prathamesh-sonpatki/a7df922273473a77dfbc742a4be4b618.
- This commit restores the behavior of Rails 4.2 and Rails 5.0.0 to
allow passing arguments and block at the same time but also deprecates
it.
- Because, these arguments do not have any effect on the output of
select when select is used with a block.
- Updated documentation to remove the example passing arguments and
block at the same time to `CollectionProxy#select`.
|
|
|
|
|
|
| |
All indentation was normalized by rubocop auto-correct at 80e66cc4d90bf8c15d1a5f6e3152e90147f00772.
But comments was still kept absolute position. This commit aligns
comments with method definitions for consistency.
|
|
|
|
|
|
|
|
|
| |
Recently, the Rails team made an effort to keep the source code consistent, using Ruboco
(bb1ecdcc677bf6e68e0252505509c089619b5b90 and below). Some of the case
statements were missed.
This changes the case statements' formatting and is consistent with changes
in 810dff7c9fa9b2a38eb1560ce0378d760529ee6b and db63406cb007ab3756d2a96d2e0b5d4e777f8231.
|
|
|
|
|
| |
Bang methods of `AR::QueryMethods` are used only internally.
We only use `left_outer_joins!`, so we can remove this alias.
|
|
|
|
| |
For reduce instantiating `Type::Value`.
|