veritas-sql-generator 0.0.3 → 0.0.4

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.
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