lib/conceptql/operators/union.rb in conceptql-0.2.0 vs lib/conceptql/operators/union.rb in conceptql-0.3.0
- old
+ new
@@ -1,19 +1,56 @@
require_relative 'pass_thru'
module ConceptQL
module Operators
class Union < PassThru
+ register __FILE__
+
desc 'Pools sets of incoming results into a single large set of results.'
allows_many_upstreams
- category 'Set Logic'
+ category "Combine Streams"
+ default_query_columns
+ validate_at_least_one_upstream
+ validate_no_arguments
def query(db)
- values.map do |expression|
+ upstreams.map do |expression|
expression.evaluate(db).from_self
end.inject do |q, query|
q.union(query, all: true)
end
+ end
+
+ def flattened
+ exprs = []
+ upstreams.each do |x|
+ if x.is_a?(Union)
+ exprs.concat x.flattened.upstreams
+ else
+ exprs << x
+ end
+ end
+ dup_values(exprs)
+ end
+
+ def optimized
+ first, *rest = flattened.upstreams
+ exprs = [first]
+
+ rest.each do |expression|
+ add = true
+ exprs.length.times do |i|
+ exp = exprs[i]
+ if exprs[i].unionable?(expression)
+ exprs[i] = exp.union(expression, all: true)
+ add = false
+ break
+ end
+ end
+ exprs << expression if add
+ end
+
+ dup_values(exprs.map{|x| x.is_a?(Operator) ? x.optimized : x})
end
end
end
end