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