veritas-optimizer 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. data/.travis.yml +4 -2
  2. data/Gemfile +8 -9
  3. data/Guardfile +3 -2
  4. data/README.rdoc +55 -0
  5. data/Rakefile +2 -2
  6. data/TODO +100 -98
  7. data/config/flay.yml +2 -2
  8. data/config/flog.yml +1 -1
  9. data/config/roodi.yml +2 -2
  10. data/config/site.reek +2 -2
  11. data/lib/veritas/optimizer/algebra/difference.rb +1 -1
  12. data/lib/veritas/optimizer/algebra/intersection.rb +1 -1
  13. data/lib/veritas/optimizer/algebra/join.rb +117 -1
  14. data/lib/veritas/optimizer/algebra/product.rb +1 -1
  15. data/lib/veritas/optimizer/algebra/rename.rb +12 -1
  16. data/lib/veritas/optimizer/algebra/restriction.rb +148 -0
  17. data/lib/veritas/optimizer/algebra/union.rb +1 -1
  18. data/lib/veritas/optimizer/function/connective/binary.rb +61 -8
  19. data/lib/veritas/optimizer/function/connective/conjunction.rb +1 -1
  20. data/lib/veritas/optimizer/function/connective/disjunction.rb +1 -1
  21. data/lib/veritas/optimizer/function/predicate/comparable.rb +4 -4
  22. data/lib/veritas/optimizer/relation/operation/binary.rb +1 -1
  23. data/lib/veritas/optimizer/support/predicate_partition.rb +182 -0
  24. data/lib/veritas/optimizer/version.rb +1 -1
  25. data/lib/veritas/optimizer.rb +2 -0
  26. data/spec/integration/veritas/algebra/rename/optimize_spec.rb +30 -30
  27. data/spec/integration/veritas/algebra/restriction/optimize_spec.rb +3 -3
  28. data/spec/integration/veritas/relation/operation/limit/optimize_spec.rb +1 -1
  29. data/spec/integration/veritas/relation/operation/offset/optimize_spec.rb +1 -1
  30. data/spec/integration/veritas/relation/operation/order/optimize_spec.rb +6 -6
  31. data/spec/integration/veritas/relation/operation/reverse/optimize_spec.rb +3 -3
  32. data/spec/spec_helper.rb +2 -1
  33. data/spec/unit/veritas/optimizer/algebra/extension/order_operand/optimizable_spec.rb +1 -1
  34. data/spec/unit/veritas/optimizer/algebra/extension/order_operand/optimize_spec.rb +1 -1
  35. data/spec/unit/veritas/optimizer/algebra/join/left_materialized_operand/optimizable_spec.rb +42 -0
  36. data/spec/unit/veritas/optimizer/algebra/join/left_materialized_operand/optimize_spec.rb +55 -0
  37. data/spec/unit/veritas/optimizer/algebra/join/right_materialized_operand/optimizable_spec.rb +42 -0
  38. data/spec/unit/veritas/optimizer/algebra/join/right_materialized_operand/optimize_spec.rb +55 -0
  39. data/spec/unit/veritas/optimizer/algebra/rename/limit_operand/optimizable_spec.rb +1 -1
  40. data/spec/unit/veritas/optimizer/algebra/rename/limit_operand/optimize_spec.rb +1 -1
  41. data/spec/unit/veritas/optimizer/algebra/rename/offset_operand/optimizable_spec.rb +1 -1
  42. data/spec/unit/veritas/optimizer/algebra/rename/offset_operand/optimize_spec.rb +1 -1
  43. data/spec/unit/veritas/optimizer/algebra/rename/order_operand/optimizable_spec.rb +1 -1
  44. data/spec/unit/veritas/optimizer/algebra/rename/order_operand/optimize_spec.rb +1 -1
  45. data/spec/unit/veritas/optimizer/algebra/rename/reverse_operand/optimizable_spec.rb +1 -1
  46. data/spec/unit/veritas/optimizer/algebra/rename/reverse_operand/optimize_spec.rb +1 -1
  47. data/spec/unit/veritas/optimizer/algebra/restriction/combination_operand/optimizable_spec.rb +41 -0
  48. data/spec/unit/veritas/optimizer/algebra/restriction/combination_operand/optimize_spec.rb +35 -0
  49. data/spec/unit/veritas/optimizer/algebra/restriction/join_operand/optimizable_spec.rb +51 -0
  50. data/spec/unit/veritas/optimizer/algebra/restriction/join_operand/optimize_spec.rb +48 -0
  51. data/spec/unit/veritas/optimizer/algebra/restriction/order_operand/optimizable_spec.rb +1 -1
  52. data/spec/unit/veritas/optimizer/algebra/restriction/order_operand/optimize_spec.rb +1 -1
  53. data/spec/unit/veritas/optimizer/algebra/restriction/product_operand/optimizable_spec.rb +44 -0
  54. data/spec/unit/veritas/optimizer/algebra/restriction/product_operand/optimize_spec.rb +48 -0
  55. data/spec/unit/veritas/optimizer/algebra/restriction/unoptimized_operand/optimize_spec.rb +4 -4
  56. data/spec/unit/veritas/optimizer/algebra/summarization/empty_operand/optimize_spec.rb +1 -1
  57. data/spec/unit/veritas/optimizer/algebra/summarization/empty_summarize_per/optimize_spec.rb +7 -7
  58. data/spec/unit/veritas/optimizer/algebra/summarization/order_operand/optimizable_spec.rb +1 -1
  59. data/spec/unit/veritas/optimizer/algebra/summarization/order_operand/optimize_spec.rb +1 -1
  60. data/spec/unit/veritas/optimizer/function/connective/conjunction/optimizable_to_exclusion/optimizable_spec.rb +38 -6
  61. data/spec/unit/veritas/optimizer/function/connective/conjunction/optimizable_to_exclusion/optimize_spec.rb +44 -6
  62. data/spec/unit/veritas/optimizer/function/connective/disjunction/optimizable_to_inclusion/optimizable_spec.rb +38 -6
  63. data/spec/unit/veritas/optimizer/function/connective/disjunction/optimizable_to_inclusion/optimize_spec.rb +44 -6
  64. data/spec/unit/veritas/optimizer/predicate_partition/left_spec.rb +149 -0
  65. data/spec/unit/veritas/optimizer/predicate_partition/remainder_spec.rb +149 -0
  66. data/spec/unit/veritas/optimizer/predicate_partition/right_spec.rb +149 -0
  67. data/spec/unit/veritas/optimizer/relation/operation/binary/left_order_operand/optimizable_spec.rb +1 -1
  68. data/spec/unit/veritas/optimizer/relation/operation/binary/left_order_operand/optimize_spec.rb +1 -1
  69. data/spec/unit/veritas/optimizer/relation/operation/binary/{materialized_operand → materialized_operands}/optimizable_spec.rb +1 -1
  70. data/spec/unit/veritas/optimizer/relation/operation/binary/{materialized_operand → materialized_operands}/optimize_spec.rb +1 -1
  71. data/spec/unit/veritas/optimizer/relation/operation/binary/right_order_operand/optimizable_spec.rb +1 -1
  72. data/spec/unit/veritas/optimizer/relation/operation/binary/right_order_operand/optimize_spec.rb +1 -1
  73. data/spec/unit/veritas/optimizer/relation/operation/limit/equal_limit_operand/optimizable_spec.rb +3 -3
  74. data/spec/unit/veritas/optimizer/relation/operation/limit/equal_limit_operand/optimize_spec.rb +4 -4
  75. data/spec/unit/veritas/optimizer/relation/operation/limit/limit_operand/optimizable_spec.rb +3 -3
  76. data/spec/unit/veritas/optimizer/relation/operation/limit/limit_operand/optimize_spec.rb +3 -3
  77. data/spec/unit/veritas/optimizer/relation/operation/limit/unoptimized_operand/optimizable_spec.rb +4 -4
  78. data/spec/unit/veritas/optimizer/relation/operation/limit/unoptimized_operand/optimize_spec.rb +4 -4
  79. data/spec/unit/veritas/optimizer/relation/operation/limit/zero_limit/optimizable_spec.rb +3 -3
  80. data/spec/unit/veritas/optimizer/relation/operation/limit/zero_limit/optimize_spec.rb +4 -4
  81. data/spec/unit/veritas/optimizer/relation/operation/offset/offset_operand/optimizable_spec.rb +3 -3
  82. data/spec/unit/veritas/optimizer/relation/operation/offset/offset_operand/optimize_spec.rb +3 -3
  83. data/spec/unit/veritas/optimizer/relation/operation/offset/unoptimized_operand/optimizable_spec.rb +4 -4
  84. data/spec/unit/veritas/optimizer/relation/operation/offset/unoptimized_operand/optimize_spec.rb +4 -4
  85. data/spec/unit/veritas/optimizer/relation/operation/offset/zero_offset/optimizable_spec.rb +3 -3
  86. data/spec/unit/veritas/optimizer/relation/operation/offset/zero_offset/optimize_spec.rb +3 -3
  87. data/spec/unit/veritas/optimizer/relation/operation/order/one_limit_operand/optimizable_spec.rb +3 -3
  88. data/spec/unit/veritas/optimizer/relation/operation/order/one_limit_operand/optimize_spec.rb +2 -2
  89. data/spec/unit/veritas/optimizer/relation/operation/order/order_operand/optimizable_spec.rb +2 -2
  90. data/spec/unit/veritas/optimizer/relation/operation/order/order_operand/optimize_spec.rb +2 -2
  91. data/spec/unit/veritas/optimizer/relation/operation/order/unoptimized_operand/optimizable_spec.rb +1 -1
  92. data/spec/unit/veritas/optimizer/relation/operation/order/unoptimized_operand/optimize_spec.rb +1 -1
  93. data/spec/unit/veritas/optimizer/relation/operation/reverse/order_operand/optimizable_spec.rb +2 -2
  94. data/spec/unit/veritas/optimizer/relation/operation/reverse/order_operand/optimize_spec.rb +1 -1
  95. data/spec/unit/veritas/optimizer/relation/operation/reverse/reverse_operand/optimizable_spec.rb +3 -3
  96. data/spec/unit/veritas/optimizer/relation/operation/reverse/reverse_operand/optimize_spec.rb +1 -1
  97. data/spec/unit/veritas/optimizer/relation/operation/reverse/unoptimized_operand/optimizable_spec.rb +3 -3
  98. data/spec/unit/veritas/optimizer/relation/operation/reverse/unoptimized_operand/optimize_spec.rb +1 -1
  99. data/spec/unit/veritas/optimizer/relation/operation/unary/order_operand/optimizable_spec.rb +1 -1
  100. data/spec/unit/veritas/optimizer/relation/operation/unary/order_operand/optimize_spec.rb +1 -1
  101. data/tasks/metrics/heckle.rake +1 -0
  102. data/veritas-optimizer.gemspec +33 -19
  103. metadata +37 -23
@@ -0,0 +1,149 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Optimizer::PredicatePartition, '#remainder' do
6
+ subject { object.remainder }
7
+
8
+ let(:left_header) { Relation::Header.new([ [ :id, Integer ], [ :user_name, String ], Attribute::Boolean.new(:active_user), Attribute::Boolean.new(:active) ]) }
9
+ let(:right_header) { Relation::Header.new([ [ :id, Integer ], [ :employee_name, String ], Attribute::Boolean.new(:active_employee), Attribute::Boolean.new(:active) ]) }
10
+ let(:object) { described_class.new(predicate, left_header, right_header) }
11
+
12
+ context 'when the predicate is a tautology' do
13
+ let(:predicate) { Function::Proposition::Tautology.instance }
14
+
15
+ it 'partitions the predicate to the remainder' do
16
+ should equal(Function::Proposition::Tautology.instance)
17
+ end
18
+ end
19
+
20
+ context 'when the predicate is a contradiction' do
21
+ let(:predicate) { Function::Proposition::Contradiction.instance }
22
+
23
+ it 'partitions the predicate to the remainder' do
24
+ should equal(Function::Proposition::Contradiction.instance)
25
+ end
26
+ end
27
+
28
+ context 'when the predicate is an attribute' do
29
+ context 'with an attribute from the left header, but not the right header' do
30
+ let(:predicate) { left_header[:active_user] }
31
+
32
+ it 'does not partition the predicate to the remainder' do
33
+ should equal(Function::Proposition::Tautology.instance)
34
+ end
35
+ end
36
+
37
+ context 'with an attribute from the right header, but not the left header' do
38
+ let(:predicate) { right_header[:active_employee] }
39
+
40
+ it 'does not partition the predicate to the remainder' do
41
+ should equal(Function::Proposition::Tautology.instance)
42
+ end
43
+ end
44
+
45
+ context 'with an attribute from the left and right header' do
46
+ let(:predicate) { left_header[:active] }
47
+
48
+ it 'does not partition the predicate to the remainder' do
49
+ should equal(Function::Proposition::Tautology.instance)
50
+ end
51
+ end
52
+ end
53
+
54
+ context 'when the predicate is a binary predicate' do
55
+ context 'with an attribute from the left header, but not the right header' do
56
+ let(:predicate) { left_header[:user_name].eq('Dan Kubb') }
57
+
58
+ it 'does not partition the predicate to the remainder' do
59
+ should equal(Function::Proposition::Tautology.instance)
60
+ end
61
+ end
62
+
63
+ context 'with an attribute from the right header, but not the left header' do
64
+ let(:predicate) { right_header[:employee_name].eq('Dan Kubb') }
65
+
66
+ it 'does not partition the predicate to the remainder' do
67
+ should equal(Function::Proposition::Tautology.instance)
68
+ end
69
+ end
70
+
71
+ context 'with an attribute from the left and right header' do
72
+ let(:predicate) { left_header[:id].eq(1) }
73
+
74
+ it 'does not partition the predicate to the remainder' do
75
+ should equal(Function::Proposition::Tautology.instance)
76
+ end
77
+ end
78
+
79
+ context 'with an attribute from the left header, and an attribute from the left and right header' do
80
+ let(:predicate) { left_header[:active_user].eq(left_header[:active]) }
81
+
82
+ it 'does not partition the predicate to the remainder' do
83
+ should equal(Function::Proposition::Tautology.instance)
84
+ end
85
+ end
86
+
87
+ context 'with an attribute from the right header, and an attribute from the left and right header' do
88
+ let(:predicate) { right_header[:active_employee].eq(left_header[:active]) }
89
+
90
+ it 'does not partition the predicate to the remainder' do
91
+ should equal(Function::Proposition::Tautology.instance)
92
+ end
93
+ end
94
+
95
+ context 'with disjoint attributes from the left and right header' do
96
+ let(:predicate) { left_header[:user_name].eq(right_header[:employee_name]) }
97
+
98
+ it 'partitions the predicate to the remainder' do
99
+ should equal(predicate)
100
+ end
101
+ end
102
+ end
103
+
104
+ context 'when the predicate is a negation' do
105
+ context 'with an attribute from the left header, but not the right header' do
106
+ let(:predicate) { Function::Connective::Negation.new(left_header[:active_user]) }
107
+
108
+ it 'does not partition the predicate to the remainder' do
109
+ should equal(Function::Proposition::Tautology.instance)
110
+ end
111
+ end
112
+
113
+ context 'with an attribute from the right header, but not the left header' do
114
+ let(:predicate) { Function::Connective::Negation.new(right_header[:active_employee]) }
115
+
116
+ it 'does not partition the predicate to the remainder' do
117
+ should equal(Function::Proposition::Tautology.instance)
118
+ end
119
+ end
120
+
121
+ context 'with an attribute from the left and right header' do
122
+ let(:predicate) { Function::Connective::Negation.new(left_header[:active]) }
123
+
124
+ it 'does not partition the predicate to the remainder' do
125
+ should equal(Function::Proposition::Tautology.instance)
126
+ end
127
+ end
128
+ end
129
+
130
+ context 'when the predicate is a conjunction' do
131
+ let(:left_predicate) { left_header[:user_name].eq('Dan Kubb') }
132
+ let(:right_predicate) { right_header[:employee_name].eq('Dan Kubb') }
133
+ let(:predicate) { left_predicate.and(right_predicate) }
134
+
135
+ it 'does not partition the predicate to the remainder' do
136
+ should equal(Function::Proposition::Tautology.instance)
137
+ end
138
+ end
139
+
140
+ context 'when the predicate is a disjunction' do
141
+ let(:left_predicate) { left_header[:user_name].eq('Dan Kubb') }
142
+ let(:right_predicate) { right_header[:employee_name].eq('Dan Kubb') }
143
+ let(:predicate) { left_predicate.or(right_predicate) }
144
+
145
+ it 'does not partition the predicate to the remainder' do
146
+ should equal(Function::Proposition::Tautology.instance)
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,149 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Optimizer::PredicatePartition, '#right' do
6
+ subject { object.right }
7
+
8
+ let(:left_header) { Relation::Header.new([ [ :id, Integer ], [ :user_name, String ], Attribute::Boolean.new(:active_user), Attribute::Boolean.new(:active) ]) }
9
+ let(:right_header) { Relation::Header.new([ [ :id, Integer ], [ :employee_name, String ], Attribute::Boolean.new(:active_employee), Attribute::Boolean.new(:active) ]) }
10
+ let(:object) { described_class.new(predicate, left_header, right_header) }
11
+
12
+ context 'when the predicate is a tautology' do
13
+ let(:predicate) { Function::Proposition::Tautology.instance }
14
+
15
+ it 'partitions the predicate to the right' do
16
+ should equal(Function::Proposition::Tautology.instance)
17
+ end
18
+ end
19
+
20
+ context 'when the predicate is a contradiction' do
21
+ let(:predicate) { Function::Proposition::Contradiction.instance }
22
+
23
+ it 'partitions the predicate to the right' do
24
+ should equal(Function::Proposition::Contradiction.instance)
25
+ end
26
+ end
27
+
28
+ context 'when the predicate is an attribute' do
29
+ context 'with an attribute from the left header, but not the right header' do
30
+ let(:predicate) { left_header[:active_user] }
31
+
32
+ it 'does not partition the predicate to the left' do
33
+ should equal(Function::Proposition::Tautology.instance)
34
+ end
35
+ end
36
+
37
+ context 'with an attribute from the right header, but not the left header' do
38
+ let(:predicate) { right_header[:active_employee] }
39
+
40
+ it 'partitions the predicate to the right' do
41
+ should equal(predicate)
42
+ end
43
+ end
44
+
45
+ context 'with an attribute from the left and right header' do
46
+ let(:predicate) { right_header[:active] }
47
+
48
+ it 'partitions the predicate to the right' do
49
+ should equal(predicate)
50
+ end
51
+ end
52
+ end
53
+
54
+ context 'when the predicate is a binary predicate' do
55
+ context 'with an attribute from the left header, but not the right header' do
56
+ let(:predicate) { left_header[:user_name].eq('Dan Kubb') }
57
+
58
+ it 'does not partition the predicate to the right' do
59
+ should equal(Function::Proposition::Tautology.instance)
60
+ end
61
+ end
62
+
63
+ context 'with an attribute from the right header, but not the left header' do
64
+ let(:predicate) { right_header[:employee_name].eq('Dan Kubb') }
65
+
66
+ it 'partitions the predicate to the right' do
67
+ should equal(predicate)
68
+ end
69
+ end
70
+
71
+ context 'with an attribute from the left and right header' do
72
+ let(:predicate) { right_header[:id].eq(1) }
73
+
74
+ it 'partitions the predicate to the right' do
75
+ should equal(predicate)
76
+ end
77
+ end
78
+
79
+ context 'with an attribute from the left header, and an attribute from the left and right header' do
80
+ let(:predicate) { left_header[:active_user].eq(right_header[:active]) }
81
+
82
+ it 'partitions the predicate to the right' do
83
+ should equal(predicate)
84
+ end
85
+ end
86
+
87
+ context 'with an attribute from the right header, and an attribute from the left and right header' do
88
+ let(:predicate) { right_header[:active_employee].eq(right_header[:active]) }
89
+
90
+ it 'partitions the predicate to the right' do
91
+ should equal(predicate)
92
+ end
93
+ end
94
+
95
+ context 'with disjoint attributes from the left and right header' do
96
+ let(:predicate) { left_header[:user_name].eq(right_header[:employee_name]) }
97
+
98
+ it 'does not partition the predicate to the right' do
99
+ should equal(Function::Proposition::Tautology.instance)
100
+ end
101
+ end
102
+ end
103
+
104
+ context 'when the predicate is a negation' do
105
+ context 'with an attribute from the left header, but not the right header' do
106
+ let(:predicate) { Function::Connective::Negation.new(left_header[:active_user]) }
107
+
108
+ it 'does not partition the predicate to the left' do
109
+ should equal(Function::Proposition::Tautology.instance)
110
+ end
111
+ end
112
+
113
+ context 'with an attribute from the right header, but not the left header' do
114
+ let(:predicate) { Function::Connective::Negation.new(right_header[:active_employee]) }
115
+
116
+ it 'partitions the predicate to the right' do
117
+ should equal(predicate)
118
+ end
119
+ end
120
+
121
+ context 'with an attribute from the left and right header' do
122
+ let(:predicate) { Function::Connective::Negation.new(right_header[:active]) }
123
+
124
+ it 'partitions the predicate to the right' do
125
+ should equal(predicate)
126
+ end
127
+ end
128
+ end
129
+
130
+ context 'when the predicate is a conjunction' do
131
+ let(:left_predicate) { left_header[:user_name].eq('Dan Kubb') }
132
+ let(:right_predicate) { right_header[:employee_name].eq('Dan Kubb') }
133
+ let(:predicate) { left_predicate.and(right_predicate) }
134
+
135
+ it 'partitions the predicate to the right that reference the right header' do
136
+ should equal(right_predicate)
137
+ end
138
+ end
139
+
140
+ context 'when the predicate is a disjunction' do
141
+ let(:left_predicate) { left_header[:user_name].eq('Dan Kubb') }
142
+ let(:right_predicate) { right_header[:employee_name].eq('Dan Kubb') }
143
+ let(:predicate) { left_predicate.or(right_predicate) }
144
+
145
+ it 'partitions the predicate to the right that reference the right header, transforming it with De Morgan\'s Law' do
146
+ should eql(right_header[:employee_name].ne('Dan Kubb'))
147
+ end
148
+ end
149
+ end
@@ -10,7 +10,7 @@ describe Optimizer::Relation::Operation::Binary::LeftOrderOperand, '#optimizable
10
10
  let(:object) { described_class.new(relation) }
11
11
 
12
12
  context 'when left is an order' do
13
- let(:left) { Relation.new([ [ :id, Integer ] ], [].each).order }
13
+ let(:left) { Relation.new([ [ :id, Integer ] ], [].each).sort_by { |r| r.id } }
14
14
 
15
15
  it { should be(true) }
16
16
  end
@@ -6,7 +6,7 @@ describe Optimizer::Relation::Operation::Binary::LeftOrderOperand, '#optimize' d
6
6
  subject { object.optimize }
7
7
 
8
8
  let(:base) { Relation.new([ [ :id, Integer ] ], [].each) }
9
- let(:left) { base.order }
9
+ let(:left) { base.sort_by { |r| r.id } }
10
10
  let(:right) { base }
11
11
  let(:relation) { left.union(right) }
12
12
  let(:object) { described_class.new(relation) }
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Optimizer::Relation::Operation::Binary::MaterializedOperand, '#optimizable?' do
5
+ describe Optimizer::Relation::Operation::Binary::MaterializedOperands, '#optimizable?' do
6
6
  subject { object.optimizable? }
7
7
 
8
8
  let(:materialized) { Relation::Materialized.new([ [ :id, Integer ] ], [ [ 1 ] ]) }
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Optimizer::Relation::Operation::Binary::MaterializedOperand, '#optimize' do
5
+ describe Optimizer::Relation::Operation::Binary::MaterializedOperands, '#optimize' do
6
6
  subject { object.optimize }
7
7
 
8
8
  let(:left) { Relation.new([ [ :id, Integer ] ], [ [ 1 ] ]) }
@@ -10,7 +10,7 @@ describe Optimizer::Relation::Operation::Binary::RightOrderOperand, '#optimizabl
10
10
  let(:object) { described_class.new(relation) }
11
11
 
12
12
  context 'when right is an order' do
13
- let(:right) { Relation.new([ [ :id, Integer ] ], [].each).order }
13
+ let(:right) { Relation.new([ [ :id, Integer ] ], [].each).sort_by { |r| r.id } }
14
14
 
15
15
  it { should be(true) }
16
16
  end
@@ -7,7 +7,7 @@ describe Optimizer::Relation::Operation::Binary::RightOrderOperand, '#optimize'
7
7
 
8
8
  let(:base) { Relation.new([ [ :id, Integer ] ], [].each) }
9
9
  let(:left) { base }
10
- let(:right) { base.order }
10
+ let(:right) { base.sort_by { |r| r.id } }
11
11
  let(:relation) { left.union(right) }
12
12
  let(:object) { described_class.new(relation) }
13
13
 
@@ -5,9 +5,9 @@ require 'spec_helper'
5
5
  describe Optimizer::Relation::Operation::Limit::EqualLimitOperand, '#optimizable?' do
6
6
  subject { object.optimizable? }
7
7
 
8
- let(:base) { Relation.new([ [ :id, Integer ] ], [ [ 1 ] ].each).order }
9
- let(:relation) { operand.take(1) }
10
- let(:object) { described_class.new(relation) }
8
+ let(:base) { Relation.new([ [ :id, Integer ] ], [ [ 1 ] ].each).sort_by { |r| r.id } }
9
+ let(:relation) { operand.take(1) }
10
+ let(:object) { described_class.new(relation) }
11
11
 
12
12
  before do
13
13
  object.operation.should be_kind_of(Relation::Operation::Limit)
@@ -5,10 +5,10 @@ require 'spec_helper'
5
5
  describe Optimizer::Relation::Operation::Limit::EqualLimitOperand, '#optimize' do
6
6
  subject { object.optimize }
7
7
 
8
- let(:order) { Relation.new([ [ :id, Integer ] ], [ [ 1 ] ].each).order }
9
- let(:limit) { order.take(1) }
10
- let(:relation) { limit.take(1) }
11
- let(:object) { described_class.new(relation) }
8
+ let(:order) { Relation.new([ [ :id, Integer ] ], [ [ 1 ] ].each).sort_by { |r| r.id } }
9
+ let(:limit) { order.take(1) }
10
+ let(:relation) { limit.take(1) }
11
+ let(:object) { described_class.new(relation) }
12
12
 
13
13
  before do
14
14
  object.should be_optimizable
@@ -5,9 +5,9 @@ require 'spec_helper'
5
5
  describe Optimizer::Relation::Operation::Limit::LimitOperand, '#optimizable?' do
6
6
  subject { object.optimizable? }
7
7
 
8
- let(:base) { Relation.new([ [ :id, Integer ] ], [ [ 1 ] ].each).order }
9
- let(:relation) { operand.take(1) }
10
- let(:object) { described_class.new(relation) }
8
+ let(:base) { Relation.new([ [ :id, Integer ] ], [ [ 1 ] ].each).sort_by { |r| r.id } }
9
+ let(:relation) { operand.take(1) }
10
+ let(:object) { described_class.new(relation) }
11
11
 
12
12
  before do
13
13
  object.operation.should be_kind_of(Relation::Operation::Limit)
@@ -5,9 +5,9 @@ require 'spec_helper'
5
5
  describe Optimizer::Relation::Operation::Limit::LimitOperand, '#optimize' do
6
6
  subject { object.optimize }
7
7
 
8
- let(:order) { Relation.new([ [ :id, Integer ] ], [ [ 1 ] ].each).order }
9
- let(:limit) { order.take(2) }
10
- let(:object) { described_class.new(relation) }
8
+ let(:order) { Relation.new([ [ :id, Integer ] ], [ [ 1 ] ].each).sort_by { |r| r.id } }
9
+ let(:limit) { order.take(2) }
10
+ let(:object) { described_class.new(relation) }
11
11
 
12
12
  before do
13
13
  object.should be_optimizable
@@ -5,10 +5,10 @@ require 'spec_helper'
5
5
  describe Optimizer::Relation::Operation::Limit::UnoptimizedOperand, '#optimizable?' do
6
6
  subject { object.optimizable? }
7
7
 
8
- let(:header) { Relation::Header.new([ [ :id, Integer ] ]) }
9
- let(:base) { Relation.new(header, [ [ 1 ] ].each).order }
10
- let(:relation) { operand.take(1) }
11
- let(:object) { described_class.new(relation) }
8
+ let(:header) { Relation::Header.new([ [ :id, Integer ] ]) }
9
+ let(:base) { Relation.new(header, [ [ 1 ] ].each).sort_by { |r| r.id } }
10
+ let(:relation) { operand.take(1) }
11
+ let(:object) { described_class.new(relation) }
12
12
 
13
13
  before do
14
14
  object.operation.should be_kind_of(Relation::Operation::Limit)
@@ -5,10 +5,10 @@ require 'spec_helper'
5
5
  describe Optimizer::Relation::Operation::Limit::UnoptimizedOperand, '#optimize' do
6
6
  subject { object.optimize }
7
7
 
8
- let(:header) { Relation::Header.new([ [ :id, Integer ] ]) }
9
- let(:order) { Relation.new(header, [ [ 1 ] ].each).order }
10
- let(:relation) { order.rename({}).take(1) }
11
- let(:object) { described_class.new(relation) }
8
+ let(:header) { Relation::Header.new([ [ :id, Integer ] ]) }
9
+ let(:order) { Relation.new(header, [ [ 1 ] ].each).sort_by { |r| r.id } }
10
+ let(:relation) { order.rename({}).take(1) }
11
+ let(:object) { described_class.new(relation) }
12
12
 
13
13
  before do
14
14
  object.should be_optimizable
@@ -5,9 +5,9 @@ require 'spec_helper'
5
5
  describe Optimizer::Relation::Operation::Limit::ZeroLimit, '#optimizable?' do
6
6
  subject { object.optimizable? }
7
7
 
8
- let(:base) { Relation.new([ [ :id, Integer ] ], [ [ 1 ] ].each).order }
9
- let(:relation) { base.take(limit) }
10
- let(:object) { described_class.new(relation) }
8
+ let(:base) { Relation.new([ [ :id, Integer ] ], [ [ 1 ] ].each).sort_by { |r| r.id } }
9
+ let(:relation) { base.take(limit) }
10
+ let(:object) { described_class.new(relation) }
11
11
 
12
12
  before do
13
13
  object.operation.should be_kind_of(Relation::Operation::Limit)
@@ -5,10 +5,10 @@ require 'spec_helper'
5
5
  describe Optimizer::Relation::Operation::Limit::ZeroLimit, '#optimize' do
6
6
  subject { object.optimize }
7
7
 
8
- let(:header) { Relation::Header.new([ [ :id, Integer ] ]) }
9
- let(:order) { Relation.new(header, [ [ 1 ] ].each).order }
10
- let(:relation) { order.take(0) }
11
- let(:object) { described_class.new(relation) }
8
+ let(:header) { Relation::Header.new([ [ :id, Integer ] ]) }
9
+ let(:order) { Relation.new(header, [ [ 1 ] ].each).sort_by { |r| r.id } }
10
+ let(:relation) { order.take(0) }
11
+ let(:object) { described_class.new(relation) }
12
12
 
13
13
  before do
14
14
  object.should be_optimizable
@@ -5,9 +5,9 @@ require 'spec_helper'
5
5
  describe Optimizer::Relation::Operation::Offset::OffsetOperand, '#optimizable?' do
6
6
  subject { object.optimizable? }
7
7
 
8
- let(:base) { Relation.new([ [ :id, Integer ] ], [ [ 1 ] ].each).order }
9
- let(:relation) { operand.drop(1) }
10
- let(:object) { described_class.new(relation) }
8
+ let(:base) { Relation.new([ [ :id, Integer ] ], [ [ 1 ] ].each).sort_by { |r| r.id } }
9
+ let(:relation) { operand.drop(1) }
10
+ let(:object) { described_class.new(relation) }
11
11
 
12
12
  before do
13
13
  object.operation.should be_kind_of(Relation::Operation::Offset)
@@ -5,9 +5,9 @@ require 'spec_helper'
5
5
  describe Optimizer::Relation::Operation::Offset::OffsetOperand, '#optimize' do
6
6
  subject { object.optimize }
7
7
 
8
- let(:order) { Relation.new([ [ :id, Integer ] ], [ [ 1 ] ].each).order }
9
- let(:relation) { order.drop(1).drop(2) }
10
- let(:object) { described_class.new(relation) }
8
+ let(:order) { Relation.new([ [ :id, Integer ] ], [ [ 1 ] ].each).sort_by { |r| r.id } }
9
+ let(:relation) { order.drop(1).drop(2) }
10
+ let(:object) { described_class.new(relation) }
11
11
 
12
12
  before do
13
13
  object.should be_optimizable
@@ -5,10 +5,10 @@ require 'spec_helper'
5
5
  describe Optimizer::Relation::Operation::Offset::UnoptimizedOperand, '#optimizable?' do
6
6
  subject { object.optimizable? }
7
7
 
8
- let(:header) { Relation::Header.new([ [ :id, Integer ] ]) }
9
- let(:base) { Relation.new(header, [ [ 1 ] ].each).order }
10
- let(:relation) { operand.drop(1) }
11
- let(:object) { described_class.new(relation) }
8
+ let(:header) { Relation::Header.new([ [ :id, Integer ] ]) }
9
+ let(:base) { Relation.new(header, [ [ 1 ] ].each).sort_by { |r| r.id } }
10
+ let(:relation) { operand.drop(1) }
11
+ let(:object) { described_class.new(relation) }
12
12
 
13
13
  before do
14
14
  object.operation.should be_kind_of(Relation::Operation::Offset)
@@ -5,10 +5,10 @@ require 'spec_helper'
5
5
  describe Optimizer::Relation::Operation::Offset::UnoptimizedOperand, '#optimize' do
6
6
  subject { object.optimize }
7
7
 
8
- let(:header) { Relation::Header.new([ [ :id, Integer ] ]) }
9
- let(:order) { Relation.new(header, [ [ 1 ] ].each).order }
10
- let(:relation) { order.rename({}).drop(1) }
11
- let(:object) { described_class.new(relation) }
8
+ let(:header) { Relation::Header.new([ [ :id, Integer ] ]) }
9
+ let(:order) { Relation.new(header, [ [ 1 ] ].each).sort_by { |r| r.id } }
10
+ let(:relation) { order.rename({}).drop(1) }
11
+ let(:object) { described_class.new(relation) }
12
12
 
13
13
  before do
14
14
  object.should be_optimizable
@@ -5,9 +5,9 @@ require 'spec_helper'
5
5
  describe Optimizer::Relation::Operation::Offset::ZeroOffset, '#optimizable?' do
6
6
  subject { object.optimizable? }
7
7
 
8
- let(:base) { Relation.new([ [ :id, Integer ] ], [ [ 1 ] ].each).order }
9
- let(:relation) { base.drop(offset) }
10
- let(:object) { described_class.new(relation) }
8
+ let(:base) { Relation.new([ [ :id, Integer ] ], [ [ 1 ] ].each).sort_by { |r| r.id } }
9
+ let(:relation) { base.drop(offset) }
10
+ let(:object) { described_class.new(relation) }
11
11
 
12
12
  before do
13
13
  object.operation.should be_kind_of(Relation::Operation::Offset)
@@ -5,9 +5,9 @@ require 'spec_helper'
5
5
  describe Optimizer::Relation::Operation::Offset::ZeroOffset, '#optimize' do
6
6
  subject { object.optimize }
7
7
 
8
- let(:order) { Relation.new([ [ :id, Integer ] ], [ [ 1 ] ].each).order }
9
- let(:relation) { order.drop(0) }
10
- let(:object) { described_class.new(relation) }
8
+ let(:order) { Relation.new([ [ :id, Integer ] ], [ [ 1 ] ].each).sort_by { |r| r.id } }
9
+ let(:relation) { order.drop(0) }
10
+ let(:object) { described_class.new(relation) }
11
11
 
12
12
  before do
13
13
  object.should be_optimizable
@@ -6,7 +6,7 @@ describe Optimizer::Relation::Operation::Order::OneLimitOperand, '#optimizable?'
6
6
  subject { object.optimizable? }
7
7
 
8
8
  let(:base) { Relation.new([ [ :id, Integer ] ], [ [ 1 ] ].each) }
9
- let(:relation) { operand.order }
9
+ let(:relation) { operand.sort_by { |r| r.id } }
10
10
  let(:object) { described_class.new(relation) }
11
11
 
12
12
  before do
@@ -14,13 +14,13 @@ describe Optimizer::Relation::Operation::Order::OneLimitOperand, '#optimizable?'
14
14
  end
15
15
 
16
16
  context 'when the operand is limited to 1' do
17
- let(:operand) { base.order.take(1) }
17
+ let(:operand) { base.sort_by { |r| r.id }.take(1) }
18
18
 
19
19
  it { should be(true) }
20
20
  end
21
21
 
22
22
  context 'when the operand is not limited to 1' do
23
- let(:operand) { base.order.take(2) }
23
+ let(:operand) { base.sort_by { |r| r.id }.take(2) }
24
24
 
25
25
  it { should be(false) }
26
26
  end
@@ -6,8 +6,8 @@ describe Optimizer::Relation::Operation::Order::OneLimitOperand, '#optimize' do
6
6
  subject { object.optimize }
7
7
 
8
8
  let(:base) { Relation.new([ [ :id, Integer ] ], [ [ 1 ] ].each) }
9
- let(:limit) { base.order.take(1) }
10
- let(:relation) { limit.order }
9
+ let(:limit) { base.sort_by { |r| r.id }.take(1) }
10
+ let(:relation) { limit.sort_by { |r| r.id } }
11
11
  let(:object) { described_class.new(relation) }
12
12
 
13
13
  before do
@@ -6,7 +6,7 @@ describe Optimizer::Relation::Operation::Order::OrderOperand, '#optimizable?' do
6
6
  subject { object.optimizable? }
7
7
 
8
8
  let(:base) { Relation.new([ [ :id, Integer ] ], [ [ 1 ] ].each) }
9
- let(:relation) { operand.order }
9
+ let(:relation) { operand.sort_by { |r| r.id } }
10
10
  let(:object) { described_class.new(relation) }
11
11
 
12
12
  before do
@@ -14,7 +14,7 @@ describe Optimizer::Relation::Operation::Order::OrderOperand, '#optimizable?' do
14
14
  end
15
15
 
16
16
  context 'when the operand is ordered' do
17
- let(:operand) { base.order }
17
+ let(:operand) { base.sort_by { |r| r.id } }
18
18
 
19
19
  it { should be(true) }
20
20
  end
@@ -6,8 +6,8 @@ describe Optimizer::Relation::Operation::Order::OrderOperand, '#optimize' do
6
6
  subject { object.optimize }
7
7
 
8
8
  let(:base) { Relation.new([ [ :id, Integer ] ], [ [ 1 ] ].each) }
9
- let(:order) { base.order }
10
- let(:relation) { order.order { |order| order.directions.reverse } }
9
+ let(:order) { base.sort_by { |r| r.id } }
10
+ let(:relation) { order.sort_by { order.directions.reverse } }
11
11
  let(:object) { described_class.new(relation) }
12
12
 
13
13
  before do
@@ -7,7 +7,7 @@ describe Optimizer::Relation::Operation::Order::UnoptimizedOperand, '#optimizabl
7
7
 
8
8
  let(:header) { Relation::Header.new([ [ :id, Integer ] ]) }
9
9
  let(:base) { Relation.new(header, [ [ 1 ] ].each) }
10
- let(:relation) { operand.order }
10
+ let(:relation) { operand.sort_by { |r| r.id } }
11
11
  let(:object) { described_class.new(relation) }
12
12
 
13
13
  before do