| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In 04ac5655be91f49cd4dfe2838df96213502fb274 I assumed that we would
never want to pass the "table_name.column_name" form to where with a
symbol. However, in Ruby 2.2 and later, you can quote symbols using the
new hash syntax, so it's a semi-reasonable thing to do if we want to
support the dot notation (which I'd rather deprecate, but that would be
too painful of a migration).
Instead we've changed the definition of "this is a table name with a
dot" to when the value associated is a hash. It would make very little
sense to write `where("table_name.column_name": { foo: :bar })` in any
scenario (other than equality for a JSON column which we don't support
through `where` in this way).
Close #24514.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This issue occured because associations now call `where` directly, and a
dot in the key name for `where` means nested tables. For this fix, we
now pass the table name as a symbol, and do not attempt to expand
symbols containing a dot.
This is a temporary fix. I do not think we should support table names
containing a dot, as it has a special meaning in most backends, as well
as most APIs that involve table names. This commit does not include a
test, as I am going to deprecate table names containing dots in the
following commit.
Fixes #24367
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Before:
```
SELECT 1 AS one FROM "topics" WHERE "topics"."title" = 'abc' LIMIT $1 [["LIMIT", 1]]
```
After:
```
SELECT 1 AS one FROM "topics" WHERE "topics"."title" = $1 LIMIT $2 [["title", "abc"], ["LIMIT", 1]]
```
|
|
|
|
|
|
|
|
| |
This commit follow up of 4d8f62d.
The difference from 4d8f62d are below:
* Change `WhereClauseFactory` to accept `Arel::Nodes::Node`
* Change test cases of `relation_test.rb`
|
|
|
|
|
|
| |
This reverts commit 4d8f62dcfa0a5157b3facbd71f75fc6639636347.
Reason: This broke the build. Please recommit again when it is green.
|
|
|
|
|
|
| |
`WhereClauseFactory` handles all other branches based on argument types,
so the code fits more naturally here, and it's just where the
responsibility belongs.
|
|
|
|
| |
[ci skip]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Stackprof output truncated.
```
TOTAL (pct) SAMPLES (pct) FRAME
23 (4.7%) 12 (2.4%) Hash#transform_keys
11 (2.2%) 11 (2.2%) block in Hash#transform_keys
30 (6.1%) 7 (1.4%) Hash#stringify_keys
```
Benchmark Script:
```
begin
require 'bundler/inline'
rescue LoadError => e
$stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
raise e
end
gemfile(true) do
source 'https://rubygems.org'
gem 'rails', path: '~/rails' # master against ref "f1f0a3f8d99aef8aacfa81ceac3880dcac03ca06"
gem 'arel', github: 'rails/arel', branch: 'master'
gem 'rack', github: 'rack/rack', branch: 'master'
gem 'sass'
gem 'sprockets-rails', github: 'rails/sprockets-rails', branch: 'master'
gem 'sprockets', github: 'rails/sprockets', branch: 'master'
gem 'pg'
gem 'benchmark-ips'
end
require 'active_record'
require 'benchmark/ips'
ActiveRecord::Base.establish_connection('postgres://postgres@localhost:5432/rubybench')
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
class User < ActiveRecord::Base; end
attributes = {
name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
email: "foobar@email.com",
}
1000.times { User.create!(attributes) }
Benchmark.ips(5, 3) do |x|
x.report('where with hash') { User.where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") }
x.report('where with string') { User.where("users.name = ?", "Lorem ipsum dolor sit amet, consectetur adipiscing elit.") }
x.compare!
end
key =
if RUBY_VERSION < '2.2'
:total_allocated_object
else
:total_allocated_objects
end
before = GC.stat[key]
User.where(name: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.")
after = GC.stat[key]
puts "Total Allocated Object: #{after - before}"
```
Before:
```
Calculating -------------------------------------
where with hash 2.796k i/100ms
where with string 4.338k i/100ms
-------------------------------------------------
where with hash 29.177k (± 1.5%) i/s - 148.188k
where with string 47.419k (± 2.8%) i/s - 238.590k
Comparison:
where with string: 47419.0 i/s
where with hash: 29176.6 i/s - 1.63x slower
Total Allocated Object: 85
```
After:
```
Calculating -------------------------------------
where with hash 2.895k i/100ms
where with string 4.416k i/100ms
-------------------------------------------------
where with hash 30.758k (± 2.0%) i/s - 156.330k
where with string 47.708k (± 2.6%) i/s - 238.464k
Comparison:
where with string: 47707.9 i/s
where with hash: 30757.7 i/s - 1.55x slower
Total Allocated Object: 84
```
|
|
Yes, I know, I called it a factory so I'm basically the worst person
ever who loves Java and worships the Gang of Four.
|