veritas-sql-generator 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. data/.gemtest +0 -0
  2. data/.rvmrc +1 -0
  3. data/.travis.yml +8 -0
  4. data/Gemfile +20 -10
  5. data/Guardfile +22 -0
  6. data/README.rdoc +2 -0
  7. data/Rakefile +4 -2
  8. data/TODO +16 -2
  9. data/config/flay.yml +2 -2
  10. data/config/flog.yml +1 -1
  11. data/config/roodi.yml +5 -5
  12. data/config/site.reek +21 -19
  13. data/lib/veritas/sql/generator.rb +25 -2
  14. data/lib/veritas/sql/generator/core_ext/date.rb +20 -0
  15. data/lib/veritas/sql/generator/core_ext/date_time.rb +45 -0
  16. data/lib/veritas/sql/generator/direction.rb +3 -1
  17. data/lib/veritas/sql/generator/function.rb +54 -0
  18. data/lib/veritas/sql/generator/function/aggregate.rb +134 -0
  19. data/lib/veritas/sql/generator/function/connective.rb +53 -0
  20. data/lib/veritas/sql/generator/function/numeric.rb +135 -0
  21. data/lib/veritas/sql/generator/function/predicate.rb +266 -0
  22. data/lib/veritas/sql/generator/function/proposition.rb +38 -0
  23. data/lib/veritas/sql/generator/function/string.rb +29 -0
  24. data/lib/veritas/sql/generator/identifier.rb +2 -1
  25. data/lib/veritas/sql/generator/literal.rb +15 -18
  26. data/lib/veritas/sql/generator/relation.rb +144 -17
  27. data/lib/veritas/sql/generator/relation/binary.rb +16 -64
  28. data/lib/veritas/sql/generator/relation/set.rb +30 -22
  29. data/lib/veritas/sql/generator/relation/unary.rb +131 -78
  30. data/lib/veritas/sql/generator/version.rb +1 -1
  31. data/spec/unit/date/iso8601_spec.rb +23 -0
  32. data/spec/unit/date_time/iso_8601_spec.rb +115 -0
  33. data/spec/unit/veritas/sql/generator/class_methods/parenthesize_spec.rb +18 -0
  34. data/spec/unit/veritas/sql/generator/function/aggregate/visit_veritas_aggregate_count_spec.rb +16 -0
  35. data/spec/unit/veritas/sql/generator/function/aggregate/visit_veritas_aggregate_maximum_spec.rb +16 -0
  36. data/spec/unit/veritas/sql/generator/function/aggregate/visit_veritas_aggregate_mean_spec.rb +16 -0
  37. data/spec/unit/veritas/sql/generator/function/aggregate/visit_veritas_aggregate_minimum_spec.rb +16 -0
  38. data/spec/unit/veritas/sql/generator/function/aggregate/visit_veritas_aggregate_standard_deviation_spec.rb +16 -0
  39. data/spec/unit/veritas/sql/generator/function/aggregate/visit_veritas_aggregate_sum_spec.rb +16 -0
  40. data/spec/unit/veritas/sql/generator/function/aggregate/visit_veritas_aggregate_variance_spec.rb +16 -0
  41. data/spec/unit/veritas/sql/generator/function/connective/visit_veritas_function_connective_conjunction_spec.rb +20 -0
  42. data/spec/unit/veritas/sql/generator/function/connective/visit_veritas_function_connective_disjunction_spec.rb +20 -0
  43. data/spec/unit/veritas/sql/generator/function/connective/visit_veritas_function_connective_negation_spec.rb +20 -0
  44. data/spec/unit/veritas/sql/generator/function/numeric/visit_veritas_function_numeric_absolute_spec.rb +15 -0
  45. data/spec/unit/veritas/sql/generator/function/numeric/visit_veritas_function_numeric_addition_spec.rb +15 -0
  46. data/spec/unit/veritas/sql/generator/function/numeric/visit_veritas_function_numeric_division_spec.rb +15 -0
  47. data/spec/unit/veritas/sql/generator/function/numeric/visit_veritas_function_numeric_exponentiation_spec.rb +15 -0
  48. data/spec/unit/veritas/sql/generator/function/numeric/visit_veritas_function_numeric_modulo_spec.rb +15 -0
  49. data/spec/unit/veritas/sql/generator/function/numeric/visit_veritas_function_numeric_multiplication_spec.rb +15 -0
  50. data/spec/unit/veritas/sql/generator/function/numeric/visit_veritas_function_numeric_square_root_spec.rb +15 -0
  51. data/spec/unit/veritas/sql/generator/function/numeric/visit_veritas_function_numeric_subtraction_spec.rb +15 -0
  52. data/spec/unit/veritas/sql/generator/function/numeric/visit_veritas_function_numeric_unary_minus_spec.rb +15 -0
  53. data/spec/unit/veritas/sql/generator/function/numeric/visit_veritas_function_numeric_unary_plus_spec.rb +15 -0
  54. data/spec/unit/veritas/sql/generator/{logic/visit_veritas_logic_predicate_equality_spec.rb → function/predicate/visit_veritas_function_predicate_equality_spec.rb} +5 -5
  55. data/spec/unit/veritas/sql/generator/{logic/visit_veritas_logic_predicate_exclusion_spec.rb → function/predicate/visit_veritas_function_predicate_exclusion_spec.rb} +10 -6
  56. data/spec/unit/veritas/sql/generator/function/predicate/visit_veritas_function_predicate_greater_than_or_equal_to_spec.rb +15 -0
  57. data/spec/unit/veritas/sql/generator/{logic/visit_veritas_logic_predicate_greater_than_spec.rb → function/predicate/visit_veritas_function_predicate_greater_than_spec.rb} +5 -5
  58. data/spec/unit/veritas/sql/generator/{logic/visit_veritas_logic_predicate_inclusion_spec.rb → function/predicate/visit_veritas_function_predicate_inclusion_spec.rb} +10 -6
  59. data/spec/unit/veritas/sql/generator/{logic/visit_veritas_logic_predicate_inequality_spec.rb → function/predicate/visit_veritas_function_predicate_inequality_spec.rb} +8 -8
  60. data/spec/unit/veritas/sql/generator/function/predicate/visit_veritas_function_predicate_less_than_or_equal_to_spec.rb +15 -0
  61. data/spec/unit/veritas/sql/generator/{logic/visit_veritas_logic_predicate_less_than_spec.rb → function/predicate/visit_veritas_function_predicate_less_than_spec.rb} +5 -5
  62. data/spec/unit/veritas/sql/generator/function/proposition/visit_veritas_function_proposition_contradiction_spec.rb +15 -0
  63. data/spec/unit/veritas/sql/generator/function/proposition/visit_veritas_function_proposition_tautology_spec.rb +15 -0
  64. data/spec/unit/veritas/sql/generator/function/string/visit_veritas_function_string_length_spec.rb +15 -0
  65. data/spec/unit/veritas/sql/generator/literal/class_methods/dup_frozen_spec.rb +2 -2
  66. data/spec/unit/veritas/sql/generator/relation/binary/base/to_subquery_spec.rb +1 -1
  67. data/spec/unit/veritas/sql/generator/relation/binary/base/{visit_veritas_base_relation_spec.rb → visit_veritas_relation_base_spec.rb} +3 -3
  68. data/spec/unit/veritas/sql/generator/relation/binary/to_s_spec.rb +2 -2
  69. data/spec/unit/veritas/sql/generator/relation/binary/to_subquery_spec.rb +2 -2
  70. data/spec/unit/veritas/sql/generator/relation/binary/visit_veritas_algebra_join_spec.rb +74 -33
  71. data/spec/unit/veritas/sql/generator/relation/binary/visit_veritas_algebra_product_spec.rb +63 -19
  72. data/spec/unit/veritas/sql/generator/relation/class_methods/visit_spec.rb +1 -1
  73. data/spec/unit/veritas/sql/generator/relation/set/class_methods/normalize_operand_headers_spec.rb +35 -0
  74. data/spec/unit/veritas/sql/generator/relation/set/to_s_spec.rb +1 -1
  75. data/spec/unit/veritas/sql/generator/relation/set/to_subquery_spec.rb +4 -4
  76. data/spec/unit/veritas/sql/generator/relation/set/visit_veritas_algebra_difference_spec.rb +83 -30
  77. data/spec/unit/veritas/sql/generator/relation/set/visit_veritas_algebra_intersection_spec.rb +80 -30
  78. data/spec/unit/veritas/sql/generator/relation/set/visit_veritas_algebra_union_spec.rb +80 -30
  79. data/spec/unit/veritas/sql/generator/relation/to_s_spec.rb +50 -0
  80. data/spec/unit/veritas/sql/generator/relation/to_subquery_spec.rb +49 -0
  81. data/spec/unit/veritas/sql/generator/relation/unary/to_s_spec.rb +1 -1
  82. data/spec/unit/veritas/sql/generator/relation/unary/to_subquery_spec.rb +6 -6
  83. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_algebra_extension_spec.rb +165 -0
  84. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_algebra_projection_spec.rb +84 -29
  85. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_algebra_rename_spec.rb +69 -27
  86. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_algebra_restriction_spec.rb +64 -22
  87. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_algebra_summarization_spec.rb +652 -0
  88. data/spec/unit/veritas/sql/generator/relation/unary/{visit_veritas_base_relation_spec.rb → visit_veritas_relation_base_spec.rb} +4 -4
  89. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_relation_operation_limit_spec.rb +60 -20
  90. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_relation_operation_offset_spec.rb +60 -20
  91. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_relation_operation_order_spec.rb +63 -23
  92. data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_relation_operation_reverse_spec.rb +60 -20
  93. data/spec/unit/veritas/sql/generator/relation/visited_spec.rb +1 -1
  94. data/tasks/metrics/ci.rake +7 -0
  95. data/tasks/{quality → metrics}/flay.rake +0 -0
  96. data/tasks/{quality → metrics}/flog.rake +0 -0
  97. data/tasks/{quality → metrics}/heckle.rake +1 -0
  98. data/tasks/{quality → metrics}/metric_fu.rake +3 -0
  99. data/tasks/{quality → metrics}/reek.rake +0 -0
  100. data/tasks/{quality → metrics}/roodi.rake +0 -0
  101. data/tasks/{quality → metrics}/yardstick.rake +0 -0
  102. data/tasks/spec.rake +1 -0
  103. data/veritas-sql-generator.gemspec +82 -114
  104. metadata +137 -125
  105. data/lib/veritas/base_relation.rb +0 -36
  106. data/lib/veritas/sql/generator/logic.rb +0 -349
  107. data/spec/unit/veritas/base_relation/name_spec.rb +0 -45
  108. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_connective_conjunction_spec.rb +0 -16
  109. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_connective_disjunction_spec.rb +0 -16
  110. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_connective_negation_spec.rb +0 -16
  111. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_predicate_greater_than_or_equal_to_spec.rb +0 -15
  112. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_predicate_less_than_or_equal_to_spec.rb +0 -15
  113. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_proposition_contradiction_spec.rb +0 -15
  114. data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_proposition_tautology_spec.rb +0 -15
  115. data/spec/unit/veritas/sql/generator/relation/binary/class_methods/subquery_spec.rb +0 -42
  116. data/spec/unit/veritas/sql/generator/relation/class_methods/subquery_spec.rb +0 -33
  117. data/tasks/quality/ci.rake +0 -2
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+
3
+ module Veritas
4
+ module SQL
5
+ module Generator
6
+ module Function
7
+
8
+ # Generates an SQL statement for a proposition function
9
+ module Proposition
10
+ include Function
11
+
12
+ # Visit a Tautology
13
+ #
14
+ # @param [Function::Proposition::Tautology] _tautology
15
+ #
16
+ # @return [#to_s]
17
+ #
18
+ # @api private
19
+ def visit_veritas_function_proposition_tautology(_tautology)
20
+ TRUE
21
+ end
22
+
23
+ # Visit a Contradiction
24
+ #
25
+ # @param [Function::Proposition::Contradiction] _contradiction
26
+ #
27
+ # @return [#to_s]
28
+ #
29
+ # @api private
30
+ def visit_veritas_function_proposition_contradiction(_contradiction)
31
+ FALSE
32
+ end
33
+
34
+ end # module Proposition
35
+ end # module Function
36
+ end # module Generator
37
+ end # module SQL
38
+ end # module Veritas
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ module Veritas
4
+ module SQL
5
+ module Generator
6
+ module Function
7
+
8
+ # Generates an SQL statement for a string function
9
+ module String
10
+ include Function
11
+
12
+ LENGTH = 'LENGTH'.freeze
13
+
14
+ # Visit a Length function
15
+ #
16
+ # @param [Function::String::Length] length
17
+ #
18
+ # @return [#to_s]
19
+ #
20
+ # @api private
21
+ def visit_veritas_function_string_length(length)
22
+ unary_prefix_operation_sql(LENGTH, length)
23
+ end
24
+
25
+ end # module String
26
+ end # module Function
27
+ end # module Generator
28
+ end # module SQL
29
+ end # module Veritas
@@ -18,7 +18,8 @@ module Veritas
18
18
  #
19
19
  # @api private
20
20
  def visit_identifier(identifier)
21
- "#{QUOTE}#{identifier.to_s.gsub(QUOTE, ESCAPED_QUOTE)}#{QUOTE}"
21
+ escaped = identifier.to_s.gsub(QUOTE, ESCAPED_QUOTE)
22
+ escaped.insert(0, QUOTE) << QUOTE
22
23
  end
23
24
 
24
25
  end # module Identifier
@@ -7,15 +7,13 @@ module Veritas
7
7
  # Generates an SQL statement for a literal
8
8
  module Literal
9
9
 
10
- TRUE = 'TRUE'.freeze
11
- FALSE = 'FALSE'.freeze
12
- NULL = 'NULL'.freeze
13
- QUOTE = "'".freeze
14
- ESCAPED_QUOTE = "''".freeze
15
- SEPARATOR = ', '.freeze
16
- DATE_FORMAT = '%F'.freeze
17
- DATETIME_FORMAT = "#{DATE_FORMAT}T%T.%N%Z".freeze
18
- TIME_SCALE = 9
10
+ TRUE = 'TRUE'.freeze
11
+ FALSE = 'FALSE'.freeze
12
+ NULL = 'NULL'.freeze
13
+ QUOTE = "'".freeze
14
+ ESCAPED_QUOTE = "''".freeze
15
+ SEPARATOR = ', '.freeze
16
+ TIME_SCALE = 9
19
17
 
20
18
  # Returns an unfrozen object
21
19
  #
@@ -41,12 +39,14 @@ module Veritas
41
39
  #
42
40
  # @api private
43
41
  def visit_enumerable(enumerable)
44
- "(#{enumerable.map { |entry| dispatch entry }.join(SEPARATOR)})"
42
+ Generator.parenthesize!(
43
+ enumerable.map { |entry| dispatch entry }.join(SEPARATOR)
44
+ )
45
45
  end
46
46
 
47
47
  # Visit a String
48
48
  #
49
- # @note The string must be utf-8 encoded
49
+ # @note The string must be UTF-8 encoded
50
50
  #
51
51
  # @param [String] string
52
52
  #
@@ -54,7 +54,8 @@ module Veritas
54
54
  #
55
55
  # @api private
56
56
  def visit_string(string)
57
- "#{QUOTE}#{string.gsub(QUOTE, ESCAPED_QUOTE)}#{QUOTE}"
57
+ escaped = string.gsub(QUOTE, ESCAPED_QUOTE)
58
+ escaped.insert(0, QUOTE) << QUOTE
58
59
  end
59
60
 
60
61
  # Visit a Numeric
@@ -86,11 +87,9 @@ module Veritas
86
87
  #
87
88
  # @return [#to_s]
88
89
  #
89
- # @todo use Date#iso8601 when added to 1.8.7 by backports
90
- #
91
90
  # @api private
92
91
  def visit_date(date)
93
- dispatch Literal.dup_frozen(date).strftime(DATE_FORMAT)
92
+ dispatch date.iso8601
94
93
  end
95
94
 
96
95
  # Visit a DateTime and return in ISO 8601 date-time format
@@ -101,11 +100,9 @@ module Veritas
101
100
  #
102
101
  # @return [#to_s]
103
102
  #
104
- # @todo use DateTime#iso8601(TIME_SCALE) when added to 1.8.7 by backports
105
- #
106
103
  # @api private
107
104
  def visit_date_time(date_time)
108
- dispatch date_time.new_offset.strftime(DATETIME_FORMAT)
105
+ dispatch date_time.new_offset.iso8601(TIME_SCALE)
109
106
  end
110
107
 
111
108
  # Visit a Time
@@ -11,7 +11,8 @@ module Veritas
11
11
 
12
12
  EMPTY_STRING = ''.freeze
13
13
  SEPARATOR = ', '.freeze
14
- ALL_COLUMNS = '*'.freeze
14
+ STAR = '*'.freeze
15
+ EMPTY_HASH = {}.freeze
15
16
 
16
17
  # Return the alias name
17
18
  #
@@ -32,34 +33,21 @@ module Veritas
32
33
  when Veritas::Relation::Operation::Set then self::Set
33
34
  when Veritas::Relation::Operation::Binary then self::Binary
34
35
  when Veritas::Relation::Operation::Unary then self::Unary
35
- when Veritas::BaseRelation then self::Base
36
+ when Veritas::Relation::Base then self::Base
36
37
  else
37
38
  raise InvalidRelationError, "#{relation.class} is not a visitable relation"
38
39
  end
39
40
  klass.new.visit(relation)
40
41
  end
41
42
 
42
- # Return the subquery for the relation and identifier
43
- #
44
- # @param [#to_subquery] relation
45
- #
46
- # @param [#to_s] identifier
47
- # optional identifier, defaults to relation.name
48
- #
49
- # @return [#to_s]
50
- #
51
- # @api private
52
- def self.subquery(relation, identifier = relation.name)
53
- "(#{relation.to_subquery}) AS #{visit_identifier(identifier)}"
54
- end
55
-
56
43
  # Initialize a Generator
57
44
  #
58
45
  # @return [undefined]
59
46
  #
60
47
  # @api private
61
48
  def initialize
62
- @sql = EMPTY_STRING
49
+ @sql = EMPTY_STRING
50
+ @extensions = {}
63
51
  end
64
52
 
65
53
  # Visit an object and generate SQL from each node
@@ -93,6 +81,29 @@ module Veritas
93
81
  @sql
94
82
  end
95
83
 
84
+ # Return the SQL for the unary relation
85
+ #
86
+ # @example
87
+ # sql = unary_relation.to_s
88
+ #
89
+ # @return [#to_s]
90
+ #
91
+ # @api public
92
+ def to_s
93
+ return EMPTY_STRING unless visited?
94
+ generate_sql(query_columns)
95
+ end
96
+
97
+ # Return the SQL suitable for an subquery
98
+ #
99
+ # @return [#to_s]
100
+ #
101
+ # @api private
102
+ def to_subquery
103
+ return EMPTY_STRING unless visited?
104
+ Generator.parenthesize!(generate_sql(subquery_columns))
105
+ end
106
+
96
107
  # Test if a visitable object has been visited
97
108
  #
98
109
  # @example
@@ -105,6 +116,122 @@ module Veritas
105
116
  !@name.nil?
106
117
  end
107
118
 
119
+ private
120
+
121
+ # Return the columns to use in a query
122
+ #
123
+ # @return [#to_s]
124
+ #
125
+ # @api private
126
+ def query_columns
127
+ explicit_columns
128
+ end
129
+
130
+ # Return the columns to use in a subquery
131
+ #
132
+ # @return [#to_s]
133
+ #
134
+ # @api private
135
+ def subquery_columns
136
+ implicit_columns
137
+ end
138
+
139
+ # Return the implicit columns for the select list
140
+ #
141
+ # @return [#to_s]
142
+ #
143
+ # @api private
144
+ def implicit_columns
145
+ sql = [ STAR, column_list_for(@extensions) ]
146
+ sql.reject! { |fragment| fragment.empty? }
147
+ sql.join(SEPARATOR)
148
+ end
149
+
150
+ # Return the explicit columns for the select list
151
+ #
152
+ # @return [#to_s]
153
+ #
154
+ # @api private
155
+ def explicit_columns
156
+ @distinct.to_s + column_list_for(@extensions.merge(@columns || EMPTY_HASH))
157
+ end
158
+
159
+ # Return the list of columns
160
+ #
161
+ # @param [#map] columns
162
+ #
163
+ # @return [#to_s]
164
+ #
165
+ # @api private
166
+ def column_list_for(columns)
167
+ sql = columns.values_at(*@header)
168
+ sql.compact!
169
+ sql.join(SEPARATOR)
170
+ end
171
+
172
+ # Return a list of columns in a header
173
+ #
174
+ # @param [Veritas::Relation] relation
175
+ #
176
+ # @param [#[]] aliases
177
+ # optional aliases for the columns
178
+ #
179
+ # @return [Hash]
180
+ #
181
+ # @api private
182
+ def columns_for(relation, aliases = EMPTY_HASH)
183
+ columns = {}
184
+ relation.header.each do |attribute|
185
+ columns[aliases.fetch(attribute, attribute)] = column_for(attribute, aliases)
186
+ end
187
+ columns
188
+ end
189
+
190
+ # Return the column for an attribute
191
+ #
192
+ # @param [Attribute] attribute
193
+ #
194
+ # @param [#[]] aliases
195
+ # aliases for the columns
196
+ #
197
+ # @return [#to_s]
198
+ #
199
+ # @api private
200
+ def column_for(attribute, aliases)
201
+ if aliases.key?(attribute)
202
+ alias_for(attribute, aliases[attribute])
203
+ else
204
+ dispatch(attribute)
205
+ end
206
+ end
207
+
208
+ # Return the column alias for an attribute
209
+ #
210
+ # @param [#to_s] attribute
211
+ #
212
+ # @param [Attribute, nil] alias_attribute
213
+ # attribute to use for the alias
214
+ #
215
+ # @return [#to_s]
216
+ #
217
+ # @api private
218
+ def alias_for(attribute, alias_attribute)
219
+ "#{dispatch(attribute)} AS #{dispatch(alias_attribute)}"
220
+ end
221
+
222
+ # Add extensions for extension and summarize queries
223
+ #
224
+ # @param [#each] extensions
225
+ #
226
+ # @return [undefined]
227
+ #
228
+ # @api private
229
+ def add_extensions(extensions)
230
+ extensions.each do |attribute, function|
231
+ @extensions[attribute] = alias_for(function, attribute)
232
+ end
233
+ end
234
+
108
235
  end # class Relation
109
236
  end # module Generator
110
237
  end # module SQL
@@ -13,17 +13,6 @@ module Veritas
13
13
  LEFT_NAME = 'left'.freeze
14
14
  RIGHT_NAME = 'right'.freeze
15
15
 
16
- # Return the subquery for the generator and identifier
17
- #
18
- # @param [#to_subquery] generator
19
- #
20
- # @return [#to_s]
21
- #
22
- # @api private
23
- def self.subquery(generator, *)
24
- generator.kind_of?(Base) ? generator.to_subquery : super
25
- end
26
-
27
16
  # Visit an Join
28
17
  #
29
18
  # @param [Algebra::Join] join
@@ -32,6 +21,7 @@ module Veritas
32
21
  #
33
22
  # @api private
34
23
  def visit_veritas_algebra_join(join)
24
+ @header = join.header
35
25
  set_operation(JOIN)
36
26
  set_columns(join)
37
27
  set_operands(join)
@@ -47,6 +37,7 @@ module Veritas
47
37
  #
48
38
  # @api private
49
39
  def visit_veritas_algebra_product(product)
40
+ @header = product.header
50
41
  set_operation(PRODUCT)
51
42
  set_columns(product)
52
43
  set_operands(product)
@@ -54,27 +45,6 @@ module Veritas
54
45
  self
55
46
  end
56
47
 
57
- # Return the SQL for the binary relation
58
- #
59
- # @example
60
- # sql = binary_relation.to_s
61
- #
62
- # @return [#to_s]
63
- #
64
- # @api public
65
- def to_s
66
- generate_sql(@columns)
67
- end
68
-
69
- # Return the SQL suitable for an subquery
70
- #
71
- # @return [#to_s]
72
- #
73
- # @api private
74
- def to_subquery
75
- generate_sql(ALL_COLUMNS)
76
- end
77
-
78
48
  private
79
49
 
80
50
  # Generate the SQL using the supplied columns
@@ -85,26 +55,7 @@ module Veritas
85
55
  #
86
56
  # @api private
87
57
  def generate_sql(columns)
88
- return EMPTY_STRING unless visited?
89
- "SELECT #{columns} FROM #{left_subquery} #{@operation} #{right_subquery}"
90
- end
91
-
92
- # Return the left subquery
93
- #
94
- # @return [#to_s]
95
- #
96
- # @api private
97
- def left_subquery
98
- self.class.subquery(@left, LEFT_NAME)
99
- end
100
-
101
- # Return the right subquery
102
- #
103
- # @return [#to_s]
104
- #
105
- # @api private
106
- def right_subquery
107
- self.class.subquery(@right, RIGHT_NAME)
58
+ "SELECT #{columns} FROM #{@left.to_subquery} AS #{visit_identifier(LEFT_NAME)} #{@operation} #{@right.to_subquery} AS #{visit_identifier(RIGHT_NAME)}"
108
59
  end
109
60
 
110
61
  # Set the operation
@@ -151,20 +102,21 @@ module Veritas
151
102
  @name = [ @left.name, @right.name ].uniq.join(UNDERSCORE).freeze
152
103
  end
153
104
 
154
- # Return a list of columns in a header
155
- #
156
- # @param [Veritas::Relation] relation
157
- #
158
- # @return [#to_s]
159
- #
160
- # @api private
161
- def columns_for(relation)
162
- relation.header.map { |attribute| dispatch(attribute) }.join(SEPARATOR)
163
- end
164
-
165
105
  # Generates an SQL statement for base relation binary operands
166
106
  class Base < Relation::Base
167
107
 
108
+ # Return the SQL suitable for an subquery
109
+ #
110
+ # Does not parenthesize the query
111
+ #
112
+ # @return [#to_s]
113
+ #
114
+ # @api private
115
+ def to_subquery
116
+ return EMPTY_STRING unless visited?
117
+ generate_sql
118
+ end
119
+
168
120
  private
169
121
 
170
122
  # Generate the SQL for this base relation
@@ -173,7 +125,7 @@ module Veritas
173
125
  #
174
126
  # @api private
175
127
  def generate_sql(*)
176
- visited? ? @from : EMPTY_STRING
128
+ @from
177
129
  end
178
130
 
179
131
  end # class Base