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,23 @@
|
|
|
1
|
+
module Helpers
|
|
2
|
+
module Compiler
|
|
3
|
+
|
|
4
|
+
def an_operand(cog = nil)
|
|
5
|
+
Alf::Algebra::Operand::Fake.new(nil, cog)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def compiler
|
|
9
|
+
@compiler ||= Alf::Sql::Compiler.new
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def builder(start = 0)
|
|
13
|
+
@builder ||= Alf::Sql::Builder.new(start)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def suppliers
|
|
17
|
+
@suppliers ||= an_operand.with_name(:suppliers)
|
|
18
|
+
.with_heading(sid: String, name: String, status: Integer, city: String)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
include Compiler
|
|
23
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Alf
|
|
3
|
+
module Sql
|
|
4
|
+
describe OrderByClause, "to_ordering" do
|
|
5
|
+
|
|
6
|
+
subject{ expr.to_ordering }
|
|
7
|
+
|
|
8
|
+
let(:ordering){
|
|
9
|
+
Ordering.new([[:a, :asc], [:b, :desc]])
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
context 'when not qualified' do
|
|
13
|
+
let(:expr){ builder.order_by_clause(ordering) }
|
|
14
|
+
|
|
15
|
+
it{ should eq(ordering) }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
context 'when qualified' do
|
|
19
|
+
let(:expr){
|
|
20
|
+
builder.order_by_clause(ordering){|a|
|
|
21
|
+
[:qualified_name, [:range_var_name, "t1"], [:column_name, a]]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
it{ should eq(ordering) }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Alf
|
|
3
|
+
module Sql
|
|
4
|
+
describe OrderByTerm, "as_name" do
|
|
5
|
+
|
|
6
|
+
subject{ expr.as_name }
|
|
7
|
+
|
|
8
|
+
context 'when qualified' do
|
|
9
|
+
let(:expr){ order_by_term(qualified_name('t1', 'a'), "asc") }
|
|
10
|
+
|
|
11
|
+
it{ should eq('a') }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
context 'when not qualified' do
|
|
15
|
+
let(:expr){ order_by_term(column_name_a, "asc") }
|
|
16
|
+
|
|
17
|
+
it{ should eq('a') }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Alf
|
|
3
|
+
module Sql
|
|
4
|
+
describe OrderByTerm, "direction" do
|
|
5
|
+
|
|
6
|
+
subject{ expr.direction }
|
|
7
|
+
|
|
8
|
+
context 'when qualified' do
|
|
9
|
+
let(:expr){ order_by_term(qualified_name('t1', 'a'), "asc") }
|
|
10
|
+
|
|
11
|
+
it{ should eq('asc') }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
context 'when not qualified' do
|
|
15
|
+
let(:expr){ order_by_term(column_name_a, "asc") }
|
|
16
|
+
|
|
17
|
+
it{ should eq('asc') }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Alf
|
|
3
|
+
module Sql
|
|
4
|
+
describe OrderByTerm, "qualifier" do
|
|
5
|
+
|
|
6
|
+
subject{ expr.qualifier }
|
|
7
|
+
|
|
8
|
+
context 'when qualified' do
|
|
9
|
+
let(:expr){ order_by_term(qualified_name('t1', 'a'), "asc") }
|
|
10
|
+
|
|
11
|
+
it{ should eq('t1') }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
context 'when not qualified' do
|
|
15
|
+
let(:expr){ order_by_term(column_name_a, "asc") }
|
|
16
|
+
|
|
17
|
+
it{ should be_nil }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Alf
|
|
3
|
+
module Sql
|
|
4
|
+
describe SelectExp, "order_by_clause" do
|
|
5
|
+
|
|
6
|
+
subject{ expr.order_by_clause }
|
|
7
|
+
|
|
8
|
+
context 'when an order by clause' do
|
|
9
|
+
let(:expr){ select_all.push(order_by_clause) }
|
|
10
|
+
|
|
11
|
+
it{ should eq(order_by_clause) }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
context 'without such clause' do
|
|
15
|
+
let(:expr){ select_all }
|
|
16
|
+
|
|
17
|
+
it{ should be_nil }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Alf
|
|
3
|
+
module Sql
|
|
4
|
+
describe SelectItem, "as_name" do
|
|
5
|
+
|
|
6
|
+
subject{ expr.as_name }
|
|
7
|
+
|
|
8
|
+
context 'on a select item with no real renaming' do
|
|
9
|
+
let(:expr){ select_item("a", "a") }
|
|
10
|
+
|
|
11
|
+
it{ should eq("a") }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
context 'on a select item with with real renaming' do
|
|
15
|
+
let(:expr){ select_item("a", "x") }
|
|
16
|
+
|
|
17
|
+
it{ should eq("x") }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Alf
|
|
3
|
+
class Predicate
|
|
4
|
+
describe Exists, "!" do
|
|
5
|
+
|
|
6
|
+
let(:expr){
|
|
7
|
+
Grammar.sexpr [:exists, :foo]
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let(:expected){
|
|
11
|
+
Grammar.sexpr [:not, [:exists, :foo]]
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
subject{ !expr }
|
|
15
|
+
|
|
16
|
+
it{ should eq(expected) }
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Alf
|
|
3
|
+
module Sql
|
|
4
|
+
class Processor
|
|
5
|
+
describe Clip, "on_select_exp" do
|
|
6
|
+
|
|
7
|
+
subject{ Clip.new(AttrList[:a], Builder.new).on_select_exp(expr) }
|
|
8
|
+
|
|
9
|
+
context 'normal_case' do
|
|
10
|
+
let(:expr){ select_all }
|
|
11
|
+
|
|
12
|
+
it{ should eq(select_all_a) }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
context 'distinct_case' do
|
|
16
|
+
let(:expr){ select_distinct }
|
|
17
|
+
|
|
18
|
+
it{ should eq(select_distinct_a) }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context 'when leading to an empty select_list' do
|
|
22
|
+
let(:expr){ select_all_b }
|
|
23
|
+
|
|
24
|
+
context 'the default behavior' do
|
|
25
|
+
it{ should eq(select_is_table_dee(select_all_star)) }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Alf
|
|
3
|
+
module Sql
|
|
4
|
+
class Processor
|
|
5
|
+
describe Clip, "on_select_list" do
|
|
6
|
+
|
|
7
|
+
subject{ Clip.new(AttrList[:a], Builder.new).on_select_list(expr) }
|
|
8
|
+
|
|
9
|
+
context 'when included' do
|
|
10
|
+
let(:expr){ select_list_ab }
|
|
11
|
+
|
|
12
|
+
it{ should eq(select_list_a) }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
context 'when unique' do
|
|
16
|
+
let(:expr){ select_list_a }
|
|
17
|
+
|
|
18
|
+
it{ should eq(select_list_a) }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Alf
|
|
3
|
+
module Sql
|
|
4
|
+
class Processor
|
|
5
|
+
describe Distinct, "on_set_quantified" do
|
|
6
|
+
|
|
7
|
+
subject{ Distinct.new(Builder.new).on_set_quantified(expr) }
|
|
8
|
+
|
|
9
|
+
let(:expected){
|
|
10
|
+
[:x, distinct]
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
context 'when already distinct' do
|
|
14
|
+
let(:expr){
|
|
15
|
+
Grammar.sexpr [:x, distinct]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
it{ should eq(expected) }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context 'when not distinct' do
|
|
22
|
+
let(:expr){
|
|
23
|
+
Grammar.sexpr [:x, all]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
it{ should eq(expected) }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Alf
|
|
3
|
+
module Sql
|
|
4
|
+
class Processor
|
|
5
|
+
describe FromSelf, "on_nonjoin_exp" do
|
|
6
|
+
|
|
7
|
+
subject{ FromSelf.new(builder).on_nonjoin_exp(expr) }
|
|
8
|
+
|
|
9
|
+
context 'on select_exp' do
|
|
10
|
+
let(:expr){
|
|
11
|
+
select_all
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let(:expected){
|
|
15
|
+
with_exp(t1: select_all)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
it{ should eq(expected) }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context 'on union' do
|
|
22
|
+
let(:expr){
|
|
23
|
+
union
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let(:expected){
|
|
27
|
+
with_exp(t1: union)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
it{ should eq(expected) }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context 'on intersect' do
|
|
34
|
+
let(:expr){
|
|
35
|
+
intersect
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
let(:expected){
|
|
39
|
+
with_exp(t1: intersect)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
it{ should eq(expected) }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context 'on except' do
|
|
46
|
+
let(:expr){
|
|
47
|
+
except
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let(:expected){
|
|
51
|
+
with_exp(t1: except)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
it{ should eq(expected) }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Alf
|
|
3
|
+
module Sql
|
|
4
|
+
class Processor
|
|
5
|
+
describe FromSelf, "on_with_exp" do
|
|
6
|
+
|
|
7
|
+
subject{ FromSelf.new(builder(1)).on_with_exp(expr) }
|
|
8
|
+
|
|
9
|
+
let(:expr){
|
|
10
|
+
with_exp({t1: select_all}, select_all_t2)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let(:expected){
|
|
14
|
+
with_exp({t1: select_all, t2: select_all_t2}, select_all_t2)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
it{ should eq(expected) }
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Alf
|
|
3
|
+
module Sql
|
|
4
|
+
class Processor
|
|
5
|
+
describe Merge, "on_select_exp" do
|
|
6
|
+
|
|
7
|
+
subject{ Merge.new(:intersect, right, builder(1)).on_select_exp(expr) }
|
|
8
|
+
|
|
9
|
+
context 'when right a simple select_exp' do
|
|
10
|
+
let(:expr){
|
|
11
|
+
# SELECT * FROM t1
|
|
12
|
+
select_all
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let(:right){
|
|
16
|
+
# SELECT * FROM t2
|
|
17
|
+
select_all_t2
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
let(:expected){
|
|
21
|
+
# SELECT * FROM t1 INTERSECT SELECT * FROM t2
|
|
22
|
+
intersect
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
it{ should eq(expected) }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context 'when right an intersect' do
|
|
29
|
+
let(:expr){
|
|
30
|
+
# SELECT * FROM t1
|
|
31
|
+
select_all
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let(:right){
|
|
35
|
+
# SELECT * FROM t1 INTERSECT SELECT * FROM t2
|
|
36
|
+
intersect
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let(:expected){
|
|
40
|
+
# SELECT * FROM t1 INTERSECT SELECT * FROM t1 INTERSECT SELECT * FROM t2
|
|
41
|
+
intersect(expr, right)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
it{ should eq(expected) }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
context 'when right is a with_exp' do
|
|
48
|
+
let(:expr){
|
|
49
|
+
# SELECT * FROM t1
|
|
50
|
+
select_all
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
let(:right){
|
|
54
|
+
# WITH t2 AS ...
|
|
55
|
+
# SELECT * FROM t2
|
|
56
|
+
with_exp({t2: select_all_t2}, select_all_t2)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
let(:expected){
|
|
60
|
+
# WITH t2 AS ...
|
|
61
|
+
# SELECT * FROM t1 INTERSECT SELECT * FROM t2
|
|
62
|
+
with_exp(
|
|
63
|
+
{t2: select_all_t2},
|
|
64
|
+
intersect(select_all, select_all_t2))
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
it{ should eq(expected) }
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|