| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
| |
This follows #35595.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The default log messages for Model.exists?, when called from .save
on an object which uses scoped uniqueness validation like:
class Example < ApplicationRecord
validates :field, uniqueness: {scope: parent_id}
end
can result in slightly misleading logs.
An example case:
↳ app/controllers/example_controller.rb:23
(0.2ms) begin transaction
↳ app/controllers/example_controller.rb:39
Example Exists (0.2ms) SELECT 1 AS one FROM "examples" WHERE "examples"."field" IS NULL AND "examples"."parent_id" = ? LIMIT ? [["parent_id", 123], ["LIMIT", 1]]
↳ app/controllers/example_controller.rb:39
(0.1ms) rollback transaction
To me, a Rails newbie, this parsed as the following:
- started the transaction to create a thing
- found that your object exists already!
- so we rolled back the transaction
(even though the actual cause of the transaction is something that happens
after the Exists check.)
All this does is add a question mark to the message, to make it clear in the
log that this is a check, not a confirmation.
This may be kind of silly, but it may save some future goofs by newbs like me.
|
|
|
|
| |
This is also resolved in `arel_column`.
|
|
|
|
| |
Follow up of c9e4c848eeeb8999b778fa1ae52185ca5537fffe.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This refactors `execute_grouped_calculation` and slightly changes
generated GROUP BY queries, since I'd not prefer to repeat same
expression in SELECT and GROUP BY clauses.
Before:
```
SELECT COUNT(*) AS count_all, "topics"."author_name" AS topics_author_name, COALESCE(type, title) AS coalesce_type_title FROM "topics" GROUP BY "topics"."author_name", COALESCE(type, title)
```
After:
```
SELECT COUNT(*) AS count_all, "topics"."author_name" AS topics_author_name, COALESCE(type, title) AS coalesce_type_title FROM "topics" GROUP BY topics_author_name, coalesce_type_title
```
Although we generally don't guarantee to support Arel node constructed
by user itself, this also fixes #24207.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Originally the `JoinDependency` has the deduplication for eager loading
(LEFT JOIN). This re-uses that deduplication for `left_joins`.
And also, This makes left join order into part of joins, i.e.:
Before:
```
association joins -> stash joins (eager loading, etc) -> string joins -> left joins
```
After:
```
association joins -> stash joins (eager loading, left joins, etc) -> string joins
```
Now string joins are able to refer left joins.
Fixes #34325.
Fixes #34332.
Fixes #34536.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This follows up ebc09ed9ad9a04338138739226a1a92c7a2707ee.
We've still experienced a regression for `size` (`count(:all)`) with
eager loading and explicit select and order when upgrading Rails to 5.1.
In that case, the eager loading enforces `distinct` to subselect but
still keep the custom select, it would cause the ORDER BY with DISTINCT
issue.
```
% ARCONN=postgresql bundle exec ruby -w -Itest test/cases/relations_test.rb -n test_size_with_eager_loading_and_custom_select_and_order
Using postgresql
Run options: -n test_size_with_eager_loading_and_custom_select_and_order --seed 8356
# Running:
E
Error:
RelationTest#test_size_with_eager_loading_and_custom_select_and_order:
ActiveRecord::StatementInvalid: PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
LINE 1: ..." ON "comments"."post_id" = "posts"."id" ORDER BY comments.i...
^
```
As another problem on `distinct` is enforced, the result of `count`
becomes fewer than expected if `select` is given explicitly.
e.g.
```ruby
Post.select(:type).count
# => 11
Post.select(:type).distinct.count
# => 3
```
As long as `distinct` is enforced, we need to care to keep the result of
`count`.
This fixes both the `count` with eager loading problems.
|
|
|
|
|
| |
I've experienced this issue in our app, some hints only works on Top
level query (e.g. `MAX_EXECUTION_TIME`).
|
|\
| |
| |
| |
| |
| | |
Update API doc for #includes on unnecessary #references
[ci skip]
|
| |
| |
| |
| | |
Update doc for #includes to clarify that #references is unnecessary when conditions are passed into #includes as a hash.
|
|/
|
|
|
| |
record (#35784)
* Add `ActiveRecord::Relation#extract_associated` for extracting associated records from a relation
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This patch has two main portions:
1. Add SQL comment support to Arel via Arel::Nodes::Comment.
2. Implement a Relation#annotate method on top of that.
== Adding SQL comment support
Adds a new Arel::Nodes::Comment node that represents an optional SQL
comment and teachers the relevant visitors how to handle it.
Comment nodes may be added to the basic CRUD statement nodes and set
through any of the four (Select|Insert|Update|Delete)Manager objects.
For example:
manager = Arel::UpdateManager.new
manager.table table
manager.comment("annotation")
manager.to_sql # UPDATE "users" /* annotation */
This new node type will be used by ActiveRecord::Relation to enable
query annotation via SQL comments.
== Implementing the Relation#annotate method
Implements `ActiveRecord::Relation#annotate`, which accepts a comment
string that will be appeneded to any queries generated by the relation.
Some examples:
relation = Post.where(id: 123).annotate("metadata string")
relation.first
# SELECT "posts".* FROM "posts" WHERE "posts"."id" = 123
# LIMIT 1 /* metadata string */
class Tag < ActiveRecord::Base
scope :foo_annotated, -> { annotate("foo") }
end
Tag.foo_annotated.annotate("bar").first
# SELECT "tags".* FROM "tags" LIMIT 1 /* foo */ /* bar */
Also wires up the plumbing so this works with `#update_all` and
`#delete_all` as well.
This feature is useful for instrumentation and general analysis of
queries generated at runtime.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We as Arm Treasure Data are using Optimizer Hints with a monkey patch
(https://gist.github.com/kamipo/4c8539f0ce4acf85075cf5a6b0d9712e),
especially in order to use `MAX_EXECUTION_TIME` (refer #31129).
Example:
```ruby
class Job < ApplicationRecord
default_scope { optimizer_hints("MAX_EXECUTION_TIME(50000) NO_INDEX_MERGE(jobs)") }
end
```
Optimizer Hints is supported not only for MySQL but also for most
databases (PostgreSQL on RDS, Oracle, SQL Server, etc), it is really
helpful to turn heavy queries for large scale applications.
|
|\
| |
| | |
Replace “can not” with “cannot”.
|
| | |
|
|/ |
|
|
|
|
|
|
|
|
|
|
| |
#35360 allows table name qualified if `from` has original table name.
But that is still too strict. We have a valid use case that `from` with
INDEX hint (e.g. `from("comments USE INDEX (PRIMARY)")`).
So I've relaxed the table name detection in `from` to allow any
extension like INDEX hint.
Fixes #35359.
|
|\
| |
| | |
Add reselect method
|
| | |
|
| |\ |
|
| |\ \ |
|
| |\ \ \ |
|
| | | | | |
|
| | | | |
| | | | |
| | | | |
| | | | | |
`primary key` is integer
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
It's mentioned everywhere as `ActiveRecord::RecordNotFound` so to be
coherent with the rest of the documentation I've applied it here.
Also doc was saying if the parameter is integer it coerces it which is
other way around.
|
| | | | |
| | | | |
| | | | |
| | | | | |
`ClassSpecificRelation`
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
DISTINCT
When using `select` with `'DISTINCT( ... )'` if you use method `size` on a non loaded relation it overrides the column selected by passing `:all` so it returns different value than count.
This fixes #35214
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
This is caused by 0ee96d1.
Since #18744, `select` columns doesn't be qualified by table name if
using `from`. 0ee96d1 follows that for `pluck` as well.
But people depends that `pluck` columns are qualified even if using
`from`.
So I've fixed that to be qualified if `from` has the original table name
to keep the behavior as much as before.
Fixes #35359.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Revert "Fix lint `ShadowingOuterLocalVariable`"
This reverts commit 38bd45a48992b500478a82d56d31468a322937a8.
Change of variable name
Fix lint `ShadowingOuterLocalVariable`
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
That is considered as silently leaking information.
If type casting doesn't return any actual value, it should not be
matched to any record.
Fixes #33624.
Closes #33946.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
This fixes a bug that the `foreign_key` and the `foreign_type` are
separated as different table conditions if a polymorphic association has
a scope that joins another tables.
|
|\ \ \ \ \
| | | | | |
| | | | | | |
Raise ActiveRecord::IrreversibleOrderError if nulls first/last is not a single ordering argument.
|
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
single ordering argument.
|
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
This follows up 0ee96d13de29680e148ccb8e5b68025f29fd091c.
|
|/ / / / /
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
as leaked
This deprecates using class level querying methods if the receiver scope
regarded as leaked, since #32380 and #35186 may cause that silently
leaking information when people upgrade the app.
We need deprecation first before making those.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
methods"
This reverts #32380, since this may cause that silently leaking
information when people upgrade the app.
We need deprecation first before making this.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
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.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
The `distinct` affects (reduces) rows of the result, so it is important
part when both `distinct` and `offset` are given.
Replacing SELECT clause to `1 AS one` and removing `distinct` and
`order` is just optimization for the `exists?`, we should not apply the
optimization for that case.
Fixes #35191.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Don't use `false` as special value to skip to find inherited scope, we
could use `skip_inherited_scope = true`, and move `_scoping` back on
Relation.
|
| | | | |
| | | | |
| | | | |
| | | | | |
This follows up d97980a16d76ad190042b4d8578109714e9c53d0.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Active Record uses `scoping` to delegate to named scopes from relations
for propagating the chaining source scope. It was needed to restore the
source scope in named scopes, but it was caused undesired behavior that
pollute all class level querying methods.
Example:
```ruby
class Topic < ActiveRecord::Base
scope :toplevel, -> { where(parent_id: nil) }
scope :children, -> { where.not(parent_id: nil) }
scope :has_children, -> { where(id: Topic.children.select(:parent_id)) }
end
# Works as expected.
Topic.toplevel.where(id: Topic.children.select(:parent_id))
# Doesn't work due to leaking `toplevel` to `Topic.children`.
Topic.toplevel.has_children
```
Since #29301, the receiver in named scopes has changed from the model
class to the chaining source scope, so the polluting class level
querying methods is no longer required for that purpose.
Fixes #14003.
|
| | | | | |
|
| | | | | |
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Currently several queries cannot return correct result due to incorrect
`RangeError` handling.
First example:
```ruby
assert_equal true, Topic.where(id: [1, 9223372036854775808]).exists?
assert_equal true, Topic.where.not(id: 9223372036854775808).exists?
```
The first example is obviously to be true, but currently it returns
false.
Second example:
```ruby
assert_equal topics(:first), Topic.where(id: 1..9223372036854775808).find(1)
```
The second example also should return the object, but currently it
raises `RecordNotFound`.
It can be seen from the examples, the queries including large number
assuming empty result is not always correct.
Therefore, This change handles `RangeError` to generate executable SQL
instead of raising `RangeError` to users to always return correct
result. By this change, it is no longer raised `RangeError` to users.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
The `unboundable?` behaves like the `infinite?`.
```ruby
inf = Topic.predicate_builder.build_bind_attribute(:id, Float::INFINITY)
inf.infinite? # => 1
oob = Topic.predicate_builder.build_bind_attribute(:id, 9999999999999999999999999999999)
oob.unboundable? # => 1
inf = Topic.predicate_builder.build_bind_attribute(:id, -Float::INFINITY)
inf.infinite? # => -1
oob = Topic.predicate_builder.build_bind_attribute(:id, -9999999999999999999999999999999)
oob.unboundable? # => -1
```
|
|\ \ \ \ \
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
dylanahsmith/better-composed-of-single-field-query
activerecord: Use a simpler query condition for aggregates with one mapping
|
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | | |
methods by default
Co-Authored-By: dylanahsmith <dylan.smith@shopify.com>
|
| | | | | | |
|
| | | | | | |
|