square-arel 2.0.9.20110222133018
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.autotest +26 -0
- data/History.txt +105 -0
- data/MIT-LICENSE.txt +20 -0
- data/Manifest.txt +124 -0
- data/README.markdown +94 -0
- data/Rakefile +20 -0
- data/lib/arel.rb +39 -0
- data/lib/arel/attributes.rb +20 -0
- data/lib/arel/attributes/attribute.rb +18 -0
- data/lib/arel/compatibility/wheres.rb +33 -0
- data/lib/arel/crud.rb +37 -0
- data/lib/arel/delete_manager.rb +18 -0
- data/lib/arel/deprecated.rb +4 -0
- data/lib/arel/expression.rb +4 -0
- data/lib/arel/expressions.rb +23 -0
- data/lib/arel/insert_manager.rb +34 -0
- data/lib/arel/nodes.rb +53 -0
- data/lib/arel/nodes/and.rb +6 -0
- data/lib/arel/nodes/as.rb +6 -0
- data/lib/arel/nodes/assignment.rb +6 -0
- data/lib/arel/nodes/avg.rb +6 -0
- data/lib/arel/nodes/between.rb +6 -0
- data/lib/arel/nodes/binary.rb +12 -0
- data/lib/arel/nodes/count.rb +13 -0
- data/lib/arel/nodes/delete_statement.rb +19 -0
- data/lib/arel/nodes/does_not_match.rb +6 -0
- data/lib/arel/nodes/equality.rb +9 -0
- data/lib/arel/nodes/except.rb +7 -0
- data/lib/arel/nodes/exists.rb +7 -0
- data/lib/arel/nodes/function.rb +18 -0
- data/lib/arel/nodes/greater_than.rb +6 -0
- data/lib/arel/nodes/greater_than_or_equal.rb +6 -0
- data/lib/arel/nodes/group.rb +6 -0
- data/lib/arel/nodes/grouping.rb +6 -0
- data/lib/arel/nodes/having.rb +6 -0
- data/lib/arel/nodes/in.rb +6 -0
- data/lib/arel/nodes/inner_join.rb +6 -0
- data/lib/arel/nodes/insert_statement.rb +19 -0
- data/lib/arel/nodes/intersect.rb +7 -0
- data/lib/arel/nodes/join.rb +13 -0
- data/lib/arel/nodes/less_than.rb +6 -0
- data/lib/arel/nodes/less_than_or_equal.rb +6 -0
- data/lib/arel/nodes/limit.rb +7 -0
- data/lib/arel/nodes/lock.rb +6 -0
- data/lib/arel/nodes/matches.rb +6 -0
- data/lib/arel/nodes/max.rb +6 -0
- data/lib/arel/nodes/min.rb +6 -0
- data/lib/arel/nodes/node.rb +44 -0
- data/lib/arel/nodes/not.rb +6 -0
- data/lib/arel/nodes/not_equal.rb +6 -0
- data/lib/arel/nodes/not_in.rb +6 -0
- data/lib/arel/nodes/offset.rb +7 -0
- data/lib/arel/nodes/on.rb +6 -0
- data/lib/arel/nodes/or.rb +6 -0
- data/lib/arel/nodes/ordering.rb +20 -0
- data/lib/arel/nodes/outer_join.rb +6 -0
- data/lib/arel/nodes/select_core.rb +26 -0
- data/lib/arel/nodes/select_statement.rb +22 -0
- data/lib/arel/nodes/sql_literal.rb +8 -0
- data/lib/arel/nodes/string_join.rb +11 -0
- data/lib/arel/nodes/sum.rb +6 -0
- data/lib/arel/nodes/table_alias.rb +13 -0
- data/lib/arel/nodes/top.rb +6 -0
- data/lib/arel/nodes/unary.rb +11 -0
- data/lib/arel/nodes/union.rb +7 -0
- data/lib/arel/nodes/union_all.rb +7 -0
- data/lib/arel/nodes/unqualified_column.rb +16 -0
- data/lib/arel/nodes/update_statement.rb +21 -0
- data/lib/arel/nodes/values.rb +14 -0
- data/lib/arel/predications.rb +183 -0
- data/lib/arel/relation.rb +6 -0
- data/lib/arel/select_manager.rb +237 -0
- data/lib/arel/sql/engine.rb +10 -0
- data/lib/arel/sql_literal.rb +4 -0
- data/lib/arel/table.rb +134 -0
- data/lib/arel/tree_manager.rb +36 -0
- data/lib/arel/update_manager.rb +49 -0
- data/lib/arel/visitors.rb +38 -0
- data/lib/arel/visitors/depth_first.rb +154 -0
- data/lib/arel/visitors/dot.rb +230 -0
- data/lib/arel/visitors/join_sql.rb +40 -0
- data/lib/arel/visitors/mssql.rb +16 -0
- data/lib/arel/visitors/mysql.rb +34 -0
- data/lib/arel/visitors/oracle.rb +116 -0
- data/lib/arel/visitors/order_clauses.rb +11 -0
- data/lib/arel/visitors/postgresql.rb +58 -0
- data/lib/arel/visitors/sqlite.rb +11 -0
- data/lib/arel/visitors/to_sql.rb +331 -0
- data/lib/arel/visitors/visitor.rb +27 -0
- data/lib/arel/visitors/where_sql.rb +9 -0
- data/square-arel.gemspec +36 -0
- data/test/attributes/test_attribute.rb +664 -0
- data/test/helper.rb +13 -0
- data/test/nodes/test_as.rb +16 -0
- data/test/nodes/test_count.rb +18 -0
- data/test/nodes/test_delete_statement.rb +14 -0
- data/test/nodes/test_equality.rb +74 -0
- data/test/nodes/test_insert_statement.rb +18 -0
- data/test/nodes/test_node.rb +33 -0
- data/test/nodes/test_not.rb +20 -0
- data/test/nodes/test_or.rb +22 -0
- data/test/nodes/test_select_core.rb +22 -0
- data/test/nodes/test_select_statement.rb +13 -0
- data/test/nodes/test_sql_literal.rb +52 -0
- data/test/nodes/test_sum.rb +12 -0
- data/test/nodes/test_update_statement.rb +18 -0
- data/test/support/fake_record.rb +91 -0
- data/test/test_activerecord_compat.rb +18 -0
- data/test/test_attributes.rb +46 -0
- data/test/test_crud.rb +69 -0
- data/test/test_delete_manager.rb +42 -0
- data/test/test_insert_manager.rb +125 -0
- data/test/test_select_manager.rb +659 -0
- data/test/test_table.rb +193 -0
- data/test/test_update_manager.rb +86 -0
- data/test/visitors/test_depth_first.rb +212 -0
- data/test/visitors/test_dot.rb +29 -0
- data/test/visitors/test_join_sql.rb +35 -0
- data/test/visitors/test_mssql.rb +18 -0
- data/test/visitors/test_mysql.rb +45 -0
- data/test/visitors/test_oracle.rb +147 -0
- data/test/visitors/test_postgres.rb +36 -0
- data/test/visitors/test_sqlite.rb +18 -0
- data/test/visitors/test_to_sql.rb +255 -0
- metadata +261 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
module Arel
|
2
|
+
module Visitors
|
3
|
+
class MySQL < Arel::Visitors::ToSql
|
4
|
+
private
|
5
|
+
def visit_Arel_Nodes_Lock o
|
6
|
+
visit o.expr
|
7
|
+
end
|
8
|
+
|
9
|
+
###
|
10
|
+
# :'(
|
11
|
+
# http://dev.mysql.com/doc/refman/5.0/en/select.html#id3482214
|
12
|
+
def visit_Arel_Nodes_SelectStatement o
|
13
|
+
o.limit = Arel::Nodes::Limit.new(18446744073709551615) if o.offset && !o.limit
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
def visit_Arel_Nodes_SelectCore o
|
18
|
+
o.froms ||= Arel.sql('DUAL')
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
def visit_Arel_Nodes_UpdateStatement o
|
23
|
+
[
|
24
|
+
"UPDATE #{visit o.relation}",
|
25
|
+
("SET #{o.values.map { |value| visit value }.join ', '}" unless o.values.empty?),
|
26
|
+
("WHERE #{o.wheres.map { |x| visit x }.join ' AND '}" unless o.wheres.empty?),
|
27
|
+
("ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?),
|
28
|
+
(visit(o.limit) if o.limit),
|
29
|
+
].compact.join ' '
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module Arel
|
2
|
+
module Visitors
|
3
|
+
class Oracle < Arel::Visitors::ToSql
|
4
|
+
private
|
5
|
+
|
6
|
+
def visit_Arel_Nodes_SelectStatement o
|
7
|
+
o = order_hacks(o)
|
8
|
+
|
9
|
+
# if need to select first records without ORDER BY and GROUP BY and without DISTINCT
|
10
|
+
# then can use simple ROWNUM in WHERE clause
|
11
|
+
if o.limit && o.orders.empty? && !o.offset && o.cores.first.projections.first !~ /^DISTINCT /
|
12
|
+
o.cores.last.wheres.push Nodes::LessThanOrEqual.new(
|
13
|
+
Nodes::SqlLiteral.new('ROWNUM'), o.limit.expr
|
14
|
+
)
|
15
|
+
return super
|
16
|
+
end
|
17
|
+
|
18
|
+
if o.limit && o.offset
|
19
|
+
o = o.dup
|
20
|
+
limit = o.limit.expr.to_i
|
21
|
+
offset = o.offset
|
22
|
+
o.offset = nil
|
23
|
+
sql = super(o)
|
24
|
+
return <<-eosql
|
25
|
+
SELECT * FROM (
|
26
|
+
SELECT raw_sql_.*, rownum raw_rnum_
|
27
|
+
FROM (#{sql}) raw_sql_
|
28
|
+
WHERE rownum <= #{offset.value.to_i + limit}
|
29
|
+
)
|
30
|
+
WHERE #{visit offset}
|
31
|
+
eosql
|
32
|
+
end
|
33
|
+
|
34
|
+
if o.limit
|
35
|
+
o = o.dup
|
36
|
+
limit = o.limit.expr
|
37
|
+
return "SELECT * FROM (#{super(o)}) WHERE ROWNUM <= #{visit limit}"
|
38
|
+
end
|
39
|
+
|
40
|
+
if o.offset
|
41
|
+
o = o.dup
|
42
|
+
offset = o.offset
|
43
|
+
o.offset = nil
|
44
|
+
sql = super(o)
|
45
|
+
return <<-eosql
|
46
|
+
SELECT * FROM (
|
47
|
+
SELECT raw_sql_.*, rownum raw_rnum_
|
48
|
+
FROM (#{sql}) raw_sql_
|
49
|
+
)
|
50
|
+
WHERE #{visit offset}
|
51
|
+
eosql
|
52
|
+
end
|
53
|
+
|
54
|
+
super
|
55
|
+
end
|
56
|
+
|
57
|
+
def visit_Arel_Nodes_Limit o
|
58
|
+
end
|
59
|
+
|
60
|
+
def visit_Arel_Nodes_Offset o
|
61
|
+
"raw_rnum_ > #{visit o.value}"
|
62
|
+
end
|
63
|
+
|
64
|
+
def visit_Arel_Nodes_Except o
|
65
|
+
"( #{visit o.left} MINUS #{visit o.right} )"
|
66
|
+
end
|
67
|
+
|
68
|
+
###
|
69
|
+
# Hacks for the order clauses specific to Oracle
|
70
|
+
def order_hacks o
|
71
|
+
return o if o.orders.empty?
|
72
|
+
return o unless o.cores.any? do |core|
|
73
|
+
core.projections.any? do |projection|
|
74
|
+
/DISTINCT.*FIRST_VALUE/ === projection
|
75
|
+
end
|
76
|
+
end
|
77
|
+
# Previous version with join and split broke ORDER BY clause
|
78
|
+
# if it contained functions with several arguments (separated by ',').
|
79
|
+
#
|
80
|
+
# orders = o.orders.map { |x| visit x }.join(', ').split(',')
|
81
|
+
orders = o.orders.map do |x|
|
82
|
+
string = visit x
|
83
|
+
if string.include?(',')
|
84
|
+
split_order_string(string)
|
85
|
+
else
|
86
|
+
string
|
87
|
+
end
|
88
|
+
end.flatten
|
89
|
+
o.orders = []
|
90
|
+
orders.each_with_index do |order, i|
|
91
|
+
o.orders <<
|
92
|
+
Nodes::SqlLiteral.new("alias_#{i}__#{' DESC' if /\bdesc$/i === order}")
|
93
|
+
end
|
94
|
+
o
|
95
|
+
end
|
96
|
+
|
97
|
+
# Split string by commas but count opening and closing brackets
|
98
|
+
# and ignore commas inside brackets.
|
99
|
+
def split_order_string(string)
|
100
|
+
array = []
|
101
|
+
i = 0
|
102
|
+
string.split(',').each do |part|
|
103
|
+
if array[i]
|
104
|
+
array[i] << ',' << part
|
105
|
+
else
|
106
|
+
# to ensure that array[i] will be String and not Arel::Nodes::SqlLiteral
|
107
|
+
array[i] = '' << part
|
108
|
+
end
|
109
|
+
i += 1 if array[i].count('(') == array[i].count(')')
|
110
|
+
end
|
111
|
+
array
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Arel
|
2
|
+
module Visitors
|
3
|
+
class PostgreSQL < Arel::Visitors::ToSql
|
4
|
+
private
|
5
|
+
def visit_Arel_Nodes_Lock o
|
6
|
+
visit o.expr
|
7
|
+
end
|
8
|
+
|
9
|
+
def visit_Arel_Nodes_SelectStatement o
|
10
|
+
if !o.orders.empty? && using_distinct_on?(o)
|
11
|
+
subquery = o.dup
|
12
|
+
subquery.orders = []
|
13
|
+
subquery.limit = nil
|
14
|
+
subquery.offset = nil
|
15
|
+
|
16
|
+
sql = super(subquery)
|
17
|
+
[
|
18
|
+
"SELECT * FROM (#{sql}) AS id_list",
|
19
|
+
"ORDER BY #{aliased_orders(o.orders).join(', ')}",
|
20
|
+
(visit(o.limit) if o.limit),
|
21
|
+
(visit(o.offset) if o.offset),
|
22
|
+
].compact.join ' '
|
23
|
+
else
|
24
|
+
super
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def visit_Arel_Nodes_Matches o
|
29
|
+
"#{visit o.left} ILIKE #{visit o.right}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def visit_Arel_Nodes_DoesNotMatch o
|
33
|
+
"#{visit o.left} NOT ILIKE #{visit o.right}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def using_distinct_on?(o)
|
37
|
+
o.cores.any? do |core|
|
38
|
+
core.projections.any? do |projection|
|
39
|
+
/DISTINCT ON/ === projection
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def aliased_orders orders
|
45
|
+
#orders = o.orders.map { |x| visit x }.join(', ').split(',')
|
46
|
+
list = []
|
47
|
+
orders.each_with_index do |o,i|
|
48
|
+
list <<
|
49
|
+
[
|
50
|
+
"id_list.alias_#{i}",
|
51
|
+
(o.index(/desc/i) && 'DESC')
|
52
|
+
].compact.join(' ')
|
53
|
+
end
|
54
|
+
list
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,331 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
module Arel
|
5
|
+
module Visitors
|
6
|
+
class ToSql < Arel::Visitors::Visitor
|
7
|
+
def initialize engine
|
8
|
+
@engine = engine
|
9
|
+
@connection = nil
|
10
|
+
@quoted_tables = {}
|
11
|
+
@quoted_columns = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def accept object
|
15
|
+
Thread.current[:arel_visitors_to_sql_last_column] = nil
|
16
|
+
@engine.connection_pool.with_connection do |conn|
|
17
|
+
@connection = conn
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
def visit_Arel_Nodes_DeleteStatement o
|
24
|
+
[
|
25
|
+
"DELETE FROM #{visit o.relation}",
|
26
|
+
("WHERE #{o.wheres.map { |x| visit x }.join ' AND '}" unless o.wheres.empty?)
|
27
|
+
].compact.join ' '
|
28
|
+
end
|
29
|
+
|
30
|
+
def visit_Arel_Nodes_UpdateStatement o
|
31
|
+
if o.orders.empty? && o.limit.nil?
|
32
|
+
wheres = o.wheres
|
33
|
+
else
|
34
|
+
stmt = Nodes::SelectStatement.new
|
35
|
+
core = stmt.cores.first
|
36
|
+
core.froms = o.relation
|
37
|
+
core.projections = [o.relation.primary_key]
|
38
|
+
stmt.limit = o.limit
|
39
|
+
stmt.orders = o.orders
|
40
|
+
|
41
|
+
wheres = [Nodes::In.new(o.relation.primary_key, [stmt])]
|
42
|
+
end
|
43
|
+
|
44
|
+
[
|
45
|
+
"UPDATE #{visit o.relation}",
|
46
|
+
("SET #{o.values.map { |value| visit value }.join ', '}" unless o.values.empty?),
|
47
|
+
("WHERE #{wheres.map { |x| visit x }.join ' AND '}" unless wheres.empty?)
|
48
|
+
].compact.join ' '
|
49
|
+
end
|
50
|
+
|
51
|
+
def visit_Arel_Nodes_InsertStatement o
|
52
|
+
[
|
53
|
+
"INSERT INTO #{visit o.relation}",
|
54
|
+
|
55
|
+
("(#{o.columns.map { |x|
|
56
|
+
quote_column_name x.name
|
57
|
+
}.join ', '})" unless o.columns.empty?),
|
58
|
+
|
59
|
+
(visit o.values if o.values),
|
60
|
+
].compact.join ' '
|
61
|
+
end
|
62
|
+
|
63
|
+
def visit_Arel_Nodes_Exists o
|
64
|
+
"EXISTS (#{visit o.select_stmt})#{
|
65
|
+
o.alias ? " AS #{visit o.alias}" : ''}"
|
66
|
+
end
|
67
|
+
|
68
|
+
def visit_Arel_Nodes_Values o
|
69
|
+
"VALUES (#{o.expressions.zip(o.columns).map { |value, column|
|
70
|
+
quote(value, column && column.column)
|
71
|
+
}.join ', '})"
|
72
|
+
end
|
73
|
+
|
74
|
+
def visit_Arel_Nodes_SelectStatement o
|
75
|
+
[
|
76
|
+
o.cores.map { |x| visit_Arel_Nodes_SelectCore x }.join,
|
77
|
+
("ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?),
|
78
|
+
(visit(o.limit) if o.limit),
|
79
|
+
(visit(o.offset) if o.offset),
|
80
|
+
(visit(o.lock) if o.lock),
|
81
|
+
].compact.join ' '
|
82
|
+
end
|
83
|
+
|
84
|
+
def visit_Arel_Nodes_SelectCore o
|
85
|
+
[
|
86
|
+
"SELECT",
|
87
|
+
(visit(o.top) if o.top),
|
88
|
+
"#{o.projections.map { |x| visit x }.join ', '}",
|
89
|
+
("FROM #{visit o.froms}" if o.froms),
|
90
|
+
("WHERE #{o.wheres.map { |x| visit x }.join ' AND ' }" unless o.wheres.empty?),
|
91
|
+
("GROUP BY #{o.groups.map { |x| visit x }.join ', ' }" unless o.groups.empty?),
|
92
|
+
(visit(o.having) if o.having),
|
93
|
+
].compact.join ' '
|
94
|
+
end
|
95
|
+
|
96
|
+
def visit_Arel_Nodes_Having o
|
97
|
+
"HAVING #{visit o.expr}"
|
98
|
+
end
|
99
|
+
|
100
|
+
def visit_Arel_Nodes_Offset o
|
101
|
+
"OFFSET #{visit o.expr}"
|
102
|
+
end
|
103
|
+
|
104
|
+
def visit_Arel_Nodes_Limit o
|
105
|
+
"LIMIT #{visit o.expr}"
|
106
|
+
end
|
107
|
+
|
108
|
+
# FIXME: this does nothing on most databases, but does on MSSQL
|
109
|
+
def visit_Arel_Nodes_Top o
|
110
|
+
""
|
111
|
+
end
|
112
|
+
|
113
|
+
# FIXME: this does nothing on SQLLite3, but should do things on other
|
114
|
+
# databases.
|
115
|
+
def visit_Arel_Nodes_Lock o
|
116
|
+
end
|
117
|
+
|
118
|
+
def visit_Arel_Nodes_Grouping o
|
119
|
+
"(#{visit o.expr})"
|
120
|
+
end
|
121
|
+
|
122
|
+
def visit_Arel_Nodes_Ordering o
|
123
|
+
"#{visit o.expr} #{o.descending? ? 'DESC' : 'ASC'}"
|
124
|
+
end
|
125
|
+
|
126
|
+
def visit_Arel_Nodes_Group o
|
127
|
+
visit o.expr
|
128
|
+
end
|
129
|
+
|
130
|
+
def visit_Arel_Nodes_Count o
|
131
|
+
"COUNT(#{o.distinct ? 'DISTINCT ' : ''}#{o.expressions.map { |x|
|
132
|
+
visit x
|
133
|
+
}.join(', ')})#{o.alias ? " AS #{visit o.alias}" : ''}"
|
134
|
+
end
|
135
|
+
|
136
|
+
def visit_Arel_Nodes_Sum o
|
137
|
+
"SUM(#{o.expressions.map { |x|
|
138
|
+
visit x }.join(', ')})#{o.alias ? " AS #{visit o.alias}" : ''}"
|
139
|
+
end
|
140
|
+
|
141
|
+
def visit_Arel_Nodes_Max o
|
142
|
+
"MAX(#{o.expressions.map { |x|
|
143
|
+
visit x }.join(', ')})#{o.alias ? " AS #{visit o.alias}" : ''}"
|
144
|
+
end
|
145
|
+
|
146
|
+
def visit_Arel_Nodes_Min o
|
147
|
+
"MIN(#{o.expressions.map { |x|
|
148
|
+
visit x }.join(', ')})#{o.alias ? " AS #{visit o.alias}" : ''}"
|
149
|
+
end
|
150
|
+
|
151
|
+
def visit_Arel_Nodes_Avg o
|
152
|
+
"AVG(#{o.expressions.map { |x|
|
153
|
+
visit x }.join(', ')})#{o.alias ? " AS #{visit o.alias}" : ''}"
|
154
|
+
end
|
155
|
+
|
156
|
+
def visit_Arel_Nodes_TableAlias o
|
157
|
+
"#{visit o.relation} #{quote_table_name o.name}"
|
158
|
+
end
|
159
|
+
|
160
|
+
def visit_Arel_Nodes_Between o
|
161
|
+
"#{visit o.left} BETWEEN #{visit o.right}"
|
162
|
+
end
|
163
|
+
|
164
|
+
def visit_Arel_Nodes_GreaterThanOrEqual o
|
165
|
+
"#{visit o.left} >= #{visit o.right}"
|
166
|
+
end
|
167
|
+
|
168
|
+
def visit_Arel_Nodes_GreaterThan o
|
169
|
+
"#{visit o.left} > #{visit o.right}"
|
170
|
+
end
|
171
|
+
|
172
|
+
def visit_Arel_Nodes_LessThanOrEqual o
|
173
|
+
"#{visit o.left} <= #{visit o.right}"
|
174
|
+
end
|
175
|
+
|
176
|
+
def visit_Arel_Nodes_LessThan o
|
177
|
+
"#{visit o.left} < #{visit o.right}"
|
178
|
+
end
|
179
|
+
|
180
|
+
def visit_Arel_Nodes_Matches o
|
181
|
+
"#{visit o.left} LIKE #{visit o.right}"
|
182
|
+
end
|
183
|
+
|
184
|
+
def visit_Arel_Nodes_DoesNotMatch o
|
185
|
+
"#{visit o.left} NOT LIKE #{visit o.right}"
|
186
|
+
end
|
187
|
+
|
188
|
+
def visit_Arel_Nodes_StringJoin o
|
189
|
+
"#{visit o.left} #{visit o.right}"
|
190
|
+
end
|
191
|
+
|
192
|
+
def visit_Arel_Nodes_OuterJoin o
|
193
|
+
"#{visit o.left} LEFT OUTER JOIN #{visit o.right} #{visit o.constraint}"
|
194
|
+
end
|
195
|
+
|
196
|
+
def visit_Arel_Nodes_InnerJoin o
|
197
|
+
"#{visit o.left} INNER JOIN #{visit o.right} #{visit o.constraint if o.constraint}"
|
198
|
+
end
|
199
|
+
|
200
|
+
def visit_Arel_Nodes_On o
|
201
|
+
"ON #{visit o.expr}"
|
202
|
+
end
|
203
|
+
|
204
|
+
def visit_Arel_Nodes_Not o
|
205
|
+
"NOT (#{visit o.expr})"
|
206
|
+
end
|
207
|
+
|
208
|
+
def visit_Arel_Nodes_Union o
|
209
|
+
"( #{visit o.left} UNION #{visit o.right} )"
|
210
|
+
end
|
211
|
+
|
212
|
+
def visit_Arel_Nodes_UnionAll o
|
213
|
+
"( #{visit o.left} UNION ALL #{visit o.right} )"
|
214
|
+
end
|
215
|
+
|
216
|
+
def visit_Arel_Nodes_Intersect o
|
217
|
+
"( #{visit o.left} INTERSECT #{visit o.right} )"
|
218
|
+
end
|
219
|
+
|
220
|
+
def visit_Arel_Nodes_Except o
|
221
|
+
"( #{visit o.left} EXCEPT #{visit o.right} )"
|
222
|
+
end
|
223
|
+
|
224
|
+
def visit_Arel_Table o
|
225
|
+
if o.table_alias
|
226
|
+
"#{quote_table_name o.name} #{quote_table_name o.table_alias}"
|
227
|
+
else
|
228
|
+
quote_table_name o.name
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
def visit_Arel_Nodes_In o
|
233
|
+
"#{visit o.left} IN (#{visit o.right})"
|
234
|
+
end
|
235
|
+
|
236
|
+
def visit_Arel_Nodes_NotIn o
|
237
|
+
"#{visit o.left} NOT IN (#{visit o.right})"
|
238
|
+
end
|
239
|
+
|
240
|
+
def visit_Arel_Nodes_And o
|
241
|
+
"#{visit o.left} AND #{visit o.right}"
|
242
|
+
end
|
243
|
+
|
244
|
+
def visit_Arel_Nodes_Or o
|
245
|
+
"#{visit o.left} OR #{visit o.right}"
|
246
|
+
end
|
247
|
+
|
248
|
+
def visit_Arel_Nodes_Assignment o
|
249
|
+
right = quote(o.right, o.left.column)
|
250
|
+
"#{visit o.left} = #{right}"
|
251
|
+
end
|
252
|
+
|
253
|
+
def visit_Arel_Nodes_Equality o
|
254
|
+
right = o.right
|
255
|
+
|
256
|
+
if right.nil?
|
257
|
+
"#{visit o.left} IS NULL"
|
258
|
+
else
|
259
|
+
"#{visit o.left} = #{visit right}"
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
def visit_Arel_Nodes_NotEqual o
|
264
|
+
right = o.right
|
265
|
+
|
266
|
+
if right.nil?
|
267
|
+
"#{visit o.left} IS NOT NULL"
|
268
|
+
else
|
269
|
+
"#{visit o.left} != #{visit right}"
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
def visit_Arel_Nodes_As o
|
274
|
+
"#{visit o.left} AS #{visit o.right}"
|
275
|
+
end
|
276
|
+
|
277
|
+
def visit_Arel_Nodes_UnqualifiedColumn o
|
278
|
+
"#{quote_column_name o.name}"
|
279
|
+
end
|
280
|
+
|
281
|
+
def visit_Arel_Attributes_Attribute o
|
282
|
+
Thread.current[:arel_visitors_to_sql_last_column] = o.column
|
283
|
+
join_name = o.relation.table_alias || o.relation.name
|
284
|
+
"#{quote_table_name join_name}.#{quote_column_name o.name}"
|
285
|
+
end
|
286
|
+
alias :visit_Arel_Attributes_Integer :visit_Arel_Attributes_Attribute
|
287
|
+
alias :visit_Arel_Attributes_Float :visit_Arel_Attributes_Attribute
|
288
|
+
alias :visit_Arel_Attributes_Decimal :visit_Arel_Attributes_Attribute
|
289
|
+
alias :visit_Arel_Attributes_String :visit_Arel_Attributes_Attribute
|
290
|
+
alias :visit_Arel_Attributes_Time :visit_Arel_Attributes_Attribute
|
291
|
+
alias :visit_Arel_Attributes_Boolean :visit_Arel_Attributes_Attribute
|
292
|
+
|
293
|
+
def visit_Fixnum o; o end
|
294
|
+
alias :visit_Arel_Nodes_SqlLiteral :visit_Fixnum
|
295
|
+
alias :visit_Arel_SqlLiteral :visit_Fixnum # This is deprecated
|
296
|
+
alias :visit_Bignum :visit_Fixnum
|
297
|
+
|
298
|
+
def visit_String o; quote(o, Thread.current[:arel_visitors_to_sql_last_column]) end
|
299
|
+
|
300
|
+
alias :visit_ActiveSupport_Multibyte_Chars :visit_String
|
301
|
+
alias :visit_BigDecimal :visit_String
|
302
|
+
alias :visit_Date :visit_String
|
303
|
+
alias :visit_DateTime :visit_String
|
304
|
+
alias :visit_FalseClass :visit_String
|
305
|
+
alias :visit_Float :visit_String
|
306
|
+
alias :visit_Hash :visit_String
|
307
|
+
alias :visit_Symbol :visit_String
|
308
|
+
alias :visit_Time :visit_String
|
309
|
+
alias :visit_TrueClass :visit_String
|
310
|
+
alias :visit_NilClass :visit_String
|
311
|
+
alias :visit_ActiveSupport_StringInquirer :visit_String
|
312
|
+
alias :visit_Class :visit_String
|
313
|
+
|
314
|
+
def visit_Array o
|
315
|
+
o.empty? ? 'NULL' : o.map { |x| visit x }.join(', ')
|
316
|
+
end
|
317
|
+
|
318
|
+
def quote value, column = nil
|
319
|
+
@connection.quote value, column
|
320
|
+
end
|
321
|
+
|
322
|
+
def quote_table_name name
|
323
|
+
@quoted_tables[name] ||= @connection.quote_table_name(name)
|
324
|
+
end
|
325
|
+
|
326
|
+
def quote_column_name name
|
327
|
+
@quoted_columns[name] ||= @connection.quote_column_name(name)
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|