| Commit message (Collapse) | Author | Age | Files | Lines |
... | |
|\ \
| | |
| | |
| | | |
Allow unscoping of left_outer_joins
|
| | | |
|
| | |
| | |
| | |
| | | |
Because `Relation` already have Arel `table`.
|
| | |
| | |
| | |
| | |
| | | |
This is a partial revert of #26182. There is no reason to change the
default value.
|
| | |
| | |
| | |
| | | |
Like other query bang methods.
|
| | |
| | |
| | |
| | |
| | |
| | | |
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.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Currently, sanitize methods are private. So need `send` to use from
outside class.
However, sometimes want to use sanitize methods from outside Class when
want to generate SQL including multiple tables like search.
In order to avoid using `send` in such a case, changed methods to public.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
- #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 https://github.com/rails/rails/blob/9965b98dc0d58a86e10b4343bb6e15e01661a8c3/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 https://github.com/rails/rails/blob/9965b98dc0d58a86e10b4343bb6e15e01661a8c3/activerecord/lib/active_record/relation/query_methods.rb#L1054-L1055
- A reproduction script can be found here https://gist.github.com/Edouard-chin/f56d464a0adcb76962afc1a9134a1536
|
|\ \ \
| | | |
| | | |
| | | | |
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.
|