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 +4 -4
- data/lib/bmg/algebra.rb +9 -0
- data/lib/bmg/operator.rb +1 -0
- data/lib/bmg/operator/autowrap.rb +11 -0
- data/lib/bmg/operator/not_matching.rb +65 -0
- data/lib/bmg/sql/processor/requalify.rb +11 -2
- data/lib/bmg/sql/processor/semi_join.rb +3 -1
- data/lib/bmg/sql/relation.rb +11 -1
- data/lib/bmg/support/keys.rb +2 -1
- data/lib/bmg/type.rb +4 -0
- data/lib/bmg/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 67347fd77660f79d3e4d4bfa09199881b03e94ae
|
4
|
+
data.tar.gz: c3f52c0219760d8382738106e78bf997633abf93
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4e91ccd011024741b24b84d31e6b4e23feda9a9b6e7398cf4ad2f534b05205f1f4fef6003635fe31232d9dfabc8852d81642b76535a046aa1f309132b770a61
|
7
|
+
data.tar.gz: c9ed01a662aec36ba2b77ca315051d512950fa008c09fd9b3abc8f30dba1d2bb4d881856d0d39919084461141756bbced69afe7a58c365382b34626fc35ec4fe
|
data/lib/bmg/algebra.rb
CHANGED
@@ -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
|
data/lib/bmg/operator.rb
CHANGED
@@ -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] =
|
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.
|
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)
|
data/lib/bmg/sql/relation.rb
CHANGED
@@ -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
|
data/lib/bmg/support/keys.rb
CHANGED
@@ -30,7 +30,8 @@ module Bmg
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def join(oldtype, newtype, right_type, on)
|
33
|
-
return nil
|
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|
|
data/lib/bmg/type.rb
CHANGED
data/lib/bmg/version.rb
CHANGED
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.
|
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
|