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
|
@@ -12,8 +12,8 @@ describe SQL::Generator::Relation::Binary, '#visit_veritas_algebra_product' do
|
|
|
12
12
|
let(:header) { [ id, name, age ] }
|
|
13
13
|
let(:other_header) { [ id.rename(:other_id), name.rename(:other_name), age.rename(:other_age) ] }
|
|
14
14
|
let(:body) { [ [ 1, 'Dan Kubb', 35 ] ].each }
|
|
15
|
-
let(:users) {
|
|
16
|
-
let(:other) {
|
|
15
|
+
let(:users) { Relation::Base.new('users', header, body) }
|
|
16
|
+
let(:other) { Relation::Base.new('other', other_header, body) }
|
|
17
17
|
let(:product) { left.product(right) }
|
|
18
18
|
let(:object) { described_class.new }
|
|
19
19
|
|
|
@@ -23,8 +23,8 @@ describe SQL::Generator::Relation::Binary, '#visit_veritas_algebra_product' do
|
|
|
23
23
|
|
|
24
24
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
25
25
|
|
|
26
|
-
its(:to_s) { should eql('SELECT "id", "name", "age", "other_id", "other_name", "other_age" FROM "users" CROSS JOIN "other"') }
|
|
27
|
-
its(:to_subquery) { should eql('SELECT * FROM "users" CROSS JOIN "other"')
|
|
26
|
+
its(:to_s) { should eql('SELECT "id", "name", "age", "other_id", "other_name", "other_age" FROM "users" AS "left" CROSS JOIN "other" AS "right"') }
|
|
27
|
+
its(:to_subquery) { should eql('(SELECT * FROM "users" AS "left" CROSS JOIN "other" AS "right")') }
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
context 'when the operands are a projection' do
|
|
@@ -34,7 +34,17 @@ describe SQL::Generator::Relation::Binary, '#visit_veritas_algebra_product' do
|
|
|
34
34
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
35
35
|
|
|
36
36
|
its(:to_s) { should eql('SELECT "id", "name", "other_id", "other_name" FROM (SELECT DISTINCT "id", "name" FROM "users") AS "left" CROSS JOIN (SELECT DISTINCT "other_id", "other_name" FROM "other") AS "right"') }
|
|
37
|
-
its(:to_subquery) { should eql('SELECT * FROM (SELECT DISTINCT "id", "name" FROM "users") AS "left" CROSS JOIN (SELECT DISTINCT "other_id", "other_name" FROM "other") AS "right"')
|
|
37
|
+
its(:to_subquery) { should eql('(SELECT * FROM (SELECT DISTINCT "id", "name" FROM "users") AS "left" CROSS JOIN (SELECT DISTINCT "other_id", "other_name" FROM "other") AS "right")') }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
context 'when the operand is an extension' do
|
|
41
|
+
let(:left) { users.extend { |r| r.add(:one, 1) } }
|
|
42
|
+
let(:right) { other.extend { |r| r.add(:two, 2) } }
|
|
43
|
+
|
|
44
|
+
it_should_behave_like 'a generated SQL SELECT query'
|
|
45
|
+
|
|
46
|
+
its(:to_s) { should eql('SELECT "id", "name", "age", "one", "other_id", "other_name", "other_age", "two" FROM (SELECT *, 1 AS "one" FROM "users") AS "left" CROSS JOIN (SELECT *, 2 AS "two" FROM "other") AS "right"') }
|
|
47
|
+
its(:to_subquery) { should eql('(SELECT * FROM (SELECT *, 1 AS "one" FROM "users") AS "left" CROSS JOIN (SELECT *, 2 AS "two" FROM "other") AS "right")') }
|
|
38
48
|
end
|
|
39
49
|
|
|
40
50
|
context 'when the operand is a rename' do
|
|
@@ -44,7 +54,7 @@ describe SQL::Generator::Relation::Binary, '#visit_veritas_algebra_product' do
|
|
|
44
54
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
45
55
|
|
|
46
56
|
its(:to_s) { should eql('SELECT "user_id", "name", "age", "other_user_id", "other_name", "other_age" FROM (SELECT "id" AS "user_id", "name", "age" FROM "users") AS "left" CROSS JOIN (SELECT "other_id" AS "other_user_id", "other_name", "other_age" FROM "other") AS "right"') }
|
|
47
|
-
its(:to_subquery) { should eql('SELECT * FROM (SELECT "id" AS "user_id", "name", "age" FROM "users") AS "left" CROSS JOIN (SELECT "other_id" AS "other_user_id", "other_name", "other_age" FROM "other") AS "right"')
|
|
57
|
+
its(:to_subquery) { should eql('(SELECT * FROM (SELECT "id" AS "user_id", "name", "age" FROM "users") AS "left" CROSS JOIN (SELECT "other_id" AS "other_user_id", "other_name", "other_age" FROM "other") AS "right")') }
|
|
48
58
|
end
|
|
49
59
|
|
|
50
60
|
context 'when the operand is a restriction' do
|
|
@@ -54,7 +64,41 @@ describe SQL::Generator::Relation::Binary, '#visit_veritas_algebra_product' do
|
|
|
54
64
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
55
65
|
|
|
56
66
|
its(:to_s) { should eql('SELECT "id", "name", "age", "other_id", "other_name", "other_age" FROM (SELECT * FROM "users" WHERE "id" = 1) AS "left" CROSS JOIN (SELECT * FROM "other" WHERE "other_id" = 1) AS "right"') }
|
|
57
|
-
its(:to_subquery) { should eql('SELECT * FROM (SELECT * FROM "users" WHERE "id" = 1) AS "left" CROSS JOIN (SELECT * FROM "other" WHERE "other_id" = 1) AS "right"')
|
|
67
|
+
its(:to_subquery) { should eql('(SELECT * FROM (SELECT * FROM "users" WHERE "id" = 1) AS "left" CROSS JOIN (SELECT * FROM "other" WHERE "other_id" = 1) AS "right")') }
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
context 'when the operand is a summarization' do
|
|
71
|
+
context 'summarize per table dee' do
|
|
72
|
+
let(:summarize_per) { TABLE_DEE }
|
|
73
|
+
let(:left) { users.summarize(summarize_per) { |r| r.add(:count, r[:id].count) } }
|
|
74
|
+
let(:right) { other.summarize(summarize_per) { |r| r.add(:other_count, r[:other_id].count) } }
|
|
75
|
+
|
|
76
|
+
it_should_behave_like 'a generated SQL SELECT query'
|
|
77
|
+
|
|
78
|
+
its(:to_s) { should eql('SELECT "count", "other_count" FROM (SELECT COUNT ("id") AS "count" FROM "users") AS "left" CROSS JOIN (SELECT COUNT ("other_id") AS "other_count" FROM "other") AS "right"') }
|
|
79
|
+
its(:to_subquery) { should eql('(SELECT * FROM (SELECT COUNT ("id") AS "count" FROM "users") AS "left" CROSS JOIN (SELECT COUNT ("other_id") AS "other_count" FROM "other") AS "right")') }
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
context 'summarize per table dum' do
|
|
83
|
+
let(:summarize_per) { TABLE_DUM }
|
|
84
|
+
let(:left) { users.summarize(summarize_per) { |r| r.add(:count, r[:id].count) } }
|
|
85
|
+
let(:right) { other.summarize(summarize_per) { |r| r.add(:other_count, r[:other_id].count) } }
|
|
86
|
+
|
|
87
|
+
it_should_behave_like 'a generated SQL SELECT query'
|
|
88
|
+
|
|
89
|
+
its(:to_s) { should eql('SELECT "count", "other_count" FROM (SELECT COUNT ("id") AS "count" FROM "users" HAVING FALSE) AS "left" CROSS JOIN (SELECT COUNT ("other_id") AS "other_count" FROM "other" HAVING FALSE) AS "right"') }
|
|
90
|
+
its(:to_subquery) { should eql('(SELECT * FROM (SELECT COUNT ("id") AS "count" FROM "users" HAVING FALSE) AS "left" CROSS JOIN (SELECT COUNT ("other_id") AS "other_count" FROM "other" HAVING FALSE) AS "right")') }
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
context 'summarize by a subset of the operand header' do
|
|
94
|
+
let(:left) { users.summarize([ :id, :name ]) { |r| r.add(:count, r[:age].count) } }
|
|
95
|
+
let(:right) { other.summarize([ :other_id, :other_name ]) { |r| r.add(:other_count, r[:other_age].count) } }
|
|
96
|
+
|
|
97
|
+
it_should_behave_like 'a generated SQL SELECT query'
|
|
98
|
+
|
|
99
|
+
its(:to_s) { should eql('SELECT "id", "name", "count", "other_id", "other_name", "other_count" FROM (SELECT "id", "name", COUNT ("age") AS "count" FROM "users" GROUP BY "id", "name" HAVING COUNT (*) > 0) AS "left" CROSS JOIN (SELECT "other_id", "other_name", COUNT ("other_age") AS "other_count" FROM "other" GROUP BY "other_id", "other_name" HAVING COUNT (*) > 0) AS "right"') }
|
|
100
|
+
its(:to_subquery) { should eql('(SELECT * FROM (SELECT "id", "name", COUNT ("age") AS "count" FROM "users" GROUP BY "id", "name" HAVING COUNT (*) > 0) AS "left" CROSS JOIN (SELECT "other_id", "other_name", COUNT ("other_age") AS "other_count" FROM "other" GROUP BY "other_id", "other_name" HAVING COUNT (*) > 0) AS "right")') }
|
|
101
|
+
end
|
|
58
102
|
end
|
|
59
103
|
|
|
60
104
|
context 'when the operand is ordered' do
|
|
@@ -64,7 +108,7 @@ describe SQL::Generator::Relation::Binary, '#visit_veritas_algebra_product' do
|
|
|
64
108
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
65
109
|
|
|
66
110
|
its(:to_s) { should eql('SELECT "id", "name", "age", "other_id", "other_name", "other_age" FROM (SELECT * FROM "users" ORDER BY "id", "name", "age") AS "left" CROSS JOIN (SELECT * FROM "other" ORDER BY "other_id", "other_name", "other_age") AS "right"') }
|
|
67
|
-
its(:to_subquery) { should eql('SELECT * FROM (SELECT * FROM "users" ORDER BY "id", "name", "age") AS "left" CROSS JOIN (SELECT * FROM "other" ORDER BY "other_id", "other_name", "other_age") AS "right"')
|
|
111
|
+
its(:to_subquery) { should eql('(SELECT * FROM (SELECT * FROM "users" ORDER BY "id", "name", "age") AS "left" CROSS JOIN (SELECT * FROM "other" ORDER BY "other_id", "other_name", "other_age") AS "right")') }
|
|
68
112
|
end
|
|
69
113
|
|
|
70
114
|
context 'when the operand is reversed' do
|
|
@@ -74,7 +118,7 @@ describe SQL::Generator::Relation::Binary, '#visit_veritas_algebra_product' do
|
|
|
74
118
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
75
119
|
|
|
76
120
|
its(:to_s) { should eql('SELECT "id", "name", "age", "other_id", "other_name", "other_age" FROM (SELECT * FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC) AS "left" CROSS JOIN (SELECT * FROM "other" ORDER BY "other_id" DESC, "other_name" DESC, "other_age" DESC) AS "right"') }
|
|
77
|
-
its(:to_subquery) { should eql('SELECT * FROM (SELECT * FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC) AS "left" CROSS JOIN (SELECT * FROM "other" ORDER BY "other_id" DESC, "other_name" DESC, "other_age" DESC) AS "right"')
|
|
121
|
+
its(:to_subquery) { should eql('(SELECT * FROM (SELECT * FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC) AS "left" CROSS JOIN (SELECT * FROM "other" ORDER BY "other_id" DESC, "other_name" DESC, "other_age" DESC) AS "right")') }
|
|
78
122
|
end
|
|
79
123
|
|
|
80
124
|
context 'when the operand is limited' do
|
|
@@ -84,7 +128,7 @@ describe SQL::Generator::Relation::Binary, '#visit_veritas_algebra_product' do
|
|
|
84
128
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
85
129
|
|
|
86
130
|
its(:to_s) { should eql('SELECT "id", "name", "age", "other_id", "other_name", "other_age" FROM (SELECT * FROM "users" ORDER BY "id", "name", "age" LIMIT 1) AS "left" CROSS JOIN (SELECT * FROM "other" ORDER BY "other_id", "other_name", "other_age" LIMIT 1) AS "right"') }
|
|
87
|
-
its(:to_subquery) { should eql('SELECT * FROM (SELECT * FROM "users" ORDER BY "id", "name", "age" LIMIT 1) AS "left" CROSS JOIN (SELECT * FROM "other" ORDER BY "other_id", "other_name", "other_age" LIMIT 1) AS "right"')
|
|
131
|
+
its(:to_subquery) { should eql('(SELECT * FROM (SELECT * FROM "users" ORDER BY "id", "name", "age" LIMIT 1) AS "left" CROSS JOIN (SELECT * FROM "other" ORDER BY "other_id", "other_name", "other_age" LIMIT 1) AS "right")') }
|
|
88
132
|
end
|
|
89
133
|
|
|
90
134
|
context 'when the operand is an offset' do
|
|
@@ -94,7 +138,7 @@ describe SQL::Generator::Relation::Binary, '#visit_veritas_algebra_product' do
|
|
|
94
138
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
95
139
|
|
|
96
140
|
its(:to_s) { should eql('SELECT "id", "name", "age", "other_id", "other_name", "other_age" FROM (SELECT * FROM "users" ORDER BY "id", "name", "age" OFFSET 1) AS "left" CROSS JOIN (SELECT * FROM "other" ORDER BY "other_id", "other_name", "other_age" OFFSET 1) AS "right"') }
|
|
97
|
-
its(:to_subquery) { should eql('SELECT * FROM (SELECT * FROM "users" ORDER BY "id", "name", "age" OFFSET 1) AS "left" CROSS JOIN (SELECT * FROM "other" ORDER BY "other_id", "other_name", "other_age" OFFSET 1) AS "right"')
|
|
141
|
+
its(:to_subquery) { should eql('(SELECT * FROM (SELECT * FROM "users" ORDER BY "id", "name", "age" OFFSET 1) AS "left" CROSS JOIN (SELECT * FROM "other" ORDER BY "other_id", "other_name", "other_age" OFFSET 1) AS "right")') }
|
|
98
142
|
end
|
|
99
143
|
|
|
100
144
|
context 'when the operand is a difference' do
|
|
@@ -103,8 +147,8 @@ describe SQL::Generator::Relation::Binary, '#visit_veritas_algebra_product' do
|
|
|
103
147
|
|
|
104
148
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
105
149
|
|
|
106
|
-
its(:to_s) { should eql('SELECT "id", "name", "age", "other_id", "other_name", "other_age" FROM ((SELECT
|
|
107
|
-
its(:to_subquery) { should eql('SELECT * FROM ((SELECT
|
|
150
|
+
its(:to_s) { should eql('SELECT "id", "name", "age", "other_id", "other_name", "other_age" FROM ((SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "users")) AS "left" CROSS JOIN ((SELECT "other_id", "other_name", "other_age" FROM "other") EXCEPT (SELECT "other_id", "other_name", "other_age" FROM "other")) AS "right"') }
|
|
151
|
+
its(:to_subquery) { should eql('(SELECT * FROM ((SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "users")) AS "left" CROSS JOIN ((SELECT "other_id", "other_name", "other_age" FROM "other") EXCEPT (SELECT "other_id", "other_name", "other_age" FROM "other")) AS "right")') }
|
|
108
152
|
end
|
|
109
153
|
|
|
110
154
|
context 'when the operand is a intersection' do
|
|
@@ -113,8 +157,8 @@ describe SQL::Generator::Relation::Binary, '#visit_veritas_algebra_product' do
|
|
|
113
157
|
|
|
114
158
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
115
159
|
|
|
116
|
-
its(:to_s) { should eql('SELECT "id", "name", "age", "other_id", "other_name", "other_age" FROM ((SELECT
|
|
117
|
-
its(:to_subquery) { should eql('SELECT * FROM ((SELECT
|
|
160
|
+
its(:to_s) { should eql('SELECT "id", "name", "age", "other_id", "other_name", "other_age" FROM ((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users")) AS "left" CROSS JOIN ((SELECT "other_id", "other_name", "other_age" FROM "other") INTERSECT (SELECT "other_id", "other_name", "other_age" FROM "other")) AS "right"') }
|
|
161
|
+
its(:to_subquery) { should eql('(SELECT * FROM ((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users")) AS "left" CROSS JOIN ((SELECT "other_id", "other_name", "other_age" FROM "other") INTERSECT (SELECT "other_id", "other_name", "other_age" FROM "other")) AS "right")') }
|
|
118
162
|
end
|
|
119
163
|
|
|
120
164
|
context 'when the operand is a union' do
|
|
@@ -123,8 +167,8 @@ describe SQL::Generator::Relation::Binary, '#visit_veritas_algebra_product' do
|
|
|
123
167
|
|
|
124
168
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
125
169
|
|
|
126
|
-
its(:to_s) { should eql('SELECT "id", "name", "age", "other_id", "other_name", "other_age" FROM ((SELECT
|
|
127
|
-
its(:to_subquery) { should eql('SELECT * FROM ((SELECT
|
|
170
|
+
its(:to_s) { should eql('SELECT "id", "name", "age", "other_id", "other_name", "other_age" FROM ((SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users")) AS "left" CROSS JOIN ((SELECT "other_id", "other_name", "other_age" FROM "other") UNION (SELECT "other_id", "other_name", "other_age" FROM "other")) AS "right"') }
|
|
171
|
+
its(:to_subquery) { should eql('(SELECT * FROM ((SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users")) AS "left" CROSS JOIN ((SELECT "other_id", "other_name", "other_age" FROM "other") UNION (SELECT "other_id", "other_name", "other_age" FROM "other")) AS "right")') }
|
|
128
172
|
end
|
|
129
173
|
|
|
130
174
|
context 'when the operand is a join' do
|
|
@@ -133,7 +177,7 @@ describe SQL::Generator::Relation::Binary, '#visit_veritas_algebra_product' do
|
|
|
133
177
|
|
|
134
178
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
135
179
|
|
|
136
|
-
its(:to_s) { should eql('SELECT "id", "name", "age", "other_id", "other_name", "other_age" FROM (SELECT * FROM "users" NATURAL JOIN "users") AS "left" CROSS JOIN (SELECT * FROM "other" NATURAL JOIN "other") AS "right"') }
|
|
137
|
-
its(:to_subquery) { should eql('SELECT * FROM (SELECT * FROM "users" NATURAL JOIN "users") AS "left" CROSS JOIN (SELECT * FROM "other" NATURAL JOIN "other") AS "right"')
|
|
180
|
+
its(:to_s) { should eql('SELECT "id", "name", "age", "other_id", "other_name", "other_age" FROM (SELECT * FROM "users" AS "left" NATURAL JOIN "users" AS "right") AS "left" CROSS JOIN (SELECT * FROM "other" AS "left" NATURAL JOIN "other" AS "right") AS "right"') }
|
|
181
|
+
its(:to_subquery) { should eql('(SELECT * FROM (SELECT * FROM "users" AS "left" NATURAL JOIN "users" AS "right") AS "left" CROSS JOIN (SELECT * FROM "other" AS "left" NATURAL JOIN "other" AS "right") AS "right")') }
|
|
138
182
|
end
|
|
139
183
|
end
|
|
@@ -10,7 +10,7 @@ describe SQL::Generator::Relation, '.visit' do
|
|
|
10
10
|
let(:age) { Attribute::Integer.new(:age, :required => false) }
|
|
11
11
|
let(:header) { [ id, name, age ] }
|
|
12
12
|
let(:body) { [ [ 1, 'Dan Kubb', 35 ] ].each }
|
|
13
|
-
let(:base_relation) {
|
|
13
|
+
let(:base_relation) { Relation::Base.new('users', header, body) }
|
|
14
14
|
let(:object) { described_class }
|
|
15
15
|
|
|
16
16
|
context 'when the relation is a set operation' do
|
data/spec/unit/veritas/sql/generator/relation/set/class_methods/normalize_operand_headers_spec.rb
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe SQL::Generator::Relation::Set, '.normalize_operand_headers' do
|
|
6
|
+
subject { object.normalize_operand_headers(relation) }
|
|
7
|
+
|
|
8
|
+
let(:object) { described_class }
|
|
9
|
+
let(:relation) { left.union(right) }
|
|
10
|
+
let(:relation_name) { 'test' }
|
|
11
|
+
let(:header) { [ [ :id, Integer, ], [ :name, String ] ] }
|
|
12
|
+
let(:body) { [].each }
|
|
13
|
+
|
|
14
|
+
context 'when the left and right headers are sorted in the same order' do
|
|
15
|
+
let(:left) { Relation::Base.new(relation_name, header, body) }
|
|
16
|
+
let(:right) { Relation::Base.new(relation_name, header, body) }
|
|
17
|
+
|
|
18
|
+
it { should equal(relation) }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context 'when the left and right headers are sorted in different order' do
|
|
22
|
+
let(:left) { Relation::Base.new(relation_name, header, body) }
|
|
23
|
+
let(:right) { Relation::Base.new(relation_name, header.reverse, body) }
|
|
24
|
+
|
|
25
|
+
it { should_not equal(relation) }
|
|
26
|
+
|
|
27
|
+
its(:right) { should_not equal(right) }
|
|
28
|
+
|
|
29
|
+
it { should be_kind_of(relation.class) }
|
|
30
|
+
|
|
31
|
+
its(:left) { should equal(left) }
|
|
32
|
+
|
|
33
|
+
its(:right) { should eql(right.project(header)) }
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -10,7 +10,7 @@ describe SQL::Generator::Relation::Set, '#to_s' do
|
|
|
10
10
|
let(:age) { Attribute::Integer.new(:age, :required => false) }
|
|
11
11
|
let(:header) { [ id, name, age ] }
|
|
12
12
|
let(:body) { [ [ 1, 'Dan Kubb', 35 ] ].each }
|
|
13
|
-
let(:base_relation) {
|
|
13
|
+
let(:base_relation) { Relation::Base.new('users', header, body) }
|
|
14
14
|
let(:object) { described_class.new }
|
|
15
15
|
|
|
16
16
|
context 'when no object visited' do
|
|
@@ -10,7 +10,7 @@ describe SQL::Generator::Relation::Set, '#to_subquery' do
|
|
|
10
10
|
let(:age) { Attribute::Integer.new(:age, :required => false) }
|
|
11
11
|
let(:header) { [ id, name, age ] }
|
|
12
12
|
let(:body) { [ [ 1, 'Dan Kubb', 35 ] ].each }
|
|
13
|
-
let(:base_relation) {
|
|
13
|
+
let(:base_relation) { Relation::Base.new('users', header, body) }
|
|
14
14
|
let(:object) { described_class.new }
|
|
15
15
|
|
|
16
16
|
context 'when no object visited' do
|
|
@@ -30,7 +30,7 @@ describe SQL::Generator::Relation::Set, '#to_subquery' do
|
|
|
30
30
|
|
|
31
31
|
it_should_behave_like 'a generated SQL expression'
|
|
32
32
|
|
|
33
|
-
its(:to_s) { should eql('(SELECT
|
|
33
|
+
its(:to_s) { should eql('((SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "users"))') }
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
context 'when an intersection is visited' do
|
|
@@ -40,7 +40,7 @@ describe SQL::Generator::Relation::Set, '#to_subquery' do
|
|
|
40
40
|
|
|
41
41
|
it_should_behave_like 'a generated SQL expression'
|
|
42
42
|
|
|
43
|
-
its(:to_s) { should eql('(SELECT
|
|
43
|
+
its(:to_s) { should eql('((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users"))') }
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
context 'when a union is visited' do
|
|
@@ -50,6 +50,6 @@ describe SQL::Generator::Relation::Set, '#to_subquery' do
|
|
|
50
50
|
|
|
51
51
|
it_should_behave_like 'a generated SQL expression'
|
|
52
52
|
|
|
53
|
-
its(:to_s) { should eql('(SELECT
|
|
53
|
+
its(:to_s) { should eql('((SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users"))') }
|
|
54
54
|
end
|
|
55
55
|
end
|
|
@@ -11,7 +11,7 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_difference' 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(:difference) { left.difference(right) }
|
|
@@ -22,8 +22,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_difference' 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") EXCEPT (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") EXCEPT (SELECT "id", "name", "age" FROM "users")') }
|
|
26
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users") EXCEPT (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_difference' 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") EXCEPT (SELECT DISTINCT "id", "name" FROM "users")')
|
|
35
|
-
its(:to_subquery) { should eql('(SELECT DISTINCT "id", "name" FROM "users") EXCEPT (SELECT DISTINCT "id", "name" FROM "users")') }
|
|
34
|
+
its(:to_s) { should eql('(SELECT DISTINCT "id", "name" FROM "users") EXCEPT (SELECT DISTINCT "id", "name" FROM "users")') }
|
|
35
|
+
its(:to_subquery) { should eql('((SELECT DISTINCT "id", "name" FROM "users") EXCEPT (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") EXCEPT (SELECT "id", "name", "age", 1 AS "one" FROM "users")') }
|
|
44
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age", 1 AS "one" FROM "users") EXCEPT (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_difference' 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") EXCEPT (SELECT "id" AS "user_id", "name", "age" FROM "users")')
|
|
44
|
-
its(:to_subquery) { should eql('(SELECT "id" AS "user_id", "name", "age" FROM "users") EXCEPT (SELECT "id" AS "user_id", "name", "age" FROM "users")') }
|
|
52
|
+
its(:to_s) { should eql('(SELECT "id" AS "user_id", "name", "age" FROM "users") EXCEPT (SELECT "id" AS "user_id", "name", "age" FROM "users")') }
|
|
53
|
+
its(:to_subquery) { should eql('((SELECT "id" AS "user_id", "name", "age" FROM "users") EXCEPT (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,42 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_difference' 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) EXCEPT (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) EXCEPT (SELECT "id", "name", "age" FROM "users" WHERE "id" = 1)') }
|
|
62
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users" WHERE "id" = 1) EXCEPT (SELECT "id", "name", "age" FROM "users" WHERE "id" = 1))') }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context 'when the operand is a summarization' do
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
context 'when the operand is a summarization' do
|
|
69
|
+
context 'summarize per table dee' do
|
|
70
|
+
let(:summarize_per) { TABLE_DEE }
|
|
71
|
+
let(:operand) { base_relation.summarize(summarize_per) { |r| r.add(:count, r[:id].count) } }
|
|
72
|
+
|
|
73
|
+
it_should_behave_like 'a generated SQL SELECT query'
|
|
74
|
+
|
|
75
|
+
its(:to_s) { should eql('(SELECT COUNT ("id") AS "count" FROM "users") EXCEPT (SELECT COUNT ("id") AS "count" FROM "users")') }
|
|
76
|
+
its(:to_subquery) { should eql('((SELECT COUNT ("id") AS "count" FROM "users") EXCEPT (SELECT COUNT ("id") AS "count" FROM "users"))') }
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
context 'summarize per table dum' do
|
|
80
|
+
let(:summarize_per) { TABLE_DUM }
|
|
81
|
+
let(:operand) { base_relation.summarize(summarize_per) { |r| r.add(:count, r[:id].count) } }
|
|
82
|
+
|
|
83
|
+
it_should_behave_like 'a generated SQL SELECT query'
|
|
84
|
+
|
|
85
|
+
its(:to_s) { should eql('(SELECT COUNT ("id") AS "count" FROM "users" HAVING FALSE) EXCEPT (SELECT COUNT ("id") AS "count" FROM "users" HAVING FALSE)') }
|
|
86
|
+
its(:to_subquery) { should eql('((SELECT COUNT ("id") AS "count" FROM "users" HAVING FALSE) EXCEPT (SELECT COUNT ("id") AS "count" FROM "users" HAVING FALSE))') }
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
context 'summarize by a subset of the operand header' do
|
|
90
|
+
let(:operand) { base_relation.summarize([ :id, :name ]) { |r| r.add(:count, r[:age].count) } }
|
|
91
|
+
|
|
92
|
+
it_should_behave_like 'a generated SQL SELECT query'
|
|
93
|
+
|
|
94
|
+
its(:to_s) { should eql('(SELECT "id", "name", COUNT ("age") AS "count" FROM "users" GROUP BY "id", "name" HAVING COUNT (*) > 0) EXCEPT (SELECT "id", "name", COUNT ("age") AS "count" FROM "users" GROUP BY "id", "name" HAVING COUNT (*) > 0)') }
|
|
95
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", COUNT ("age") AS "count" FROM "users" GROUP BY "id", "name" HAVING COUNT (*) > 0) EXCEPT (SELECT "id", "name", COUNT ("age") AS "count" FROM "users" GROUP BY "id", "name" HAVING COUNT (*) > 0))') }
|
|
96
|
+
end
|
|
54
97
|
end
|
|
55
98
|
|
|
56
99
|
context 'when the operand is ordered' do
|
|
@@ -58,8 +101,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_difference' do
|
|
|
58
101
|
|
|
59
102
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
60
103
|
|
|
61
|
-
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age") EXCEPT (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age")')
|
|
62
|
-
its(:to_subquery) { should eql('(SELECT
|
|
104
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age") EXCEPT (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age")') }
|
|
105
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age") EXCEPT (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age"))') }
|
|
63
106
|
end
|
|
64
107
|
|
|
65
108
|
context 'when the operand is reversed' do
|
|
@@ -67,8 +110,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_difference' do
|
|
|
67
110
|
|
|
68
111
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
69
112
|
|
|
70
|
-
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC) EXCEPT (SELECT "id", "name", "age" FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC)')
|
|
71
|
-
its(:to_subquery) { should eql('(SELECT
|
|
113
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC) EXCEPT (SELECT "id", "name", "age" FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC)') }
|
|
114
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC) EXCEPT (SELECT "id", "name", "age" FROM "users" ORDER BY "id" DESC, "name" DESC, "age" DESC))') }
|
|
72
115
|
end
|
|
73
116
|
|
|
74
117
|
context 'when the operand is limited' do
|
|
@@ -76,8 +119,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_difference' do
|
|
|
76
119
|
|
|
77
120
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
78
121
|
|
|
79
|
-
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1) EXCEPT (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1)')
|
|
80
|
-
its(:to_subquery) { should eql('(SELECT
|
|
122
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1) EXCEPT (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1)') }
|
|
123
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1) EXCEPT (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" LIMIT 1))') }
|
|
81
124
|
end
|
|
82
125
|
|
|
83
126
|
context 'when the operands are offsets' do
|
|
@@ -85,8 +128,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_difference' do
|
|
|
85
128
|
|
|
86
129
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
87
130
|
|
|
88
|
-
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1) EXCEPT (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1)')
|
|
89
|
-
its(:to_subquery) { should eql('(SELECT
|
|
131
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1) EXCEPT (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1)') }
|
|
132
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1) EXCEPT (SELECT "id", "name", "age" FROM "users" ORDER BY "id", "name", "age" OFFSET 1))') }
|
|
90
133
|
end
|
|
91
134
|
|
|
92
135
|
context 'when the operands are differences' do
|
|
@@ -94,8 +137,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_difference' do
|
|
|
94
137
|
|
|
95
138
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
96
139
|
|
|
97
|
-
its(:to_s) { should eql('((SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "users")) EXCEPT ((SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "users"))')
|
|
98
|
-
its(:to_subquery) { should eql('((SELECT
|
|
140
|
+
its(:to_s) { should eql('((SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "users")) EXCEPT ((SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "users"))') }
|
|
141
|
+
its(:to_subquery) { should eql('(((SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "users")) EXCEPT ((SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "users")))') }
|
|
99
142
|
end
|
|
100
143
|
|
|
101
144
|
context 'when the operands are intersections' do
|
|
@@ -103,8 +146,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_difference' do
|
|
|
103
146
|
|
|
104
147
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
105
148
|
|
|
106
|
-
its(:to_s) { should eql('((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users")) EXCEPT ((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users"))')
|
|
107
|
-
its(:to_subquery) { should eql('((SELECT
|
|
149
|
+
its(:to_s) { should eql('((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users")) EXCEPT ((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users"))') }
|
|
150
|
+
its(:to_subquery) { should eql('(((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users")) EXCEPT ((SELECT "id", "name", "age" FROM "users") INTERSECT (SELECT "id", "name", "age" FROM "users")))') }
|
|
108
151
|
end
|
|
109
152
|
|
|
110
153
|
context 'when the operands are unions' do
|
|
@@ -112,8 +155,8 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_difference' do
|
|
|
112
155
|
|
|
113
156
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
114
157
|
|
|
115
|
-
its(:to_s) { should eql('((SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users")) EXCEPT ((SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users"))')
|
|
116
|
-
its(:to_subquery) { should eql('((SELECT
|
|
158
|
+
its(:to_s) { should eql('((SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users")) EXCEPT ((SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users"))') }
|
|
159
|
+
its(:to_subquery) { should eql('(((SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users")) EXCEPT ((SELECT "id", "name", "age" FROM "users") UNION (SELECT "id", "name", "age" FROM "users")))') }
|
|
117
160
|
end
|
|
118
161
|
|
|
119
162
|
context 'when the operands are joins' do
|
|
@@ -121,18 +164,28 @@ describe SQL::Generator::Relation::Set, '#visit_veritas_algebra_difference' do
|
|
|
121
164
|
|
|
122
165
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
123
166
|
|
|
124
|
-
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" NATURAL JOIN "users") EXCEPT (SELECT "id", "name", "age" FROM "users" NATURAL JOIN "users")')
|
|
125
|
-
its(:to_subquery) { should eql('(SELECT
|
|
167
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users" AS "left" NATURAL JOIN "users" AS "right") EXCEPT (SELECT "id", "name", "age" FROM "users" AS "left" NATURAL JOIN "users" AS "right")') }
|
|
168
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users" AS "left" NATURAL JOIN "users" AS "right") EXCEPT (SELECT "id", "name", "age" FROM "users" AS "left" NATURAL JOIN "users" AS "right"))') }
|
|
126
169
|
end
|
|
127
170
|
|
|
128
171
|
context 'when the operands have different base relations' do
|
|
129
|
-
let(:relation_name) { 'users_others'
|
|
130
|
-
let(:left) {
|
|
131
|
-
let(:right) {
|
|
172
|
+
let(:relation_name) { 'users_others' }
|
|
173
|
+
let(:left) { Relation::Base.new('users', header, body) }
|
|
174
|
+
let(:right) { Relation::Base.new('others', header, body) }
|
|
175
|
+
|
|
176
|
+
it_should_behave_like 'a generated SQL SELECT query'
|
|
177
|
+
|
|
178
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "others")') }
|
|
179
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "others"))') }
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
context 'when the operands have headers sorted in different orders' do
|
|
183
|
+
let(:left) { Relation::Base.new(relation_name, header, body) }
|
|
184
|
+
let(:right) { Relation::Base.new(relation_name, header.reverse, body) }
|
|
132
185
|
|
|
133
186
|
it_should_behave_like 'a generated SQL SELECT query'
|
|
134
187
|
|
|
135
|
-
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT "id", "name", "age" FROM "
|
|
136
|
-
its(:to_subquery) { should eql('(SELECT
|
|
188
|
+
its(:to_s) { should eql('(SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT DISTINCT "id", "name", "age" FROM "users")') }
|
|
189
|
+
its(:to_subquery) { should eql('((SELECT "id", "name", "age" FROM "users") EXCEPT (SELECT DISTINCT "id", "name", "age" FROM "users"))') }
|
|
137
190
|
end
|
|
138
191
|
end
|