veritas-sql-generator 0.0.3 → 0.0.4
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/.gemtest +0 -0
- data/.rvmrc +1 -0
- data/.travis.yml +8 -0
- data/Gemfile +20 -10
- data/Guardfile +22 -0
- data/README.rdoc +2 -0
- data/Rakefile +4 -2
- data/TODO +16 -2
- data/config/flay.yml +2 -2
- data/config/flog.yml +1 -1
- data/config/roodi.yml +5 -5
- data/config/site.reek +21 -19
- data/lib/veritas/sql/generator.rb +25 -2
- data/lib/veritas/sql/generator/core_ext/date.rb +20 -0
- data/lib/veritas/sql/generator/core_ext/date_time.rb +45 -0
- data/lib/veritas/sql/generator/direction.rb +3 -1
- data/lib/veritas/sql/generator/function.rb +54 -0
- data/lib/veritas/sql/generator/function/aggregate.rb +134 -0
- data/lib/veritas/sql/generator/function/connective.rb +53 -0
- data/lib/veritas/sql/generator/function/numeric.rb +135 -0
- data/lib/veritas/sql/generator/function/predicate.rb +266 -0
- data/lib/veritas/sql/generator/function/proposition.rb +38 -0
- data/lib/veritas/sql/generator/function/string.rb +29 -0
- data/lib/veritas/sql/generator/identifier.rb +2 -1
- data/lib/veritas/sql/generator/literal.rb +15 -18
- data/lib/veritas/sql/generator/relation.rb +144 -17
- data/lib/veritas/sql/generator/relation/binary.rb +16 -64
- data/lib/veritas/sql/generator/relation/set.rb +30 -22
- data/lib/veritas/sql/generator/relation/unary.rb +131 -78
- data/lib/veritas/sql/generator/version.rb +1 -1
- data/spec/unit/date/iso8601_spec.rb +23 -0
- data/spec/unit/date_time/iso_8601_spec.rb +115 -0
- data/spec/unit/veritas/sql/generator/class_methods/parenthesize_spec.rb +18 -0
- data/spec/unit/veritas/sql/generator/function/aggregate/visit_veritas_aggregate_count_spec.rb +16 -0
- data/spec/unit/veritas/sql/generator/function/aggregate/visit_veritas_aggregate_maximum_spec.rb +16 -0
- data/spec/unit/veritas/sql/generator/function/aggregate/visit_veritas_aggregate_mean_spec.rb +16 -0
- data/spec/unit/veritas/sql/generator/function/aggregate/visit_veritas_aggregate_minimum_spec.rb +16 -0
- data/spec/unit/veritas/sql/generator/function/aggregate/visit_veritas_aggregate_standard_deviation_spec.rb +16 -0
- data/spec/unit/veritas/sql/generator/function/aggregate/visit_veritas_aggregate_sum_spec.rb +16 -0
- data/spec/unit/veritas/sql/generator/function/aggregate/visit_veritas_aggregate_variance_spec.rb +16 -0
- data/spec/unit/veritas/sql/generator/function/connective/visit_veritas_function_connective_conjunction_spec.rb +20 -0
- data/spec/unit/veritas/sql/generator/function/connective/visit_veritas_function_connective_disjunction_spec.rb +20 -0
- data/spec/unit/veritas/sql/generator/function/connective/visit_veritas_function_connective_negation_spec.rb +20 -0
- data/spec/unit/veritas/sql/generator/function/numeric/visit_veritas_function_numeric_absolute_spec.rb +15 -0
- data/spec/unit/veritas/sql/generator/function/numeric/visit_veritas_function_numeric_addition_spec.rb +15 -0
- data/spec/unit/veritas/sql/generator/function/numeric/visit_veritas_function_numeric_division_spec.rb +15 -0
- data/spec/unit/veritas/sql/generator/function/numeric/visit_veritas_function_numeric_exponentiation_spec.rb +15 -0
- data/spec/unit/veritas/sql/generator/function/numeric/visit_veritas_function_numeric_modulo_spec.rb +15 -0
- data/spec/unit/veritas/sql/generator/function/numeric/visit_veritas_function_numeric_multiplication_spec.rb +15 -0
- data/spec/unit/veritas/sql/generator/function/numeric/visit_veritas_function_numeric_square_root_spec.rb +15 -0
- data/spec/unit/veritas/sql/generator/function/numeric/visit_veritas_function_numeric_subtraction_spec.rb +15 -0
- data/spec/unit/veritas/sql/generator/function/numeric/visit_veritas_function_numeric_unary_minus_spec.rb +15 -0
- data/spec/unit/veritas/sql/generator/function/numeric/visit_veritas_function_numeric_unary_plus_spec.rb +15 -0
- data/spec/unit/veritas/sql/generator/{logic/visit_veritas_logic_predicate_equality_spec.rb → function/predicate/visit_veritas_function_predicate_equality_spec.rb} +5 -5
- data/spec/unit/veritas/sql/generator/{logic/visit_veritas_logic_predicate_exclusion_spec.rb → function/predicate/visit_veritas_function_predicate_exclusion_spec.rb} +10 -6
- data/spec/unit/veritas/sql/generator/function/predicate/visit_veritas_function_predicate_greater_than_or_equal_to_spec.rb +15 -0
- data/spec/unit/veritas/sql/generator/{logic/visit_veritas_logic_predicate_greater_than_spec.rb → function/predicate/visit_veritas_function_predicate_greater_than_spec.rb} +5 -5
- data/spec/unit/veritas/sql/generator/{logic/visit_veritas_logic_predicate_inclusion_spec.rb → function/predicate/visit_veritas_function_predicate_inclusion_spec.rb} +10 -6
- data/spec/unit/veritas/sql/generator/{logic/visit_veritas_logic_predicate_inequality_spec.rb → function/predicate/visit_veritas_function_predicate_inequality_spec.rb} +8 -8
- data/spec/unit/veritas/sql/generator/function/predicate/visit_veritas_function_predicate_less_than_or_equal_to_spec.rb +15 -0
- data/spec/unit/veritas/sql/generator/{logic/visit_veritas_logic_predicate_less_than_spec.rb → function/predicate/visit_veritas_function_predicate_less_than_spec.rb} +5 -5
- data/spec/unit/veritas/sql/generator/function/proposition/visit_veritas_function_proposition_contradiction_spec.rb +15 -0
- data/spec/unit/veritas/sql/generator/function/proposition/visit_veritas_function_proposition_tautology_spec.rb +15 -0
- data/spec/unit/veritas/sql/generator/function/string/visit_veritas_function_string_length_spec.rb +15 -0
- data/spec/unit/veritas/sql/generator/literal/class_methods/dup_frozen_spec.rb +2 -2
- data/spec/unit/veritas/sql/generator/relation/binary/base/to_subquery_spec.rb +1 -1
- data/spec/unit/veritas/sql/generator/relation/binary/base/{visit_veritas_base_relation_spec.rb → visit_veritas_relation_base_spec.rb} +3 -3
- data/spec/unit/veritas/sql/generator/relation/binary/to_s_spec.rb +2 -2
- data/spec/unit/veritas/sql/generator/relation/binary/to_subquery_spec.rb +2 -2
- data/spec/unit/veritas/sql/generator/relation/binary/visit_veritas_algebra_join_spec.rb +74 -33
- data/spec/unit/veritas/sql/generator/relation/binary/visit_veritas_algebra_product_spec.rb +63 -19
- data/spec/unit/veritas/sql/generator/relation/class_methods/visit_spec.rb +1 -1
- data/spec/unit/veritas/sql/generator/relation/set/class_methods/normalize_operand_headers_spec.rb +35 -0
- data/spec/unit/veritas/sql/generator/relation/set/to_s_spec.rb +1 -1
- data/spec/unit/veritas/sql/generator/relation/set/to_subquery_spec.rb +4 -4
- data/spec/unit/veritas/sql/generator/relation/set/visit_veritas_algebra_difference_spec.rb +83 -30
- data/spec/unit/veritas/sql/generator/relation/set/visit_veritas_algebra_intersection_spec.rb +80 -30
- data/spec/unit/veritas/sql/generator/relation/set/visit_veritas_algebra_union_spec.rb +80 -30
- data/spec/unit/veritas/sql/generator/relation/to_s_spec.rb +50 -0
- data/spec/unit/veritas/sql/generator/relation/to_subquery_spec.rb +49 -0
- data/spec/unit/veritas/sql/generator/relation/unary/to_s_spec.rb +1 -1
- data/spec/unit/veritas/sql/generator/relation/unary/to_subquery_spec.rb +6 -6
- data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_algebra_extension_spec.rb +165 -0
- data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_algebra_projection_spec.rb +84 -29
- data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_algebra_rename_spec.rb +69 -27
- data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_algebra_restriction_spec.rb +64 -22
- data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_algebra_summarization_spec.rb +652 -0
- data/spec/unit/veritas/sql/generator/relation/unary/{visit_veritas_base_relation_spec.rb → visit_veritas_relation_base_spec.rb} +4 -4
- data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_relation_operation_limit_spec.rb +60 -20
- data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_relation_operation_offset_spec.rb +60 -20
- data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_relation_operation_order_spec.rb +63 -23
- data/spec/unit/veritas/sql/generator/relation/unary/visit_veritas_relation_operation_reverse_spec.rb +60 -20
- data/spec/unit/veritas/sql/generator/relation/visited_spec.rb +1 -1
- data/tasks/metrics/ci.rake +7 -0
- data/tasks/{quality → metrics}/flay.rake +0 -0
- data/tasks/{quality → metrics}/flog.rake +0 -0
- data/tasks/{quality → metrics}/heckle.rake +1 -0
- data/tasks/{quality → metrics}/metric_fu.rake +3 -0
- data/tasks/{quality → metrics}/reek.rake +0 -0
- data/tasks/{quality → metrics}/roodi.rake +0 -0
- data/tasks/{quality → metrics}/yardstick.rake +0 -0
- data/tasks/spec.rake +1 -0
- data/veritas-sql-generator.gemspec +82 -114
- metadata +137 -125
- data/lib/veritas/base_relation.rb +0 -36
- data/lib/veritas/sql/generator/logic.rb +0 -349
- data/spec/unit/veritas/base_relation/name_spec.rb +0 -45
- data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_connective_conjunction_spec.rb +0 -16
- data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_connective_disjunction_spec.rb +0 -16
- data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_connective_negation_spec.rb +0 -16
- data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_predicate_greater_than_or_equal_to_spec.rb +0 -15
- data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_predicate_less_than_or_equal_to_spec.rb +0 -15
- data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_proposition_contradiction_spec.rb +0 -15
- data/spec/unit/veritas/sql/generator/logic/visit_veritas_logic_proposition_tautology_spec.rb +0 -15
- data/spec/unit/veritas/sql/generator/relation/binary/class_methods/subquery_spec.rb +0 -42
- data/spec/unit/veritas/sql/generator/relation/class_methods/subquery_spec.rb +0 -33
- data/tasks/quality/ci.rake +0 -2
data/spec/unit/veritas/sql/generator/relation/set/visit_veritas_algebra_intersection_spec.rb
CHANGED
|
@@ -11,7 +11,7 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_intersection' do
|
|
|
11
11
|
let(:age) { Attribute::Integer.new(:age, :required => false) }
|
|
12
12
|
let(:header) { [ id, name, age ] }
|
|
13
13
|
let(:body) { [ [ 1, 'Dan Kubb', 35 ] ].each }
|
|
14
|
-
let(:base_relation) {
|
|
14
|
+
let(:base_relation) { Relation::Base.new(relation_name, header, body) }
|
|
15
15
|
let(:left) { operand }
|
|
16
16
|
let(:right) { operand }
|
|
17
17
|
let(:intersection) { left.intersect(right) }
|
|
@@ -22,8 +22,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_intersection' do
|
|
|
22
22
|
|
|
23
23
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
24
24
|
|
|
25
|
-
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users")')
|
|
26
|
-
its(:to_subquery) { should eql('(SELECT
|
|
25
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users")') }
|
|
26
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users"))') }
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
context 'when the operands are projections' do
|
|
@@ -31,8 +31,17 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_intersection' do
|
|
|
31
31
|
|
|
32
32
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
33
33
|
|
|
34
|
-
its(:to_s) { should eql('(SELECT DISTINCT "id", "name" FROM "users") INTERSECT (SELECT DISTINCT "id", "name" FROM "users")')
|
|
35
|
-
its(:to_subquery) { should eql('(SELECT DISTINCT "id", "name" FROM "users") INTERSECT (SELECT DISTINCT "id", "name" FROM "users")') }
|
|
34
|
+
its(:to_s) { should eql('(SELECT DISTINCT "id", "name" FROM "users") INTERSECT (SELECT DISTINCT "id", "name" FROM "users")') }
|
|
35
|
+
its(:to_subquery) { should eql('((SELECT DISTINCT "id", "name" FROM "users") INTERSECT (SELECT DISTINCT "id", "name" FROM "users"))') }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
context 'when the operand is an extension' do
|
|
39
|
+
let(:operand) { base_relation.extend { |r| r.add(:one, 1) } }
|
|
40
|
+
|
|
41
|
+
it_should_behave_like 'a generated SQL SELECT query'
|
|
42
|
+
|
|
43
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age", 1 AS "one" FROM "users") INTERSECT (SELECT "id", "name", "age", 1 AS "one" FROM "users")') }
|
|
44
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age", 1 AS "one" FROM "users") INTERSECT (SELECT "id", "name", "age", 1 AS "one" FROM "users"))') }
|
|
36
45
|
end
|
|
37
46
|
|
|
38
47
|
context 'when the operands are renames' do
|
|
@@ -40,8 +49,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_intersection' do
|
|
|
40
49
|
|
|
41
50
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
42
51
|
|
|
43
|
-
its(:to_s) { should eql('(SELECT "id" AS "user_id", "name", "age" FROM "users") INTERSECT (SELECT "id" AS "user_id", "name", "age" FROM "users")')
|
|
44
|
-
its(:to_subquery) { should eql('(SELECT "id" AS "user_id", "name", "age" FROM "users") INTERSECT (SELECT "id" AS "user_id", "name", "age" FROM "users")') }
|
|
52
|
+
its(:to_s) { should eql('(SELECT "id" AS "user_id", "name", "age" FROM "users") INTERSECT (SELECT "id" AS "user_id", "name", "age" FROM "users")') }
|
|
53
|
+
its(:to_subquery) { should eql('((SELECT "id" AS "user_id", "name", "age" FROM "users") INTERSECT (SELECT "id" AS "user_id", "name", "age" FROM "users"))') }
|
|
45
54
|
end
|
|
46
55
|
|
|
47
56
|
context 'when the operands are restrictions' do
|
|
@@ -49,8 +58,39 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_intersection' do
|
|
|
49
58
|
|
|
50
59
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
51
60
|
|
|
52
|
-
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" WHERE "id" = 1) INTERSECT (SELECT "id", "name", "age" FROM "users" WHERE "id" = 1)')
|
|
53
|
-
its(:to_subquery) { should eql('(SELECT
|
|
61
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" WHERE "id" = 1) INTERSECT (SELECT "id", "name", "age" FROM "users" WHERE "id" = 1)') }
|
|
62
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users" WHERE "id" = 1) INTERSECT (SELECT "id", "name", "age" FROM "users" WHERE "id" = 1))') }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context 'when the operand is a summarization' do
|
|
66
|
+
context 'summarize per table dee' do
|
|
67
|
+
let(:summarize_per) { TABLE_DEE }
|
|
68
|
+
let(:operand) { base_relation.summarize(summarize_per) { |r| r.add(:count, r[:id].count) } }
|
|
69
|
+
|
|
70
|
+
it_should_behave_like 'a generated SQL SELECT query'
|
|
71
|
+
|
|
72
|
+
its(:to_s) { should eql('(SELECT COUNT ("id") AS "count" FROM "users") INTERSECT (SELECT COUNT ("id") AS "count" FROM "users")') }
|
|
73
|
+
its(:to_subquery) { should eql('((SELECT COUNT ("id") AS "count" FROM "users") INTERSECT (SELECT COUNT ("id") AS "count" FROM "users"))') }
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
context 'summarize per table dum' do
|
|
77
|
+
let(:summarize_per) { TABLE_DUM }
|
|
78
|
+
let(:operand) { base_relation.summarize(summarize_per) { |r| r.add(:count, r[:id].count) } }
|
|
79
|
+
|
|
80
|
+
it_should_behave_like 'a generated SQL SELECT query'
|
|
81
|
+
|
|
82
|
+
its(:to_s) { should eql('(SELECT COUNT ("id") AS "count" FROM "users" HAVING FALSE) INTERSECT (SELECT COUNT ("id") AS "count" FROM "users" HAVING FALSE)') }
|
|
83
|
+
its(:to_subquery) { should eql('((SELECT COUNT ("id") AS "count" FROM "users" HAVING FALSE) INTERSECT (SELECT COUNT ("id") AS "count" FROM "users" HAVING FALSE))') }
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
context 'summarize by a subset of the operand header' do
|
|
87
|
+
let(:operand) { base_relation.summarize([ :id, :name ]) { |r| r.add(:count, r[:age].count) } }
|
|
88
|
+
|
|
89
|
+
it_should_behave_like 'a generated SQL SELECT query'
|
|
90
|
+
|
|
91
|
+
its(:to_s) { should eql('(SELECT "id", "name", COUNT ("age") AS "count" FROM "users" GROUP BY "id", "name" HAVING COUNT (*) > 0) INTERSECT (SELECT "id", "name", COUNT ("age") AS "count" FROM "users" GROUP BY "id", "name" HAVING COUNT (*) > 0)') }
|
|
92
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", COUNT ("age") AS "count" FROM "users" GROUP BY "id", "name" HAVING COUNT (*) > 0) INTERSECT (SELECT "id", "name", COUNT ("age") AS "count" FROM "users" GROUP BY "id", "name" HAVING COUNT (*) > 0))') }
|
|
93
|
+
end
|
|
54
94
|
end
|
|
55
95
|
|
|
56
96
|
context 'when the operand is ordered' do
|
|
@@ -58,8 +98,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_intersection' do
|
|
|
58
98
|
|
|
59
99
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
60
100
|
|
|
61
|
-
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age") INTERSECT (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age")')
|
|
62
|
-
its(:to_subquery) { should eql('(SELECT
|
|
101
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age") INTERSECT (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age")') }
|
|
102
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age") INTERSECT (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age"))') }
|
|
63
103
|
end
|
|
64
104
|
|
|
65
105
|
context 'when the operand is reversed' do
|
|
@@ -67,8 +107,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_intersection' do
|
|
|
67
107
|
|
|
68
108
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
69
109
|
|
|
70
|
-
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC) INTERSECT (SELECT "id", "name", "age" FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC)')
|
|
71
|
-
its(:to_subquery) { should eql('(SELECT
|
|
110
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC) INTERSECT (SELECT "id", "name", "age" FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC)') }
|
|
111
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC) INTERSECT (SELECT "id", "name", "age" FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC))') }
|
|
72
112
|
end
|
|
73
113
|
|
|
74
114
|
context 'when the operand is limited' do
|
|
@@ -76,8 +116,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_intersection' do
|
|
|
76
116
|
|
|
77
117
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
78
118
|
|
|
79
|
-
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1) INTERSECT (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1)')
|
|
80
|
-
its(:to_subquery) { should eql('(SELECT
|
|
119
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1) INTERSECT (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1)') }
|
|
120
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1) INTERSECT (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1))') }
|
|
81
121
|
end
|
|
82
122
|
|
|
83
123
|
context 'when the operands are offsets' do
|
|
@@ -85,8 +125,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_intersection' do
|
|
|
85
125
|
|
|
86
126
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
87
127
|
|
|
88
|
-
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1) INTERSECT (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1)')
|
|
89
|
-
its(:to_subquery) { should eql('(SELECT
|
|
128
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1) INTERSECT (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1)') }
|
|
129
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1) INTERSECT (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1))') }
|
|
90
130
|
end
|
|
91
131
|
|
|
92
132
|
context 'when the operands are differences' do
|
|
@@ -94,8 +134,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_intersection' do
|
|
|
94
134
|
|
|
95
135
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
96
136
|
|
|
97
|
-
its(:to_s) { should eql('((SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "users")) INTERSECT ((SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "users"))')
|
|
98
|
-
its(:to_subquery) { should eql('((SELECT
|
|
137
|
+
its(:to_s) { should eql('((SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "users")) INTERSECT ((SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "users"))') }
|
|
138
|
+
its(:to_subquery) { should eql('(((SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "users")) INTERSECT ((SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "users")))') }
|
|
99
139
|
end
|
|
100
140
|
|
|
101
141
|
context 'when the operands are intersections' do
|
|
@@ -103,8 +143,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_intersection' do
|
|
|
103
143
|
|
|
104
144
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
105
145
|
|
|
106
|
-
its(:to_s) { should eql('((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users")) INTERSECT ((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users"))')
|
|
107
|
-
its(:to_subquery) { should eql('((SELECT
|
|
146
|
+
its(:to_s) { should eql('((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users")) INTERSECT ((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users"))') }
|
|
147
|
+
its(:to_subquery) { should eql('(((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users")) INTERSECT ((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users")))') }
|
|
108
148
|
end
|
|
109
149
|
|
|
110
150
|
context 'when the operands are unions' do
|
|
@@ -112,8 +152,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_intersection' do
|
|
|
112
152
|
|
|
113
153
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
114
154
|
|
|
115
|
-
its(:to_s) { should eql('((SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users")) INTERSECT ((SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users"))')
|
|
116
|
-
its(:to_subquery) { should eql('((SELECT
|
|
155
|
+
its(:to_s) { should eql('((SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users")) INTERSECT ((SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users"))') }
|
|
156
|
+
its(:to_subquery) { should eql('(((SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users")) INTERSECT ((SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users")))') }
|
|
117
157
|
end
|
|
118
158
|
|
|
119
159
|
context 'when the operands are joins' do
|
|
@@ -121,18 +161,28 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_intersection' do
|
|
|
121
161
|
|
|
122
162
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
123
163
|
|
|
124
|
-
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" NATURAL JOIN "users") INTERSECT (SELECT "id", "name", "age" FROM "users" NATURAL JOIN "users")')
|
|
125
|
-
its(:to_subquery) { should eql('(SELECT
|
|
164
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" AS "left" NATURAL JOIN "users" AS "right") INTERSECT (SELECT "id", "name", "age" FROM "users" AS "left" NATURAL JOIN "users" AS "right")') }
|
|
165
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users" AS "left" NATURAL JOIN "users" AS "right") INTERSECT (SELECT "id", "name", "age" FROM "users" AS "left" NATURAL JOIN "users" AS "right"))') }
|
|
126
166
|
end
|
|
127
167
|
|
|
128
168
|
context 'when the operands have different base relations' do
|
|
129
|
-
let(:relation_name) { 'users_others'
|
|
130
|
-
let(:left) {
|
|
131
|
-
let(:right) {
|
|
169
|
+
let(:relation_name) { 'users_others' }
|
|
170
|
+
let(:left) { Relation::Base.new('users', header, body) }
|
|
171
|
+
let(:right) { Relation::Base.new('others', header, body) }
|
|
172
|
+
|
|
173
|
+
it_should_behave_like 'a generated SQL SELECT query'
|
|
174
|
+
|
|
175
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "others")') }
|
|
176
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "others"))') }
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
context 'when the operands have headers sorted in different orders' do
|
|
180
|
+
let(:left) { Relation::Base.new(relation_name, header, body) }
|
|
181
|
+
let(:right) { Relation::Base.new(relation_name, header.reverse, body) }
|
|
132
182
|
|
|
133
183
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
134
184
|
|
|
135
|
-
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "
|
|
136
|
-
its(:to_subquery) { should eql('(SELECT
|
|
185
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT DISTINCT "id", "name", "age" FROM "users")') }
|
|
186
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT DISTINCT "id", "name", "age" FROM "users"))') }
|
|
137
187
|
end
|
|
138
188
|
end
|
|
@@ -11,7 +11,7 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_union' do
|
|
|
11
11
|
let(:age) { Attribute::Integer.new(:age, :required => false) }
|
|
12
12
|
let(:header) { [ id, name, age ] }
|
|
13
13
|
let(:body) { [ [ 1, 'Dan Kubb', 35 ] ].each }
|
|
14
|
-
let(:base_relation) {
|
|
14
|
+
let(:base_relation) { Relation::Base.new(relation_name, header, body) }
|
|
15
15
|
let(:left) { operand }
|
|
16
16
|
let(:right) { operand }
|
|
17
17
|
let(:union) { left.union(right) }
|
|
@@ -22,8 +22,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_union' do
|
|
|
22
22
|
|
|
23
23
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
24
24
|
|
|
25
|
-
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users")')
|
|
26
|
-
its(:to_subquery) { should eql('(SELECT
|
|
25
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users")') }
|
|
26
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users"))') }
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
context 'when the operands are projections' do
|
|
@@ -31,8 +31,17 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_union' do
|
|
|
31
31
|
|
|
32
32
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
33
33
|
|
|
34
|
-
its(:to_s) { should eql('(SELECT DISTINCT "id", "name" FROM "users") UNION (SELECT DISTINCT "id", "name" FROM "users")')
|
|
35
|
-
its(:to_subquery) { should eql('(SELECT DISTINCT "id", "name" FROM "users") UNION (SELECT DISTINCT "id", "name" FROM "users")') }
|
|
34
|
+
its(:to_s) { should eql('(SELECT DISTINCT "id", "name" FROM "users") UNION (SELECT DISTINCT "id", "name" FROM "users")') }
|
|
35
|
+
its(:to_subquery) { should eql('((SELECT DISTINCT "id", "name" FROM "users") UNION (SELECT DISTINCT "id", "name" FROM "users"))') }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
context 'when the operand is an extension' do
|
|
39
|
+
let(:operand) { base_relation.extend { |r| r.add(:one, 1) } }
|
|
40
|
+
|
|
41
|
+
it_should_behave_like 'a generated SQL SELECT query'
|
|
42
|
+
|
|
43
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age", 1 AS "one" FROM "users") UNION (SELECT "id", "name", "age", 1 AS "one" FROM "users")') }
|
|
44
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age", 1 AS "one" FROM "users") UNION (SELECT "id", "name", "age", 1 AS "one" FROM "users"))') }
|
|
36
45
|
end
|
|
37
46
|
|
|
38
47
|
context 'when the operands are renames' do
|
|
@@ -40,8 +49,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_union' do
|
|
|
40
49
|
|
|
41
50
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
42
51
|
|
|
43
|
-
its(:to_s) { should eql('(SELECT "id" AS "user_id", "name", "age" FROM "users") UNION (SELECT "id" AS "user_id", "name", "age" FROM "users")')
|
|
44
|
-
its(:to_subquery) { should eql('(SELECT "id" AS "user_id", "name", "age" FROM "users") UNION (SELECT "id" AS "user_id", "name", "age" FROM "users")') }
|
|
52
|
+
its(:to_s) { should eql('(SELECT "id" AS "user_id", "name", "age" FROM "users") UNION (SELECT "id" AS "user_id", "name", "age" FROM "users")') }
|
|
53
|
+
its(:to_subquery) { should eql('((SELECT "id" AS "user_id", "name", "age" FROM "users") UNION (SELECT "id" AS "user_id", "name", "age" FROM "users"))') }
|
|
45
54
|
end
|
|
46
55
|
|
|
47
56
|
context 'when the operands are restrictions' do
|
|
@@ -49,8 +58,39 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_union' do
|
|
|
49
58
|
|
|
50
59
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
51
60
|
|
|
52
|
-
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" WHERE "id" = 1) UNION (SELECT "id", "name", "age" FROM "users" WHERE "id" = 1)')
|
|
53
|
-
its(:to_subquery) { should eql('(SELECT
|
|
61
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" WHERE "id" = 1) UNION (SELECT "id", "name", "age" FROM "users" WHERE "id" = 1)') }
|
|
62
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users" WHERE "id" = 1) UNION (SELECT "id", "name", "age" FROM "users" WHERE "id" = 1))') }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context 'when the operand is a summarization' do
|
|
66
|
+
context 'summarize per table dee' do
|
|
67
|
+
let(:summarize_per) { TABLE_DEE }
|
|
68
|
+
let(:operand) { base_relation.summarize(summarize_per) { |r| r.add(:count, r[:id].count) } }
|
|
69
|
+
|
|
70
|
+
it_should_behave_like 'a generated SQL SELECT query'
|
|
71
|
+
|
|
72
|
+
its(:to_s) { should eql('(SELECT COUNT ("id") AS "count" FROM "users") UNION (SELECT COUNT ("id") AS "count" FROM "users")') }
|
|
73
|
+
its(:to_subquery) { should eql('((SELECT COUNT ("id") AS "count" FROM "users") UNION (SELECT COUNT ("id") AS "count" FROM "users"))') }
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
context 'summarize per table dum' do
|
|
77
|
+
let(:summarize_per) { TABLE_DUM }
|
|
78
|
+
let(:operand) { base_relation.summarize(summarize_per) { |r| r.add(:count, r[:id].count) } }
|
|
79
|
+
|
|
80
|
+
it_should_behave_like 'a generated SQL SELECT query'
|
|
81
|
+
|
|
82
|
+
its(:to_s) { should eql('(SELECT COUNT ("id") AS "count" FROM "users" HAVING FALSE) UNION (SELECT COUNT ("id") AS "count" FROM "users" HAVING FALSE)') }
|
|
83
|
+
its(:to_subquery) { should eql('((SELECT COUNT ("id") AS "count" FROM "users" HAVING FALSE) UNION (SELECT COUNT ("id") AS "count" FROM "users" HAVING FALSE))') }
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
context 'summarize by a subset of the operand header' do
|
|
87
|
+
let(:operand) { base_relation.summarize([ :id, :name ]) { |r| r.add(:count, r[:age].count) } }
|
|
88
|
+
|
|
89
|
+
it_should_behave_like 'a generated SQL SELECT query'
|
|
90
|
+
|
|
91
|
+
its(:to_s) { should eql('(SELECT "id", "name", COUNT ("age") AS "count" FROM "users" GROUP BY "id", "name" HAVING COUNT (*) > 0) UNION (SELECT "id", "name", COUNT ("age") AS "count" FROM "users" GROUP BY "id", "name" HAVING COUNT (*) > 0)') }
|
|
92
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", COUNT ("age") AS "count" FROM "users" GROUP BY "id", "name" HAVING COUNT (*) > 0) UNION (SELECT "id", "name", COUNT ("age") AS "count" FROM "users" GROUP BY "id", "name" HAVING COUNT (*) > 0))') }
|
|
93
|
+
end
|
|
54
94
|
end
|
|
55
95
|
|
|
56
96
|
context 'when the operand is ordered' do
|
|
@@ -58,8 +98,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_union' do
|
|
|
58
98
|
|
|
59
99
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
60
100
|
|
|
61
|
-
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age") UNION (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age")')
|
|
62
|
-
its(:to_subquery) { should eql('(SELECT
|
|
101
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age") UNION (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age")') }
|
|
102
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age") UNION (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age"))') }
|
|
63
103
|
end
|
|
64
104
|
|
|
65
105
|
context 'when the operand is reversed' do
|
|
@@ -67,8 +107,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_union' do
|
|
|
67
107
|
|
|
68
108
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
69
109
|
|
|
70
|
-
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC) UNION (SELECT "id", "name", "age" FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC)')
|
|
71
|
-
its(:to_subquery) { should eql('(SELECT
|
|
110
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC) UNION (SELECT "id", "name", "age" FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC)') }
|
|
111
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC) UNION (SELECT "id", "name", "age" FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC))') }
|
|
72
112
|
end
|
|
73
113
|
|
|
74
114
|
context 'when the operand is limited' do
|
|
@@ -76,8 +116,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_union' do
|
|
|
76
116
|
|
|
77
117
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
78
118
|
|
|
79
|
-
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1) UNION (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1)')
|
|
80
|
-
its(:to_subquery) { should eql('(SELECT
|
|
119
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1) UNION (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1)') }
|
|
120
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1) UNION (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1))') }
|
|
81
121
|
end
|
|
82
122
|
|
|
83
123
|
context 'when the operands are offsets' do
|
|
@@ -85,8 +125,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_union' do
|
|
|
85
125
|
|
|
86
126
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
87
127
|
|
|
88
|
-
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1) UNION (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1)')
|
|
89
|
-
its(:to_subquery) { should eql('(SELECT
|
|
128
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1) UNION (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1)') }
|
|
129
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1) UNION (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1))') }
|
|
90
130
|
end
|
|
91
131
|
|
|
92
132
|
context 'when the operands are differences' do
|
|
@@ -94,8 +134,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_union' do
|
|
|
94
134
|
|
|
95
135
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
96
136
|
|
|
97
|
-
its(:to_s) { should eql('((SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "users")) UNION ((SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "users"))')
|
|
98
|
-
its(:to_subquery) { should eql('((SELECT
|
|
137
|
+
its(:to_s) { should eql('((SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "users")) UNION ((SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "users"))') }
|
|
138
|
+
its(:to_subquery) { should eql('(((SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "users")) UNION ((SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "users")))') }
|
|
99
139
|
end
|
|
100
140
|
|
|
101
141
|
context 'when the operands are intersections' do
|
|
@@ -103,8 +143,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_union' do
|
|
|
103
143
|
|
|
104
144
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
105
145
|
|
|
106
|
-
its(:to_s) { should eql('((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users")) UNION ((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users"))')
|
|
107
|
-
its(:to_subquery) { should eql('((SELECT
|
|
146
|
+
its(:to_s) { should eql('((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users")) UNION ((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users"))') }
|
|
147
|
+
its(:to_subquery) { should eql('(((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users")) UNION ((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users")))') }
|
|
108
148
|
end
|
|
109
149
|
|
|
110
150
|
context 'when the operands are unions' do
|
|
@@ -112,8 +152,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_union' do
|
|
|
112
152
|
|
|
113
153
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
114
154
|
|
|
115
|
-
its(:to_s) { should eql('((SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users")) UNION ((SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users"))')
|
|
116
|
-
its(:to_subquery) { should eql('((SELECT
|
|
155
|
+
its(:to_s) { should eql('((SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users")) UNION ((SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users"))') }
|
|
156
|
+
its(:to_subquery) { should eql('(((SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users")) UNION ((SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users")))') }
|
|
117
157
|
end
|
|
118
158
|
|
|
119
159
|
context 'when the operands are joins' do
|
|
@@ -121,18 +161,28 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_union' do
|
|
|
121
161
|
|
|
122
162
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
123
163
|
|
|
124
|
-
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" NATURAL JOIN "users") UNION (SELECT "id", "name", "age" FROM "users" NATURAL JOIN "users")')
|
|
125
|
-
its(:to_subquery) { should eql('(SELECT
|
|
164
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" AS "left" NATURAL JOIN "users" AS "right") UNION (SELECT "id", "name", "age" FROM "users" AS "left" NATURAL JOIN "users" AS "right")') }
|
|
165
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users" AS "left" NATURAL JOIN "users" AS "right") UNION (SELECT "id", "name", "age" FROM "users" AS "left" NATURAL JOIN "users" AS "right"))') }
|
|
126
166
|
end
|
|
127
167
|
|
|
128
168
|
context 'when the operands have different base relations' do
|
|
129
|
-
let(:relation_name) { 'users_others'
|
|
130
|
-
let(:left) {
|
|
131
|
-
let(:right) {
|
|
169
|
+
let(:relation_name) { 'users_others' }
|
|
170
|
+
let(:left) { Relation::Base.new('users', header, body) }
|
|
171
|
+
let(:right) { Relation::Base.new('others', header, body) }
|
|
172
|
+
|
|
173
|
+
it_should_behave_like 'a generated SQL SELECT query'
|
|
174
|
+
|
|
175
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "others")') }
|
|
176
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "others"))') }
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
context 'when the operands have headers sorted in different orders' do
|
|
180
|
+
let(:left) { Relation::Base.new(relation_name, header, body) }
|
|
181
|
+
let(:right) { Relation::Base.new(relation_name, header.reverse, body) }
|
|
132
182
|
|
|
133
183
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
134
184
|
|
|
135
|
-
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "
|
|
136
|
-
its(:to_subquery) { should eql('(SELECT
|
|
185
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users") UNION (SELECT DISTINCT "id", "name", "age" FROM "users")') }
|
|
186
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users") UNION (SELECT DISTINCT "id", "name", "age" FROM "users"))') }
|
|
137
187
|
end
|
|
138
188
|
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe SQL::Generator::Relation, '#to_s' do
|
|
6
|
+
subject { object.to_s }
|
|
7
|
+
|
|
8
|
+
let(:described_class) { Class.new(SQL::Generator::Relation) }
|
|
9
|
+
let(:id) { Attribute::Integer.new(:id) }
|
|
10
|
+
let(:name) { Attribute::String.new(:name) }
|
|
11
|
+
let(:age) { Attribute::Integer.new(:age, :required => false) }
|
|
12
|
+
let(:header) { [ id, name, age ] }
|
|
13
|
+
let(:body) { [ [ 1, 'Dan Kubb', 35 ] ].each }
|
|
14
|
+
let(:base_relation) { Relation::Base.new('users', header, body) }
|
|
15
|
+
let(:object) { described_class.new }
|
|
16
|
+
|
|
17
|
+
context 'when no object visited' do
|
|
18
|
+
it_should_behave_like 'an idempotent method'
|
|
19
|
+
|
|
20
|
+
it { should respond_to(:to_s) }
|
|
21
|
+
|
|
22
|
+
it { should be_frozen }
|
|
23
|
+
|
|
24
|
+
its(:to_s) { should == '' }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
context 'when an object is visited' do
|
|
28
|
+
let(:visitable) { mock('Visitable') }
|
|
29
|
+
|
|
30
|
+
before do
|
|
31
|
+
described_class.class_eval do
|
|
32
|
+
def visit_spec_mocks_mock(mock)
|
|
33
|
+
@name = mock.instance_variable_get(:@name)
|
|
34
|
+
@distinct = 'DISTINCT'
|
|
35
|
+
@scope = Set.new
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def generate_sql(columns)
|
|
39
|
+
"SELECT #{columns} FROM #{@name}"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
object.visit(visitable)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it_should_behave_like 'a generated SQL expression'
|
|
47
|
+
|
|
48
|
+
its(:to_s) { should eql('SELECT DISTINCT FROM Visitable') }
|
|
49
|
+
end
|
|
50
|
+
end
|