| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
| |
Follow up of #31513.
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
| |
I've found the skewness of delegation methods between `except` and
`only` in a88b6f2.
The `only` method is closely similar with `except` as `SpawnMethods`.
https://github.com/rails/rails/blob/e056b9bfb07c4eb3bcc6672d885aadd72bec574f/activerecord/lib/active_record/relation/spawn_methods.rb#L53-L67
It is preferable both behaves the same way.
|
|
|
|
| |
This makes to ease testing `QUERYING_METHODS`.
|
| |
|
|\
| |
| |
| | |
Introduce delete_by and destroy_by methods to ActiveRecord::Relation
|
|/ |
|
|
|
|
| |
Fixed the CI failure https://travis-ci.org/rails/rails/jobs/492291248#L1185-L1191.
|
|
|
|
|
|
| |
* Break up long sentences
* Reword some sentences to clarify subject, predicate, and object
* Explain drawbacks of using count_by_sql
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This commit speeds up allocating homogeneous lists of AR objects. We
can know if the result set contains an STI column before initializing
every AR object, so this change pulls the "does this result set contain
an STI column?" test up, then uses a specialized instantiation function.
This way we only have to check for an STI column once rather than N
times.
This change also introduces a new initialization function that is meant
for use when allocating AR objects that come from the database. Doing
this allows us to eliminate one hash allocation per AR instance.
Here is a benchmark:
```ruby
require 'active_record'
require 'benchmark/ips'
ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
ActiveRecord::Migration.verbose = false
ActiveRecord::Schema.define do
create_table :users, force: true do |t|
t.string :name
t.timestamps null: false
end
end
class User < ActiveRecord::Base; end
2000.times do
User.create!(name: "Gorby")
end
Benchmark.ips do |x|
x.report("find") do
User.limit(2000).to_a
end
end
```
Results:
Before:
```
[aaron@TC activerecord (master)]$ be ruby -I lib:~/git/allocation_tracer/lib speed.rb
Warming up --------------------------------------
find 5.000 i/100ms
Calculating -------------------------------------
find 56.192 (± 3.6%) i/s - 285.000 in 5.080940s
```
After:
```
[aaron@TC activerecord (homogeneous-allocation)]$ be ruby -I lib:~/git/allocation_tracer/lib speed.rb
Warming up --------------------------------------
find 7.000 i/100ms
Calculating -------------------------------------
find 72.204 (± 2.8%) i/s - 364.000 in 5.044592s
```
|
|\
| |
| |
| |
| |
| | |
yujideveloper/feature/delegate-ar-base-pick-to-all
Add `delegate :pick, to: :all`
|
|/ |
|
|
|
| |
Add #create_or_find_by to lean on unique constraints
|
|
|
|
|
|
|
|
|
|
| |
`Persistence::ClassMethods`
The docs are obviously for class level `update`, `destroy`, and
`delete`. It should be placed in `Persistence::ClassMethods` rather than
`Relation`. And also, these methods are not dependent on relation. So it
is not needed to delegate to `all` (plus, `klass.find` is faster than
`relation.find`).
|
| |
|
|
|
|
|
| |
This reverts commit 3420a14590c0e6915d8b6c242887f74adb4120f9, reversing
changes made to afb66a5a598ce4ac74ad84b125a5abf046dcf5aa.
|
| |
|
| |
|
|
|
|
|
| |
This was causing an infinity loop since it was delegating to `all` and
all delegating back to this module.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If a parent association was accessed in an `after_find` or
`after_initialize` callback, it would always end up loading the
association, and then immediately overwriting the association we just
loaded. If this occurred in a way that the parent's `current_scope` was
set to eager load the child, this would result in an infinite loop and
eventually overflow the stack.
For records that are created with `.new`, we have a mechanism to
perform an action before the callbacks are run. I've introduced the same
code path for records created with `instantiate`, and updated all code
which sets inverse instances on newly loaded associations to use this
block instead.
Fixes #26320.
|
|
|
|
| |
Because `sanitize_conditions` protected method is only used in one place.
|
|
|
|
|
| |
The current code base is not uniform. After some discussion,
we have chosen to go with double quotes by default.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Changing the order of method chaining `merge` and other query
method such as `joins` should produce the same result.
```ruby
class Topic < ApplicationRecord
scope :safe_chaininig, -> { joins(:comments).merge(Comment.newest) }
scope :unsafe_chaininig, -> { merge(Comment.newest).joins(:comments) } #=> NoMethodError
end
```
|
|
|
|
|
|
|
|
|
|
| |
Unlike `one?` and `none?`, `empty?` has interactions with methods
outside of enumerable. It also doesn't fit in the same vein.
`Topic.any?` makes sense. `Topic.empty?` does not, as `Topic` is not a
container.
Fixes #24808
Close #24812
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In Rails 5, we're much more restrictive about when we do or don't cache
a prepared statement. In particular, we never cache when we are sending
an IN statement or a SQL string literal
However, in the case of Adequate Record, we are *always* sending a raw
SQL string, and we *always* want to cache the result.
Fixes #23507
/cc @tgxworld
|
| |
|
| |
|
| |
|
|\
| |
| |
| | |
added ActiveRecord::Relation#outer_joins
|
| |
| |
| |
| |
| |
| | |
Example:
User.left_outer_joins(:posts)
=> SELECT "users".* FROM "users" LEFT OUTER JOIN "posts" ON "posts"."user_id" = "users"."id"
|
|/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
`in_batches` yields Relation objects if a block is given, otherwise it
returns an instance of `BatchEnumerator`. The existing `find_each` and
`find_in_batches` methods work with batches of records. The new API
allows working with relation batches as well.
Examples:
Person.in_batches.each_record(&:party_all_night!)
Person.in_batches.update_all(awesome: true)
Person.in_batches.delete_all
Person.in_batches.map do |relation|
relation.delete_all
sleep 10 # Throttles the delete queries
end
|
|
|
|
|
|
|
| |
Post.where('id = 1').or(Post.where('id = 2'))
# => SELECT * FROM posts WHERE (id = 1) OR (id = 2)
[Matthew Draper & Gael Muller]
|
|
|
|
|
|
|
|
|
|
|
|
| |
Before:
![before](https://cloud.githubusercontent.com/assets/10076/5592809/25ce08e8-9199-11e4-9dfe-5baa8bd6b658.png)
After:
![after](https://cloud.githubusercontent.com/assets/10076/5592810/25ceef9c-9199-11e4-88f4-d286203d7f6f.png)
[ci skip]
|
|
|
|
|
|
|
|
|
|
| |
This reverts commit 8fee923888192a658d8823b31e77ed0683dfd665.
Conflicts:
activerecord/lib/active_record/attribute_set/builder.rb
This solution sucks, and is hard to actually apply across the board.
Going to try other solutions
|
|
|
|
|
|
|
| |
We introduced a performance hit by adding an additional iteration
through a model's attributes on creation. We don't actually need the
values from `Result` to be a hash, we can separate the columns and
values and zip them up ourself during the iteration that we have to do.
|
|
|
|
|
| |
emit an event when we instantiate AR objects so we can see how many
records were instantiated and how long it took
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Benchmark:
```ruby
require 'objspace'
require 'active_record'
ActiveRecord::Base.establish_connection adapter: "sqlite3",
database: ":memory:"
ActiveRecord::Base.connection.instance_eval do
create_table(:articles) { |t| t.string :name }
end
class Article < ActiveRecord::Base; end
a = Article.create name: "foo"
a = Article.find a.id
N = 10
ObjectSpace::AllocationTracer.trace do
N.times { Article.find a.id }
end
ObjectSpace::AllocationTracer.allocated_count_table
table.sort_by { |_,x| x }.each do |k,v|
p k => (v / N)
end
```
|
|
|
|
|
| |
This has been around for a couple of versions now, a `NoMethodError`
should suffice at this point.
|
|
|
|
|
|
|
| |
We never want result types to override column types, and
`decorate_columns` can only affect column types. No need to go through
the decoration multiple times, we can just exclude the column types from
the result types instead.
|
|
|
|
|
|
|
|
|
|
|
|
| |
MySQL and PostgreSQL provide a column type override in order to properly
type cast computed columns included in a result set. This should never
override the known types of full fledged columns. In addition to messing
up computed properties, this would have led to inconsistent behavior
between a record created with `new`, and a record created with `last` on
the mysql adapter in the following cases:
- `tinyint(1)` with `emulate_booleans` set to `false`
- `text`, `string`, `binary`, and `decimal` columns
|
|
|
|
|
|
|
|
|
|
|
|
| |
This commit bring the famous ordinal Array instance methods defined
in ActiveSupport into ActiveRecord as fully-fledged finders.
These finders ensure a default ascending order of the table's primary
key, and utilize the OFFSET SQL verb to locate the user's desired
record. If an offset is defined in the query, calling #second adds
to the offset to get the actual desired record.
Fixes #13743.
|
| |
|
|
|
|
|
|
|
|
| |
These two methods aren't really statistical helper methods and don't
really belong in any other group which is being delegated for querying,
so I'm moving them to their own group of methods.
I've also changed the `:to => :all` hash syntax to `to: :all`.
|
| |
|
| |
|
|
|
|
|
|
|
|
| |
The similarity of `Relation#uniq` to `Array#uniq` is confusing. Since our
Relation API is close to SQL terms I renamed `#uniq` to `#distinct`.
There is no deprecation. `#uniq` and `#uniq!` are aliases and will continue
to work. I also updated the documentation to promote the use of `#distinct`.
|