arel_extensions 1.2.3 → 1.2.5

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 (53) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +10 -10
  3. data/Gemfile +2 -2
  4. data/README.md +10 -10
  5. data/appveyor.yml +1 -1
  6. data/functions.html +1 -1
  7. data/init/mssql.sql +4 -4
  8. data/init/mysql.sql +38 -38
  9. data/init/postgresql.sql +21 -21
  10. data/lib/arel_extensions.rb +17 -1
  11. data/lib/arel_extensions/common_sql_functions.rb +1 -1
  12. data/lib/arel_extensions/comparators.rb +4 -2
  13. data/lib/arel_extensions/math_functions.rb +9 -4
  14. data/lib/arel_extensions/nodes.rb +1 -1
  15. data/lib/arel_extensions/nodes/aggregate_function.rb +14 -0
  16. data/lib/arel_extensions/nodes/coalesce.rb +2 -2
  17. data/lib/arel_extensions/nodes/concat.rb +6 -13
  18. data/lib/arel_extensions/nodes/date_diff.rb +2 -2
  19. data/lib/arel_extensions/nodes/format.rb +8 -8
  20. data/lib/arel_extensions/nodes/formatted_number.rb +6 -6
  21. data/lib/arel_extensions/nodes/function.rb +2 -0
  22. data/lib/arel_extensions/nodes/matches.rb +4 -4
  23. data/lib/arel_extensions/nodes/power.rb +2 -2
  24. data/lib/arel_extensions/nodes/repeat.rb +2 -2
  25. data/lib/arel_extensions/nodes/replace.rb +1 -1
  26. data/lib/arel_extensions/nodes/soundex.rb +4 -4
  27. data/lib/arel_extensions/nodes/std.rb +19 -21
  28. data/lib/arel_extensions/nodes/substring.rb +1 -1
  29. data/lib/arel_extensions/nodes/sum.rb +7 -0
  30. data/lib/arel_extensions/nodes/trim.rb +2 -2
  31. data/lib/arel_extensions/nodes/union.rb +2 -2
  32. data/lib/arel_extensions/null_functions.rb +2 -2
  33. data/lib/arel_extensions/string_functions.rb +10 -7
  34. data/lib/arel_extensions/version.rb +1 -1
  35. data/lib/arel_extensions/visitors/mssql.rb +4 -4
  36. data/lib/arel_extensions/visitors/mysql.rb +28 -4
  37. data/lib/arel_extensions/visitors/oracle.rb +4 -4
  38. data/lib/arel_extensions/visitors/postgresql.rb +34 -6
  39. data/lib/arel_extensions/visitors/to_sql.rb +29 -22
  40. data/test/helper.rb +1 -1
  41. data/test/real_db_test.rb +1 -1
  42. data/test/test_comparators.rb +1 -1
  43. data/test/visitors/test_bulk_insert_sqlite.rb +1 -1
  44. data/test/visitors/test_bulk_insert_to_sql.rb +7 -9
  45. data/test/visitors/test_oracle.rb +1 -0
  46. data/test/visitors/test_to_sql.rb +6 -0
  47. data/test/with_ar/all_agnostic_test.rb +14 -3
  48. data/test/with_ar/insert_agnostic_test.rb +2 -1
  49. data/test/with_ar/test_bulk_sqlite.rb +1 -1
  50. data/test/with_ar/test_math_sqlite.rb +2 -2
  51. data/test/with_ar/test_string_mysql.rb +3 -3
  52. data/test/with_ar/test_string_sqlite.rb +2 -2
  53. metadata +5 -4
@@ -139,16 +139,16 @@ module ArelExtensions
139
139
  def visit_ArelExtensions_Nodes_GroupConcat o, collector
140
140
  collector << "GROUP_CONCAT("
141
141
  collector = visit o.left, collector
142
- if !o.orders.blank?
142
+ if !o.order.blank?
143
143
  collector << ' ORDER BY '
144
- o.orders.each_with_index do |order,i|
144
+ o.order.each_with_index do |order,i|
145
145
  collector << Arel::Visitors::ToSql::COMMA unless i == 0
146
146
  collector = visit order, collector
147
147
  end
148
148
  end
149
- if o.right && o.right != 'NULL'
149
+ if o.separator && o.separator != 'NULL'
150
150
  collector << ' SEPARATOR '
151
- collector = visit o.right, collector
151
+ collector = visit o.separator, collector
152
152
  end
153
153
  collector << ")"
154
154
  collector
@@ -398,10 +398,34 @@ module ArelExtensions
398
398
  collector
399
399
  end
400
400
 
401
+ def visit_Aggregate_For_AggregateFunction o, collector
402
+ if !(Arel::Table.engine.connection.send(:version) >= (Arel::Table.engine.connection.send(:mariadb?) ? '10.2.3' : '8.0'))
403
+ warn("Warning : ArelExtensions: Window Functions are not available in the current version on the DBMS.")
404
+ return collector
405
+ end
406
+
407
+ if o.order || o.group
408
+ collector << " OVER ("
409
+ if o.group
410
+ collector << " PARTITION BY ("
411
+ visit o.group, collector
412
+ collector << ")"
413
+ end
414
+ if o.order
415
+ collector << " ORDER BY ("
416
+ visit o.order, collector
417
+ collector << ")"
418
+ end
419
+ collector << ")"
420
+ end
421
+ collector
422
+ end
423
+
401
424
  def visit_ArelExtensions_Nodes_Std o, collector
402
425
  collector << (o.unbiased_estimator ? "STDDEV_SAMP(" : "STDDEV_POP(")
403
426
  visit o.left, collector
404
427
  collector << ")"
428
+ visit_Aggregate_For_AggregateFunction o, collector
405
429
  collector
406
430
  end
407
431
 
@@ -131,14 +131,14 @@ module ArelExtensions
131
131
  collector << "(LISTAGG("
132
132
  collector = visit o.left, collector
133
133
  collector << Arel::Visitors::Oracle::COMMA
134
- if o.right && o.right != 'NULL'
135
- collector = visit o.right, collector
134
+ if o.separator && o.separator != 'NULL'
135
+ collector = visit o.separator, collector
136
136
  else
137
137
  collector = visit Arel::Nodes.build_quoted(','), collector
138
138
  end
139
139
  collector << ") WITHIN GROUP (ORDER BY "
140
- if !o.orders.blank?
141
- o.orders.each_with_index do |order,i|
140
+ if !o.order.blank?
141
+ o.order.each_with_index do |order,i|
142
142
  collector << Arel::Visitors::Oracle::COMMA unless i == 0
143
143
  collector = visit order, collector
144
144
  end
@@ -83,20 +83,45 @@ module ArelExtensions
83
83
  collector
84
84
  end
85
85
 
86
+ def visit_Aggregate_For_AggregateFunction o, collector
87
+ if !o.order.blank? || !o.group.blank?
88
+ collector << " OVER ("
89
+ if !o.group.blank?
90
+ collector << " PARTITION BY "
91
+ o.group.each_with_index do |group, i|
92
+ collector << Arel::Visitors::PostgreSQL::COMMA unless i == 0
93
+ visit group, collector
94
+ end
95
+ end
96
+ if !o.order.blank?
97
+ collector << " ORDER BY "
98
+ o.order.each_with_index do |order, i|
99
+ collector << Arel::Visitors::PostgreSQL::COMMA unless i == 0
100
+ visit order, collector
101
+ end
102
+ end
103
+ collector << ")"
104
+ end
105
+ collector
106
+ end
107
+
86
108
  def visit_ArelExtensions_Nodes_GroupConcat o, collector
87
109
  collector << "array_to_string(array_agg("
88
110
  collector = visit o.left, collector
89
- if !o.orders.blank?
90
- collector << ' ORDER BY '
91
- o.orders.each_with_index do |order,i|
111
+ if o.order && !o.order.blank?
112
+ collector << " ORDER BY"
113
+ o.order.each_with_index do |order, i|
92
114
  collector << Arel::Visitors::PostgreSQL::COMMA unless i == 0
93
- collector = visit order, collector
115
+ collector << " "
116
+ visit order, collector
94
117
  end
95
118
  end
96
119
  collector << ")"
120
+ o.order = nil
121
+ visit_Aggregate_For_AggregateFunction o, collector
97
122
  collector << Arel::Visitors::PostgreSQL::COMMA
98
- if o.right && o.right != 'NULL'
99
- collector = visit o.right, collector
123
+ if o.separator && o.separator != 'NULL'
124
+ collector = visit o.separator, collector
100
125
  else
101
126
  collector = visit Arel::Nodes.build_quoted(','), collector
102
127
  end
@@ -293,6 +318,7 @@ module ArelExtensions
293
318
  collector << "sum("
294
319
  collector = visit o.expr, collector
295
320
  collector << ")"
321
+ visit_Aggregate_For_AggregateFunction o, collector
296
322
  collector
297
323
  end
298
324
 
@@ -420,6 +446,7 @@ module ArelExtensions
420
446
  collector << (o.unbiased_estimator ? "STDDEV_SAMP(" : "STDDEV_POP(")
421
447
  visit o.left, collector
422
448
  collector << ")"
449
+ visit_Aggregate_For_AggregateFunction o, collector
423
450
  collector
424
451
  end
425
452
 
@@ -427,6 +454,7 @@ module ArelExtensions
427
454
  collector << (o.unbiased_estimator ? "VAR_SAMP(" : "VAR_POP(")
428
455
  visit o.left, collector
429
456
  collector << ")"
457
+ visit_Aggregate_For_AggregateFunction o, collector
430
458
  collector
431
459
  end
432
460
 
@@ -52,14 +52,14 @@ module ArelExtensions
52
52
  collector << ")"
53
53
  collector
54
54
  end
55
-
55
+
56
56
  def visit_ArelExtensions_Nodes_Log10 o, collector
57
57
  collector << "LOG10("
58
58
  collector = visit o.left, collector
59
59
  collector << ")"
60
60
  collector
61
61
  end
62
-
62
+
63
63
  def visit_ArelExtensions_Nodes_Power o, collector
64
64
  collector << "POW("
65
65
  o.expressions.each_with_index { |arg, i|
@@ -70,6 +70,13 @@ module ArelExtensions
70
70
  collector
71
71
  end
72
72
 
73
+ def visit_ArelExtensions_Nodes_Sum o, collector
74
+ collector << "SUM("
75
+ collector = visit o.expr, collector
76
+ collector << ")"
77
+ collector
78
+ end
79
+
73
80
  # String functions
74
81
  def visit_ArelExtensions_Nodes_Concat o, collector
75
82
  collector << "CONCAT("
@@ -84,9 +91,9 @@ module ArelExtensions
84
91
  def visit_ArelExtensions_Nodes_GroupConcat o, collector
85
92
  collector << "GROUP_CONCAT("
86
93
  collector = visit o.left, collector
87
- if o.right && o.right != 'NULL'
94
+ if o.separator && o.separator != 'NULL'
88
95
  collector << Arel::Visitors::ToSql::COMMA
89
- collector = visit o.right, collector
96
+ collector = visit o.separator, collector
90
97
  end
91
98
  collector << ")"
92
99
  collector
@@ -134,7 +141,7 @@ module ArelExtensions
134
141
  collector << ")"
135
142
  collector
136
143
  end
137
-
144
+
138
145
  def visit_ArelExtensions_Nodes_Repeat o, collector
139
146
  collector << "REPEAT("
140
147
  o.expressions.each_with_index { |arg, i|
@@ -269,12 +276,12 @@ module ArelExtensions
269
276
  as_attr = Arel::Nodes::SqlLiteral.new('int')
270
277
  when :decimal, :float, :number
271
278
  as_attr = Arel::Nodes::SqlLiteral.new('float')
272
- when :datetime
279
+ when :datetime
273
280
  as_attr = Arel::Nodes::SqlLiteral.new('datetime')
274
281
  when :time
275
282
  as_attr = Arel::Nodes::SqlLiteral.new('time')
276
- when :binary
277
- as_attr = Arel::Nodes::SqlLiteral.new('binary')
283
+ when :binary
284
+ as_attr = Arel::Nodes::SqlLiteral.new('binary')
278
285
  else
279
286
  as_attr = Arel::Nodes::SqlLiteral.new(o.as_attr.to_s)
280
287
  end
@@ -305,7 +312,7 @@ module ArelExtensions
305
312
  collector << ")"
306
313
  collector
307
314
  end
308
-
315
+
309
316
  def visit_ArelExtensions_Nodes_DateSub o, collector
310
317
  collector << "DATE_SUB("
311
318
  collector = visit o.left, collector
@@ -384,7 +391,7 @@ module ArelExtensions
384
391
  collector = visit o.left, collector
385
392
  collector << ") THEN "
386
393
  collector = visit o.right, collector
387
- if o.expressions[2]
394
+ if o.expressions[2]
388
395
  collector << " ELSE "
389
396
  collector = visit o.expressions[2], collector
390
397
  end
@@ -452,7 +459,7 @@ module ArelExtensions
452
459
  collector = visit o.right, collector
453
460
  collector
454
461
  end
455
-
462
+
456
463
  def visit_ArelExtensions_Nodes_UnionAll o, collector
457
464
  collector = visit o.left, collector
458
465
  collector << " UNION ALL "
@@ -489,25 +496,25 @@ module ArelExtensions
489
496
  visit Arel::Nodes.build_quoted(o.expr), collector
490
497
  end
491
498
 
492
- def visit_ArelExtensions_Nodes_FormattedNumber o, collector
499
+ def visit_ArelExtensions_Nodes_FormattedNumber o, collector
493
500
  visit o.left, collector
494
501
  end
495
-
496
- remove_method(:visit_Arel_Nodes_LessThan) rescue nil
502
+
503
+ remove_method(:visit_Arel_Nodes_LessThan) rescue nil
497
504
  def visit_Arel_Nodes_LessThan o, collector
498
505
  collector = visit o.left, collector
499
506
  collector << " < "
500
507
  visit o.right, collector
501
508
  end
502
-
503
- def visit_ArelExtensions_Nodes_Std o, collector
509
+
510
+ def visit_ArelExtensions_Nodes_Std o, collector
504
511
  collector << "STD("
505
512
  visit o.left, collector
506
513
  collector << ")"
507
514
  collector
508
515
  end
509
-
510
- def visit_ArelExtensions_Nodes_Variance o, collector
516
+
517
+ def visit_ArelExtensions_Nodes_Variance o, collector
511
518
  collector << "VARIANCE("
512
519
  visit o.left, collector
513
520
  collector << ")"
@@ -525,40 +532,40 @@ module ArelExtensions
525
532
 
526
533
  alias_method :old_visit_Arel_Nodes_And, :visit_Arel_Nodes_And
527
534
  def visit_Arel_Nodes_And o, collector
535
+ collector << '('
528
536
  case o.children.length
529
537
  when 0
530
538
  collector << '1=1' # but this should not happen
531
539
  when 1
532
540
  collector = visit o.children[0], collector
533
541
  else
534
- collector << '('
535
542
  o.children.each_with_index { |arg, i|
536
543
  if i != 0
537
544
  collector << ') AND ('
538
545
  end
539
546
  collector = visit arg, collector
540
547
  }
541
- collector << ')'
542
548
  end
549
+ collector << ')'
543
550
  collector
544
551
  end
545
552
 
546
553
  def visit_ArelExtensions_Nodes_Or o, collector
554
+ collector << '('
547
555
  case o.children.length
548
556
  when 0
549
557
  collector << '0=1' # but this should not happen
550
558
  when 1
551
559
  collector = visit o.children[0], collector
552
560
  else
553
- collector << '('
554
561
  o.children.each_with_index { |arg, i|
555
562
  if i != 0
556
563
  collector << ') OR ('
557
564
  end
558
565
  collector = visit arg, collector
559
566
  }
560
- collector << ')'
561
567
  end
568
+ collector << ')'
562
569
  collector
563
570
  end
564
571
 
@@ -15,4 +15,4 @@ class Object
15
15
  def must_be_like other
16
16
  gsub(/\s+/, ' ').strip.must_equal other.gsub(/\s+/, ' ').strip
17
17
  end
18
- end
18
+ end
@@ -29,7 +29,7 @@ def setup_db
29
29
  func.result = value1.index(value2)
30
30
  end
31
31
  end
32
- @cnx.drop_table(:users) rescue nil
32
+ @cnx.drop_table(:users) rescue nil
33
33
  @cnx.create_table :users do |t|
34
34
  t.column :age, :integer
35
35
  t.column :name, :string
@@ -22,7 +22,7 @@ module ArelExtensions
22
22
  it "< is equal lt" do
23
23
  compile(@table[:id] < 10).must_be_like('"users"."id" < 10')
24
24
  end
25
-
25
+
26
26
  it "<= is equal lteq" do
27
27
  compile(@table[:id] <= 10).must_be_like('"users"."id" <= 10')
28
28
  end
@@ -15,7 +15,7 @@ module ArelExtensions
15
15
  [25, 'nom2', "sdfdsfdsfsdf", '2016-01-01']
16
16
  ]
17
17
  end
18
-
18
+
19
19
  def compile node
20
20
  if Arel::VERSION.to_i > 5
21
21
  @visitor.accept(node, Arel::Collectors::SQLString.new).value
@@ -10,8 +10,8 @@ module ArelExtensions
10
10
  @table = Arel::Table.new(:users)
11
11
  @cols = ['id', 'name', 'comments', 'created_at']
12
12
  @data = [
13
- [23, 'nom1', "sdfdsfdsfsdf", '2016-01-01'],
14
- [25, 'nom2', "sdfdsfdsfsdf", '2016-01-01']
13
+ [23, 'nom1', "sdfdsfdsfsdf", '2016-01-01'],
14
+ [25, 'nom2', "sdfdsfdsfsdf", '2016-01-01']
15
15
  ]
16
16
  end
17
17
 
@@ -26,12 +26,10 @@ module ArelExtensions
26
26
 
27
27
  it "should import large set of data using ToSql" do
28
28
  insert_manager = Arel::VERSION.to_i > 6 ? Arel::InsertManager.new().into(@table) : Arel::InsertManager.new(@conn).into(@table)
29
- insert_manager.bulk_insert(@cols, @data)
30
- sql = compile(insert_manager.ast)
31
- sql.must_be_like %Q[INSERT INTO "users" ("id", "name", "comments", "created_at") VALUES (23, 'nom1', 'sdfdsfdsfsdf', '2016-01-01'), (25, 'nom2', 'sdfdsfdsfsdf', '2016-01-01')]
29
+ insert_manager.bulk_insert(@cols, @data)
30
+ sql = compile(insert_manager.ast)
31
+ sql.must_be_like %Q[INSERT INTO "users" ("id", "name", "comments", "created_at") VALUES (23, 'nom1', 'sdfdsfdsfsdf', '2016-01-01'), (25, 'nom2', 'sdfdsfdsfsdf', '2016-01-01')]
32
32
  end
33
-
34
-
35
- end
33
+ end
36
34
  end
37
- end
35
+ end
@@ -50,6 +50,7 @@ module ArelExtensions
50
50
  compile((c >= 'test').as('new_name')).must_be_like %{("users"."name" >= 'test') AS new_name}
51
51
  compile(c <= @table[:comments]).must_be_like %{"users"."name" <= "users"."comments"}
52
52
  compile(c =~ /\Atest\Z/).must_be_like %{REGEXP_LIKE("users"."name", '^test$')}
53
+ compile(c =~ /\Atest\z/).must_be_like %{REGEXP_LIKE("users"."name", '^test$')}
53
54
  compile(c =~ '^test$').must_be_like %{REGEXP_LIKE("users"."name", '^test$')}
54
55
  compile(c !~ /\Ate\Dst\Z/).must_be_like %{NOT REGEXP_LIKE("users"."name", '^te[^0-9]st$')}
55
56
  compile(c.imatches('%test%')).must_be_like %{LOWER("users"."name") LIKE LOWER('%test%')}
@@ -88,6 +88,7 @@ module ArelExtensions
88
88
  compile((c >= 'test').as('new_name')).must_be_like %{("users"."name" >= 'test') AS new_name}
89
89
  compile(c <= @table[:comments]).must_be_like %{"users"."name" <= "users"."comments"}
90
90
  compile(c =~ /\Atest\Z/).must_be_like %{"users"."name" REGEXP '^test$'}
91
+ compile(c =~ /\Atest\z/).must_be_like %{"users"."name" REGEXP '^test$'}
91
92
  compile(c !~ /\Ate\Dst\Z/).must_be_like %{"users"."name" NOT REGEXP '^te[^0-9]st$'}
92
93
  compile(c.imatches('%test%')).must_be_like %{"users"."name" ILIKE '%test%'}
93
94
  compile(c.imatches_any(['%test%', 't2'])).must_be_like %{(("users"."name" ILIKE '%test%') OR ("users"."name" ILIKE 't2'))}
@@ -120,6 +121,11 @@ module ArelExtensions
120
121
  compile(@table[:id] < 42).must_match %{"users"."id" < 42}
121
122
  compile(@table[:id] <= 42).must_match %{"users"."id" <= 42}
122
123
  compile((@table[:id] <= 42).as('new_name')).must_match %{("users"."id" <= 42) AS new_name}
124
+ puts @table[:id].count.class
125
+ compile(@table[:id].count.eq 42).must_match %{COUNT("users"."id") = 42}
126
+ #compile(@table[:id].count == 42).must_match %{COUNT("users"."id") = 42} # TODO
127
+ #compile(@table[:id].count != 42).must_match %{COUNT("users"."id") != 42}
128
+ #compile(@table[:id].count >= 42).must_match %{COUNT("users"."id") >= 42}
123
129
  end
124
130
 
125
131
  it "should accept comparators on dates" do
@@ -154,7 +154,7 @@ module ArelExtensions
154
154
  else
155
155
  assert_equal 68, User.select((@age.sum + 1).as("res")).take(50).first.res
156
156
  assert_equal 134, User.select((@age.sum + @age.sum).as("res")).take(50).first.res
157
- assert_equal 201, User.select(((@age * 3).sum).as("res")).take(50).first.res
157
+ assert_equal 201, User.select((@age * 3).sum.as("res")).take(50).first.res
158
158
  assert_equal 4009, User.select(((@age * @age).sum).as("res")).take(50).first.res
159
159
  end
160
160
  end
@@ -175,6 +175,7 @@ module ArelExtensions
175
175
  assert_equal "Sophie,Lucas,Arthur", t(User.where(:name => ['Lucas', 'Sophie','Arthur']), @name.group_concat(',',@name.desc))
176
176
  assert_equal "Lucas,Sophie,Arthur", t(User.where(:name => ['Lucas', 'Sophie','Arthur']), @name.group_concat(',',[@score.asc,@name.asc]))
177
177
  assert_equal "Lucas,Sophie,Arthur", t(User.where(:name => ['Lucas', 'Sophie','Arthur']), @name.group_concat(',',@score.asc,@name.asc))
178
+ assert_equal "Lucas,Sophie,Arthur", t(User.where(:name => ['Lucas', 'Sophie','Arthur']), @name.group_concat(',',order: [@score.asc,@name.asc]))
178
179
  end
179
180
 
180
181
  def test_length
@@ -733,9 +734,14 @@ module ArelExtensions
733
734
 
734
735
  assert ( 15.98625 - t(User.where(nil), @score.average)).abs < 0.01
735
736
  assert (613.75488 - t(User.where(nil), @score.variance)).abs < 0.01
736
- assert ( 537.0355 - t(User.where(nil), @score.variance(false))).abs < 0.01
737
+ assert ( 537.0355 - t(User.where(nil), @score.variance(unbiased: false))).abs < 0.01
737
738
  assert ( 24.77408 - t(User.where(nil), @score.std)).abs < 0.01
738
- assert ( 23.17403 - t(User.where(nil), @score.std(false))).abs < 0.01
739
+ assert ( 23.17403 - t(User.where(nil), @score.std(unbiased: false))).abs < 0.01
740
+ skip "Not Yet Implemented" if !['postgresql'].include?(@env_db)
741
+ assert_equal 2, User.select(@score.std(group: Arel.when(@name > "M").then(0).else(1)).as('res')).map(&:res).uniq.length
742
+ assert_equal 2, User.select(@score.variance(group: Arel.when(@name > "M").then(0).else(1)).as('res')).map(&:res).uniq.length
743
+ assert_equal 2, User.select(@score.sum(group: Arel.when(@name > "M").then(0).else(1)).as('res')).map(&:res).uniq.length
744
+ assert_equal 2, User.select(@comments.group_concat(group: Arel.when(@name > "M").then(0).else(1)).as('res')).map(&:res).uniq.length
739
745
  end
740
746
 
741
747
  def test_levenshtein_distance
@@ -791,6 +797,11 @@ module ArelExtensions
791
797
  assert_equal 'ArthurArthur', @arthur.select((@name+@name).as('Na-Me')).first.attributes["Na-Me"]
792
798
  end
793
799
 
800
+ def test_exists_in_subquery
801
+ assert User.where(User.where(nil).exists).first
802
+ end
803
+
804
+
794
805
  end
795
806
  end
796
807
  end