bmg 0.9.1 → 0.10.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 +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
|