alf-sql 0.15.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.
- data/CHANGELOG.md +5 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +38 -0
- data/LICENCE.md +22 -0
- data/Manifest.txt +12 -0
- data/README.md +52 -0
- data/Rakefile +11 -0
- data/lib/alf-sql.rb +1 -0
- data/lib/alf/algebra/operand.rb +18 -0
- data/lib/alf/predicate/nodes.rb +20 -0
- data/lib/alf/predicate/nodes/and.rb +11 -0
- data/lib/alf/predicate/nodes/contradiction.rb +12 -0
- data/lib/alf/predicate/nodes/dyadic_comp.rb +14 -0
- data/lib/alf/predicate/nodes/eq.rb +11 -0
- data/lib/alf/predicate/nodes/exists.rb +14 -0
- data/lib/alf/predicate/nodes/expr.rb +20 -0
- data/lib/alf/predicate/nodes/gt.rb +11 -0
- data/lib/alf/predicate/nodes/gte.rb +11 -0
- data/lib/alf/predicate/nodes/identifier.rb +12 -0
- data/lib/alf/predicate/nodes/in.rb +31 -0
- data/lib/alf/predicate/nodes/literal.rb +12 -0
- data/lib/alf/predicate/nodes/lt.rb +11 -0
- data/lib/alf/predicate/nodes/lte.rb +11 -0
- data/lib/alf/predicate/nodes/nadic_bool.rb +18 -0
- data/lib/alf/predicate/nodes/native.rb +11 -0
- data/lib/alf/predicate/nodes/neq.rb +11 -0
- data/lib/alf/predicate/nodes/not.rb +14 -0
- data/lib/alf/predicate/nodes/or.rb +11 -0
- data/lib/alf/predicate/nodes/qualified_identifier.rb +12 -0
- data/lib/alf/predicate/nodes/tautology.rb +12 -0
- data/lib/alf/sql.rb +15 -0
- data/lib/alf/sql/builder.rb +152 -0
- data/lib/alf/sql/cog.rb +32 -0
- data/lib/alf/sql/compiler.rb +137 -0
- data/lib/alf/sql/grammar.rb +44 -0
- data/lib/alf/sql/grammar.sexp.yml +92 -0
- data/lib/alf/sql/loader.rb +2 -0
- data/lib/alf/sql/nodes/column_name.rb +25 -0
- data/lib/alf/sql/nodes/cross_join.rb +28 -0
- data/lib/alf/sql/nodes/except.rb +14 -0
- data/lib/alf/sql/nodes/expr.rb +90 -0
- data/lib/alf/sql/nodes/from_clause.rb +24 -0
- data/lib/alf/sql/nodes/inner_join.rb +37 -0
- data/lib/alf/sql/nodes/intersect.rb +14 -0
- data/lib/alf/sql/nodes/limit_clause.rb +19 -0
- data/lib/alf/sql/nodes/literal.rb +18 -0
- data/lib/alf/sql/nodes/name_intro.rb +23 -0
- data/lib/alf/sql/nodes/offset_clause.rb +19 -0
- data/lib/alf/sql/nodes/order_by_clause.rb +25 -0
- data/lib/alf/sql/nodes/order_by_term.rb +30 -0
- data/lib/alf/sql/nodes/qualified_name.rb +32 -0
- data/lib/alf/sql/nodes/range_var_name.rb +17 -0
- data/lib/alf/sql/nodes/select_exp.rb +101 -0
- data/lib/alf/sql/nodes/select_item.rb +37 -0
- data/lib/alf/sql/nodes/select_list.rb +31 -0
- data/lib/alf/sql/nodes/select_star.rb +15 -0
- data/lib/alf/sql/nodes/set_operator.rb +64 -0
- data/lib/alf/sql/nodes/set_quantifier.rb +20 -0
- data/lib/alf/sql/nodes/subquery_as.rb +28 -0
- data/lib/alf/sql/nodes/table_as.rb +31 -0
- data/lib/alf/sql/nodes/table_name.rb +17 -0
- data/lib/alf/sql/nodes/union.rb +14 -0
- data/lib/alf/sql/nodes/where_clause.rb +20 -0
- data/lib/alf/sql/nodes/with_exp.rb +50 -0
- data/lib/alf/sql/nodes/with_spec.rb +24 -0
- data/lib/alf/sql/processor.rb +85 -0
- data/lib/alf/sql/processor/all.rb +17 -0
- data/lib/alf/sql/processor/clip.rb +39 -0
- data/lib/alf/sql/processor/distinct.rb +17 -0
- data/lib/alf/sql/processor/flatten.rb +24 -0
- data/lib/alf/sql/processor/from_self.rb +29 -0
- data/lib/alf/sql/processor/join.rb +80 -0
- data/lib/alf/sql/processor/join_support.rb +27 -0
- data/lib/alf/sql/processor/limit_offset.rb +30 -0
- data/lib/alf/sql/processor/merge.rb +42 -0
- data/lib/alf/sql/processor/order_by.rb +32 -0
- data/lib/alf/sql/processor/rename.rb +25 -0
- data/lib/alf/sql/processor/reorder.rb +21 -0
- data/lib/alf/sql/processor/requalify.rb +24 -0
- data/lib/alf/sql/processor/semi_join.rb +57 -0
- data/lib/alf/sql/processor/star.rb +17 -0
- data/lib/alf/sql/processor/where.rb +25 -0
- data/lib/alf/sql/version.rb +16 -0
- data/spec/algebra/operand/test_to_sql.rb +32 -0
- data/spec/builder/test_order_by_clause.rb +44 -0
- data/spec/helpers/ast.rb +242 -0
- data/spec/helpers/compiler.rb +23 -0
- data/spec/nodes/column_name/test_as_name.rb +14 -0
- data/spec/nodes/column_name/test_qualifier.rb +14 -0
- data/spec/nodes/order_by_clause/test_to_ordering.rb +30 -0
- data/spec/nodes/order_by_term/test_as_name.rb +22 -0
- data/spec/nodes/order_by_term/test_direction.rb +22 -0
- data/spec/nodes/order_by_term/test_qualifier.rb +22 -0
- data/spec/nodes/select_exp/test_order_by_clause.rb +22 -0
- data/spec/nodes/select_item/test_as_name.rb +22 -0
- data/spec/predicate/nodes/exists/test_not.rb +20 -0
- data/spec/processor/clip/test_on_select_exp.rb +32 -0
- data/spec/processor/clip/test_on_select_list.rb +24 -0
- data/spec/processor/distinct/test_on_set_quantified.rb +31 -0
- data/spec/processor/from_self/test_on_nonjoin_exp.rb +60 -0
- data/spec/processor/from_self/test_on_with_exp.rb +22 -0
- data/spec/processor/merge/test_on_select_exp.rb +73 -0
- data/spec/processor/merge/test_on_with_exp.rb +56 -0
- data/spec/processor/order_by/test_on_select_exp.rb +24 -0
- data/spec/processor/rename/test_on_select_item.rb +30 -0
- data/spec/processor/rename/test_on_select_list.rb +22 -0
- data/spec/processor/reorder/test_on_select_list.rb +22 -0
- data/spec/processor/requalify/test_on_select_exp.rb +24 -0
- data/spec/processor/star/test_on_select_exp.rb +24 -0
- data/spec/processor/test_clip.rb +24 -0
- data/spec/processor/test_distinct.rb +24 -0
- data/spec/processor/test_on_select_exp.rb +28 -0
- data/spec/processor/test_on_set_operator.rb +28 -0
- data/spec/processor/test_rename.rb +24 -0
- data/spec/shared/compiled_examples.rb +13 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/test_sql.rb +10 -0
- data/tasks/bench.rake +40 -0
- data/tasks/gem.rake +8 -0
- data/tasks/test.rake +6 -0
- metadata +235 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module Alf
|
|
2
|
+
module Sql
|
|
3
|
+
class Processor
|
|
4
|
+
class Merge < Processor
|
|
5
|
+
|
|
6
|
+
def initialize(kind, right, builder)
|
|
7
|
+
super(builder)
|
|
8
|
+
@kind = kind
|
|
9
|
+
@right = right
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def on_with_exp(sexpr)
|
|
13
|
+
if @right.with_exp?
|
|
14
|
+
reordered = Reorder.new(sexpr.to_attr_list, builder).call(@right)
|
|
15
|
+
main = [ @kind, builder.distinct, sexpr.select_exp, reordered.select_exp ]
|
|
16
|
+
merge_with_exps(sexpr, reordered, main)
|
|
17
|
+
else
|
|
18
|
+
[ :with_exp,
|
|
19
|
+
sexpr.with_spec,
|
|
20
|
+
apply(sexpr.last) ]
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def on_nonjoin_exp(sexpr)
|
|
25
|
+
reordered = Reorder.new(sexpr.to_attr_list, builder).call(@right)
|
|
26
|
+
if @right.with_exp?
|
|
27
|
+
[ :with_exp,
|
|
28
|
+
reordered.with_spec,
|
|
29
|
+
[ @kind, builder.distinct, sexpr, reordered.select_exp ] ]
|
|
30
|
+
else
|
|
31
|
+
[ @kind, builder.distinct, sexpr, reordered ]
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
alias :on_union :on_nonjoin_exp
|
|
35
|
+
alias :on_except :on_nonjoin_exp
|
|
36
|
+
alias :on_intersect :on_nonjoin_exp
|
|
37
|
+
alias :on_select_exp :on_nonjoin_exp
|
|
38
|
+
|
|
39
|
+
end # class Merge
|
|
40
|
+
end # class Processor
|
|
41
|
+
end # module Sql
|
|
42
|
+
end # module Alf
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Alf
|
|
2
|
+
module Sql
|
|
3
|
+
class Processor
|
|
4
|
+
class OrderBy < Processor
|
|
5
|
+
|
|
6
|
+
def initialize(ordering, builder)
|
|
7
|
+
super(builder)
|
|
8
|
+
@ordering = ordering
|
|
9
|
+
end
|
|
10
|
+
attr_reader :ordering
|
|
11
|
+
|
|
12
|
+
def on_set_operator(sexpr)
|
|
13
|
+
call(builder.from_self(sexpr))
|
|
14
|
+
end
|
|
15
|
+
alias :on_union :on_set_operator
|
|
16
|
+
alias :on_except :on_set_operator
|
|
17
|
+
alias :on_intersect :on_set_operator
|
|
18
|
+
|
|
19
|
+
def on_select_exp(sexpr)
|
|
20
|
+
if obc = sexpr.order_by_clause
|
|
21
|
+
sexpr = builder.from_self(sexpr)
|
|
22
|
+
call(sexpr)
|
|
23
|
+
else
|
|
24
|
+
needed = builder.order_by_clause(ordering, &sexpr.desaliaser)
|
|
25
|
+
sexpr.dup.push(needed)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end # class OrderBy
|
|
30
|
+
end # class Processor
|
|
31
|
+
end # module Sql
|
|
32
|
+
end # module Alf
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Alf
|
|
2
|
+
module Sql
|
|
3
|
+
class Processor
|
|
4
|
+
class Rename < Processor
|
|
5
|
+
|
|
6
|
+
def initialize(renaming, builder)
|
|
7
|
+
super(builder)
|
|
8
|
+
@renaming = renaming
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def on_select_list(sexpr)
|
|
12
|
+
sexpr.each_with_index.map{|child,index|
|
|
13
|
+
index == 0 ? child : apply(child)
|
|
14
|
+
}
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def on_select_item(sexpr)
|
|
18
|
+
return sexpr unless newname = @renaming[sexpr.as_name.to_sym]
|
|
19
|
+
builder.select_item(sexpr.qualifier, sexpr.would_be_name, newname.to_s)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end # class Rename
|
|
23
|
+
end # class Processor
|
|
24
|
+
end # module Sql
|
|
25
|
+
end # module Alf
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Alf
|
|
2
|
+
module Sql
|
|
3
|
+
class Processor
|
|
4
|
+
class Reorder < Processor
|
|
5
|
+
|
|
6
|
+
def initialize(attr_list, builder)
|
|
7
|
+
super(builder)
|
|
8
|
+
@indexes = Hash[attr_list.to_a.map(&:to_s).each_with_index.to_a]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def on_select_list(sexpr)
|
|
12
|
+
reordered = sexpr.sexpr_body.sort{|i1,i2|
|
|
13
|
+
@indexes[i1.as_name] <=> @indexes[i2.as_name]
|
|
14
|
+
}
|
|
15
|
+
reordered.unshift(:select_list)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end # class Reorder
|
|
19
|
+
end # class Processor
|
|
20
|
+
end # module Sql
|
|
21
|
+
end # module Alf
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Alf
|
|
2
|
+
module Sql
|
|
3
|
+
class Processor
|
|
4
|
+
class Requalify < Processor
|
|
5
|
+
|
|
6
|
+
def initialize(builder)
|
|
7
|
+
super
|
|
8
|
+
@requalify = Hash.new{|h,k|
|
|
9
|
+
h[k] = Grammar.sexpr [:range_var_name, builder.next_qualifier!]
|
|
10
|
+
}
|
|
11
|
+
end
|
|
12
|
+
attr_reader :requalify
|
|
13
|
+
|
|
14
|
+
alias :on_select_exp :copy_and_apply
|
|
15
|
+
alias :on_missing :copy_and_apply
|
|
16
|
+
|
|
17
|
+
def on_range_var_name(sexpr)
|
|
18
|
+
requalify[sexpr]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end # class Requalify
|
|
22
|
+
end # class Processor
|
|
23
|
+
end # module Sql
|
|
24
|
+
end # module Alf
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module Alf
|
|
2
|
+
module Sql
|
|
3
|
+
class Processor
|
|
4
|
+
class SemiJoin < Processor
|
|
5
|
+
include JoinSupport
|
|
6
|
+
|
|
7
|
+
def initialize(right, negate = false, builder)
|
|
8
|
+
super(builder)
|
|
9
|
+
@right = right
|
|
10
|
+
@negate = negate
|
|
11
|
+
end
|
|
12
|
+
attr_reader :right, :negate
|
|
13
|
+
|
|
14
|
+
def call(sexpr)
|
|
15
|
+
if sexpr.set_operator?
|
|
16
|
+
call(builder.from_self(sexpr))
|
|
17
|
+
elsif right.set_operator?
|
|
18
|
+
SemiJoin.new(builder.from_self(right), negate, builder).call(sexpr)
|
|
19
|
+
else
|
|
20
|
+
super(sexpr)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def apply_join_strategy(left, right)
|
|
27
|
+
commons = left.to_attr_list & right.to_attr_list
|
|
28
|
+
subquery = Clip.new(commons, :star, builder).call(right)
|
|
29
|
+
if commons.size == 0
|
|
30
|
+
predicate = builder.exists(subquery)
|
|
31
|
+
elsif commons.size == 1
|
|
32
|
+
identifier = left.desaliaser[commons.to_a.first]
|
|
33
|
+
predicate = Predicate::Factory.in(identifier, subquery)
|
|
34
|
+
else
|
|
35
|
+
join_pre = join_predicate(left, subquery, commons)
|
|
36
|
+
subquery = expand_where_clause(subquery, join_pre)
|
|
37
|
+
predicate = builder.exists(subquery)
|
|
38
|
+
end
|
|
39
|
+
expand_where_clause(left, negate ? !predicate : predicate)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def expand_where_clause(sexpr, predicate)
|
|
43
|
+
Grammar.sexpr \
|
|
44
|
+
[ :select_exp,
|
|
45
|
+
sexpr.set_quantifier,
|
|
46
|
+
sexpr.select_list,
|
|
47
|
+
sexpr.from_clause,
|
|
48
|
+
[ :where_clause, (sexpr.predicate || tautology) & predicate ],
|
|
49
|
+
sexpr.order_by_clause,
|
|
50
|
+
sexpr.limit_clause,
|
|
51
|
+
sexpr.offset_clause ].compact
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end # class SemiJoin
|
|
55
|
+
end # class Processor
|
|
56
|
+
end # module Sql
|
|
57
|
+
end # module Alf
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Alf
|
|
2
|
+
module Sql
|
|
3
|
+
class Processor
|
|
4
|
+
class Star < Processor
|
|
5
|
+
|
|
6
|
+
def on_select_exp(sexpr)
|
|
7
|
+
if sexpr.from_clause
|
|
8
|
+
sexpr.with_update(:select_list, builder.select_star)
|
|
9
|
+
else
|
|
10
|
+
sexpr
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end # class Star
|
|
15
|
+
end # class Processor
|
|
16
|
+
end # module Sql
|
|
17
|
+
end # module Alf
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Alf
|
|
2
|
+
module Sql
|
|
3
|
+
class Processor
|
|
4
|
+
class Where < Processor
|
|
5
|
+
|
|
6
|
+
def initialize(predicate, builder)
|
|
7
|
+
super(builder)
|
|
8
|
+
@predicate = predicate
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def on_select_exp(sexpr)
|
|
12
|
+
pred = @predicate.rename(sexpr.desaliaser).sexpr
|
|
13
|
+
if sexpr.where_clause
|
|
14
|
+
anded = [:and, sexpr.where_clause.predicate, pred ]
|
|
15
|
+
anded = Alf::Predicate::Grammar.sexpr(anded)
|
|
16
|
+
sexpr.with_update(:where_clause, [ :where_clause, anded ])
|
|
17
|
+
else
|
|
18
|
+
sexpr.with_insert(4, [ :where_clause, pred ])
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end # class Where
|
|
23
|
+
end # class Processor
|
|
24
|
+
end # module Sql
|
|
25
|
+
end # module Alf
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Alf
|
|
3
|
+
module Algebra
|
|
4
|
+
describe Operand, "to_sql" do
|
|
5
|
+
|
|
6
|
+
subject{ op.to_sql }
|
|
7
|
+
|
|
8
|
+
context 'when to_cog does not support to_sql' do
|
|
9
|
+
let(:op) { restrict(suppliers, city: 'London') }
|
|
10
|
+
|
|
11
|
+
before do
|
|
12
|
+
op.to_cog.should_not respond_to(:to_sql)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it{ should eq("SELECT t1.sid, t1.name, t1.status, t1.city FROM suppliers AS t1 WHERE t1.city = 'London'") }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
context 'when to_cog does support to_sql' do
|
|
19
|
+
let(:op) { restrict(suppliers, city: 'London') }
|
|
20
|
+
|
|
21
|
+
before do
|
|
22
|
+
def op.to_sql
|
|
23
|
+
:foo
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it{ should eq(:foo) }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Alf
|
|
3
|
+
module Sql
|
|
4
|
+
describe Builder, "order_by_clause" do
|
|
5
|
+
|
|
6
|
+
let(:ordering){ Ordering.new([[:name, :asc], [:city, :desc]]) }
|
|
7
|
+
|
|
8
|
+
context 'without desaliaser' do
|
|
9
|
+
subject{ builder.order_by_clause(ordering) }
|
|
10
|
+
|
|
11
|
+
let(:expected){
|
|
12
|
+
[:order_by_clause,
|
|
13
|
+
[:order_by_term, [:column_name, 'name'], 'asc'],
|
|
14
|
+
[:order_by_term, [:column_name, 'city'], 'desc'] ]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
it{ should eq(expected) }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context 'with a desaliaser' do
|
|
21
|
+
let(:desaliaser){
|
|
22
|
+
->(a){
|
|
23
|
+
if a == "name"
|
|
24
|
+
[:qualified_name, [:range_var_name, "t1"], [:column_name, a]]
|
|
25
|
+
else
|
|
26
|
+
nil
|
|
27
|
+
end
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
subject{ builder.order_by_clause(ordering, &desaliaser) }
|
|
32
|
+
|
|
33
|
+
let(:expected){
|
|
34
|
+
[:order_by_clause,
|
|
35
|
+
[:order_by_term, [:qualified_name, [:range_var_name, "t1"], [:column_name, 'name']], 'asc'],
|
|
36
|
+
[:order_by_term, [:column_name, 'city'], 'desc'] ]
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
it{ should eq(expected) }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
data/spec/helpers/ast.rb
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
module Helpers
|
|
2
|
+
module Ast
|
|
3
|
+
|
|
4
|
+
def sexpr(arg)
|
|
5
|
+
Alf::Sql::Grammar.sexpr(arg)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def with_exp(spec, selection = select_ab)
|
|
9
|
+
sexpr [:with_exp, with_spec(spec), selection]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def with_spec(spec = nil)
|
|
13
|
+
spec = {} if spec.nil?
|
|
14
|
+
sexpr spec.map{|k,v|
|
|
15
|
+
[:name_intro, [:table_name, k.to_s], v]
|
|
16
|
+
}.unshift(:with_spec)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def union(left = select_all, right = select_all_t2)
|
|
20
|
+
sexpr [:union, distinct, left, right]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def except(left = select_all, right = select_all_t2)
|
|
24
|
+
sexpr [:except, distinct, left, right]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def intersect(left = select_all, right = select_all_t2)
|
|
28
|
+
sexpr [:intersect, distinct, left, right]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def select_is_table_dee(where)
|
|
32
|
+
exists = Alf::Predicate::Grammar.sexpr([:exists, where])
|
|
33
|
+
sexpr [:select_exp, all,
|
|
34
|
+
[:select_list,
|
|
35
|
+
[:select_item,
|
|
36
|
+
[:literal, true],
|
|
37
|
+
[:column_name, "is_table_dee"]] ],
|
|
38
|
+
[:where_clause, exists] ]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def select_ab
|
|
42
|
+
sexpr [:select_exp, all, select_list, from_clause]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def select_a
|
|
46
|
+
sexpr [:select_exp, all, select_list_a, from_clause]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def select_distinct
|
|
50
|
+
sexpr [:select_exp, distinct, select_list, from_clause]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def select_distinct_star
|
|
54
|
+
sexpr [:select_exp, distinct, select_star, from_clause]
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def select_distinct_ab
|
|
58
|
+
sexpr [:select_exp, distinct, select_list_ab, from_clause]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def select_distinct_a
|
|
62
|
+
sexpr [:select_exp, distinct, select_list_a, from_clause]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def select_all
|
|
66
|
+
sexpr [:select_exp, all, select_list, from_clause]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def select_all_star
|
|
70
|
+
sexpr [:select_exp, all, select_star, from_clause]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def select_all_from_t1_as_t2
|
|
74
|
+
sexpr [:select_exp, all, select_list_t2, from_clause_t1_as_t2]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def select_all_t2
|
|
78
|
+
sexpr [:select_exp, all, select_list_t2, from_clause_t2]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def select_all_t3
|
|
82
|
+
sexpr [:select_exp, all, select_list_t3, from_clause_t3]
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def select_all_ab
|
|
86
|
+
sexpr [:select_exp, all, select_list_ab, from_clause]
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def select_all_a
|
|
90
|
+
sexpr [:select_exp, all, select_list_a, from_clause]
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def select_all_a_as_b
|
|
94
|
+
sexpr [:select_exp, all, select_list_a_as_b, from_clause]
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def select_all_b
|
|
98
|
+
sexpr [:select_exp, all, select_list_b, from_clause]
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def select_star
|
|
102
|
+
sexpr [:select_star]
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def select_list(hash = {"a" => "a", "b" => "b"})
|
|
106
|
+
sexpr [:select_list] + hash.map{|(k,v)| select_item(k, v) }
|
|
107
|
+
end
|
|
108
|
+
alias :select_list_ab :select_list
|
|
109
|
+
|
|
110
|
+
def select_list_t2
|
|
111
|
+
sexpr [:select_list, select_item_a_t2, select_item_b_t2 ]
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def select_list_t3
|
|
115
|
+
sexpr [:select_list, select_item_a_t3, select_item_b_t3 ]
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def select_list_ab
|
|
119
|
+
sexpr [:select_list, select_item_a, select_item_b]
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def select_list_ba
|
|
123
|
+
sexpr [:select_list, select_item_b, select_item_a]
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def select_list_a
|
|
127
|
+
sexpr [:select_list, select_item_a]
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def select_list_a_as_b
|
|
131
|
+
sexpr [:select_list, select_item("a","b")]
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def select_list_b
|
|
135
|
+
sexpr [:select_list, select_item_b]
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def select_item_a
|
|
139
|
+
select_item("a")
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def select_item_a_t2
|
|
143
|
+
select_item(qualified_name("t2", "a"), "a")
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def select_item_a_t3
|
|
147
|
+
select_item(qualified_name("t3", "a"), "a")
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def select_item_b_t2
|
|
151
|
+
select_item(qualified_name("t2", "b"), "b")
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def select_item_b_t3
|
|
155
|
+
select_item(qualified_name("t3", "b"), "b")
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def select_item_b
|
|
159
|
+
select_item("b")
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def select_item(name, as = name)
|
|
163
|
+
name = qualified_name("t1", name) unless name.is_a?(Array)
|
|
164
|
+
sexpr [:select_item, name, column_name(as)]
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def column_name_a
|
|
168
|
+
column_name("a")
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def column_name_b
|
|
172
|
+
column_name("b")
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def column_name(x)
|
|
176
|
+
sexpr [:column_name, x]
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def qualified_name_a
|
|
180
|
+
qualified_name("t1", "a")
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def qualified_name_b
|
|
184
|
+
qualified_name("t2", "b")
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def qualified_name(qualifier, name)
|
|
188
|
+
sexpr [:qualified_name, [:range_var_name, qualifier], [:column_name, name]]
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def from_clause
|
|
192
|
+
sexpr [:from_clause, [:table_as, [:table_name, "t1"], [:range_var_name, "t1"]]]
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def from_clause_t2
|
|
196
|
+
sexpr [:from_clause, [:table_as, [:table_name, "t2"], [:range_var_name, "t2"]]]
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def from_clause_t1_as_t2
|
|
200
|
+
sexpr [:from_clause, [:table_as, [:table_name, "t1"], [:range_var_name, "t2"]]]
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def from_clause_t3
|
|
204
|
+
sexpr [:from_clause, [:table_as, [:table_name, "t3"], [:range_var_name, "t3"]]]
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def ordering
|
|
208
|
+
Alf::Ordering.new([[:a, :asc], [:b, :desc]])
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def subordering
|
|
212
|
+
Alf::Ordering.new([[:a, :desc], [:b, :asc]])
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def order_by_clause
|
|
216
|
+
[:order_by_clause,
|
|
217
|
+
order_by_term("a", "asc"),
|
|
218
|
+
order_by_term("b", "desc")]
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def order_by_clause_2
|
|
222
|
+
[:order_by_clause,
|
|
223
|
+
order_by_term("a", "desc"),
|
|
224
|
+
order_by_term("b", "asc")]
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def order_by_term(name, direction)
|
|
228
|
+
name = qualified_name("t1", name) unless name.is_a?(Array)
|
|
229
|
+
sexpr [:order_by_term, name, direction]
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def distinct
|
|
233
|
+
[:set_quantifier, "distinct"]
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def all
|
|
237
|
+
[:set_quantifier, "all"]
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
end
|
|
241
|
+
include Ast
|
|
242
|
+
end
|