bmg 0.11.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 31a0ebe96dae3801143c423e0b014bc9dee902b9
4
- data.tar.gz: 6c4c003b7af5154301bf64f68f12e2bd7ab880f9
3
+ metadata.gz: 67347fd77660f79d3e4d4bfa09199881b03e94ae
4
+ data.tar.gz: c3f52c0219760d8382738106e78bf997633abf93
5
5
  SHA512:
6
- metadata.gz: acaf31901fc7b3da45dfce9d7e1e23f1fe4ca86437db8c954538e3817fb4f4297825177ceb77d2fba60afabbb57e199fd0e932b1e944c5a750882c568fe0ea48
7
- data.tar.gz: b27cd4e4d9132ac73a5fa27b0e03fa6badd197283b369aab9a463519df3b3f5092e3a669c856528063baa7f2a7eadc98c72aadd2a2a11b40f0a9614f0793c9cf
6
+ metadata.gz: b4e91ccd011024741b24b84d31e6b4e23feda9a9b6e7398cf4ad2f534b05205f1f4fef6003635fe31232d9dfabc8852d81642b76535a046aa1f309132b770a61
7
+ data.tar.gz: c9ed01a662aec36ba2b77ca315051d512950fa008c09fd9b3abc8f30dba1d2bb4d881856d0d39919084461141756bbced69afe7a58c365382b34626fc35ec4fe
@@ -82,6 +82,15 @@ module Bmg
82
82
  end
83
83
  protected :_matching
84
84
 
85
+ def not_matching(right, on = [])
86
+ _not_matching self.type.not_matching(right, on), right, on
87
+ end
88
+
89
+ def _not_matching(type, right, on)
90
+ Operator::NotMatching.new(type, self, right, on)
91
+ end
92
+ protected :_not_matching
93
+
85
94
  def page(ordering, page_index, options)
86
95
  _page self.type.page(ordering, page_index, options), ordering, page_index, options
87
96
  end
@@ -74,6 +74,7 @@ require_relative 'operator/group'
74
74
  require_relative 'operator/image'
75
75
  require_relative 'operator/join'
76
76
  require_relative 'operator/matching'
77
+ require_relative 'operator/not_matching'
77
78
  require_relative 'operator/page'
78
79
  require_relative 'operator/project'
79
80
  require_relative 'operator/rename'
@@ -51,6 +51,17 @@ module Bmg
51
51
 
52
52
  protected ### optimization
53
53
 
54
+ def _page(type, ordering, page_index, opts)
55
+ return super unless operand.type.knows_attrlist?
56
+ roots = Support.wrapped_roots(operand.type.to_attrlist, options[:split])
57
+ attrs = ordering.map{|(a,d)| a }
58
+ if (roots & attrs).empty?
59
+ operand.page(ordering, page_index, opts).autowrap(options)
60
+ else
61
+ super
62
+ end
63
+ end
64
+
54
65
  def _restrict(type, predicate)
55
66
  return super unless operand.type.knows_attrlist?
56
67
  roots = Support.wrapped_roots(operand.type.to_attrlist, options[:split])
@@ -0,0 +1,65 @@
1
+ module Bmg
2
+ module Operator
3
+ #
4
+ # NotMatching operator.
5
+ #
6
+ # Filters tuples of left operand to those matching no tuple
7
+ # in right operand.
8
+ #
9
+ class NotMatching
10
+ include Operator::Binary
11
+
12
+ def initialize(type, left, right, on)
13
+ @type = type
14
+ @left = left
15
+ @right = right
16
+ @on = on
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :on
22
+
23
+ public
24
+
25
+ def each
26
+ index = Hash.new
27
+ right.each_with_object(index) do |t, index|
28
+ key = tuple_project(t, on)
29
+ index[key] = true
30
+ end
31
+ left.each do |tuple|
32
+ key = tuple_project(tuple, on)
33
+ yield tuple unless index.has_key?(key)
34
+ end
35
+ end
36
+
37
+ def to_ast
38
+ [ :not_matching, left.to_ast, right.to_ast, on ]
39
+ end
40
+
41
+ protected ### optimization
42
+
43
+ def _restrict(type, predicate)
44
+ # Predicate can always be fully applied to left
45
+ # It can never be applied on right, unlike matching
46
+ left
47
+ .restrict(predicate)
48
+ .not_matching(right, on)
49
+ end
50
+
51
+ protected ### inspect
52
+
53
+ def args
54
+ [ on ]
55
+ end
56
+
57
+ private
58
+
59
+ def tuple_project(tuple, on)
60
+ TupleAlgebra.project(tuple, on)
61
+ end
62
+
63
+ end # class NotMatching
64
+ end # module Operator
65
+ end # module Bmg
@@ -6,7 +6,7 @@ module Bmg
6
6
  def initialize(builder)
7
7
  super
8
8
  @requalify = Hash.new{|h,k|
9
- h[k] = Grammar.sexpr [:range_var_name, builder.next_qualifier!]
9
+ h[k.to_s] = builder.next_qualifier!
10
10
  }
11
11
  end
12
12
  attr_reader :requalify
@@ -15,7 +15,16 @@ module Bmg
15
15
  alias :on_missing :copy_and_apply
16
16
 
17
17
  def on_range_var_name(sexpr)
18
- requalify[sexpr]
18
+ Grammar.sexpr [:range_var_name, requalify[sexpr.qualifier.to_s] ]
19
+ end
20
+
21
+ def on_where_clause(sexpr)
22
+ pred = Predicate::Grammar.sexpr(apply(sexpr.predicate))
23
+ sexpr([:where_clause, pred])
24
+ end
25
+
26
+ def on_qualified_identifier(sexpr)
27
+ Predicate::Factory.qualified_identifier(requalify[sexpr.qualifier.to_s].to_sym, sexpr.name.to_sym)
19
28
  end
20
29
 
21
30
  end # class Requalify
@@ -36,11 +36,13 @@ module Bmg
36
36
  commons = self.on
37
37
  subquery = Clip.new(commons, false, :star, builder).call(right)
38
38
  subquery = Requalify.new(builder).call(subquery)
39
+ subquery = All.new(builder).call(subquery)
39
40
  if commons.size == 0
40
41
  builder.exists(subquery)
41
42
  elsif commons.size == 1
42
43
  identifier = left.desaliaser[commons.to_a.first]
43
- Predicate::Factory.in(identifier, subquery)
44
+ qualified = Predicate::Factory.qualified_identifier(identifier.qualifier, identifier.as_name)
45
+ Predicate::Factory.in(qualified, subquery)
44
46
  else
45
47
  join_pre = join_predicate(left, subquery, commons)
46
48
  subquery = expand_where_clause(subquery, join_pre)
@@ -58,7 +58,17 @@ module Bmg
58
58
  def _matching(type, right, on)
59
59
  if right_expr = extract_compatible_sexpr(right)
60
60
  expr = before_use(self.expr)
61
- expr = Processor::SemiJoin.new(right_expr, on, builder).call(expr)
61
+ expr = Processor::SemiJoin.new(right_expr, on, false, builder).call(expr)
62
+ _instance(type, builder, expr)
63
+ else
64
+ super
65
+ end
66
+ end
67
+
68
+ def _not_matching(type, right, on)
69
+ if right_expr = extract_compatible_sexpr(right)
70
+ expr = before_use(self.expr)
71
+ expr = Processor::SemiJoin.new(right_expr, on, true, builder).call(expr)
62
72
  _instance(type, builder, expr)
63
73
  else
64
74
  super
@@ -30,7 +30,8 @@ module Bmg
30
30
  end
31
31
 
32
32
  def join(oldtype, newtype, right_type, on)
33
- return nil unless rkeys = right_type.keys
33
+ return nil unless rkeys = right_type.keys
34
+ return self if rkeys.any?{|k| (k - on).empty? }
34
35
  keys = []
35
36
  @keys.each do |k1|
36
37
  right_type.keys.each do |k2|
@@ -136,6 +136,10 @@ module Bmg
136
136
  self
137
137
  end
138
138
 
139
+ def not_matching(right, on)
140
+ self
141
+ end
142
+
139
143
  def page(ordering, page_size, options)
140
144
  self
141
145
  end
@@ -1,7 +1,7 @@
1
1
  module Bmg
2
2
  module Version
3
3
  MAJOR = 0
4
- MINOR = 11
4
+ MINOR = 12
5
5
  TINY = 0
6
6
  end
7
7
  VERSION = "#{Version::MAJOR}.#{Version::MINOR}.#{Version::TINY}"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bmg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bernard Lambeau
@@ -133,6 +133,7 @@ files:
133
133
  - lib/bmg/operator/image.rb
134
134
  - lib/bmg/operator/join.rb
135
135
  - lib/bmg/operator/matching.rb
136
+ - lib/bmg/operator/not_matching.rb
136
137
  - lib/bmg/operator/page.rb
137
138
  - lib/bmg/operator/project.rb
138
139
  - lib/bmg/operator/rename.rb