Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
张重言
rails
提交
9817d74f
R
rails
项目概览
张重言
/
rails
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rails
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
9817d74f
编写于
5月 05, 2020
作者:
R
Ryuta Kamizono
提交者:
GitHub
5月 05, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #39022 from kamipo/perf_where_in
PERF: Improve performance of where when using an array of values
上级
d326b029
c3a2b54b
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
34 addition
and
38 deletion
+34
-38
activerecord/lib/active_record/relation/predicate_builder/array_handler.rb
...active_record/relation/predicate_builder/array_handler.rb
+6
-9
activerecord/lib/active_record/relation/where_clause.rb
activerecord/lib/active_record/relation/where_clause.rb
+1
-1
activerecord/lib/arel/nodes/casted.rb
activerecord/lib/arel/nodes/casted.rb
+10
-0
activerecord/lib/arel/predications.rb
activerecord/lib/arel/predications.rb
+2
-2
activerecord/lib/arel/table.rb
activerecord/lib/arel/table.rb
+1
-0
activerecord/lib/arel/visitors/to_sql.rb
activerecord/lib/arel/visitors/to_sql.rb
+8
-12
activerecord/test/cases/arel/attributes/attribute_test.rb
activerecord/test/cases/arel/attributes/attribute_test.rb
+6
-14
未找到文件。
activerecord/lib/active_record/relation/predicate_builder/array_handler.rb
浏览文件 @
9817d74f
...
...
@@ -20,20 +20,17 @@ def call(attribute, value)
case
values
.
length
when
0
then
NullPredicate
when
1
then
predicate_builder
.
build
(
attribute
,
values
.
first
)
else
values
.
map!
do
|
v
|
predicate_builder
.
build_bind_attribute
(
attribute
.
name
,
v
)
end
values
.
empty?
?
NullPredicate
:
attribute
.
in
(
values
)
else
attribute
.
in
(
values
)
end
unless
nils
.
empty?
if
nils
.
empty?
return
values_predicate
if
ranges
.
empty?
else
values_predicate
=
values_predicate
.
or
(
predicate_builder
.
build
(
attribute
,
nil
))
end
array_predicates
=
ranges
.
map
{
|
range
|
predicate_builder
.
build
(
attribute
,
range
)
}
array_predicates
.
unshift
(
values_predicate
)
array_predicates
.
inject
(
&
:or
)
array_predicates
=
ranges
.
map!
{
|
range
|
predicate_builder
.
build
(
attribute
,
range
)
}
array_predicates
.
inject
(
values_predicate
,
&
:or
)
end
private
...
...
activerecord/lib/active_record/relation/where_clause.rb
浏览文件 @
9817d74f
...
...
@@ -91,7 +91,7 @@ def contradiction?
predicates
.
any?
do
|
x
|
case
x
when
Arel
::
Nodes
::
In
Ar
ray
===
x
.
right
&&
x
.
right
.
empty?
Ar
el
::
Nodes
::
CastedArray
===
x
.
right
&&
x
.
right
.
value
.
empty?
when
Arel
::
Nodes
::
Equality
x
.
right
.
respond_to?
(
:unboundable?
)
&&
x
.
right
.
unboundable?
end
...
...
activerecord/lib/arel/nodes/casted.rb
浏览文件 @
9817d74f
...
...
@@ -34,6 +34,16 @@ def eql?(other)
alias
:==
:eql?
end
class
CastedArray
<
Casted
# :nodoc:
def
value_for_database
if
attribute
.
able_to_type_cast?
value
.
map
{
|
v
|
attribute
.
type_cast_for_database
(
v
)
}
else
value
end
end
end
class
Quoted
<
Arel
::
Nodes
::
Unary
# :nodoc:
alias
:value_for_database
:value
alias
:value_before_type_cast
:value
...
...
activerecord/lib/arel/predications.rb
浏览文件 @
9817d74f
...
...
@@ -31,7 +31,7 @@ def eq_any(others)
end
def
eq_all
(
others
)
grouping_all
:eq
,
quoted_array
(
others
)
grouping_all
:eq
,
others
end
def
between
(
other
)
...
...
@@ -238,7 +238,7 @@ def quoted_node(other)
end
def
quoted_array
(
others
)
others
.
map
{
|
v
|
quoted_node
(
v
)
}
Nodes
::
CastedArray
.
new
(
others
,
self
)
end
def
infinity?
(
value
)
...
...
activerecord/lib/arel/table.rb
浏览文件 @
9817d74f
...
...
@@ -98,6 +98,7 @@ def eql?(other)
def
type_cast_for_database
(
attribute_name
,
value
)
type_caster
.
type_cast_for_database
(
attribute_name
,
value
)
rescue
::
RangeError
end
def
able_to_type_cast?
...
...
activerecord/lib/arel/visitors/to_sql.rb
浏览文件 @
9817d74f
...
...
@@ -81,6 +81,10 @@ def visit_Arel_Nodes_Exists(o, collector)
end
end
def
visit_Arel_Nodes_CastedArray
(
o
,
collector
)
collector
<<
o
.
value_for_database
.
map!
{
|
v
|
quote
(
v
)
}.
join
(
", "
)
end
def
visit_Arel_Nodes_Casted
(
o
,
collector
)
collector
<<
quote
(
o
.
value_for_database
).
to_s
end
...
...
@@ -513,12 +517,8 @@ def visit_Arel_Nodes_In(o, collector)
collector
.
preparable
=
false
attr
,
values
=
o
.
left
,
o
.
right
if
Array
===
values
unless
values
.
empty?
values
.
delete_if
{
|
value
|
unboundable?
(
value
)
}
end
return
collector
<<
"1=0"
if
values
.
empty?
if
Arel
::
Nodes
::
CastedArray
===
values
return
collector
<<
"1=0"
if
values
.
value
.
empty?
end
visit
(
attr
,
collector
)
<<
" IN ("
...
...
@@ -529,12 +529,8 @@ def visit_Arel_Nodes_NotIn(o, collector)
collector
.
preparable
=
false
attr
,
values
=
o
.
left
,
o
.
right
if
Array
===
values
unless
values
.
empty?
values
.
delete_if
{
|
value
|
unboundable?
(
value
)
}
end
return
collector
<<
"1=1"
if
values
.
empty?
if
Arel
::
Nodes
::
CastedArray
===
values
return
collector
<<
"1=1"
if
values
.
value
.
empty?
end
visit
(
attr
,
collector
)
<<
" NOT IN ("
...
...
activerecord/test/cases/arel/attributes/attribute_test.rb
浏览文件 @
9817d74f
...
...
@@ -618,14 +618,14 @@ class AttributeTest < Arel::Spec
attribute
=
Attribute
.
new
nil
,
nil
node
=
attribute
.
between
(
-::
Float
::
INFINITY
..::
Float
::
INFINITY
)
_
(
node
).
must_equal
Nodes
::
NotIn
.
new
(
attribute
,
[])
_
(
node
).
must_equal
attribute
.
not_in
(
[])
end
it
"can be constructed with a quoted infinite range"
do
attribute
=
Attribute
.
new
nil
,
nil
node
=
attribute
.
between
(
quoted_range
(
-::
Float
::
INFINITY
,
::
Float
::
INFINITY
,
false
))
_
(
node
).
must_equal
Nodes
::
NotIn
.
new
(
attribute
,
[])
_
(
node
).
must_equal
attribute
.
not_in
(
[])
end
it
"can be constructed with a range ending at Infinity"
do
...
...
@@ -707,11 +707,7 @@ class AttributeTest < Arel::Spec
_
(
node
).
must_equal
Nodes
::
In
.
new
(
attribute
,
[
Nodes
::
Casted
.
new
(
1
,
attribute
),
Nodes
::
Casted
.
new
(
2
,
attribute
),
Nodes
::
Casted
.
new
(
3
,
attribute
),
]
Nodes
::
CastedArray
.
new
([
1
,
2
,
3
],
attribute
)
)
end
...
...
@@ -831,14 +827,14 @@ class AttributeTest < Arel::Spec
attribute
=
Attribute
.
new
nil
,
nil
node
=
attribute
.
not_between
(
-::
Float
::
INFINITY
..::
Float
::
INFINITY
)
_
(
node
).
must_equal
Nodes
::
In
.
new
(
attribute
,
[])
_
(
node
).
must_equal
attribute
.
in
(
[])
end
it
"can be constructed with a quoted infinite range"
do
attribute
=
Attribute
.
new
nil
,
nil
node
=
attribute
.
not_between
(
quoted_range
(
-::
Float
::
INFINITY
,
::
Float
::
INFINITY
,
false
))
_
(
node
).
must_equal
Nodes
::
In
.
new
(
attribute
,
[])
_
(
node
).
must_equal
attribute
.
in
(
[])
end
it
"can be constructed with a range ending at Infinity"
do
...
...
@@ -934,11 +930,7 @@ class AttributeTest < Arel::Spec
_
(
node
).
must_equal
Nodes
::
NotIn
.
new
(
attribute
,
[
Nodes
::
Casted
.
new
(
1
,
attribute
),
Nodes
::
Casted
.
new
(
2
,
attribute
),
Nodes
::
Casted
.
new
(
3
,
attribute
),
]
Nodes
::
CastedArray
.
new
([
1
,
2
,
3
],
attribute
)
)
end
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录