arel-compat 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. data/History.txt +25 -0
  2. data/README.markdown +182 -0
  3. data/lib/arel.rb +13 -0
  4. data/lib/arel/algebra.rb +10 -0
  5. data/lib/arel/algebra/attributes.rb +7 -0
  6. data/lib/arel/algebra/attributes/attribute.rb +270 -0
  7. data/lib/arel/algebra/attributes/boolean.rb +21 -0
  8. data/lib/arel/algebra/attributes/decimal.rb +9 -0
  9. data/lib/arel/algebra/attributes/float.rb +9 -0
  10. data/lib/arel/algebra/attributes/integer.rb +10 -0
  11. data/lib/arel/algebra/attributes/string.rb +10 -0
  12. data/lib/arel/algebra/attributes/time.rb +6 -0
  13. data/lib/arel/algebra/core_extensions.rb +4 -0
  14. data/lib/arel/algebra/core_extensions/class.rb +32 -0
  15. data/lib/arel/algebra/core_extensions/hash.rb +11 -0
  16. data/lib/arel/algebra/core_extensions/object.rb +30 -0
  17. data/lib/arel/algebra/core_extensions/symbol.rb +9 -0
  18. data/lib/arel/algebra/expression.rb +43 -0
  19. data/lib/arel/algebra/header.rb +67 -0
  20. data/lib/arel/algebra/ordering.rb +23 -0
  21. data/lib/arel/algebra/predicates.rb +190 -0
  22. data/lib/arel/algebra/relations.rb +17 -0
  23. data/lib/arel/algebra/relations/operations/alias.rb +7 -0
  24. data/lib/arel/algebra/relations/operations/from.rb +6 -0
  25. data/lib/arel/algebra/relations/operations/group.rb +12 -0
  26. data/lib/arel/algebra/relations/operations/having.rb +17 -0
  27. data/lib/arel/algebra/relations/operations/join.rb +69 -0
  28. data/lib/arel/algebra/relations/operations/lock.rb +12 -0
  29. data/lib/arel/algebra/relations/operations/order.rb +19 -0
  30. data/lib/arel/algebra/relations/operations/project.rb +20 -0
  31. data/lib/arel/algebra/relations/operations/skip.rb +7 -0
  32. data/lib/arel/algebra/relations/operations/take.rb +11 -0
  33. data/lib/arel/algebra/relations/operations/where.rb +17 -0
  34. data/lib/arel/algebra/relations/relation.rb +136 -0
  35. data/lib/arel/algebra/relations/row.rb +26 -0
  36. data/lib/arel/algebra/relations/utilities/compound.rb +54 -0
  37. data/lib/arel/algebra/relations/utilities/externalization.rb +24 -0
  38. data/lib/arel/algebra/relations/utilities/nil.rb +7 -0
  39. data/lib/arel/algebra/relations/writes.rb +36 -0
  40. data/lib/arel/algebra/value.rb +14 -0
  41. data/lib/arel/engines.rb +2 -0
  42. data/lib/arel/engines/memory.rb +4 -0
  43. data/lib/arel/engines/memory/engine.rb +16 -0
  44. data/lib/arel/engines/memory/predicates.rb +99 -0
  45. data/lib/arel/engines/memory/primitives.rb +27 -0
  46. data/lib/arel/engines/memory/relations.rb +5 -0
  47. data/lib/arel/engines/memory/relations/array.rb +35 -0
  48. data/lib/arel/engines/memory/relations/compound.rb +9 -0
  49. data/lib/arel/engines/memory/relations/operations.rb +67 -0
  50. data/lib/arel/engines/memory/relations/writes.rb +7 -0
  51. data/lib/arel/engines/sql.rb +8 -0
  52. data/lib/arel/engines/sql/attributes.rb +40 -0
  53. data/lib/arel/engines/sql/christener.rb +14 -0
  54. data/lib/arel/engines/sql/compilers/ibm_db_compiler.rb +48 -0
  55. data/lib/arel/engines/sql/compilers/mysql_compiler.rb +11 -0
  56. data/lib/arel/engines/sql/compilers/oracle_compiler.rb +95 -0
  57. data/lib/arel/engines/sql/compilers/postgresql_compiler.rb +42 -0
  58. data/lib/arel/engines/sql/compilers/sqlite_compiler.rb +9 -0
  59. data/lib/arel/engines/sql/core_extensions.rb +4 -0
  60. data/lib/arel/engines/sql/core_extensions/array.rb +24 -0
  61. data/lib/arel/engines/sql/core_extensions/nil_class.rb +15 -0
  62. data/lib/arel/engines/sql/core_extensions/object.rb +19 -0
  63. data/lib/arel/engines/sql/core_extensions/range.rb +19 -0
  64. data/lib/arel/engines/sql/engine.rb +55 -0
  65. data/lib/arel/engines/sql/formatters.rb +122 -0
  66. data/lib/arel/engines/sql/predicates.rb +103 -0
  67. data/lib/arel/engines/sql/primitives.rb +97 -0
  68. data/lib/arel/engines/sql/relations.rb +10 -0
  69. data/lib/arel/engines/sql/relations/compiler.rb +118 -0
  70. data/lib/arel/engines/sql/relations/operations/alias.rb +5 -0
  71. data/lib/arel/engines/sql/relations/operations/join.rb +33 -0
  72. data/lib/arel/engines/sql/relations/relation.rb +65 -0
  73. data/lib/arel/engines/sql/relations/table.rb +88 -0
  74. data/lib/arel/engines/sql/relations/utilities/compound.rb +10 -0
  75. data/lib/arel/engines/sql/relations/utilities/externalization.rb +14 -0
  76. data/lib/arel/engines/sql/relations/utilities/nil.rb +6 -0
  77. data/lib/arel/engines/sql/relations/utilities/recursion.rb +13 -0
  78. data/lib/arel/engines/sql/relations/writes.rb +19 -0
  79. data/lib/arel/session.rb +51 -0
  80. data/lib/arel/version.rb +3 -0
  81. data/spec/algebra/unit/predicates/binary_spec.rb +35 -0
  82. data/spec/algebra/unit/predicates/equality_spec.rb +29 -0
  83. data/spec/algebra/unit/predicates/in_spec.rb +12 -0
  84. data/spec/algebra/unit/primitives/attribute_spec.rb +181 -0
  85. data/spec/algebra/unit/primitives/expression_spec.rb +45 -0
  86. data/spec/algebra/unit/primitives/value_spec.rb +15 -0
  87. data/spec/algebra/unit/relations/alias_spec.rb +16 -0
  88. data/spec/algebra/unit/relations/delete_spec.rb +9 -0
  89. data/spec/algebra/unit/relations/group_spec.rb +10 -0
  90. data/spec/algebra/unit/relations/insert_spec.rb +9 -0
  91. data/spec/algebra/unit/relations/join_spec.rb +25 -0
  92. data/spec/algebra/unit/relations/order_spec.rb +21 -0
  93. data/spec/algebra/unit/relations/project_spec.rb +34 -0
  94. data/spec/algebra/unit/relations/relation_spec.rb +187 -0
  95. data/spec/algebra/unit/relations/skip_spec.rb +10 -0
  96. data/spec/algebra/unit/relations/table_spec.rb +38 -0
  97. data/spec/algebra/unit/relations/take_spec.rb +10 -0
  98. data/spec/algebra/unit/relations/update_spec.rb +9 -0
  99. data/spec/algebra/unit/relations/where_spec.rb +19 -0
  100. data/spec/algebra/unit/session/session_spec.rb +84 -0
  101. data/spec/attributes/boolean_spec.rb +57 -0
  102. data/spec/attributes/float_spec.rb +119 -0
  103. data/spec/attributes/header_spec.rb +42 -0
  104. data/spec/attributes/integer_spec.rb +119 -0
  105. data/spec/attributes/string_spec.rb +43 -0
  106. data/spec/attributes/time_spec.rb +24 -0
  107. data/spec/engines/memory/integration/joins/cross_engine_spec.rb +51 -0
  108. data/spec/engines/memory/unit/relations/array_spec.rb +32 -0
  109. data/spec/engines/memory/unit/relations/insert_spec.rb +28 -0
  110. data/spec/engines/memory/unit/relations/join_spec.rb +31 -0
  111. data/spec/engines/memory/unit/relations/order_spec.rb +27 -0
  112. data/spec/engines/memory/unit/relations/project_spec.rb +27 -0
  113. data/spec/engines/memory/unit/relations/skip_spec.rb +26 -0
  114. data/spec/engines/memory/unit/relations/take_spec.rb +26 -0
  115. data/spec/engines/memory/unit/relations/where_spec.rb +39 -0
  116. data/spec/engines/sql/integration/joins/with_adjacency_spec.rb +258 -0
  117. data/spec/engines/sql/integration/joins/with_aggregations_spec.rb +221 -0
  118. data/spec/engines/sql/integration/joins/with_compounds_spec.rb +137 -0
  119. data/spec/engines/sql/unit/engine_spec.rb +45 -0
  120. data/spec/engines/sql/unit/predicates/binary_spec.rb +140 -0
  121. data/spec/engines/sql/unit/predicates/equality_spec.rb +75 -0
  122. data/spec/engines/sql/unit/predicates/in_spec.rb +179 -0
  123. data/spec/engines/sql/unit/predicates/noteq_spec.rb +75 -0
  124. data/spec/engines/sql/unit/predicates/predicates_spec.rb +79 -0
  125. data/spec/engines/sql/unit/primitives/attribute_spec.rb +36 -0
  126. data/spec/engines/sql/unit/primitives/expression_spec.rb +28 -0
  127. data/spec/engines/sql/unit/primitives/literal_spec.rb +43 -0
  128. data/spec/engines/sql/unit/primitives/value_spec.rb +29 -0
  129. data/spec/engines/sql/unit/relations/alias_spec.rb +53 -0
  130. data/spec/engines/sql/unit/relations/delete_spec.rb +83 -0
  131. data/spec/engines/sql/unit/relations/from_spec.rb +64 -0
  132. data/spec/engines/sql/unit/relations/group_spec.rb +72 -0
  133. data/spec/engines/sql/unit/relations/having_spec.rb +78 -0
  134. data/spec/engines/sql/unit/relations/insert_spec.rb +143 -0
  135. data/spec/engines/sql/unit/relations/join_spec.rb +180 -0
  136. data/spec/engines/sql/unit/relations/lock_spec.rb +86 -0
  137. data/spec/engines/sql/unit/relations/order_spec.rb +161 -0
  138. data/spec/engines/sql/unit/relations/project_spec.rb +143 -0
  139. data/spec/engines/sql/unit/relations/skip_spec.rb +41 -0
  140. data/spec/engines/sql/unit/relations/table_spec.rb +129 -0
  141. data/spec/engines/sql/unit/relations/take_spec.rb +49 -0
  142. data/spec/engines/sql/unit/relations/update_spec.rb +203 -0
  143. data/spec/engines/sql/unit/relations/where_spec.rb +72 -0
  144. data/spec/relations/join_spec.rb +42 -0
  145. data/spec/relations/relation_spec.rb +31 -0
  146. data/spec/shared/relation_spec.rb +255 -0
  147. data/spec/spec_helper.rb +36 -0
  148. data/spec/support/check.rb +6 -0
  149. data/spec/support/connections/mysql_connection.rb +14 -0
  150. data/spec/support/connections/oracle_connection.rb +17 -0
  151. data/spec/support/connections/postgresql_connection.rb +13 -0
  152. data/spec/support/connections/sqlite3_connection.rb +24 -0
  153. data/spec/support/guards.rb +28 -0
  154. data/spec/support/matchers.rb +4 -0
  155. data/spec/support/matchers/be_like.rb +24 -0
  156. data/spec/support/matchers/disambiguate_attributes.rb +28 -0
  157. data/spec/support/matchers/hash_the_same_as.rb +26 -0
  158. data/spec/support/matchers/have_rows.rb +18 -0
  159. data/spec/support/model.rb +62 -0
  160. data/spec/support/schemas/mysql_schema.rb +26 -0
  161. data/spec/support/schemas/oracle_schema.rb +20 -0
  162. data/spec/support/schemas/postgresql_schema.rb +26 -0
  163. data/spec/support/schemas/sqlite3_schema.rb +26 -0
  164. metadata +258 -0
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ module Arel
4
+ describe Array do
5
+ before do
6
+ @relation = Array.new([
7
+ [1, 'duck' ],
8
+ [2, 'duck' ],
9
+ [3, 'goose']
10
+ ], [[:id, Attributes::Integer], [:name, Attributes::String]])
11
+ end
12
+
13
+ describe '#attributes' do
14
+ it 'manufactures attributes corresponding to the names given on construction' do
15
+ @relation.attributes.should == [
16
+ Attribute.new(@relation, :id),
17
+ Attribute.new(@relation, :name)
18
+ ]
19
+ end
20
+ end
21
+
22
+ describe '#call' do
23
+ it "manufactures an array of hashes of attributes to values" do
24
+ @relation.call.should == [
25
+ Row.new(@relation, [1, 'duck']),
26
+ Row.new(@relation, [2, 'duck']),
27
+ Row.new(@relation, [3, 'goose'])
28
+ ]
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ module Arel
4
+ describe Insert do
5
+ before do
6
+ @relation = Array.new([
7
+ [1, 'duck' ],
8
+ [2, 'duck' ],
9
+ [3, 'goose']
10
+ ], [[:id, Attributes::Integer], [:name, Attributes::String]])
11
+ end
12
+
13
+ describe '#call' do
14
+ it "manufactures an array of hashes of attributes to values" do
15
+ @relation \
16
+ .insert(@relation[:id] => 4, @relation[:name] => 'guinea fowl') \
17
+ do |relation|
18
+ relation.should == [
19
+ Row.new(relation, [1, 'duck']),
20
+ Row.new(relation, [2, 'duck']),
21
+ Row.new(relation, [3, 'goose']),
22
+ Row.new(relation, [4, 'guinea fowl'])
23
+ ]
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ module Arel
4
+ describe Join do
5
+ before do
6
+ @relation1 = Array.new([
7
+ [1, 'duck' ],
8
+ [2, 'duck' ],
9
+ [3, 'goose']
10
+ ], [[:id, Attributes::Integer], [:name, Attributes::String]])
11
+ @relation2 = @relation1.alias
12
+ end
13
+
14
+ describe InnerJoin do
15
+ describe '#call' do
16
+ it 'combines the two tables where the predicate obtains' do
17
+ @relation1 \
18
+ .join(@relation2) \
19
+ .on(@relation1[:id].eq(@relation2[:id])) \
20
+ .let do |relation|
21
+ relation.call.should == [
22
+ Row.new(relation, [1, 'duck', 1, 'duck' ]),
23
+ Row.new(relation, [2, 'duck', 2, 'duck' ]),
24
+ Row.new(relation, [3, 'goose', 3, 'goose'])
25
+ ]
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ module Arel
4
+ describe Order do
5
+ before do
6
+ @relation = Array.new([
7
+ [1, 'duck' ],
8
+ [2, 'duck' ],
9
+ [3, 'goose']
10
+ ], [[:id, Attributes::Integer], [:name, Attributes::String]])
11
+ end
12
+
13
+ describe '#call' do
14
+ it 'sorts the relation with the provided ordering' do
15
+ @relation \
16
+ .order(@relation[:id].desc) \
17
+ .let do |relation|
18
+ relation.call.should == [
19
+ Row.new(relation, [3, 'goose']),
20
+ Row.new(relation, [2, 'duck' ]),
21
+ Row.new(relation, [1, 'duck' ])
22
+ ]
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ module Arel
4
+ describe Project do
5
+ before do
6
+ @relation = Array.new([
7
+ [1, 'duck' ],
8
+ [2, 'duck' ],
9
+ [3, 'goose']
10
+ ], [[:id, Attributes::Integer], [:name, Attributes::String]])
11
+ end
12
+
13
+ describe '#call' do
14
+ it 'retains only the attributes that are provided' do
15
+ @relation \
16
+ .project(@relation[:id]) \
17
+ .let do |relation|
18
+ relation.call.should == [
19
+ Row.new(relation, [1]),
20
+ Row.new(relation, [2]),
21
+ Row.new(relation, [3])
22
+ ]
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ module Arel
4
+ describe Skip do
5
+ before do
6
+ @relation = Array.new([
7
+ [1, 'duck' ],
8
+ [2, 'duck' ],
9
+ [3, 'goose']
10
+ ], [[:id, Attributes::Integer], [:name, Attributes::String]])
11
+ end
12
+
13
+ describe '#call' do
14
+ it 'removes the first n rows' do
15
+ @relation \
16
+ .skip(1) \
17
+ .let do |relation|
18
+ relation.call.should == [
19
+ Row.new(relation, [2, 'duck']),
20
+ Row.new(relation, [3, 'goose']),
21
+ ]
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ module Arel
4
+ describe Take do
5
+ before do
6
+ @relation = Array.new([
7
+ [1, 'duck' ],
8
+ [2, 'duck' ],
9
+ [3, 'goose']
10
+ ], [[:id, Attributes::Integer], [:name, Attributes::String]])
11
+ end
12
+
13
+ describe '#call' do
14
+ it 'removes the rows after the first n' do
15
+ @relation \
16
+ .take(2) \
17
+ .let do |relation|
18
+ relation.call.should == [
19
+ Row.new(relation, [1, 'duck']),
20
+ Row.new(relation, [2, 'duck']),
21
+ ]
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ module Arel
4
+ describe Where do
5
+ before do
6
+ @relation = Array.new([
7
+ [1, 'duck' ],
8
+ [2, 'duck' ],
9
+ [3, 'goose']
10
+ ], [[:id, Attributes::Integer], [:name, Attributes::String]])
11
+ end
12
+
13
+ describe '#call' do
14
+ it 'filters the relation with the provided predicate' do
15
+ @relation \
16
+ .where(@relation[:id].lt(3)) \
17
+ .let do |relation|
18
+ relation.call.should == [
19
+ Row.new(relation, [1, 'duck']),
20
+ Row.new(relation, [2, 'duck']),
21
+ ]
22
+ end
23
+ end
24
+
25
+ describe 'when filtering a where relation' do
26
+ it 'further filters the already-filtered relation with the provided predicate' do
27
+ @relation \
28
+ .where(@relation[:id].gt(1)) \
29
+ .where(@relation[:id].lt(3)) \
30
+ .let do |relation|
31
+ relation.call.should == [
32
+ Row.new(relation, [2, 'duck'])
33
+ ]
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,258 @@
1
+ require 'spec_helper'
2
+
3
+ module Arel
4
+ describe Join do
5
+ before do
6
+ @relation1 = Table(:users)
7
+ @relation2 = @relation1.alias
8
+ @predicate = @relation1[:id].eq(@relation2[:id])
9
+ end
10
+
11
+ describe 'when joining a relation to itself' do
12
+ describe '#to_sql' do
13
+ it 'manufactures sql aliasing the table and attributes properly in the join predicate and the where clause' do
14
+ sql = @relation1.join(@relation2).on(@predicate).to_sql
15
+
16
+ adapter_is :mysql do
17
+ sql.should be_like(%Q{
18
+ SELECT `users`.`id`, `users`.`name`, `users_2`.`id`, `users_2`.`name`
19
+ FROM `users`
20
+ INNER JOIN `users` `users_2`
21
+ ON `users`.`id` = `users_2`.`id`
22
+ })
23
+ end
24
+
25
+ adapter_is :oracle do
26
+ sql.should be_like(%Q{
27
+ SELECT "USERS"."ID", "USERS"."NAME", "USERS_2"."ID", "USERS_2"."NAME"
28
+ FROM "USERS"
29
+ INNER JOIN "USERS" "USERS_2"
30
+ ON "USERS"."ID" = "USERS_2"."ID"
31
+ })
32
+ end
33
+
34
+ adapter_is_not :mysql, :oracle do
35
+ sql.should be_like(%Q{
36
+ SELECT "users"."id", "users"."name", "users_2"."id", "users_2"."name"
37
+ FROM "users"
38
+ INNER JOIN "users" "users_2"
39
+ ON "users"."id" = "users_2"."id"
40
+ })
41
+ end
42
+ end
43
+
44
+ describe 'when joining with a where on the same relation' do
45
+ it 'manufactures sql aliasing the tables properly' do
46
+ sql = @relation1 \
47
+ .join(@relation2.where(@relation2[:id].eq(1))) \
48
+ .on(@predicate) \
49
+ .to_sql
50
+
51
+ adapter_is :mysql do
52
+ sql.should be_like(%Q{
53
+ SELECT `users`.`id`, `users`.`name`, `users_2`.`id`, `users_2`.`name`
54
+ FROM `users`
55
+ INNER JOIN `users` `users_2`
56
+ ON `users`.`id` = `users_2`.`id` AND `users_2`.`id` = 1
57
+ })
58
+ end
59
+
60
+ adapter_is :oracle do
61
+ sql.should be_like(%Q{
62
+ SELECT "USERS"."ID", "USERS"."NAME", "USERS_2"."ID", "USERS_2"."NAME"
63
+ FROM "USERS"
64
+ INNER JOIN "USERS" "USERS_2"
65
+ ON "USERS"."ID" = "USERS_2"."ID" AND "USERS_2"."ID" = 1
66
+ })
67
+ end
68
+
69
+ adapter_is_not :mysql, :oracle do
70
+ sql.should be_like(%Q{
71
+ SELECT "users"."id", "users"."name", "users_2"."id", "users_2"."name"
72
+ FROM "users"
73
+ INNER JOIN "users" "users_2"
74
+ ON "users"."id" = "users_2"."id" AND "users_2"."id" = 1
75
+ })
76
+ end
77
+ end
78
+
79
+ describe 'when the where occurs before the alias' do
80
+ it 'manufactures sql aliasing the predicates properly' do
81
+ relation2 = @relation1.where(@relation1[:id].eq(1)).alias
82
+
83
+ sql = @relation1 \
84
+ .join(relation2) \
85
+ .on(relation2[:id].eq(@relation1[:id])) \
86
+ .to_sql
87
+
88
+ adapter_is :mysql do
89
+ sql.should be_like(%Q{
90
+ SELECT `users`.`id`, `users`.`name`, `users_2`.`id`, `users_2`.`name`
91
+ FROM `users`
92
+ INNER JOIN `users` `users_2`
93
+ ON `users_2`.`id` = `users`.`id` AND `users_2`.`id` = 1
94
+ })
95
+ end
96
+
97
+ adapter_is :oracle do
98
+ sql.should be_like(%Q{
99
+ SELECT "USERS"."ID", "USERS"."NAME", "USERS_2"."ID", "USERS_2"."NAME"
100
+ FROM "USERS"
101
+ INNER JOIN "USERS" "USERS_2"
102
+ ON "USERS_2"."ID" = "USERS"."ID" AND "USERS_2"."ID" = 1
103
+ })
104
+ end
105
+
106
+ adapter_is_not :mysql, :oracle do
107
+ sql.should be_like(%Q{
108
+ SELECT "users"."id", "users"."name", "users_2"."id", "users_2"."name"
109
+ FROM "users"
110
+ INNER JOIN "users" "users_2"
111
+ ON "users_2"."id" = "users"."id" AND "users_2"."id" = 1
112
+ })
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+ describe 'when joining the relation to itself multiple times' do
119
+ before do
120
+ @relation3 = @relation1.alias
121
+ end
122
+
123
+ describe 'when joining left-associatively' do
124
+ it 'manufactures sql aliasing the tables properly' do
125
+ sql = @relation1 \
126
+ .join(@relation2 \
127
+ .join(@relation3) \
128
+ .on(@relation2[:id].eq(@relation3[:id]))) \
129
+ .on(@relation1[:id].eq(@relation2[:id])) \
130
+ .to_sql
131
+
132
+ adapter_is :mysql do
133
+ sql.should be_like(%Q{
134
+ SELECT `users`.`id`, `users`.`name`, `users_2`.`id`, `users_2`.`name`, `users_3`.`id`, `users_3`.`name`
135
+ FROM `users`
136
+ INNER JOIN `users` `users_2`
137
+ ON `users`.`id` = `users_2`.`id`
138
+ INNER JOIN `users` `users_3`
139
+ ON `users_2`.`id` = `users_3`.`id`
140
+ })
141
+ end
142
+
143
+ adapter_is :oracle do
144
+ sql.should be_like(%Q{
145
+ SELECT "USERS"."ID", "USERS"."NAME", "USERS_2"."ID", "USERS_2"."NAME", "USERS_3"."ID", "USERS_3"."NAME"
146
+ FROM "USERS"
147
+ INNER JOIN "USERS" "USERS_2"
148
+ ON "USERS"."ID" = "USERS_2"."ID"
149
+ INNER JOIN "USERS" "USERS_3"
150
+ ON "USERS_2"."ID" = "USERS_3"."ID"
151
+ })
152
+ end
153
+
154
+ adapter_is_not :mysql, :oracle do
155
+ sql.should be_like(%Q{
156
+ SELECT "users"."id", "users"."name", "users_2"."id", "users_2"."name", "users_3"."id", "users_3"."name"
157
+ FROM "users"
158
+ INNER JOIN "users" "users_2"
159
+ ON "users"."id" = "users_2"."id"
160
+ INNER JOIN "users" "users_3"
161
+ ON "users_2"."id" = "users_3"."id"
162
+ })
163
+ end
164
+ end
165
+ end
166
+
167
+ describe 'when joining right-associatively' do
168
+ it 'manufactures sql aliasing the tables properly' do
169
+ sql = @relation1 \
170
+ .join(@relation2).on(@relation1[:id].eq(@relation2[:id])) \
171
+ .join(@relation3).on(@relation2[:id].eq(@relation3[:id])) \
172
+ .to_sql
173
+
174
+ adapter_is :mysql do
175
+ sql.should be_like(%Q{
176
+ SELECT `users`.`id`, `users`.`name`, `users_2`.`id`, `users_2`.`name`, `users_3`.`id`, `users_3`.`name`
177
+ FROM `users`
178
+ INNER JOIN `users` `users_2`
179
+ ON `users`.`id` = `users_2`.`id`
180
+ INNER JOIN `users` `users_3`
181
+ ON `users_2`.`id` = `users_3`.`id`
182
+ })
183
+ end
184
+
185
+ adapter_is :oracle do
186
+ sql.should be_like(%Q{
187
+ SELECT "USERS"."ID", "USERS"."NAME", "USERS_2"."ID", "USERS_2"."NAME", "USERS_3"."ID", "USERS_3"."NAME"
188
+ FROM "USERS"
189
+ INNER JOIN "USERS" "USERS_2"
190
+ ON "USERS"."ID" = "USERS_2"."ID"
191
+ INNER JOIN "USERS" "USERS_3"
192
+ ON "USERS_2"."ID" = "USERS_3"."ID"
193
+ })
194
+ end
195
+
196
+ adapter_is_not :mysql, :oracle do
197
+ sql.should be_like(%Q{
198
+ SELECT "users"."id", "users"."name", "users_2"."id", "users_2"."name", "users_3"."id", "users_3"."name"
199
+ FROM "users"
200
+ INNER JOIN "users" "users_2"
201
+ ON "users"."id" = "users_2"."id"
202
+ INNER JOIN "users" "users_3"
203
+ ON "users_2"."id" = "users_3"."id"
204
+ })
205
+ end
206
+ end
207
+ end
208
+ end
209
+ end
210
+
211
+ describe '[]' do
212
+ describe 'when given an attribute belonging to both sub-relations' do
213
+ it 'disambiguates the relation that serves as the ancestor to the attribute' do
214
+ @relation1 \
215
+ .join(@relation2) \
216
+ .on(@predicate) \
217
+ .should disambiguate_attributes(@relation1[:id], @relation2[:id])
218
+ end
219
+
220
+ describe 'when both relations are compound and only one is an alias' do
221
+ it 'disambiguates the relation that serves as the ancestor to the attribute' do
222
+ compound1 = @relation1.where(@predicate)
223
+ compound2 = compound1.alias
224
+ compound1 \
225
+ .join(compound2) \
226
+ .on(@predicate) \
227
+ .should disambiguate_attributes(compound1[:id], compound2[:id])
228
+ end
229
+ end
230
+
231
+ describe 'when the left relation is extremely compound' do
232
+ it 'disambiguates the relation that serves as the ancestor to the attribute' do
233
+ @relation1 \
234
+ .where(@predicate) \
235
+ .where(@predicate) \
236
+ .join(@relation2) \
237
+ .on(@predicate) \
238
+ .should disambiguate_attributes(@relation1[:id], @relation2[:id])
239
+ end
240
+ end
241
+
242
+ describe 'when the right relation is extremely compound' do
243
+ it 'disambiguates the relation that serves as the ancestor to the attribute' do
244
+ @relation1 \
245
+ .join( \
246
+ @relation2 \
247
+ .where(@predicate) \
248
+ .where(@predicate) \
249
+ .where(@predicate)) \
250
+ .on(@predicate) \
251
+ .should disambiguate_attributes(@relation1[:id], @relation2[:id])
252
+ end
253
+ end
254
+ end
255
+ end
256
+ end
257
+ end
258
+ end