arel 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/History.txt +8 -0
  2. data/README.markdown +0 -2
  3. data/Rakefile +2 -2
  4. data/arel.gemspec +13 -3
  5. data/lib/arel.rb +2 -2
  6. data/lib/arel/algebra/relations/relation.rb +3 -2
  7. data/lib/arel/engines/sql/compilers/ibm_db_compiler.rb +62 -0
  8. data/lib/arel/engines/sql/compilers/mysql_compiler.rb +11 -0
  9. data/lib/arel/engines/sql/compilers/oracle_compiler.rb +95 -0
  10. data/lib/arel/engines/sql/compilers/postgresql_compiler.rb +42 -0
  11. data/lib/arel/engines/sql/compilers/sqlite_compiler.rb +9 -0
  12. data/lib/arel/engines/sql/engine.rb +17 -3
  13. data/lib/arel/engines/sql/formatters.rb +3 -3
  14. data/lib/arel/engines/sql/relations.rb +1 -0
  15. data/lib/arel/engines/sql/relations/compiler.rb +118 -0
  16. data/lib/arel/engines/sql/relations/relation.rb +38 -63
  17. data/lib/arel/engines/sql/relations/table.rb +23 -3
  18. data/lib/arel/engines/sql/relations/utilities/externalization.rb +1 -1
  19. data/lib/arel/engines/sql/relations/writes.rb +4 -71
  20. data/spec/arel/algebra/unit/relations/relation_spec.rb +1 -2
  21. data/spec/arel/algebra/unit/relations/table_spec.rb +0 -1
  22. data/spec/arel/engines/memory/integration/joins/cross_engine_spec.rb +9 -4
  23. data/spec/arel/engines/sql/integration/joins/with_adjacency_spec.rb +68 -19
  24. data/spec/arel/engines/sql/integration/joins/with_aggregations_spec.rb +74 -20
  25. data/spec/arel/engines/sql/integration/joins/with_compounds_spec.rb +33 -3
  26. data/spec/arel/engines/sql/unit/predicates/binary_spec.rb +22 -2
  27. data/spec/arel/engines/sql/unit/predicates/equality_spec.rb +15 -3
  28. data/spec/arel/engines/sql/unit/predicates/in_spec.rb +59 -5
  29. data/spec/arel/engines/sql/unit/predicates/predicates_spec.rb +12 -0
  30. data/spec/arel/engines/sql/unit/primitives/attribute_spec.rb +24 -1
  31. data/spec/arel/engines/sql/unit/primitives/expression_spec.rb +5 -1
  32. data/spec/arel/engines/sql/unit/primitives/literal_spec.rb +10 -2
  33. data/spec/arel/engines/sql/unit/relations/alias_spec.rb +11 -1
  34. data/spec/arel/engines/sql/unit/relations/delete_spec.rb +23 -3
  35. data/spec/arel/engines/sql/unit/relations/from_spec.rb +16 -2
  36. data/spec/arel/engines/sql/unit/relations/group_spec.rb +18 -2
  37. data/spec/arel/engines/sql/unit/relations/having_spec.rb +12 -3
  38. data/spec/arel/engines/sql/unit/relations/insert_spec.rb +37 -1
  39. data/spec/arel/engines/sql/unit/relations/join_spec.rb +53 -11
  40. data/spec/arel/engines/sql/unit/relations/lock_spec.rb +25 -0
  41. data/spec/arel/engines/sql/unit/relations/order_spec.rb +52 -4
  42. data/spec/arel/engines/sql/unit/relations/project_spec.rb +38 -5
  43. data/spec/arel/engines/sql/unit/relations/skip_spec.rb +10 -1
  44. data/spec/arel/engines/sql/unit/relations/table_spec.rb +26 -5
  45. data/spec/arel/engines/sql/unit/relations/take_spec.rb +18 -1
  46. data/spec/arel/engines/sql/unit/relations/update_spec.rb +47 -1
  47. data/spec/arel/engines/sql/unit/relations/where_spec.rb +18 -2
  48. data/spec/connections/oracle_connection.rb +19 -0
  49. data/spec/schemas/mysql_schema.rb +2 -1
  50. data/spec/schemas/oracle_schema.rb +20 -0
  51. data/spec/schemas/postgresql_schema.rb +2 -1
  52. data/spec/schemas/sqlite3_schema.rb +2 -1
  53. data/spec/spec_helper.rb +16 -7
  54. metadata +31 -9
data/History.txt CHANGED
@@ -1,3 +1,11 @@
1
+ == 0.3.0 / 2010-02-05
2
+
3
+ * Enhancements
4
+
5
+ * Introduced "SQL compilers" for query generation.
6
+ * Added support for Oracle (Raimonds Simanovskis) and IBM/DB (Praveen Devarao).
7
+ * Improvements to give better support to ActiveRecord.
8
+
1
9
  == 0.2.1 / 2010-02-05
2
10
 
3
11
  * Enhancements
data/README.markdown CHANGED
@@ -4,8 +4,6 @@ Arel is a Relational Algebra for Ruby. It 1) simplifies the generation complex o
4
4
 
5
5
  ## Status ##
6
6
 
7
- Arel is alpha software, BEWARE. Nevertheless, at this point, many (most?) SELECT queries can be composed, including very very complicated ones. Writes are only experimental for now.
8
-
9
7
  For the moment, Arel uses ActiveRecord's connection adapters to connect to the various engines, connection pooling, perform quoting, and do type conversion. On the horizon is the use of DataObjects instead.
10
8
 
11
9
  The long term goal, following both LINQ and DataMapper, is to have Arel adapt to engines beyond RDBMS, including XML, IMAP, YAML, etc.
data/Rakefile CHANGED
@@ -20,13 +20,13 @@ else
20
20
  end
21
21
 
22
22
  namespace :spec do
23
- for adapter in %w[mysql sqlite3 postgresql]
23
+ for adapter in %w[mysql sqlite3 postgresql oracle]
24
24
  desc "Run specs with the #{adapter} database adapter"
25
25
  Spec::Rake::SpecTask.new(adapter) do |t|
26
26
  t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
27
27
  t.libs << "#{File.dirname(__FILE__)}/vendor/rails/activerecord/lib"
28
28
  t.libs << "#{File.dirname(__FILE__)}/spec"
29
- t.warning = true
29
+ # t.warning = true
30
30
  t.spec_files =
31
31
  ["spec/connections/#{adapter}_connection.rb"] +
32
32
  ["spec/schemas/#{adapter}_schema.rb"] +
data/arel.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{arel}
5
- s.version = "0.2.1"
5
+ s.version = "0.3.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Bryan Helmkamp", "Nick Kallen", "Emilio Tagua"]
9
- s.date = %q{2010-02-05}
9
+ s.date = %q{2010-03-10}
10
10
  s.description = %q{Arel is a Relational Algebra for Ruby. It 1) simplifies the generation complex
11
11
  of SQL queries and it 2) adapts to various RDBMS systems. It is intended to be
12
12
  a framework framework; that is, you can build your own ORM with it, focusing on
@@ -69,6 +69,11 @@ and query generation.}
69
69
  "lib/arel/engines/memory/relations/writes.rb",
70
70
  "lib/arel/engines/sql.rb",
71
71
  "lib/arel/engines/sql/christener.rb",
72
+ "lib/arel/engines/sql/compilers/ibm_db_compiler.rb",
73
+ "lib/arel/engines/sql/compilers/mysql_compiler.rb",
74
+ "lib/arel/engines/sql/compilers/oracle_compiler.rb",
75
+ "lib/arel/engines/sql/compilers/postgresql_compiler.rb",
76
+ "lib/arel/engines/sql/compilers/sqlite_compiler.rb",
72
77
  "lib/arel/engines/sql/core_extensions.rb",
73
78
  "lib/arel/engines/sql/core_extensions/array.rb",
74
79
  "lib/arel/engines/sql/core_extensions/nil_class.rb",
@@ -79,6 +84,7 @@ and query generation.}
79
84
  "lib/arel/engines/sql/predicates.rb",
80
85
  "lib/arel/engines/sql/primitives.rb",
81
86
  "lib/arel/engines/sql/relations.rb",
87
+ "lib/arel/engines/sql/relations/compiler.rb",
82
88
  "lib/arel/engines/sql/relations/operations/alias.rb",
83
89
  "lib/arel/engines/sql/relations/operations/join.rb",
84
90
  "lib/arel/engines/sql/relations/relation.rb",
@@ -146,6 +152,7 @@ and query generation.}
146
152
  "spec/arel/engines/sql/unit/relations/update_spec.rb",
147
153
  "spec/arel/engines/sql/unit/relations/where_spec.rb",
148
154
  "spec/connections/mysql_connection.rb",
155
+ "spec/connections/oracle_connection.rb",
149
156
  "spec/connections/postgresql_connection.rb",
150
157
  "spec/connections/sqlite3_connection.rb",
151
158
  "spec/doubles/hash.rb",
@@ -153,6 +160,7 @@ and query generation.}
153
160
  "spec/matchers/disambiguate_attributes.rb",
154
161
  "spec/matchers/hash_the_same_as.rb",
155
162
  "spec/schemas/mysql_schema.rb",
163
+ "spec/schemas/oracle_schema.rb",
156
164
  "spec/schemas/postgresql_schema.rb",
157
165
  "spec/schemas/sqlite3_schema.rb",
158
166
  "spec/spec.opts",
@@ -161,7 +169,7 @@ and query generation.}
161
169
  s.homepage = %q{http://github.com/brynary/arel}
162
170
  s.require_paths = ["lib"]
163
171
  s.rubyforge_project = %q{arel}
164
- s.rubygems_version = %q{1.3.5}
172
+ s.rubygems_version = %q{1.3.6}
165
173
  s.summary = %q{Arel is a relational algebra engine for Ruby}
166
174
  s.test_files = [
167
175
  "spec/arel/algebra/unit/predicates/binary_spec.rb",
@@ -221,6 +229,7 @@ and query generation.}
221
229
  "spec/arel/engines/sql/unit/relations/update_spec.rb",
222
230
  "spec/arel/engines/sql/unit/relations/where_spec.rb",
223
231
  "spec/connections/mysql_connection.rb",
232
+ "spec/connections/oracle_connection.rb",
224
233
  "spec/connections/postgresql_connection.rb",
225
234
  "spec/connections/sqlite3_connection.rb",
226
235
  "spec/doubles/hash.rb",
@@ -228,6 +237,7 @@ and query generation.}
228
237
  "spec/matchers/disambiguate_attributes.rb",
229
238
  "spec/matchers/hash_the_same_as.rb",
230
239
  "spec/schemas/mysql_schema.rb",
240
+ "spec/schemas/oracle_schema.rb",
231
241
  "spec/schemas/postgresql_schema.rb",
232
242
  "spec/schemas/sqlite3_schema.rb",
233
243
  "spec/spec_helper.rb"
data/lib/arel.rb CHANGED
@@ -7,5 +7,5 @@ module Arel
7
7
  require 'arel/engines'
8
8
  autoload :Session, 'arel/session'
9
9
 
10
- VERSION = "0.2.1"
11
- end
10
+ VERSION = "0.3.0"
11
+ end
@@ -84,7 +84,8 @@ module Arel
84
84
 
85
85
  module AttributeAccessable
86
86
  def [](index)
87
- case index
87
+ @cached_attributes ||= {}
88
+ @cached_attributes[index] ||= case index
88
89
  when Symbol, String
89
90
  find_attribute_matching_name(index)
90
91
  when Attribute, Expression
@@ -96,7 +97,7 @@ module Arel
96
97
  end
97
98
 
98
99
  def find_attribute_matching_name(name)
99
- attributes.detect { |a| a.named?(name) }
100
+ attributes.detect { |a| a.named?(name) } || Attribute.new(self, name)
100
101
  end
101
102
 
102
103
  def find_attribute_matching_attribute(attribute)
@@ -0,0 +1,62 @@
1
+ # +-----------------------------------------------------------------------+
2
+ # | |
3
+ # | Copyright (c) 2010 IBM Corporation |
4
+ # | |
5
+ # | Permission is hereby granted, free of charge, to any person obtaining |
6
+ # | a copy of this software and associated documentation files (the |
7
+ # | "Software"), to deal in the Software without restriction, including |
8
+ # | without limitation the rights to use, copy, modify, merge, publish, |
9
+ # | distribute, sublicense, and/or sell copies of the Software, and to |
10
+ # | permit persons to whom the Software is furnished to do so, subject to |
11
+ # | the following conditions: |
12
+ # | |
13
+ # | The above copyright notice and this permission notice shall be |
14
+ # | included in all copies or substantial portions of the Software. |
15
+ # | |
16
+ # | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
17
+ # | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
18
+ # | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.|
19
+ # | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR |
20
+ # | ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
21
+ # | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
22
+ # | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
23
+ # | |
24
+ # +-----------------------------------------------------------------------+
25
+
26
+ #
27
+ # Author: Praveen Devarao <praveendrl@in.ibm.com>
28
+ #
29
+
30
+ module Arel
31
+ module SqlCompiler
32
+ class IBM_DBCompiler < GenericCompiler
33
+
34
+ def select_sql
35
+ query = build_query \
36
+ "SELECT #{select_clauses.join(', ')}",
37
+ "FROM #{from_clauses}",
38
+ (joins(self) unless joins(self).blank? ),
39
+ ("WHERE #{where_clauses.join(" AND ")}" unless wheres.blank? ),
40
+ ("GROUP BY #{group_clauses.join(', ')}" unless groupings.blank? ),
41
+ ("HAVING #{having_clauses.join(', ')}" unless havings.blank? ),
42
+ ("ORDER BY #{order_clauses.join(', ')}" unless orders.blank? )
43
+ engine.add_limit_offset!(query,{:limit=>taken,:offset=>skipped}) unless taken.blank?
44
+ query << "#{locked}" unless locked.blank?
45
+ query
46
+ end
47
+
48
+ def limited_update_conditions(conditions, taken)
49
+ quoted_primary_key = engine.quote_table_name(primary_key)
50
+ update_conditions = "WHERE #{quoted_primary_key} IN (SELECT #{quoted_primary_key} FROM #{engine.connection.quote_table_name table.name} #{conditions} " #Note: - ')' not added, limit segment is to be appended
51
+ engine.add_limit_offset!(update_conditions,{:limit=>taken,:offset=>nil})
52
+ update_conditions << ")" # Close the sql segment
53
+ update_conditions
54
+ end
55
+
56
+ def add_limit_on_delete(taken)
57
+ raise "IBM_DB does not support limit on deletion" # Limiting the number of rows to be deleted is not supported by IBM_DB
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,11 @@
1
+ module Arel
2
+ module SqlCompiler
3
+ class MySQLCompiler < GenericCompiler
4
+ def limited_update_conditions(conditions, taken)
5
+ conditions << " LIMIT #{taken}"
6
+ conditions
7
+ end
8
+ end
9
+ end
10
+ end
11
+
@@ -0,0 +1,95 @@
1
+ module Arel
2
+ module SqlCompiler
3
+ class OracleCompiler < GenericCompiler
4
+
5
+ def select_sql
6
+ where_clauses_array = where_clauses
7
+ if limit_or_offset = !taken.blank? || !skipped.blank?
8
+ # if need to select first records without ORDER BY and GROUP BY
9
+ # then can use simple ROWNUM in WHERE clause
10
+ if skipped.blank? && groupings.blank? && orders.blank?
11
+ where_clauses_array << "ROWNUM <= #{taken}" if !taken.blank? && skipped.blank? && groupings.blank? && orders.blank?
12
+ limit_or_offset = false
13
+ end
14
+ end
15
+
16
+ # when limit or offset subquery is used then cannot use FOR UPDATE directly
17
+ # and need to construct separate subquery for primary key
18
+ if use_subquery_for_lock = limit_or_offset && !locked.blank?
19
+ quoted_primary_key = engine.quote_column_name(primary_key)
20
+ end
21
+ select_attributes_string = use_subquery_for_lock ? quoted_primary_key : select_clauses.join(', ')
22
+
23
+ # OracleEnhanced adapter workaround when ORDER BY is used with columns not
24
+ # present in DISTINCT columns list
25
+ order_clauses_array = if select_attributes_string =~ /DISTINCT.*FIRST_VALUE/ && !orders.blank?
26
+ order = order_clauses.join(', ').split(',').map { |s| s.strip }.reject(&:blank?)
27
+ order = order.zip((0...order.size).to_a).map { |s,i| "alias_#{i}__ #{'DESC' if s =~ /\bdesc$/i}" }
28
+ else
29
+ order_clauses
30
+ end
31
+
32
+ query = build_query \
33
+ "SELECT #{select_attributes_string}",
34
+ "FROM #{from_clauses}",
35
+ (joins(self) unless joins(self).blank? ),
36
+ ("WHERE #{where_clauses_array.join(" AND ")}" unless where_clauses_array.blank? ),
37
+ ("GROUP BY #{group_clauses.join(', ')}" unless groupings.blank? ),
38
+ ("HAVING #{having_clauses.join(', ')}" unless havings.blank? ),
39
+ ("ORDER BY #{order_clauses_array.join(', ')}" unless order_clauses_array.blank? )
40
+
41
+ # Use existing method from oracle_enhanced adapter to implement limit and offset using subqueries
42
+ engine.add_limit_offset!(query, :limit => taken, :offset => skipped) if limit_or_offset
43
+
44
+ if use_subquery_for_lock
45
+ build_query \
46
+ "SELECT #{select_clauses.join(', ')}",
47
+ "FROM #{from_clauses}",
48
+ "WHERE #{quoted_primary_key} IN (#{query})",
49
+ "#{locked}"
50
+ elsif !locked.blank?
51
+ build_query query, "#{locked}"
52
+ else
53
+ query
54
+ end
55
+ end
56
+
57
+ def delete_sql
58
+ where_clauses_array = wheres.collect(&:to_sql)
59
+ where_clauses_array << "ROWNUM <= #{taken}" unless taken.blank?
60
+ build_query \
61
+ "DELETE",
62
+ "FROM #{table_sql}",
63
+ ("WHERE #{where_clauses_array.join(' AND ')}" unless where_clauses_array.blank? )
64
+ end
65
+
66
+ protected
67
+
68
+ def build_update_conditions_sql
69
+ conditions = ""
70
+ where_clauses_array = wheres.collect(&:to_sql)
71
+ # if need to select first records without ORDER BY
72
+ # then can use simple ROWNUM in WHERE clause
73
+ if !taken.blank? && orders.blank?
74
+ where_clauses_array << "ROWNUM <= #{taken}"
75
+ end
76
+ conditions << " WHERE #{where_clauses_array.join(' AND ')}" unless where_clauses_array.blank?
77
+ unless taken.blank?
78
+ conditions = limited_update_conditions(conditions, taken)
79
+ end
80
+ conditions
81
+ end
82
+
83
+ def limited_update_conditions(conditions, taken)
84
+ # need to add ORDER BY only if just taken ones should be updated
85
+ conditions << " ORDER BY #{order_clauses.join(', ')}" unless orders.blank?
86
+ quoted_primary_key = engine.quote_column_name(primary_key)
87
+ subquery = "SELECT #{quoted_primary_key} FROM #{engine.connection.quote_table_name table.name} #{conditions}"
88
+ # Use existing method from oracle_enhanced adapter to get taken records when ORDER BY is used
89
+ engine.add_limit_offset!(subquery, :limit => taken) unless orders.blank?
90
+ "WHERE #{quoted_primary_key} IN (#{subquery})"
91
+ end
92
+
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,42 @@
1
+ module Arel
2
+ module SqlCompiler
3
+ class PostgreSQLCompiler < GenericCompiler
4
+
5
+ def select_sql
6
+ if !orders.blank? && using_distinct_on?
7
+ subquery = build_query \
8
+ "SELECT #{select_clauses.kind_of?(::Array) ? select_clauses.join("") : select_clauses.to_s}",
9
+ "FROM #{from_clauses}",
10
+ (joins(self) unless joins(self).blank? ),
11
+ ("WHERE #{where_clauses.join(" AND ")}" unless wheres.blank? ),
12
+ ("GROUP BY #{group_clauses.join(', ')}" unless groupings.blank? ),
13
+ ("HAVING #{having_clauses.join(', ')}" unless havings.blank? ),
14
+ ("#{locked}" unless locked.blank? )
15
+
16
+ build_query \
17
+ "SELECT * FROM (#{subquery}) AS id_list",
18
+ "ORDER BY #{aliased_orders(order_clauses)}",
19
+ ("LIMIT #{taken}" unless taken.blank? ),
20
+ ("OFFSET #{skipped}" unless skipped.blank? )
21
+ else
22
+ super
23
+ end
24
+ end
25
+
26
+ def using_distinct_on?
27
+ select_clauses.any? { |x| x =~ /DISTINCT ON/ }
28
+ end
29
+
30
+ def aliased_orders(orders)
31
+ # PostgreSQL does not allow arbitrary ordering when using DISTINCT ON, so we work around this
32
+ # by wrapping the +sql+ string as a sub-select and ordering in that query.
33
+ order = orders.join(', ').split(/,/).map { |s| s.strip }.reject(&:blank?)
34
+ order = order.zip((0...order.size).to_a).map { |s,i| "id_list.alias_#{i} #{'DESC' if s =~ /\bdesc$/i}" }.join(', ')
35
+ end
36
+
37
+ def supports_insert_with_returning?
38
+ engine.postgresql_version >= 80200
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,9 @@
1
+ module Arel
2
+ module SqlCompiler
3
+ class SQLiteCompiler < GenericCompiler
4
+ def locked
5
+ nil
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,16 +1,23 @@
1
1
  module Arel
2
2
  module Sql
3
3
  class Engine
4
+
4
5
  def initialize(ar = nil)
5
6
  @ar = ar
6
7
  end
7
8
 
8
9
  def connection
9
- @ar.connection
10
+ @ar ? @ar.connection : nil
10
11
  end
11
12
 
12
13
  def adapter_name
13
- @adapter_name ||= connection.adapter_name
14
+ @adapter_name ||= case (name = connection.adapter_name)
15
+ # map OracleEnanced adapter to Oracle
16
+ when /Oracle/
17
+ 'Oracle'
18
+ else
19
+ name
20
+ end
14
21
  end
15
22
 
16
23
  def method_missing(method, *args, &block)
@@ -19,7 +26,14 @@ module Arel
19
26
 
20
27
  module CRUD
21
28
  def create(relation)
22
- connection.insert(relation.to_sql)
29
+ primary_key_value = if relation.primary_key.blank?
30
+ nil
31
+ elsif relation.record.is_a?(Hash)
32
+ attribute = relation.record.detect { |attr, _| attr.name.to_s == relation.primary_key.to_s }
33
+ attribute && attribute.last.value
34
+ end
35
+
36
+ connection.insert(relation.to_sql(false), nil, relation.primary_key, primary_key_value)
23
37
  end
24
38
 
25
39
  def read(relation)
@@ -93,7 +93,7 @@ module Arel
93
93
 
94
94
  class TableReference < Formatter
95
95
  def select(select_sql, table)
96
- "(#{select_sql}) AS #{quote_table_name(name_for(table))}"
96
+ "(#{select_sql}) #{quote_table_name(name_for(table))}"
97
97
  end
98
98
 
99
99
  def table(table)
@@ -101,7 +101,7 @@ module Arel
101
101
  table.name
102
102
  else
103
103
  quote_table_name(table.name) +
104
- (table.name != name_for(table) ? " AS " + quote_table_name(name_for(table)) : '')
104
+ (table.name != name_for(table) ? " #{quote_table_name(name_for(table))}" : '')
105
105
  end
106
106
  end
107
107
  end
@@ -112,7 +112,7 @@ module Arel
112
112
  end
113
113
 
114
114
  def range(left, right)
115
- "#{left} AND #{right}"
115
+ "#{scalar(left)} AND #{scalar(right)}"
116
116
  end
117
117
  end
118
118
 
@@ -2,6 +2,7 @@ require 'arel/engines/sql/relations/utilities/compound'
2
2
  require 'arel/engines/sql/relations/utilities/recursion'
3
3
  require 'arel/engines/sql/relations/utilities/externalization'
4
4
  require 'arel/engines/sql/relations/utilities/nil'
5
+ require 'arel/engines/sql/relations/compiler'
5
6
  require 'arel/engines/sql/relations/relation'
6
7
  require 'arel/engines/sql/relations/table'
7
8
  require 'arel/engines/sql/relations/operations/join'