bmg 0.11.0 → 0.12.0

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