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
@@ -0,0 +1,19 @@
|
|
1
|
+
module Bmg
|
2
|
+
module Sql
|
3
|
+
module LimitClause
|
4
|
+
include Expr
|
5
|
+
|
6
|
+
LIMIT = "LIMIT"
|
7
|
+
|
8
|
+
def limit
|
9
|
+
last.to_i
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_sql(buffer, dialect)
|
13
|
+
buffer << LIMIT << SPACE << limit.to_s
|
14
|
+
buffer
|
15
|
+
end
|
16
|
+
|
17
|
+
end # module LimitClause
|
18
|
+
end # module Sql
|
19
|
+
end # module Bmg
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Bmg
|
2
|
+
module Sql
|
3
|
+
module Literal
|
4
|
+
include Expr
|
5
|
+
include Predicate::Expr
|
6
|
+
|
7
|
+
def would_be_name
|
8
|
+
nil
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_sql(buffer, dialect)
|
12
|
+
to_sql_literal(buffer, last)
|
13
|
+
buffer
|
14
|
+
end
|
15
|
+
|
16
|
+
end # module Literal
|
17
|
+
end # module Sql
|
18
|
+
end # module Bmg
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Bmg
|
2
|
+
module Sql
|
3
|
+
module NameIntro
|
4
|
+
include Expr
|
5
|
+
|
6
|
+
def table_name
|
7
|
+
self[1]
|
8
|
+
end
|
9
|
+
|
10
|
+
def subquery
|
11
|
+
self[2]
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_sql(buffer, dialect)
|
15
|
+
table_name.to_sql(buffer, dialect)
|
16
|
+
buffer << SPACE << AS << SPACE
|
17
|
+
subquery.to_sql(buffer, dialect, true)
|
18
|
+
buffer
|
19
|
+
end
|
20
|
+
|
21
|
+
end # module WithSpec
|
22
|
+
end # module Sql
|
23
|
+
end # module Bmg
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Bmg
|
2
|
+
module Sql
|
3
|
+
module NativeTableAs
|
4
|
+
include Expr
|
5
|
+
|
6
|
+
def left
|
7
|
+
self[1]
|
8
|
+
end
|
9
|
+
|
10
|
+
def right
|
11
|
+
self[2]
|
12
|
+
end
|
13
|
+
|
14
|
+
def native_table
|
15
|
+
self[1].last
|
16
|
+
end
|
17
|
+
|
18
|
+
def as_name
|
19
|
+
self[2].last
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_sql(buffer, dialect)
|
23
|
+
buffer << self[1].to_s
|
24
|
+
buffer << SPACE << AS << SPACE
|
25
|
+
self[2].to_sql(buffer, dialect)
|
26
|
+
buffer
|
27
|
+
end
|
28
|
+
|
29
|
+
end # module NativeTableAs
|
30
|
+
end # module Sql
|
31
|
+
end # module Bmg
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Bmg
|
2
|
+
module Sql
|
3
|
+
module OffsetClause
|
4
|
+
include Expr
|
5
|
+
|
6
|
+
OFFSET = "OFFSET"
|
7
|
+
|
8
|
+
def offset
|
9
|
+
last.to_i
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_sql(buffer, dialect)
|
13
|
+
buffer << OFFSET << SPACE << offset.to_s
|
14
|
+
buffer
|
15
|
+
end
|
16
|
+
|
17
|
+
end # module OffsetClause
|
18
|
+
end # module Sql
|
19
|
+
end # module Bmg
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Bmg
|
2
|
+
module Sql
|
3
|
+
module OrderByClause
|
4
|
+
include Expr
|
5
|
+
|
6
|
+
ORDER_BY = "ORDER BY".freeze
|
7
|
+
|
8
|
+
def to_ordering
|
9
|
+
@ordering ||= sexpr_body.map{|x|
|
10
|
+
[x.as_name.to_sym, x.direction.to_sym]
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_sql(buffer, dialect)
|
15
|
+
buffer << ORDER_BY << SPACE
|
16
|
+
each_child do |item,index|
|
17
|
+
buffer << COMMA << SPACE unless index == 0
|
18
|
+
item.to_sql(buffer, dialect)
|
19
|
+
end
|
20
|
+
buffer
|
21
|
+
end
|
22
|
+
|
23
|
+
end # module OrderByClause
|
24
|
+
end # module Sql
|
25
|
+
end # module Bmg
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Bmg
|
2
|
+
module Sql
|
3
|
+
module OrderByTerm
|
4
|
+
include Expr
|
5
|
+
|
6
|
+
def qualified_name
|
7
|
+
self[1]
|
8
|
+
end
|
9
|
+
|
10
|
+
def qualifier
|
11
|
+
qualified_name.qualifier
|
12
|
+
end
|
13
|
+
|
14
|
+
def as_name
|
15
|
+
qualified_name.as_name
|
16
|
+
end
|
17
|
+
|
18
|
+
def direction
|
19
|
+
last
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_sql(buffer, dialect)
|
23
|
+
self[1].to_sql(buffer, dialect)
|
24
|
+
buffer << SPACE << direction.upcase
|
25
|
+
buffer
|
26
|
+
end
|
27
|
+
|
28
|
+
end # module OrderByTerm
|
29
|
+
end # module Sql
|
30
|
+
end # module Bmg
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Bmg
|
2
|
+
module Sql
|
3
|
+
#
|
4
|
+
# [:qualified_name,
|
5
|
+
# [:range_var_name `qualifier`],
|
6
|
+
# [:column_name, `as_name`] ]
|
7
|
+
#
|
8
|
+
module QualifiedName
|
9
|
+
include Expr
|
10
|
+
|
11
|
+
def qualifier
|
12
|
+
self[1].qualifier
|
13
|
+
end
|
14
|
+
|
15
|
+
def as_name
|
16
|
+
last.as_name
|
17
|
+
end
|
18
|
+
|
19
|
+
def would_be_name
|
20
|
+
as_name
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_sql(buffer, dialect)
|
24
|
+
self[1].to_sql(buffer, dialect)
|
25
|
+
buffer << '.'
|
26
|
+
self[2].to_sql(buffer, dialect)
|
27
|
+
buffer
|
28
|
+
end
|
29
|
+
|
30
|
+
end # module QualifiedName
|
31
|
+
end # module Sql
|
32
|
+
end # module Bmg
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Bmg
|
2
|
+
module Sql
|
3
|
+
module RangeVarName
|
4
|
+
include Expr
|
5
|
+
|
6
|
+
def qualifier
|
7
|
+
last
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_sql(buffer, dialect)
|
11
|
+
buffer << dialect.quote_identifier(last)
|
12
|
+
buffer
|
13
|
+
end
|
14
|
+
|
15
|
+
end # module RangeVarName
|
16
|
+
end # module Sql
|
17
|
+
end # module Bmg
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module Bmg
|
2
|
+
module Sql
|
3
|
+
module SelectExp
|
4
|
+
include Expr
|
5
|
+
|
6
|
+
SELECT_DISTINCT = "SELECT DISTINCT".freeze
|
7
|
+
|
8
|
+
SELECT = "SELECT".freeze
|
9
|
+
|
10
|
+
def set_quantifier
|
11
|
+
self[1]
|
12
|
+
end
|
13
|
+
|
14
|
+
def with_exp?
|
15
|
+
false
|
16
|
+
end
|
17
|
+
|
18
|
+
def is_table_dee?
|
19
|
+
from_clause.nil? && select_list.is_table_dee?
|
20
|
+
end
|
21
|
+
|
22
|
+
def distinct?
|
23
|
+
set_quantifier.distinct?
|
24
|
+
end
|
25
|
+
|
26
|
+
def all?
|
27
|
+
set_quantifier.all?
|
28
|
+
end
|
29
|
+
|
30
|
+
def join?
|
31
|
+
from_clause && from_clause.join?
|
32
|
+
end
|
33
|
+
|
34
|
+
def should_be_reused?
|
35
|
+
join? or distinct? or complex_clause?
|
36
|
+
end
|
37
|
+
|
38
|
+
def complex_clause?
|
39
|
+
where_clause or order_by_clause or limit_clause or offset_clause
|
40
|
+
end
|
41
|
+
|
42
|
+
def select_exp
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
def select_list
|
47
|
+
self[2]
|
48
|
+
end
|
49
|
+
|
50
|
+
def is_select_star?
|
51
|
+
self[2].first == :select_star
|
52
|
+
end
|
53
|
+
|
54
|
+
def where_clause
|
55
|
+
find_child(:where_clause)
|
56
|
+
end
|
57
|
+
|
58
|
+
def predicate
|
59
|
+
where_clause && where_clause.predicate
|
60
|
+
end
|
61
|
+
|
62
|
+
def from_clause
|
63
|
+
find_child(:from_clause)
|
64
|
+
end
|
65
|
+
|
66
|
+
def table_spec
|
67
|
+
from_clause.table_spec
|
68
|
+
end
|
69
|
+
|
70
|
+
def order_by_clause
|
71
|
+
find_child(:order_by_clause)
|
72
|
+
end
|
73
|
+
|
74
|
+
def limit_clause
|
75
|
+
find_child(:limit_clause)
|
76
|
+
end
|
77
|
+
|
78
|
+
def offset_clause
|
79
|
+
find_child(:offset_clause)
|
80
|
+
end
|
81
|
+
|
82
|
+
def desaliaser
|
83
|
+
select_list.desaliaser
|
84
|
+
end
|
85
|
+
|
86
|
+
### to_xxx
|
87
|
+
|
88
|
+
def to_attr_list
|
89
|
+
select_list.to_attr_list
|
90
|
+
end
|
91
|
+
|
92
|
+
### to_sql
|
93
|
+
|
94
|
+
def to_sql(buffer, dialect, parenthesize = !buffer.empty?)
|
95
|
+
if parenthesize
|
96
|
+
sql_parenthesized(buffer){|b| to_sql(b, dialect, false) }
|
97
|
+
else
|
98
|
+
buffer << (distinct? ? SELECT_DISTINCT : SELECT)
|
99
|
+
each_child(1) do |elm,i|
|
100
|
+
buffer << SPACE
|
101
|
+
elm.to_sql(buffer, dialect)
|
102
|
+
end
|
103
|
+
buffer
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
end # module SelectExp
|
108
|
+
end # module Sql
|
109
|
+
end # module Bmg
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Bmg
|
2
|
+
module Sql
|
3
|
+
module SelectItem
|
4
|
+
include Expr
|
5
|
+
|
6
|
+
def left
|
7
|
+
self[1]
|
8
|
+
end
|
9
|
+
|
10
|
+
def right
|
11
|
+
self[2]
|
12
|
+
end
|
13
|
+
|
14
|
+
def qualifier
|
15
|
+
left.qualifier
|
16
|
+
end
|
17
|
+
|
18
|
+
def would_be_name
|
19
|
+
left.would_be_name
|
20
|
+
end
|
21
|
+
|
22
|
+
def as_name
|
23
|
+
last.as_name
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_sql(buffer, dialect)
|
27
|
+
self[1].to_sql(buffer, dialect)
|
28
|
+
unless would_be_name == as_name
|
29
|
+
buffer << SPACE << AS << SPACE
|
30
|
+
last.to_sql(buffer, dialect)
|
31
|
+
end
|
32
|
+
buffer
|
33
|
+
end
|
34
|
+
|
35
|
+
end # module SelectItem
|
36
|
+
end # module Sql
|
37
|
+
end # module Bmg
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Bmg
|
2
|
+
module Sql
|
3
|
+
module SelectList
|
4
|
+
include Expr
|
5
|
+
|
6
|
+
def desaliaser
|
7
|
+
->(a){
|
8
|
+
item = sexpr_body.find{|item| item.as_name.to_s == a.to_s }
|
9
|
+
item && item.left
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
def is_table_dee?
|
14
|
+
Builder::IS_TABLE_DEE == self
|
15
|
+
end
|
16
|
+
|
17
|
+
def knows?(as_name)
|
18
|
+
find_child{|child| child.as_name == as_name }
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_attr_list
|
22
|
+
sexpr_body.map{|a| a.as_name.to_sym }
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_sql(buffer, dialect)
|
26
|
+
sexpr_body.each_with_index do |item,index|
|
27
|
+
buffer << COMMA << SPACE unless index == 0
|
28
|
+
item.to_sql(buffer, dialect)
|
29
|
+
end
|
30
|
+
buffer
|
31
|
+
end
|
32
|
+
|
33
|
+
end # module SelectList
|
34
|
+
end # module Sql
|
35
|
+
end # module Bmg
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Bmg
|
2
|
+
module Sql
|
3
|
+
module SelectStar
|
4
|
+
include Expr
|
5
|
+
|
6
|
+
STAR = "*".freeze
|
7
|
+
|
8
|
+
def desaliaser
|
9
|
+
->(a){
|
10
|
+
Predicate::Grammar.sexpr [ :qualified_identifier, last[1], a.to_s ]
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_sql(buffer, dialect)
|
15
|
+
last.to_sql(buffer, dialect)
|
16
|
+
buffer << DOT << STAR
|
17
|
+
buffer
|
18
|
+
end
|
19
|
+
|
20
|
+
end # module SelectStar
|
21
|
+
end # module Sql
|
22
|
+
end # module Bmg
|