bmg 0.13.0 → 0.14.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 +3 -3
- data/lib/bmg/error.rb +3 -0
- data/lib/bmg/operator.rb +7 -3
- data/lib/bmg/operator/group.rb +1 -1
- data/lib/bmg/reader.rb +2 -1
- data/lib/bmg/relation.rb +12 -0
- data/lib/bmg/relation/empty.rb +2 -1
- data/lib/bmg/relation/in_memory.rb +3 -1
- data/lib/bmg/relation/spied.rb +5 -0
- data/lib/bmg/sequel/translator.rb +2 -4
- data/lib/bmg/sql/processor/semi_join.rb +1 -1
- data/lib/bmg/sql/relation.rb +3 -1
- data/lib/bmg/type.rb +76 -1
- data/lib/bmg/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e9b2b82ef90b6ca136323d9ef107a1e94733c1b6
|
4
|
+
data.tar.gz: 4fdf4e423a73779e03a4870da5d647c6d2c6f403
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c692d1ae8b5146b96e117621721a69880a82fa6f58292fd4d8b3fe709e0189b194701acefb17244201af3a15dcfc284d746e009a4b11a16207ba64195aee68c
|
7
|
+
data.tar.gz: 45cdc9e8479d8e1c30cf733339cbc60a08bf36c64fd388002fcd96c3aa52b2b5e7810869c3587246a25d8f620d6a381cfaec33e6735317e6a99244f6b45214c0
|
data/lib/bmg/algebra.rb
CHANGED
@@ -57,7 +57,7 @@ module Bmg
|
|
57
57
|
protected :_group
|
58
58
|
|
59
59
|
def image(right, as = :image, on = [], options = {})
|
60
|
-
_image self.type.image(right, as, on, options), right, as, on, options
|
60
|
+
_image self.type.image(right.type, as, on, options), right, as, on, options
|
61
61
|
end
|
62
62
|
|
63
63
|
def _image(type, right, as, on, options)
|
@@ -75,7 +75,7 @@ module Bmg
|
|
75
75
|
protected :_join
|
76
76
|
|
77
77
|
def matching(right, on = [])
|
78
|
-
_matching self.type.matching(right, on), right, on
|
78
|
+
_matching self.type.matching(right.type, on), right, on
|
79
79
|
end
|
80
80
|
|
81
81
|
def _matching(type, right, on)
|
@@ -84,7 +84,7 @@ module Bmg
|
|
84
84
|
protected :_matching
|
85
85
|
|
86
86
|
def not_matching(right, on = [])
|
87
|
-
_not_matching self.type.not_matching(right, on), right, on
|
87
|
+
_not_matching self.type.not_matching(right.type, on), right, on
|
88
88
|
end
|
89
89
|
|
90
90
|
def _not_matching(type, right, on)
|
data/lib/bmg/error.rb
CHANGED
data/lib/bmg/operator.rb
CHANGED
@@ -2,6 +2,10 @@ module Bmg
|
|
2
2
|
module Operator
|
3
3
|
include Relation
|
4
4
|
|
5
|
+
attr_reader :type
|
6
|
+
attr_writer :type
|
7
|
+
protected :type=
|
8
|
+
|
5
9
|
def to_s
|
6
10
|
str = "(#{self.class.name.split('::').last.downcase}\n"
|
7
11
|
str << operands.map{|op| op.to_s.gsub(/^/m, " ") }.join("\n")
|
@@ -23,7 +27,7 @@ module Bmg
|
|
23
27
|
module Unary
|
24
28
|
include Operator
|
25
29
|
|
26
|
-
attr_reader :
|
30
|
+
attr_reader :operand
|
27
31
|
|
28
32
|
def _visit(parent, visitor)
|
29
33
|
visitor.call(self, parent)
|
@@ -39,7 +43,7 @@ module Bmg
|
|
39
43
|
module Binary
|
40
44
|
include Operator
|
41
45
|
|
42
|
-
attr_reader :
|
46
|
+
attr_reader :left, :right
|
43
47
|
|
44
48
|
def _visit(parent, visitor)
|
45
49
|
visitor.call(self, parent)
|
@@ -55,7 +59,7 @@ module Bmg
|
|
55
59
|
module Nary
|
56
60
|
include Operator
|
57
61
|
|
58
|
-
attr_reader :
|
62
|
+
attr_reader :operands
|
59
63
|
|
60
64
|
def _visit(parent, visitor)
|
61
65
|
visitor.call(self, parent)
|
data/lib/bmg/operator/group.rb
CHANGED
data/lib/bmg/reader.rb
CHANGED
data/lib/bmg/relation.rb
CHANGED
@@ -13,6 +13,18 @@ module Bmg
|
|
13
13
|
Relation::Empty.new(type)
|
14
14
|
end
|
15
15
|
|
16
|
+
def with_typecheck
|
17
|
+
dup.tap{|r|
|
18
|
+
r.type = r.type.with_typecheck
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def without_typecheck
|
23
|
+
dup.tap{|r|
|
24
|
+
r.type = r.type.with_typecheck
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
16
28
|
def empty?
|
17
29
|
each{|t| return false }
|
18
30
|
true
|
data/lib/bmg/relation/empty.rb
CHANGED
data/lib/bmg/relation/spied.rb
CHANGED
@@ -134,10 +134,8 @@ module Bmg
|
|
134
134
|
|
135
135
|
public ### Predicate hack
|
136
136
|
|
137
|
-
def
|
138
|
-
|
139
|
-
right = apply(right) if sexpr.subquery?
|
140
|
-
::Sequel.expr(left => right)
|
137
|
+
def on_opaque(sexpr)
|
138
|
+
apply(sexpr.last)
|
141
139
|
end
|
142
140
|
|
143
141
|
def on_exists(sexpr)
|
@@ -41,7 +41,7 @@ module Bmg
|
|
41
41
|
builder.exists(subquery)
|
42
42
|
elsif commons.size == 1
|
43
43
|
identifier = left.desaliaser(true)[commons.to_a.first]
|
44
|
-
Predicate::Factory.in(identifier, subquery)
|
44
|
+
Predicate::Factory.in(identifier, Predicate::Factory.opaque(subquery))
|
45
45
|
else
|
46
46
|
join_pre = join_predicate(left, subquery, commons)
|
47
47
|
subquery = expand_where_clause(subquery, join_pre)
|
data/lib/bmg/sql/relation.rb
CHANGED
data/lib/bmg/type.rb
CHANGED
@@ -3,11 +3,33 @@ module Bmg
|
|
3
3
|
|
4
4
|
def initialize(predicate = Predicate.tautology)
|
5
5
|
@predicate = predicate
|
6
|
+
@typechecked = false
|
6
7
|
raise ArgumentError if @predicate.nil?
|
7
8
|
end
|
8
9
|
|
9
10
|
ANY = Type.new
|
10
11
|
|
12
|
+
public ## type checking
|
13
|
+
|
14
|
+
attr_writer :typechecked
|
15
|
+
protected :typechecked=
|
16
|
+
|
17
|
+
def typechecked?
|
18
|
+
@typechecked
|
19
|
+
end
|
20
|
+
|
21
|
+
def with_typecheck
|
22
|
+
dup.tap{|x|
|
23
|
+
x.typechecked = true
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def without_typecheck
|
28
|
+
dup.tap{|x|
|
29
|
+
x.typechecked = false
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
11
33
|
public ## predicate
|
12
34
|
|
13
35
|
attr_accessor :predicate
|
@@ -69,6 +91,7 @@ module Bmg
|
|
69
91
|
public ### algebra
|
70
92
|
|
71
93
|
def allbut(butlist)
|
94
|
+
known_attributes!(butlist) if typechecked? && knows_attrlist?
|
72
95
|
dup.tap{|x|
|
73
96
|
x.attrlist = self.attrlist - butlist if knows_attrlist?
|
74
97
|
x.predicate = Predicate.tautology
|
@@ -89,10 +112,16 @@ module Bmg
|
|
89
112
|
end
|
90
113
|
|
91
114
|
def autosummarize(by, summarization)
|
92
|
-
|
115
|
+
known_attributes!(by + summarization.keys) if typechecked? && knows_attrlist?
|
116
|
+
dup.tap{|x|
|
117
|
+
x.attrlist = nil
|
118
|
+
x.predicate = Predicate.tautology
|
119
|
+
x.keys = nil
|
120
|
+
}
|
93
121
|
end
|
94
122
|
|
95
123
|
def constants(cs)
|
124
|
+
unknown_attributes!(cs.keys) if typechecked? && knows_attrlist?
|
96
125
|
dup.tap{|x|
|
97
126
|
x.attrlist = self.attrlist + cs.keys if knows_attrlist?
|
98
127
|
x.predicate = self.predicate & Predicate.eq(cs)
|
@@ -101,6 +130,7 @@ module Bmg
|
|
101
130
|
end
|
102
131
|
|
103
132
|
def extend(extension)
|
133
|
+
unknown_attributes!(extension.keys) if typechecked? && knows_attrlist?
|
104
134
|
dup.tap{|x|
|
105
135
|
x.attrlist = self.attrlist + extension.keys if knows_attrlist?
|
106
136
|
x.predicate = Predicate.tautology
|
@@ -109,6 +139,10 @@ module Bmg
|
|
109
139
|
end
|
110
140
|
|
111
141
|
def group(attrs, as)
|
142
|
+
if typechecked? && knows_attrlist?
|
143
|
+
known_attributes!(attrs)
|
144
|
+
unknown_attributes!([as])
|
145
|
+
end
|
112
146
|
dup.tap{|x|
|
113
147
|
x.attrlist = self.attrlist - attrs + [as] if knows_attrlist?
|
114
148
|
x.predicate = Predicate.tautology
|
@@ -117,6 +151,10 @@ module Bmg
|
|
117
151
|
end
|
118
152
|
|
119
153
|
def image(right, as, on, options)
|
154
|
+
if typechecked? && knows_attrlist?
|
155
|
+
join_compatible!(right, on)
|
156
|
+
unknown_attributes!([as])
|
157
|
+
end
|
120
158
|
dup.tap{|x|
|
121
159
|
x.attrlist = self.attrlist + [as] if knows_attrlist?
|
122
160
|
x.predicate = Predicate.tautology
|
@@ -125,6 +163,7 @@ module Bmg
|
|
125
163
|
end
|
126
164
|
|
127
165
|
def join(right, on)
|
166
|
+
join_compatible!(right, on) if typechecked? && knows_attrlist?
|
128
167
|
dup.tap{|x|
|
129
168
|
x.attrlist = (knows_attrlist? and right.knows_attrlist?) ? (self.attrlist + right.attrlist).uniq : nil
|
130
169
|
x.predicate = self.predicate & right.predicate
|
@@ -133,18 +172,22 @@ module Bmg
|
|
133
172
|
end
|
134
173
|
|
135
174
|
def matching(right, on)
|
175
|
+
join_compatible!(right, on) if typechecked? && knows_attrlist?
|
136
176
|
self
|
137
177
|
end
|
138
178
|
|
139
179
|
def not_matching(right, on)
|
180
|
+
join_compatible!(right, on) if typechecked? && knows_attrlist?
|
140
181
|
self
|
141
182
|
end
|
142
183
|
|
143
184
|
def page(ordering, page_size, options)
|
185
|
+
known_attributes!(ordering.map{|(k,v)| k}) if typechecked? && knows_attrlist?
|
144
186
|
self
|
145
187
|
end
|
146
188
|
|
147
189
|
def project(attrlist)
|
190
|
+
known_attributes!(attrlist) if typechecked? && knows_attrlist?
|
148
191
|
dup.tap{|x|
|
149
192
|
x.attrlist = attrlist
|
150
193
|
x.predicate = Predicate.tautology
|
@@ -153,6 +196,10 @@ module Bmg
|
|
153
196
|
end
|
154
197
|
|
155
198
|
def rename(renaming)
|
199
|
+
if typechecked? && knows_attrlist?
|
200
|
+
known_attributes!(renaming.keys)
|
201
|
+
unknown_attributes!(renaming.values)
|
202
|
+
end
|
156
203
|
dup.tap{|x|
|
157
204
|
x.attrlist = self.attrlist.map{|a| renaming[a] || a } if knows_attrlist?
|
158
205
|
x.predicate = self.predicate.rename(renaming)
|
@@ -161,6 +208,7 @@ module Bmg
|
|
161
208
|
end
|
162
209
|
|
163
210
|
def restrict(predicate)
|
211
|
+
known_attributes!(predicate.free_variables) if typechecked? && knows_attrlist?
|
164
212
|
dup.tap{|x|
|
165
213
|
### attrlist stays the same
|
166
214
|
x.predicate = self.predicate & predicate
|
@@ -169,6 +217,12 @@ module Bmg
|
|
169
217
|
end
|
170
218
|
|
171
219
|
def union(other)
|
220
|
+
if typechecked? && knows_attrlist? && other.knows_attrlist?
|
221
|
+
missing = self.attrlist - other.attrlist
|
222
|
+
raise TypeError, "Union incompatible: missing right attributes #{missing.join(', ')}" unless missing.empty?
|
223
|
+
extra = other.attrlist - self.attrlist
|
224
|
+
raise TypeError, "Union incompatible: missing left attributes #{extra.join(', ')}" unless extra.empty?
|
225
|
+
end
|
172
226
|
dup.tap{|x|
|
173
227
|
### attrlist stays the same
|
174
228
|
x.predicate = self.predicate | predicate
|
@@ -176,5 +230,26 @@ module Bmg
|
|
176
230
|
}
|
177
231
|
end
|
178
232
|
|
233
|
+
private
|
234
|
+
|
235
|
+
def known_attributes!(attrs)
|
236
|
+
extra = attrs - self.attrlist
|
237
|
+
raise TypeError, "Unknown attributes #{extra.join(', ')}" unless extra.empty?
|
238
|
+
end
|
239
|
+
|
240
|
+
def unknown_attributes!(attrs)
|
241
|
+
clash = self.attrlist & attrs
|
242
|
+
raise TypeError, "Existing attributes #{clash.join(', ')}" unless clash.empty?
|
243
|
+
end
|
244
|
+
|
245
|
+
def join_compatible!(right, on)
|
246
|
+
extra = on - self.attrlist
|
247
|
+
raise TypeError, "Unknow attributes #{extra.join(', ')}" unless extra.empty?
|
248
|
+
if right.knows_attrlist?
|
249
|
+
extra = on - right.attrlist
|
250
|
+
raise TypeError, "Unknow attributes #{extra.join(', ')}" unless extra.empty?
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
179
254
|
end # class Type
|
180
255
|
end # module Bmg
|
data/lib/bmg/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bmg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bernard Lambeau
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-06-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: predicate
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '2.
|
19
|
+
version: '2.1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '2.
|
26
|
+
version: '2.1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|