square-arel 2.0.9.20110222133018

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. data/.autotest +26 -0
  2. data/History.txt +105 -0
  3. data/MIT-LICENSE.txt +20 -0
  4. data/Manifest.txt +124 -0
  5. data/README.markdown +94 -0
  6. data/Rakefile +20 -0
  7. data/lib/arel.rb +39 -0
  8. data/lib/arel/attributes.rb +20 -0
  9. data/lib/arel/attributes/attribute.rb +18 -0
  10. data/lib/arel/compatibility/wheres.rb +33 -0
  11. data/lib/arel/crud.rb +37 -0
  12. data/lib/arel/delete_manager.rb +18 -0
  13. data/lib/arel/deprecated.rb +4 -0
  14. data/lib/arel/expression.rb +4 -0
  15. data/lib/arel/expressions.rb +23 -0
  16. data/lib/arel/insert_manager.rb +34 -0
  17. data/lib/arel/nodes.rb +53 -0
  18. data/lib/arel/nodes/and.rb +6 -0
  19. data/lib/arel/nodes/as.rb +6 -0
  20. data/lib/arel/nodes/assignment.rb +6 -0
  21. data/lib/arel/nodes/avg.rb +6 -0
  22. data/lib/arel/nodes/between.rb +6 -0
  23. data/lib/arel/nodes/binary.rb +12 -0
  24. data/lib/arel/nodes/count.rb +13 -0
  25. data/lib/arel/nodes/delete_statement.rb +19 -0
  26. data/lib/arel/nodes/does_not_match.rb +6 -0
  27. data/lib/arel/nodes/equality.rb +9 -0
  28. data/lib/arel/nodes/except.rb +7 -0
  29. data/lib/arel/nodes/exists.rb +7 -0
  30. data/lib/arel/nodes/function.rb +18 -0
  31. data/lib/arel/nodes/greater_than.rb +6 -0
  32. data/lib/arel/nodes/greater_than_or_equal.rb +6 -0
  33. data/lib/arel/nodes/group.rb +6 -0
  34. data/lib/arel/nodes/grouping.rb +6 -0
  35. data/lib/arel/nodes/having.rb +6 -0
  36. data/lib/arel/nodes/in.rb +6 -0
  37. data/lib/arel/nodes/inner_join.rb +6 -0
  38. data/lib/arel/nodes/insert_statement.rb +19 -0
  39. data/lib/arel/nodes/intersect.rb +7 -0
  40. data/lib/arel/nodes/join.rb +13 -0
  41. data/lib/arel/nodes/less_than.rb +6 -0
  42. data/lib/arel/nodes/less_than_or_equal.rb +6 -0
  43. data/lib/arel/nodes/limit.rb +7 -0
  44. data/lib/arel/nodes/lock.rb +6 -0
  45. data/lib/arel/nodes/matches.rb +6 -0
  46. data/lib/arel/nodes/max.rb +6 -0
  47. data/lib/arel/nodes/min.rb +6 -0
  48. data/lib/arel/nodes/node.rb +44 -0
  49. data/lib/arel/nodes/not.rb +6 -0
  50. data/lib/arel/nodes/not_equal.rb +6 -0
  51. data/lib/arel/nodes/not_in.rb +6 -0
  52. data/lib/arel/nodes/offset.rb +7 -0
  53. data/lib/arel/nodes/on.rb +6 -0
  54. data/lib/arel/nodes/or.rb +6 -0
  55. data/lib/arel/nodes/ordering.rb +20 -0
  56. data/lib/arel/nodes/outer_join.rb +6 -0
  57. data/lib/arel/nodes/select_core.rb +26 -0
  58. data/lib/arel/nodes/select_statement.rb +22 -0
  59. data/lib/arel/nodes/sql_literal.rb +8 -0
  60. data/lib/arel/nodes/string_join.rb +11 -0
  61. data/lib/arel/nodes/sum.rb +6 -0
  62. data/lib/arel/nodes/table_alias.rb +13 -0
  63. data/lib/arel/nodes/top.rb +6 -0
  64. data/lib/arel/nodes/unary.rb +11 -0
  65. data/lib/arel/nodes/union.rb +7 -0
  66. data/lib/arel/nodes/union_all.rb +7 -0
  67. data/lib/arel/nodes/unqualified_column.rb +16 -0
  68. data/lib/arel/nodes/update_statement.rb +21 -0
  69. data/lib/arel/nodes/values.rb +14 -0
  70. data/lib/arel/predications.rb +183 -0
  71. data/lib/arel/relation.rb +6 -0
  72. data/lib/arel/select_manager.rb +237 -0
  73. data/lib/arel/sql/engine.rb +10 -0
  74. data/lib/arel/sql_literal.rb +4 -0
  75. data/lib/arel/table.rb +134 -0
  76. data/lib/arel/tree_manager.rb +36 -0
  77. data/lib/arel/update_manager.rb +49 -0
  78. data/lib/arel/visitors.rb +38 -0
  79. data/lib/arel/visitors/depth_first.rb +154 -0
  80. data/lib/arel/visitors/dot.rb +230 -0
  81. data/lib/arel/visitors/join_sql.rb +40 -0
  82. data/lib/arel/visitors/mssql.rb +16 -0
  83. data/lib/arel/visitors/mysql.rb +34 -0
  84. data/lib/arel/visitors/oracle.rb +116 -0
  85. data/lib/arel/visitors/order_clauses.rb +11 -0
  86. data/lib/arel/visitors/postgresql.rb +58 -0
  87. data/lib/arel/visitors/sqlite.rb +11 -0
  88. data/lib/arel/visitors/to_sql.rb +331 -0
  89. data/lib/arel/visitors/visitor.rb +27 -0
  90. data/lib/arel/visitors/where_sql.rb +9 -0
  91. data/square-arel.gemspec +36 -0
  92. data/test/attributes/test_attribute.rb +664 -0
  93. data/test/helper.rb +13 -0
  94. data/test/nodes/test_as.rb +16 -0
  95. data/test/nodes/test_count.rb +18 -0
  96. data/test/nodes/test_delete_statement.rb +14 -0
  97. data/test/nodes/test_equality.rb +74 -0
  98. data/test/nodes/test_insert_statement.rb +18 -0
  99. data/test/nodes/test_node.rb +33 -0
  100. data/test/nodes/test_not.rb +20 -0
  101. data/test/nodes/test_or.rb +22 -0
  102. data/test/nodes/test_select_core.rb +22 -0
  103. data/test/nodes/test_select_statement.rb +13 -0
  104. data/test/nodes/test_sql_literal.rb +52 -0
  105. data/test/nodes/test_sum.rb +12 -0
  106. data/test/nodes/test_update_statement.rb +18 -0
  107. data/test/support/fake_record.rb +91 -0
  108. data/test/test_activerecord_compat.rb +18 -0
  109. data/test/test_attributes.rb +46 -0
  110. data/test/test_crud.rb +69 -0
  111. data/test/test_delete_manager.rb +42 -0
  112. data/test/test_insert_manager.rb +125 -0
  113. data/test/test_select_manager.rb +659 -0
  114. data/test/test_table.rb +193 -0
  115. data/test/test_update_manager.rb +86 -0
  116. data/test/visitors/test_depth_first.rb +212 -0
  117. data/test/visitors/test_dot.rb +29 -0
  118. data/test/visitors/test_join_sql.rb +35 -0
  119. data/test/visitors/test_mssql.rb +18 -0
  120. data/test/visitors/test_mysql.rb +45 -0
  121. data/test/visitors/test_oracle.rb +147 -0
  122. data/test/visitors/test_postgres.rb +36 -0
  123. data/test/visitors/test_sqlite.rb +18 -0
  124. data/test/visitors/test_to_sql.rb +255 -0
  125. metadata +261 -0
@@ -0,0 +1,38 @@
1
+ require 'arel/visitors/visitor'
2
+ require 'arel/visitors/depth_first'
3
+ require 'arel/visitors/to_sql'
4
+ require 'arel/visitors/sqlite'
5
+ require 'arel/visitors/postgresql'
6
+ require 'arel/visitors/mysql'
7
+ require 'arel/visitors/mssql'
8
+ require 'arel/visitors/oracle'
9
+ require 'arel/visitors/join_sql'
10
+ require 'arel/visitors/where_sql'
11
+ require 'arel/visitors/order_clauses'
12
+ require 'arel/visitors/dot'
13
+
14
+ module Arel
15
+ module Visitors
16
+ VISITORS = {
17
+ 'postgresql' => Arel::Visitors::PostgreSQL,
18
+ 'mysql' => Arel::Visitors::MySQL,
19
+ 'mysql2' => Arel::Visitors::MySQL,
20
+ 'mssql' => Arel::Visitors::MSSQL,
21
+ 'sqlserver' => Arel::Visitors::MSSQL,
22
+ 'oracle_enhanced' => Arel::Visitors::Oracle,
23
+ 'sqlite' => Arel::Visitors::SQLite,
24
+ 'sqlite3' => Arel::Visitors::SQLite,
25
+ }
26
+
27
+ ENGINE_VISITORS = Hash.new do |hash, engine|
28
+ pool = engine.connection_pool
29
+ adapter = pool.spec.config[:adapter]
30
+ hash[engine] = (VISITORS[adapter] || Visitors::ToSql).new(engine)
31
+ end
32
+
33
+ def self.visitor_for engine
34
+ ENGINE_VISITORS[engine]
35
+ end
36
+ class << self; alias :for :visitor_for; end
37
+ end
38
+ end
@@ -0,0 +1,154 @@
1
+ module Arel
2
+ module Visitors
3
+ class DepthFirst < Arel::Visitors::Visitor
4
+ def initialize block = nil
5
+ @block = block || Proc.new
6
+ end
7
+
8
+ private
9
+
10
+ def visit o
11
+ super
12
+ @block.call o
13
+ end
14
+
15
+ def unary o
16
+ visit o.expr
17
+ end
18
+ alias :visit_Arel_Nodes_Group :unary
19
+ alias :visit_Arel_Nodes_Grouping :unary
20
+ alias :visit_Arel_Nodes_Having :unary
21
+ alias :visit_Arel_Nodes_Limit :unary
22
+ alias :visit_Arel_Nodes_Not :unary
23
+ alias :visit_Arel_Nodes_Offset :unary
24
+ alias :visit_Arel_Nodes_On :unary
25
+ alias :visit_Arel_Nodes_Top :unary
26
+ alias :visit_Arel_Nodes_UnqualifiedColumn :unary
27
+
28
+ def function o
29
+ visit o.expressions
30
+ visit o.alias
31
+ end
32
+ alias :visit_Arel_Nodes_Avg :function
33
+ alias :visit_Arel_Nodes_Exists :function
34
+ alias :visit_Arel_Nodes_Max :function
35
+ alias :visit_Arel_Nodes_Min :function
36
+ alias :visit_Arel_Nodes_Sum :function
37
+
38
+ def visit_Arel_Nodes_Count o
39
+ visit o.expressions
40
+ visit o.alias
41
+ visit o.distinct
42
+ end
43
+
44
+ def join o
45
+ visit o.left
46
+ visit o.right
47
+ visit o.constraint
48
+ end
49
+ alias :visit_Arel_Nodes_InnerJoin :join
50
+ alias :visit_Arel_Nodes_OuterJoin :join
51
+
52
+ def binary o
53
+ visit o.left
54
+ visit o.right
55
+ end
56
+ alias :visit_Arel_Nodes_And :binary
57
+ alias :visit_Arel_Nodes_As :binary
58
+ alias :visit_Arel_Nodes_Assignment :binary
59
+ alias :visit_Arel_Nodes_Between :binary
60
+ alias :visit_Arel_Nodes_DeleteStatement :binary
61
+ alias :visit_Arel_Nodes_DoesNotMatch :binary
62
+ alias :visit_Arel_Nodes_Equality :binary
63
+ alias :visit_Arel_Nodes_GreaterThan :binary
64
+ alias :visit_Arel_Nodes_GreaterThanOrEqual :binary
65
+ alias :visit_Arel_Nodes_In :binary
66
+ alias :visit_Arel_Nodes_LessThan :binary
67
+ alias :visit_Arel_Nodes_LessThanOrEqual :binary
68
+ alias :visit_Arel_Nodes_Matches :binary
69
+ alias :visit_Arel_Nodes_NotEqual :binary
70
+ alias :visit_Arel_Nodes_NotIn :binary
71
+ alias :visit_Arel_Nodes_Or :binary
72
+ alias :visit_Arel_Nodes_Ordering :binary
73
+ alias :visit_Arel_Nodes_StringJoin :binary
74
+ alias :visit_Arel_Nodes_TableAlias :binary
75
+ alias :visit_Arel_Nodes_Values :binary
76
+
77
+ def visit_Arel_Attribute o
78
+ visit o.relation
79
+ visit o.name
80
+ end
81
+ alias :visit_Arel_Attributes_Integer :visit_Arel_Attribute
82
+ alias :visit_Arel_Attributes_Float :visit_Arel_Attribute
83
+ alias :visit_Arel_Attributes_String :visit_Arel_Attribute
84
+ alias :visit_Arel_Attributes_Time :visit_Arel_Attribute
85
+ alias :visit_Arel_Attributes_Boolean :visit_Arel_Attribute
86
+ alias :visit_Arel_Attributes_Attribute :visit_Arel_Attribute
87
+ alias :visit_Arel_Attributes_Decimal :visit_Arel_Attribute
88
+
89
+ def visit_Arel_Table o
90
+ visit o.name
91
+ end
92
+
93
+ def terminal o
94
+ end
95
+ alias :visit_ActiveSupport_Multibyte_Chars :terminal
96
+ alias :visit_ActiveSupport_StringInquirer :terminal
97
+ alias :visit_Arel_Nodes_Lock :terminal
98
+ alias :visit_Arel_Nodes_Node :terminal
99
+ alias :visit_Arel_Nodes_SqlLiteral :terminal
100
+ alias :visit_Arel_SqlLiteral :terminal
101
+ alias :visit_BigDecimal :terminal
102
+ alias :visit_Bignum :terminal
103
+ alias :visit_Class :terminal
104
+ alias :visit_Date :terminal
105
+ alias :visit_DateTime :terminal
106
+ alias :visit_FalseClass :terminal
107
+ alias :visit_Fixnum :terminal
108
+ alias :visit_Float :terminal
109
+ alias :visit_NilClass :terminal
110
+ alias :visit_String :terminal
111
+ alias :visit_Symbol :terminal
112
+ alias :visit_Time :terminal
113
+ alias :visit_TrueClass :terminal
114
+
115
+ def visit_Arel_Nodes_InsertStatement o
116
+ visit o.relation
117
+ visit o.columns
118
+ visit o.values
119
+ end
120
+
121
+ def visit_Arel_Nodes_SelectCore o
122
+ visit o.projections
123
+ visit o.froms
124
+ visit o.wheres
125
+ visit o.groups
126
+ visit o.having
127
+ end
128
+
129
+ def visit_Arel_Nodes_SelectStatement o
130
+ visit o.cores
131
+ visit o.orders
132
+ visit o.limit
133
+ visit o.lock
134
+ visit o.offset
135
+ end
136
+
137
+ def visit_Arel_Nodes_UpdateStatement o
138
+ visit o.relation
139
+ visit o.values
140
+ visit o.wheres
141
+ visit o.orders
142
+ visit o.limit
143
+ end
144
+
145
+ def visit_Array o
146
+ o.each { |i| visit i }
147
+ end
148
+
149
+ def visit_Hash o
150
+ o.each { |k,v| visit(k); visit(v) }
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,230 @@
1
+ module Arel
2
+ module Visitors
3
+ class Dot < Arel::Visitors::Visitor
4
+ class Node # :nodoc:
5
+ attr_accessor :name, :id, :fields
6
+
7
+ def initialize name, id, fields = []
8
+ @name = name
9
+ @id = id
10
+ @fields = fields
11
+ end
12
+ end
13
+
14
+ class Edge < Struct.new :name, :from, :to # :nodoc:
15
+ end
16
+
17
+ def initialize
18
+ @nodes = []
19
+ @edges = []
20
+ @node_stack = []
21
+ @edge_stack = []
22
+ @seen = {}
23
+ end
24
+
25
+ def accept object
26
+ super
27
+ to_dot
28
+ end
29
+
30
+ private
31
+ def visit_Arel_Nodes_Ordering o
32
+ visit_edge o, "expr"
33
+ visit_edge o, "direction"
34
+ end
35
+
36
+ def visit_Arel_Nodes_TableAlias o
37
+ visit_edge o, "name"
38
+ visit_edge o, "relation"
39
+ visit_edge o, "columns"
40
+ end
41
+
42
+ def visit_Arel_Nodes_Sum o
43
+ visit_edge o, "expressions"
44
+ visit_edge o, "alias"
45
+ end
46
+ alias :visit_Arel_Nodes_Max :visit_Arel_Nodes_Sum
47
+ alias :visit_Arel_Nodes_Avg :visit_Arel_Nodes_Sum
48
+
49
+ def visit_Arel_Nodes_Count o
50
+ visit_edge o, "expressions"
51
+ visit_edge o, "distinct"
52
+ end
53
+
54
+ def visit_Arel_Nodes_Values o
55
+ visit_edge o, "expressions"
56
+ end
57
+
58
+ def visit_Arel_Nodes_StringJoin o
59
+ visit_edge o, "left"
60
+ visit_edge o, "right"
61
+ end
62
+
63
+ def visit_Arel_Nodes_InnerJoin o
64
+ visit_edge o, "left"
65
+ visit_edge o, "right"
66
+ visit_edge o, "constraint"
67
+ end
68
+ alias :visit_Arel_Nodes_OuterJoin :visit_Arel_Nodes_InnerJoin
69
+
70
+ def visit_Arel_Nodes_DeleteStatement o
71
+ visit_edge o, "relation"
72
+ visit_edge o, "wheres"
73
+ end
74
+
75
+ def unary o
76
+ visit_edge o, "expr"
77
+ end
78
+ alias :visit_Arel_Nodes_Group :unary
79
+ alias :visit_Arel_Nodes_Grouping :unary
80
+ alias :visit_Arel_Nodes_Having :unary
81
+ alias :visit_Arel_Nodes_Limit :unary
82
+ alias :visit_Arel_Nodes_Not :unary
83
+ alias :visit_Arel_Nodes_Offset :unary
84
+ alias :visit_Arel_Nodes_On :unary
85
+ alias :visit_Arel_Nodes_Top :unary
86
+ alias :visit_Arel_Nodes_UnqualifiedColumn :unary
87
+
88
+ def visit_Arel_Nodes_InsertStatement o
89
+ visit_edge o, "relation"
90
+ visit_edge o, "columns"
91
+ visit_edge o, "values"
92
+ end
93
+
94
+ def visit_Arel_Nodes_SelectCore o
95
+ visit_edge o, "froms"
96
+ visit_edge o, "projections"
97
+ visit_edge o, "wheres"
98
+ end
99
+
100
+ def visit_Arel_Nodes_SelectStatement o
101
+ visit_edge o, "cores"
102
+ visit_edge o, "limit"
103
+ visit_edge o, "orders"
104
+ visit_edge o, "offset"
105
+ end
106
+
107
+ def visit_Arel_Nodes_UpdateStatement o
108
+ visit_edge o, "relation"
109
+ visit_edge o, "wheres"
110
+ visit_edge o, "values"
111
+ end
112
+
113
+ def visit_Arel_Table o
114
+ visit_edge o, "name"
115
+ end
116
+
117
+ def visit_Arel_Attribute o
118
+ visit_edge o, "relation"
119
+ visit_edge o, "name"
120
+ end
121
+ alias :visit_Arel_Attributes_Integer :visit_Arel_Attribute
122
+ alias :visit_Arel_Attributes_Float :visit_Arel_Attribute
123
+ alias :visit_Arel_Attributes_String :visit_Arel_Attribute
124
+ alias :visit_Arel_Attributes_Time :visit_Arel_Attribute
125
+ alias :visit_Arel_Attributes_Boolean :visit_Arel_Attribute
126
+ alias :visit_Arel_Attributes_Attribute :visit_Arel_Attribute
127
+
128
+ def visit_Arel_Nodes_Equality o
129
+ visit_edge o, "left"
130
+ visit_edge o, "right"
131
+ end
132
+ alias :visit_Arel_Nodes_And :visit_Arel_Nodes_Equality
133
+ alias :visit_Arel_Nodes_Or :visit_Arel_Nodes_Equality
134
+ alias :visit_Arel_Nodes_NotEqual :visit_Arel_Nodes_Equality
135
+ alias :visit_Arel_Nodes_GreaterThan :visit_Arel_Nodes_Equality
136
+ alias :visit_Arel_Nodes_GreaterThanOrEqual :visit_Arel_Nodes_Equality
137
+ alias :visit_Arel_Nodes_Assignment :visit_Arel_Nodes_Equality
138
+ alias :visit_Arel_Nodes_In :visit_Arel_Nodes_Equality
139
+ alias :visit_Arel_Nodes_LessThan :visit_Arel_Nodes_Equality
140
+ alias :visit_Arel_Nodes_LessThanOrEqual :visit_Arel_Nodes_Equality
141
+ alias :visit_Arel_Nodes_Between :visit_Arel_Nodes_Equality
142
+ alias :visit_Arel_Nodes_NotIn :visit_Arel_Nodes_Equality
143
+ alias :visit_Arel_Nodes_DoesNotMatch :visit_Arel_Nodes_Equality
144
+ alias :visit_Arel_Nodes_Matches :visit_Arel_Nodes_Equality
145
+
146
+ def visit_String o
147
+ @node_stack.last.fields << o
148
+ end
149
+ alias :visit_Time :visit_String
150
+ alias :visit_Date :visit_String
151
+ alias :visit_DateTime :visit_String
152
+ alias :visit_NilClass :visit_String
153
+ alias :visit_TrueClass :visit_String
154
+ alias :visit_FalseClass :visit_String
155
+ alias :visit_Arel_SqlLiteral :visit_String
156
+ alias :visit_Fixnum :visit_String
157
+ alias :visit_BigDecimal :visit_String
158
+ alias :visit_Float :visit_String
159
+ alias :visit_Symbol :visit_String
160
+ alias :visit_Arel_Nodes_SqlLiteral :visit_String
161
+
162
+ def visit_Hash o
163
+ o.each_with_index do |pair, i|
164
+ edge("pair_#{i}") { visit pair }
165
+ end
166
+ end
167
+
168
+ def visit_Array o
169
+ o.each_with_index do |x,i|
170
+ edge(i) { visit x }
171
+ end
172
+ end
173
+
174
+ def visit_edge o, method
175
+ edge(method) { visit o.send(method) }
176
+ end
177
+
178
+ def visit o
179
+ if node = @seen[o.object_id]
180
+ @edge_stack.last.to = node
181
+ return
182
+ end
183
+
184
+ node = Node.new(o.class.name, o.object_id)
185
+ @seen[node.id] = node
186
+ @nodes << node
187
+ with_node node do
188
+ super
189
+ end
190
+ end
191
+
192
+ def edge name
193
+ edge = Edge.new(name, @node_stack.last)
194
+ @edge_stack.push edge
195
+ @edges << edge
196
+ yield
197
+ @edge_stack.pop
198
+ end
199
+
200
+ def with_node node
201
+ if edge = @edge_stack.last
202
+ edge.to = node
203
+ end
204
+
205
+ @node_stack.push node
206
+ yield
207
+ @node_stack.pop
208
+ end
209
+
210
+ def quote string
211
+ string.to_s.gsub('"', '\"')
212
+ end
213
+
214
+ def to_dot
215
+ "digraph \"ARel\" {\nnode [width=0.375,height=0.25,shape=record];\n" +
216
+ @nodes.map { |node|
217
+ label = "<f0>#{node.name}"
218
+
219
+ node.fields.each_with_index do |field, i|
220
+ label << "|<f#{i + 1}>#{quote field}"
221
+ end
222
+
223
+ "#{node.id} [label=\"#{label}\"];"
224
+ }.join("\n") + "\n" + @edges.map { |edge|
225
+ "#{edge.from.id} -> #{edge.to.id} [label=\"#{edge.name}\"];"
226
+ }.join("\n") + "\n}"
227
+ end
228
+ end
229
+ end
230
+ end
@@ -0,0 +1,40 @@
1
+ module Arel
2
+ module Visitors
3
+ ###
4
+ # This class produces SQL for JOIN clauses but omits the "single-source"
5
+ # part of the Join grammar:
6
+ #
7
+ # http://www.sqlite.org/syntaxdiagrams.html#join-source
8
+ #
9
+ # This visitor is used in SelectManager#join_sql and is for backwards
10
+ # compatibility with Arel V1.0
11
+ class JoinSql < Arel::Visitors::ToSql
12
+ private
13
+
14
+ def visit_Arel_Nodes_SelectCore o
15
+ [o.froms].grep(Nodes::Join).map { |x| visit x }.join ', '
16
+ end
17
+
18
+ def visit_Arel_Nodes_StringJoin o
19
+ [
20
+ (visit o.left if Nodes::Join === o.left),
21
+ visit(o.right)
22
+ ].compact.join ' '
23
+ end
24
+
25
+ def visit_Arel_Nodes_OuterJoin o
26
+ [
27
+ (visit o.left if Nodes::Join === o.left),
28
+ "LEFT OUTER JOIN #{visit o.right} #{visit o.constraint if o.constraint}"
29
+ ].compact.join ' '
30
+ end
31
+
32
+ def visit_Arel_Nodes_InnerJoin o
33
+ [
34
+ (visit o.left if Nodes::Join === o.left),
35
+ "INNER JOIN #{visit o.right} #{visit o.constraint if o.constraint}"
36
+ ].compact.join ' '
37
+ end
38
+ end
39
+ end
40
+ end