43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
# File 'lib/select.rb', line 43
def render(context = nil, depth = 0, id = nil)
raise 'No FROM clause was specified' unless @source
indent = ' ' * depth
context ||= Context.new
parameters = {}
source_query = @source.create_query
source_query_id = context.create_id
source_result = source_query.render(context, depth + 1, source_query_id)
inner_join_fragments = []
inner_join_results = []
@inner_joins.each do |inner_join|
inner_join_query = inner_join.source.create_query
inner_join_query_id = context.create_id
inner_join_result = inner_join_query.render(context, depth + 1, inner_join_query_id)
inner_join_results << inner_join_result
x = ColumnProxy.new(source_result)
y = ColumnProxy.new(inner_join_result)
predicate = inner_join.predicate_block.call(x, y)
bah = {
source_result => source_result.id,
inner_join_result => inner_join_result.id,
}
predicate_result = predicate.render_sql(context, bah)
inner_join_fragments << "#{indent}INNER JOIN #{inner_join_result.sql}"
inner_join_fragments << "#{indent}ON #{predicate_result.sql}\n"
end
columns = @column_set.capture(source_result, inner_join_results)
column_results = columns.collect { |x| x.render_sql(context, x.source.id) }
fragments = []
fragments << "#{indent}SELECT\n"
column_results.each_with_index do |column_result, index|
fragments << "#{indent} #{column_result.sql}#{index < column_results.size - 1 ? ',' : ''}\n"
end
fragments << "#{indent}FROM #{source_result.sql}"
fragments += inner_join_fragments
if @where_predicate_block
blah = [source_result] + inner_join_results
proxies = blah.collect { |x| ColumnProxy.new(x) }
where_predicate = @where_predicate_block.call(Util::fix_block_params(proxies))
bah = blah.inject({}) { |acc, x| acc[x] = x.id; acc }
where_predicate_result = where_predicate.render_sql(context, bah)
parameters.merge!(where_predicate_result.parameters)
fragments << "#{indent}WHERE #{where_predicate_result.sql}\n"
end
if @order_by_column_set
order_by_columns = @order_by_column_set.capture(source_result, inner_join_results)
order_by_column_results = order_by_columns.collect { |x| x.render_sql(context, x.source.id) }
fragments << "#{indent}ORDER BY #{order_by_column_results.collect(&:sql).join(', ')}\n"
end
if @count
fragments << "LIMIT #{@count}"
end
sql = fragments.join
RenderResult.new(
id,
sql,
columns.collect(&:name),
parameters
)
end
|