bmg 0.9.1 → 0.10.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 +2 -26
- data/lib/bmg/algebra/shortcuts.rb +14 -0
- data/lib/bmg/operator/autowrap.rb +32 -2
- data/lib/bmg/operator/constants.rb +12 -0
- data/lib/bmg/operator/image.rb +10 -0
- data/lib/bmg/operator/rename.rb +8 -0
- data/lib/bmg/relation/spied.rb +4 -9
- data/lib/bmg/sequel.rb +53 -2
- data/lib/bmg/sequel/relation.rb +24 -19
- data/lib/bmg/sequel/translator.rb +153 -0
- data/lib/bmg/sequel/type_inference.rb +42 -0
- data/lib/bmg/sql.rb +20 -0
- data/lib/bmg/sql/builder.rb +177 -0
- data/lib/bmg/sql/dialect.rb +15 -0
- data/lib/bmg/sql/ext/predicate.rb +23 -0
- data/lib/bmg/sql/ext/predicate/and.rb +9 -0
- data/lib/bmg/sql/ext/predicate/contradiction.rb +10 -0
- data/lib/bmg/sql/ext/predicate/dyadic_comp.rb +12 -0
- data/lib/bmg/sql/ext/predicate/eq.rb +9 -0
- data/lib/bmg/sql/ext/predicate/exists.rb +12 -0
- data/lib/bmg/sql/ext/predicate/expr.rb +18 -0
- data/lib/bmg/sql/ext/predicate/gt.rb +9 -0
- data/lib/bmg/sql/ext/predicate/gte.rb +9 -0
- data/lib/bmg/sql/ext/predicate/identifier.rb +10 -0
- data/lib/bmg/sql/ext/predicate/in.rb +29 -0
- data/lib/bmg/sql/ext/predicate/literal.rb +10 -0
- data/lib/bmg/sql/ext/predicate/lt.rb +9 -0
- data/lib/bmg/sql/ext/predicate/lte.rb +9 -0
- data/lib/bmg/sql/ext/predicate/nadic_bool.rb +16 -0
- data/lib/bmg/sql/ext/predicate/native.rb +9 -0
- data/lib/bmg/sql/ext/predicate/neq.rb +9 -0
- data/lib/bmg/sql/ext/predicate/not.rb +12 -0
- data/lib/bmg/sql/ext/predicate/or.rb +9 -0
- data/lib/bmg/sql/ext/predicate/qualified_identifier.rb +12 -0
- data/lib/bmg/sql/ext/predicate/tautology.rb +10 -0
- data/lib/bmg/sql/grammar.rb +45 -0
- data/lib/bmg/sql/grammar.sexp.yml +96 -0
- data/lib/bmg/sql/nodes/column_name.rb +25 -0
- data/lib/bmg/sql/nodes/cross_join.rb +28 -0
- data/lib/bmg/sql/nodes/except.rb +14 -0
- data/lib/bmg/sql/nodes/expr.rb +94 -0
- data/lib/bmg/sql/nodes/from_clause.rb +24 -0
- data/lib/bmg/sql/nodes/inner_join.rb +37 -0
- data/lib/bmg/sql/nodes/intersect.rb +14 -0
- data/lib/bmg/sql/nodes/limit_clause.rb +19 -0
- data/lib/bmg/sql/nodes/literal.rb +18 -0
- data/lib/bmg/sql/nodes/name_intro.rb +23 -0
- data/lib/bmg/sql/nodes/native_table_as.rb +31 -0
- data/lib/bmg/sql/nodes/offset_clause.rb +19 -0
- data/lib/bmg/sql/nodes/order_by_clause.rb +25 -0
- data/lib/bmg/sql/nodes/order_by_term.rb +30 -0
- data/lib/bmg/sql/nodes/qualified_name.rb +32 -0
- data/lib/bmg/sql/nodes/range_var_name.rb +17 -0
- data/lib/bmg/sql/nodes/select_exp.rb +109 -0
- data/lib/bmg/sql/nodes/select_item.rb +37 -0
- data/lib/bmg/sql/nodes/select_list.rb +35 -0
- data/lib/bmg/sql/nodes/select_star.rb +22 -0
- data/lib/bmg/sql/nodes/set_operator.rb +68 -0
- data/lib/bmg/sql/nodes/set_quantifier.rb +20 -0
- data/lib/bmg/sql/nodes/subquery_as.rb +28 -0
- data/lib/bmg/sql/nodes/table_as.rb +31 -0
- data/lib/bmg/sql/nodes/table_name.rb +17 -0
- data/lib/bmg/sql/nodes/union.rb +14 -0
- data/lib/bmg/sql/nodes/where_clause.rb +20 -0
- data/lib/bmg/sql/nodes/with_exp.rb +51 -0
- data/lib/bmg/sql/nodes/with_spec.rb +24 -0
- data/lib/bmg/sql/processor.rb +85 -0
- data/lib/bmg/sql/processor/all.rb +17 -0
- data/lib/bmg/sql/processor/clip.rb +57 -0
- data/lib/bmg/sql/processor/distinct.rb +17 -0
- data/lib/bmg/sql/processor/flatten.rb +24 -0
- data/lib/bmg/sql/processor/from_self.rb +29 -0
- data/lib/bmg/sql/processor/join.rb +80 -0
- data/lib/bmg/sql/processor/join_support.rb +28 -0
- data/lib/bmg/sql/processor/limit_offset.rb +30 -0
- data/lib/bmg/sql/processor/merge.rb +49 -0
- data/lib/bmg/sql/processor/order_by.rb +32 -0
- data/lib/bmg/sql/processor/rename.rb +25 -0
- data/lib/bmg/sql/processor/reorder.rb +21 -0
- data/lib/bmg/sql/processor/requalify.rb +24 -0
- data/lib/bmg/sql/processor/semi_join.rb +68 -0
- data/lib/bmg/sql/processor/star.rb +17 -0
- data/lib/bmg/sql/processor/where.rb +25 -0
- data/lib/bmg/sql/relation.rb +141 -0
- data/lib/bmg/sql/version.rb +16 -0
- data/lib/bmg/support.rb +1 -0
- data/lib/bmg/support/keys.rb +59 -0
- data/lib/bmg/type.rb +95 -14
- data/lib/bmg/version.rb +2 -2
- data/tasks/test.rake +9 -2
- metadata +97 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4b5e5a6fe330469b706c911dbc8d54e7feebd903
|
4
|
+
data.tar.gz: f14ca254437c5dd3c896c24cf0b31b75a338f280
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b6510a06199ceeca0a06d95ba6d58685483d9dd47c1780f156b2a5854c916c9e4458e2b0ba1862569d657a2dbe1b0e5957c1c5cb29fda6ee5e9de5c1fc4bca67
|
7
|
+
data.tar.gz: 980af325f9e60808fd8c84ad5b9a75f5b63acb416b665e1b66a5c0a95a017e7f35c01a6796ebe89477373ca7c055b34e22a1ab4e4fdaf938547b4afac73075df
|
data/lib/bmg/algebra.rb
CHANGED
@@ -1,23 +1,6 @@
|
|
1
1
|
module Bmg
|
2
2
|
module Algebra
|
3
3
|
|
4
|
-
METHODS = [
|
5
|
-
:allbut,
|
6
|
-
:autowrap,
|
7
|
-
:autosummarize,
|
8
|
-
:constants,
|
9
|
-
:extend,
|
10
|
-
:group,
|
11
|
-
:image,
|
12
|
-
:matching,
|
13
|
-
:page,
|
14
|
-
:project,
|
15
|
-
:rename,
|
16
|
-
:restrict,
|
17
|
-
:rxmatch,
|
18
|
-
:union
|
19
|
-
]
|
20
|
-
|
21
4
|
def allbut(butlist = [])
|
22
5
|
_allbut self.type.allbut(butlist), butlist
|
23
6
|
end
|
@@ -140,15 +123,6 @@ module Bmg
|
|
140
123
|
end
|
141
124
|
protected :_restrict
|
142
125
|
|
143
|
-
def rxmatch(attrs, matcher, options = {})
|
144
|
-
_rxmatch type.rxmatch(attrs, matcher, options), attrs, matcher, options
|
145
|
-
end
|
146
|
-
|
147
|
-
def _rxmatch(type, attrs, matcher, options)
|
148
|
-
Operator::Rxmatch.new(type, self, attrs, matcher, options)
|
149
|
-
end
|
150
|
-
protected :_rxmatch
|
151
|
-
|
152
126
|
def union(other, options = {})
|
153
127
|
_union self.type.union(other.type), other, options
|
154
128
|
end
|
@@ -167,5 +141,7 @@ module Bmg
|
|
167
141
|
self
|
168
142
|
end
|
169
143
|
|
144
|
+
require_relative 'algebra/shortcuts'
|
145
|
+
include Shortcuts
|
170
146
|
end # module Algebra
|
171
147
|
end # module Bmg
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Bmg
|
2
|
+
module Algebra
|
3
|
+
module Shortcuts
|
4
|
+
|
5
|
+
def rxmatch(attrs, matcher, options = {})
|
6
|
+
predicate = attrs.inject(Predicate.contradiction){|p,a|
|
7
|
+
p | Predicate.match(a, matcher, options)
|
8
|
+
}
|
9
|
+
self.restrict(predicate)
|
10
|
+
end
|
11
|
+
|
12
|
+
end # module Shortcuts
|
13
|
+
end # module Algebra
|
14
|
+
end # module Bmg
|
@@ -41,7 +41,7 @@ module Bmg
|
|
41
41
|
|
42
42
|
def each
|
43
43
|
@operand.each do |tuple|
|
44
|
-
yield
|
44
|
+
yield autowrap_tuple(tuple)
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
@@ -49,6 +49,19 @@ module Bmg
|
|
49
49
|
[ :autowrap, operand.to_ast, @original_options.dup ]
|
50
50
|
end
|
51
51
|
|
52
|
+
protected ### optimization
|
53
|
+
|
54
|
+
def _restrict(type, predicate)
|
55
|
+
return super unless operand.type.knows_attrlist?
|
56
|
+
roots = Support.wrapped_roots(operand.type.to_attrlist, options[:split])
|
57
|
+
vars = predicate.free_variables
|
58
|
+
if (roots & vars).empty?
|
59
|
+
operand.restrict(predicate).autowrap(options)
|
60
|
+
else
|
61
|
+
super
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
52
65
|
protected ### inspect
|
53
66
|
|
54
67
|
def args
|
@@ -57,7 +70,7 @@ module Bmg
|
|
57
70
|
|
58
71
|
private
|
59
72
|
|
60
|
-
def
|
73
|
+
def autowrap_tuple(tuple)
|
61
74
|
separator = @options[:split]
|
62
75
|
autowrapped = tuple.each_with_object({}){|(k,v),h|
|
63
76
|
parts = k.to_s.split(separator).map(&:to_sym)
|
@@ -97,6 +110,11 @@ module Bmg
|
|
97
110
|
none: ->(t,k){ t }
|
98
111
|
}
|
99
112
|
|
113
|
+
def self.new(remover)
|
114
|
+
return remover if remover.is_a?(NoLeftJoinNoise)
|
115
|
+
super
|
116
|
+
end
|
117
|
+
|
100
118
|
def initialize(remover)
|
101
119
|
@remover_to_s = remover
|
102
120
|
@remover = case remover
|
@@ -128,6 +146,18 @@ module Bmg
|
|
128
146
|
|
129
147
|
end # NoLeftJoinNoise
|
130
148
|
|
149
|
+
module Support
|
150
|
+
|
151
|
+
def wrapped_roots(attrlist, split_symbol)
|
152
|
+
attrlist.map{|a|
|
153
|
+
split = a.to_s.split(split_symbol)
|
154
|
+
split.size == 1 ? nil : split[0]
|
155
|
+
}.compact.uniq.map(&:to_sym)
|
156
|
+
end
|
157
|
+
module_function :wrapped_roots
|
158
|
+
|
159
|
+
end # module Support
|
160
|
+
|
131
161
|
end # class Autowrap
|
132
162
|
end # module Operator
|
133
163
|
end # module Bmg
|
@@ -56,6 +56,18 @@ module Bmg
|
|
56
56
|
|
57
57
|
protected ### optimization
|
58
58
|
|
59
|
+
def _page(type, ordering, page_index, options)
|
60
|
+
attrs = ordering.map{|(k,v)| k}
|
61
|
+
cs_attrs = constants.keys
|
62
|
+
if (attrs & cs_attrs).empty?
|
63
|
+
operand
|
64
|
+
.page(ordering, page_index, options)
|
65
|
+
.constants(constants)
|
66
|
+
else
|
67
|
+
super
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
59
71
|
def _restrict(type, predicate)
|
60
72
|
# bottom_p makes no reference to constants, top_p possibly
|
61
73
|
# does...
|
data/lib/bmg/operator/image.rb
CHANGED
@@ -55,6 +55,16 @@ module Bmg
|
|
55
55
|
|
56
56
|
protected ### optimization
|
57
57
|
|
58
|
+
def _page(type, ordering, page_index, opts)
|
59
|
+
if ordering.map{|(k,v)| k}.include?(as)
|
60
|
+
super
|
61
|
+
else
|
62
|
+
left
|
63
|
+
.page(ordering, page_index, opts)
|
64
|
+
.image(right, as, on, options)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
58
68
|
def _restrict(type, predicate)
|
59
69
|
on_as, rest = predicate.and_split([as])
|
60
70
|
if rest.tautology?
|
data/lib/bmg/operator/rename.rb
CHANGED
@@ -62,6 +62,14 @@ module Bmg
|
|
62
62
|
|
63
63
|
protected ### optimization
|
64
64
|
|
65
|
+
def _page(type, ordering, page_index, options)
|
66
|
+
rr = reverse_renaming
|
67
|
+
ordering = ordering.map{|(k,v)|
|
68
|
+
v.nil? ? rr[k] || k : [rr[k] || k, v]
|
69
|
+
}
|
70
|
+
operand.page(ordering, page_index, options).rename(renaming)
|
71
|
+
end
|
72
|
+
|
65
73
|
def _restrict(type, predicate)
|
66
74
|
operand.restrict(predicate.rename(reverse_renaming)).rename(renaming)
|
67
75
|
end
|
data/lib/bmg/relation/spied.rb
CHANGED
@@ -29,20 +29,15 @@ module Bmg
|
|
29
29
|
|
30
30
|
public ### algebra
|
31
31
|
|
32
|
-
Algebra
|
32
|
+
Algebra.public_instance_methods(false).each do |m|
|
33
|
+
next if [:spied, :unspied].include?(m)
|
34
|
+
|
33
35
|
define_method(m) do |*args, &bl|
|
36
|
+
args = args.map{|a| a.respond_to?(:unspied) ? a.unspied : a }
|
34
37
|
operand.send(m, *args, &bl).spied(spy)
|
35
38
|
end
|
36
39
|
end
|
37
40
|
|
38
|
-
def image(right, *args)
|
39
|
-
operand.image(right.unspied, *args).spied(spy)
|
40
|
-
end
|
41
|
-
|
42
|
-
def union(right, *args)
|
43
|
-
operand.union(right.unspied, *args).spied(spy)
|
44
|
-
end
|
45
|
-
|
46
41
|
def unspied
|
47
42
|
operand
|
48
43
|
end
|
data/lib/bmg/sequel.rb
CHANGED
@@ -1,11 +1,62 @@
|
|
1
|
+
require 'bmg/sql'
|
1
2
|
require 'sequel'
|
2
3
|
require 'predicate/sequel'
|
3
4
|
module Bmg
|
4
5
|
|
5
|
-
|
6
|
-
|
6
|
+
module Sequel
|
7
|
+
|
8
|
+
def sequel(*args, &bl)
|
9
|
+
source, sequel_db, type = sequel_params(*args, &bl)
|
10
|
+
builder = Sql::Builder.new
|
11
|
+
sexpr = builder.select_all(type.to_attrlist, source)
|
12
|
+
Sequel::Relation.new(type, builder, sexpr, sequel_db).spied(Bmg.main_spy)
|
13
|
+
end
|
14
|
+
module_function :sequel
|
15
|
+
|
16
|
+
def sequel_params(source, sequel_db = nil, type = nil)
|
17
|
+
sequel_db, type = nil, sequel_db if sequel_db.nil? or sequel_db.is_a?(Type)
|
18
|
+
sequel_db = source.db if sequel_db.nil? and source.is_a?(::Sequel::Dataset)
|
19
|
+
raise ArgumentError, "A Sequel::Database object is required" if sequel_db.nil?
|
20
|
+
raise ArgumentError, "Type's attrlist must be known (#{type})" if type && !type.knows_attrlist?
|
21
|
+
type = infer_type!(sequel_db, source) if type.nil?
|
22
|
+
[source, sequel_db, type]
|
23
|
+
end
|
24
|
+
module_function :sequel_params
|
25
|
+
|
26
|
+
def infer_type!(sequel_db, source)
|
27
|
+
raise "Sequel::Relation requires a type for `#{source}`" unless source.is_a?(Symbol)
|
28
|
+
TypeInference.new(sequel_db).call(source)
|
29
|
+
end
|
30
|
+
module_function :infer_type!
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
# Builds a Relation that uses Sequel for managing real data
|
35
|
+
# accesses.
|
36
|
+
#
|
37
|
+
# Supported signatures:
|
38
|
+
#
|
39
|
+
# # Table name, providing the Sequel's Database object
|
40
|
+
# Bmg.sequel(:suppliers, DB)
|
41
|
+
#
|
42
|
+
# # Sequel dataset object, embedding the Database object
|
43
|
+
# # `from_self` will be used at compilation time, you don't
|
44
|
+
# # need to call it yourself.
|
45
|
+
# Bmg.sequel(DB[:suppliers])
|
46
|
+
#
|
47
|
+
# # Similar, but with with a pure SQL query
|
48
|
+
# Bmg.sequel(DB[%Q{SELECT ... FROM ...}])
|
49
|
+
#
|
50
|
+
# # All signatures above with an explicit type object, e.g.:
|
51
|
+
# Bmg.sequel(:suppliers, DB, Type::ANY)
|
52
|
+
# Bmg.sequel(DB[:suppliers], Type::ANY)
|
53
|
+
#
|
54
|
+
def sequel(source, sequel_db = nil, type = nil)
|
55
|
+
Sequel.sequel(source, sequel_db, type)
|
7
56
|
end
|
8
57
|
module_function :sequel
|
9
58
|
|
10
59
|
end
|
60
|
+
require_relative 'sequel/translator'
|
61
|
+
require_relative 'sequel/type_inference'
|
11
62
|
require_relative 'sequel/relation'
|
data/lib/bmg/sequel/relation.rb
CHANGED
@@ -1,22 +1,15 @@
|
|
1
1
|
module Bmg
|
2
2
|
module Sequel
|
3
|
-
class Relation
|
4
|
-
include Bmg::Relation
|
3
|
+
class Relation < Sql::Relation
|
5
4
|
|
6
|
-
def initialize(type,
|
7
|
-
|
8
|
-
@
|
5
|
+
def initialize(type, builder, source, sequel_db)
|
6
|
+
super(type, builder, source)
|
7
|
+
@sequel_db = sequel_db
|
9
8
|
end
|
10
|
-
attr_reader :
|
11
|
-
|
12
|
-
protected
|
13
|
-
|
14
|
-
attr_reader :dataset
|
15
|
-
|
16
|
-
public
|
9
|
+
attr_reader :sequel_db
|
17
10
|
|
18
11
|
def each(&bl)
|
19
|
-
|
12
|
+
dataset.each(&bl)
|
20
13
|
end
|
21
14
|
|
22
15
|
def delete
|
@@ -44,19 +37,31 @@ module Bmg
|
|
44
37
|
[:sequel, dataset.sql]
|
45
38
|
end
|
46
39
|
|
40
|
+
def to_sql
|
41
|
+
dataset.sql
|
42
|
+
end
|
43
|
+
|
47
44
|
def to_s
|
48
45
|
"(sequel #{dataset.sql})"
|
49
46
|
end
|
50
47
|
alias :inspect :to_s
|
51
48
|
|
52
|
-
protected
|
49
|
+
protected
|
50
|
+
|
51
|
+
def dataset
|
52
|
+
@dataset ||= Translator.new(sequel_db).call(self.expr)
|
53
|
+
end
|
54
|
+
|
55
|
+
def _instance(type, builder, expr)
|
56
|
+
Relation.new(type, builder, expr, sequel_db)
|
57
|
+
end
|
53
58
|
|
54
|
-
def
|
55
|
-
|
56
|
-
|
57
|
-
|
59
|
+
def extract_compatible_sexpr(operand)
|
60
|
+
return nil unless operand.is_a?(Bmg::Sequel::Relation)
|
61
|
+
return nil unless self.sequel_db == operand.sequel_db
|
62
|
+
operand.expr
|
58
63
|
end
|
59
64
|
|
60
65
|
end # class Relation
|
61
|
-
end # module
|
66
|
+
end # module Sequel
|
62
67
|
end # module Bmg
|
@@ -0,0 +1,153 @@
|
|
1
|
+
module Bmg
|
2
|
+
module Sequel
|
3
|
+
class Translator < Sexpr::Processor
|
4
|
+
include ::Predicate::ToSequel::Methods
|
5
|
+
|
6
|
+
def initialize(sequel_db)
|
7
|
+
@sequel_db = sequel_db
|
8
|
+
end
|
9
|
+
attr_reader :sequel_db
|
10
|
+
|
11
|
+
def on_with_exp(sexpr)
|
12
|
+
if sequel_db.select(1).supports_cte?
|
13
|
+
dataset = apply(sexpr.select_exp)
|
14
|
+
apply(sexpr.with_spec).each_pair do |name,subquery|
|
15
|
+
dataset = dataset.with(name, subquery)
|
16
|
+
end
|
17
|
+
dataset
|
18
|
+
else
|
19
|
+
apply(Sql::Processor::Flatten.new(Sql::Builder.new).call(sexpr))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def on_with_spec(sexpr)
|
24
|
+
sexpr.each_with_object({}){|child,hash|
|
25
|
+
next if child == :with_spec
|
26
|
+
hash[apply(child.table_name)] = apply(child.subquery)
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def on_set_operator(sexpr)
|
31
|
+
left, right = apply(sexpr.left), apply(sexpr.right)
|
32
|
+
left = left.from_self if sexpr.left.set_operator?
|
33
|
+
left.send(sexpr.first, right, all: sexpr.all?, from_self: false)
|
34
|
+
end
|
35
|
+
alias :on_union :on_set_operator
|
36
|
+
alias :on_intersect :on_set_operator
|
37
|
+
alias :on_except :on_set_operator
|
38
|
+
|
39
|
+
def on_select_exp(sexpr)
|
40
|
+
dataset = sequel_db.select(1)
|
41
|
+
dataset = dataset(apply(sexpr.from_clause)) if sexpr.from_clause
|
42
|
+
#
|
43
|
+
selection = apply(sexpr.select_list)
|
44
|
+
predicate = apply(sexpr.predicate) if sexpr.predicate
|
45
|
+
order = apply(sexpr.order_by_clause) if sexpr.order_by_clause
|
46
|
+
limit = apply(sexpr.limit_clause) if sexpr.limit_clause
|
47
|
+
offset = apply(sexpr.offset_clause) if sexpr.offset_clause
|
48
|
+
#
|
49
|
+
dataset = dataset.select(*selection)
|
50
|
+
dataset = dataset.distinct if sexpr.distinct?
|
51
|
+
dataset = dataset.where(predicate) if predicate
|
52
|
+
dataset = dataset.order_by(*order) if order
|
53
|
+
dataset = dataset.limit(limit, offset == 0 ? nil : offset) if limit or offset
|
54
|
+
dataset
|
55
|
+
end
|
56
|
+
|
57
|
+
def on_select_list(sexpr)
|
58
|
+
sexpr.sexpr_body.map{|c| apply(c) }
|
59
|
+
end
|
60
|
+
|
61
|
+
def on_select_star(sexpr)
|
62
|
+
::Sequel.lit('*')
|
63
|
+
end
|
64
|
+
|
65
|
+
def on_select_item(sexpr)
|
66
|
+
left = apply(sexpr.left)
|
67
|
+
right = apply(sexpr.right)
|
68
|
+
if left.column == right.value
|
69
|
+
left
|
70
|
+
else
|
71
|
+
::Sequel.as(left, right)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def on_qualified_name(sexpr)
|
76
|
+
apply(sexpr.last).qualify(sexpr.qualifier)
|
77
|
+
end
|
78
|
+
|
79
|
+
def on_column_name(sexpr)
|
80
|
+
::Sequel.expr(sexpr.last.to_sym)
|
81
|
+
end
|
82
|
+
|
83
|
+
def on_from_clause(sexpr)
|
84
|
+
apply(sexpr.table_spec)
|
85
|
+
end
|
86
|
+
|
87
|
+
def on_table_name(sexpr)
|
88
|
+
::Sequel.identifier(sexpr.last)
|
89
|
+
end
|
90
|
+
|
91
|
+
def on_cross_join(sexpr)
|
92
|
+
left, right = apply(sexpr.left), apply(sexpr.right)
|
93
|
+
dataset(left).cross_join(right)
|
94
|
+
end
|
95
|
+
|
96
|
+
def on_inner_join(sexpr)
|
97
|
+
left, right = apply(sexpr.left), apply(sexpr.right)
|
98
|
+
options = {qualify: false, table_alias: false}
|
99
|
+
dataset(left).join_table(:inner, right, nil, options){|*args|
|
100
|
+
apply(sexpr.predicate)
|
101
|
+
}
|
102
|
+
end
|
103
|
+
|
104
|
+
def on_table_as(sexpr)
|
105
|
+
::Sequel.as(::Sequel.identifier(sexpr.table_name), ::Sequel.identifier(sexpr.as_name))
|
106
|
+
end
|
107
|
+
|
108
|
+
def on_subquery_as(sexpr)
|
109
|
+
::Sequel.as(apply(sexpr.subquery), ::Sequel.identifier(sexpr.as_name))
|
110
|
+
end
|
111
|
+
|
112
|
+
def on_native_table_as(sexpr)
|
113
|
+
sexpr[1].from_self(:alias => sexpr.as_name)
|
114
|
+
end
|
115
|
+
|
116
|
+
def on_order_by_clause(sexpr)
|
117
|
+
sexpr.sexpr_body.map{|c| apply(c)}
|
118
|
+
end
|
119
|
+
|
120
|
+
def on_order_by_term(sexpr)
|
121
|
+
::Sequel.send(sexpr.direction, apply(sexpr.qualified_name))
|
122
|
+
end
|
123
|
+
|
124
|
+
def on_limit_clause(sexpr)
|
125
|
+
sexpr.last
|
126
|
+
end
|
127
|
+
|
128
|
+
def on_offset_clause(sexpr)
|
129
|
+
sexpr.last
|
130
|
+
end
|
131
|
+
|
132
|
+
public ### Predicate hack
|
133
|
+
|
134
|
+
def on_in(sexpr)
|
135
|
+
left, right = apply(sexpr.identifier), sexpr.last
|
136
|
+
right = apply(right) if sexpr.subquery?
|
137
|
+
::Sequel.expr(left => right)
|
138
|
+
end
|
139
|
+
|
140
|
+
def on_exists(sexpr)
|
141
|
+
apply(sexpr.last).exists
|
142
|
+
end
|
143
|
+
|
144
|
+
private
|
145
|
+
|
146
|
+
def dataset(expr)
|
147
|
+
return expr if ::Sequel::Dataset===expr
|
148
|
+
sequel_db[expr]
|
149
|
+
end
|
150
|
+
|
151
|
+
end # class Translator
|
152
|
+
end # module Sequel
|
153
|
+
end # module Bmg
|