activerecord 4.2.0.beta4 → 4.2.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +107 -34
- data/lib/active_record/aggregations.rb +2 -2
- data/lib/active_record/associations.rb +1 -1
- data/lib/active_record/associations/alias_tracker.rb +3 -12
- data/lib/active_record/associations/association_scope.rb +1 -2
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +2 -2
- data/lib/active_record/associations/collection_association.rb +29 -6
- data/lib/active_record/associations/has_many_association.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +2 -2
- data/lib/active_record/associations/join_dependency.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +1 -1
- data/lib/active_record/associations/preloader.rb +1 -0
- data/lib/active_record/associations/preloader/association.rb +3 -8
- data/lib/active_record/associations/preloader/through_association.rb +1 -0
- data/lib/active_record/associations/singular_association.rb +2 -1
- data/lib/active_record/attribute_methods.rb +2 -2
- data/lib/active_record/attribute_methods/dirty.rb +1 -1
- data/lib/active_record/attribute_methods/primary_key.rb +2 -1
- data/lib/active_record/attribute_methods/read.rb +13 -5
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -1
- data/lib/active_record/attribute_set.rb +7 -11
- data/lib/active_record/attribute_set/builder.rb +66 -17
- data/lib/active_record/attributes.rb +20 -3
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +0 -4
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +1 -3
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +25 -24
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +9 -3
- data/lib/active_record/connection_adapters/abstract_adapter.rb +9 -7
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +25 -13
- data/lib/active_record/connection_adapters/connection_specification.rb +1 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +6 -0
- data/lib/active_record/connection_adapters/mysql_adapter.rb +6 -2
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +0 -4
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +6 -16
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +29 -7
- data/lib/active_record/connection_adapters/postgresql/utils.rb +15 -4
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +15 -6
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +5 -7
- data/lib/active_record/connection_handling.rb +1 -1
- data/lib/active_record/core.rb +5 -3
- data/lib/active_record/enum.rb +1 -1
- data/lib/active_record/errors.rb +21 -0
- data/lib/active_record/fixtures.rb +4 -2
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/locking/optimistic.rb +1 -1
- data/lib/active_record/migration.rb +15 -4
- data/lib/active_record/model_schema.rb +8 -4
- data/lib/active_record/persistence.rb +5 -5
- data/lib/active_record/railtie.rb +0 -2
- data/lib/active_record/railties/databases.rake +7 -6
- data/lib/active_record/reflection.rb +2 -2
- data/lib/active_record/relation.rb +21 -13
- data/lib/active_record/relation/calculations.rb +1 -0
- data/lib/active_record/relation/finder_methods.rb +8 -5
- data/lib/active_record/relation/merger.rb +0 -12
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +30 -18
- data/lib/active_record/sanitization.rb +4 -1
- data/lib/active_record/schema_dumper.rb +1 -6
- data/lib/active_record/scoping/named.rb +1 -1
- data/lib/active_record/statement_cache.rb +21 -10
- data/lib/active_record/tasks/database_tasks.rb +17 -2
- data/lib/active_record/tasks/mysql_database_tasks.rb +1 -0
- data/lib/active_record/type.rb +1 -0
- data/lib/active_record/type/big_integer.rb +13 -0
- data/lib/active_record/type/decimal_without_scale.rb +2 -2
- data/lib/active_record/type/hash_lookup_type_map.rb +5 -7
- data/lib/active_record/type/integer.rb +29 -1
- data/lib/active_record/type/serialized.rb +1 -1
- data/lib/active_record/type/string.rb +4 -4
- data/lib/active_record/type/type_map.rb +23 -7
- data/lib/active_record/validations.rb +4 -3
- data/lib/active_record/validations/uniqueness.rb +1 -1
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +3 -0
- data/lib/rails/generators/active_record/migration/templates/migration.rb +6 -0
- metadata +15 -20
@@ -571,6 +571,9 @@ module ActiveRecord
|
|
571
571
|
# rename_index :people, 'index_people_on_last_name', 'index_users_on_last_name'
|
572
572
|
#
|
573
573
|
def rename_index(table_name, old_name, new_name)
|
574
|
+
if new_name.length > allowed_index_name_length
|
575
|
+
raise ArgumentError, "Index name '#{new_name}' on table '#{table_name}' is too long; the limit is #{allowed_index_name_length} characters"
|
576
|
+
end
|
574
577
|
# this is a naive implementation; some DBs may support this more efficiently (Postgres, for instance)
|
575
578
|
old_index_def = indexes(table_name).detect { |i| i.name == old_name }
|
576
579
|
return unless old_index_def
|
@@ -740,7 +743,7 @@ module ActiveRecord
|
|
740
743
|
end
|
741
744
|
|
742
745
|
fk_name_to_delete = options.fetch(:name) do
|
743
|
-
fk_to_delete = foreign_keys(from_table).detect {|fk| fk.column == options[:column] }
|
746
|
+
fk_to_delete = foreign_keys(from_table).detect {|fk| fk.column == options[:column].to_s }
|
744
747
|
|
745
748
|
if fk_to_delete
|
746
749
|
fk_to_delete.name
|
@@ -835,11 +838,14 @@ module ActiveRecord
|
|
835
838
|
columns
|
836
839
|
end
|
837
840
|
|
838
|
-
|
841
|
+
include TimestampDefaultDeprecation
|
842
|
+
# Adds timestamps (+created_at+ and +updated_at+) columns to +table_name+.
|
843
|
+
# Additional options (like <tt>null: false</tt>) are forwarded to #add_column.
|
839
844
|
#
|
840
|
-
# add_timestamps(:suppliers)
|
845
|
+
# add_timestamps(:suppliers, null: false)
|
841
846
|
#
|
842
847
|
def add_timestamps(table_name, options = {})
|
848
|
+
emit_warning_if_null_unspecified(options)
|
843
849
|
add_column table_name, :created_at, :datetime, options
|
844
850
|
add_column table_name, :updated_at, :datetime, options
|
845
851
|
end
|
@@ -14,10 +14,7 @@ module ActiveRecord
|
|
14
14
|
module ConnectionAdapters # :nodoc:
|
15
15
|
extend ActiveSupport::Autoload
|
16
16
|
|
17
|
-
|
18
|
-
autoload :Column
|
19
|
-
autoload :NullColumn
|
20
|
-
end
|
17
|
+
autoload :Column
|
21
18
|
autoload :ConnectionSpecification
|
22
19
|
|
23
20
|
autoload_at 'active_record/connection_adapters/abstract/schema_definitions' do
|
@@ -27,6 +24,7 @@ module ActiveRecord
|
|
27
24
|
autoload :TableDefinition
|
28
25
|
autoload :Table
|
29
26
|
autoload :AlterTable
|
27
|
+
autoload :TimestampDefaultDeprecation
|
30
28
|
end
|
31
29
|
|
32
30
|
autoload_at 'active_record/connection_adapters/abstract/connection_pool' do
|
@@ -265,10 +263,10 @@ module ActiveRecord
|
|
265
263
|
|
266
264
|
# QUOTING ==================================================
|
267
265
|
|
268
|
-
# Returns a bind substitution value given a bind +
|
266
|
+
# Returns a bind substitution value given a bind +column+
|
269
267
|
# NOTE: The column param is currently being used by the sqlserver-adapter
|
270
|
-
def substitute_at(column,
|
271
|
-
Arel::Nodes::BindParam.new
|
268
|
+
def substitute_at(column, _unused = 0)
|
269
|
+
Arel::Nodes::BindParam.new
|
272
270
|
end
|
273
271
|
|
274
272
|
# REFERENTIAL INTEGRITY ====================================
|
@@ -386,6 +384,10 @@ module ActiveRecord
|
|
386
384
|
type_map.lookup(sql_type)
|
387
385
|
end
|
388
386
|
|
387
|
+
def column_name_for_operation(operation, node) # :nodoc:
|
388
|
+
node.to_sql
|
389
|
+
end
|
390
|
+
|
389
391
|
protected
|
390
392
|
|
391
393
|
def initialize_type_map(m) # :nodoc:
|
@@ -285,7 +285,9 @@ module ActiveRecord
|
|
285
285
|
end
|
286
286
|
end
|
287
287
|
|
288
|
+
#--
|
288
289
|
# DATABASE STATEMENTS ======================================
|
290
|
+
#++
|
289
291
|
|
290
292
|
def clear_cache!
|
291
293
|
super
|
@@ -585,14 +587,6 @@ module ActiveRecord
|
|
585
587
|
end
|
586
588
|
end
|
587
589
|
|
588
|
-
def add_column_position!(sql, options)
|
589
|
-
if options[:first]
|
590
|
-
sql << " FIRST"
|
591
|
-
elsif options[:after]
|
592
|
-
sql << " AFTER #{quote_column_name(options[:after])}"
|
593
|
-
end
|
594
|
-
end
|
595
|
-
|
596
590
|
# SHOW VARIABLES LIKE 'name'
|
597
591
|
def show_variable(name)
|
598
592
|
variables = select_all("SHOW VARIABLES LIKE '#{name}'", 'SCHEMA')
|
@@ -639,10 +633,6 @@ module ActiveRecord
|
|
639
633
|
end
|
640
634
|
end
|
641
635
|
|
642
|
-
def limited_update_conditions(where_sql, quoted_table_name, quoted_primary_key)
|
643
|
-
where_sql
|
644
|
-
end
|
645
|
-
|
646
636
|
def strict_mode?
|
647
637
|
self.class.type_cast_config_to_boolean(@config.fetch(:strict, true))
|
648
638
|
end
|
@@ -656,6 +646,8 @@ module ActiveRecord
|
|
656
646
|
def initialize_type_map(m) # :nodoc:
|
657
647
|
super
|
658
648
|
|
649
|
+
register_class_with_limit m, %r(char)i, MysqlString
|
650
|
+
|
659
651
|
m.register_type %r(tinytext)i, Type::Text.new(limit: 2**8 - 1)
|
660
652
|
m.register_type %r(tinyblob)i, Type::Binary.new(limit: 2**8 - 1)
|
661
653
|
m.register_type %r(text)i, Type::Text.new(limit: 2**16 - 1)
|
@@ -680,7 +672,7 @@ module ActiveRecord
|
|
680
672
|
m.register_type(%r(enum)i) do |sql_type|
|
681
673
|
limit = sql_type[/^enum\((.+)\)/i, 1]
|
682
674
|
.split(',').map{|enum| enum.strip.length - 2}.max
|
683
|
-
|
675
|
+
MysqlString.new(limit: limit)
|
684
676
|
end
|
685
677
|
end
|
686
678
|
|
@@ -855,6 +847,26 @@ module ActiveRecord
|
|
855
847
|
end
|
856
848
|
end
|
857
849
|
end
|
850
|
+
|
851
|
+
class MysqlString < Type::String # :nodoc:
|
852
|
+
def type_cast_for_database(value)
|
853
|
+
case value
|
854
|
+
when true then "1"
|
855
|
+
when false then "0"
|
856
|
+
else super
|
857
|
+
end
|
858
|
+
end
|
859
|
+
|
860
|
+
private
|
861
|
+
|
862
|
+
def cast_value(value)
|
863
|
+
case value
|
864
|
+
when true then "1"
|
865
|
+
when false then "0"
|
866
|
+
else super
|
867
|
+
end
|
868
|
+
end
|
869
|
+
end
|
858
870
|
end
|
859
871
|
end
|
860
872
|
end
|
@@ -234,7 +234,7 @@ module ActiveRecord
|
|
234
234
|
end
|
235
235
|
end
|
236
236
|
|
237
|
-
# Takes the environment such as
|
237
|
+
# Takes the environment such as +:production+ or +:development+.
|
238
238
|
# This requires that the @configurations was initialized with a key that
|
239
239
|
# matches.
|
240
240
|
#
|
@@ -66,7 +66,9 @@ module ActiveRecord
|
|
66
66
|
exception.error_number if exception.respond_to?(:error_number)
|
67
67
|
end
|
68
68
|
|
69
|
+
#--
|
69
70
|
# QUOTING ==================================================
|
71
|
+
#++
|
70
72
|
|
71
73
|
def quote_string(string)
|
72
74
|
@connection.escape(string)
|
@@ -80,7 +82,9 @@ module ActiveRecord
|
|
80
82
|
end
|
81
83
|
end
|
82
84
|
|
85
|
+
#--
|
83
86
|
# CONNECTION MANAGEMENT ====================================
|
87
|
+
#++
|
84
88
|
|
85
89
|
def active?
|
86
90
|
return false unless @connection
|
@@ -104,7 +108,9 @@ module ActiveRecord
|
|
104
108
|
end
|
105
109
|
end
|
106
110
|
|
111
|
+
#--
|
107
112
|
# DATABASE STATEMENTS ======================================
|
113
|
+
#++
|
108
114
|
|
109
115
|
def explain(arel, binds = [])
|
110
116
|
sql = "EXPLAIN #{to_sql(arel, binds.dup)}"
|
@@ -58,7 +58,7 @@ module ActiveRecord
|
|
58
58
|
# * <tt>:encoding</tt> - (Optional) Sets the client encoding by executing "SET NAMES <encoding>" after connection.
|
59
59
|
# * <tt>:reconnect</tt> - Defaults to false (See MySQL documentation: http://dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html).
|
60
60
|
# * <tt>:strict</tt> - Defaults to true. Enable STRICT_ALL_TABLES. (See MySQL documentation: http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html)
|
61
|
-
# * <tt>:variables</tt> - (Optional) A hash session variables to send as
|
61
|
+
# * <tt>:variables</tt> - (Optional) A hash session variables to send as <tt>SET @@SESSION.key = value</tt> on each database connection. Use the value +:default+ to set a variable to its DEFAULT value. (See MySQL documentation: http://dev.mysql.com/doc/refman/5.0/en/set-statement.html).
|
62
62
|
# * <tt>:sslca</tt> - Necessary to use MySQL with an SSL connection.
|
63
63
|
# * <tt>:sslkey</tt> - Necessary to use MySQL with an SSL connection.
|
64
64
|
# * <tt>:sslcert</tt> - Necessary to use MySQL with an SSL connection.
|
@@ -88,7 +88,7 @@ module ActiveRecord
|
|
88
88
|
end
|
89
89
|
|
90
90
|
def clear
|
91
|
-
cache.
|
91
|
+
cache.each_value do |hash|
|
92
92
|
hash[:stmt].close
|
93
93
|
end
|
94
94
|
cache.clear
|
@@ -137,7 +137,9 @@ module ActiveRecord
|
|
137
137
|
@connection.quote(string)
|
138
138
|
end
|
139
139
|
|
140
|
+
#--
|
140
141
|
# CONNECTION MANAGEMENT ====================================
|
142
|
+
#++
|
141
143
|
|
142
144
|
def active?
|
143
145
|
if @connection.respond_to?(:stat)
|
@@ -178,7 +180,9 @@ module ActiveRecord
|
|
178
180
|
end
|
179
181
|
end
|
180
182
|
|
183
|
+
#--
|
181
184
|
# DATABASE STATEMENTS ======================================
|
185
|
+
#++
|
182
186
|
|
183
187
|
def select_rows(sql, name = nil, binds = [])
|
184
188
|
@connection.query_with_result = true
|
@@ -156,10 +156,6 @@ module ActiveRecord
|
|
156
156
|
end
|
157
157
|
end
|
158
158
|
|
159
|
-
def substitute_at(column, index)
|
160
|
-
Arel::Nodes::BindParam.new "$#{index + 1}"
|
161
|
-
end
|
162
|
-
|
163
159
|
def exec_query(sql, name = 'SQL', binds = [])
|
164
160
|
execute_and_clear(sql, name, binds) do |result|
|
165
161
|
types = {}
|
@@ -14,22 +14,6 @@ module ActiveRecord
|
|
14
14
|
@connection.unescape_bytea(value) if value
|
15
15
|
end
|
16
16
|
|
17
|
-
# Quotes PostgreSQL-specific data types for SQL input.
|
18
|
-
def quote(value, column = nil) #:nodoc:
|
19
|
-
return super unless column
|
20
|
-
|
21
|
-
case value
|
22
|
-
when Float
|
23
|
-
if value.infinite? || value.nan?
|
24
|
-
"'#{value}'"
|
25
|
-
else
|
26
|
-
super
|
27
|
-
end
|
28
|
-
else
|
29
|
-
super
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
17
|
# Quotes strings for use in SQL input.
|
34
18
|
def quote_string(s) #:nodoc:
|
35
19
|
@connection.escape(s)
|
@@ -94,6 +78,12 @@ module ActiveRecord
|
|
94
78
|
elsif value.hex?
|
95
79
|
"X'#{value}'"
|
96
80
|
end
|
81
|
+
when Float
|
82
|
+
if value.infinite? || value.nan?
|
83
|
+
"'#{value}'"
|
84
|
+
else
|
85
|
+
super
|
86
|
+
end
|
97
87
|
else
|
98
88
|
super
|
99
89
|
end
|
@@ -4,12 +4,6 @@ module ActiveRecord
|
|
4
4
|
class SchemaCreation < AbstractAdapter::SchemaCreation
|
5
5
|
private
|
6
6
|
|
7
|
-
def visit_AddColumn(o)
|
8
|
-
sql_type = type_to_sql(o.type, o.limit, o.precision, o.scale)
|
9
|
-
sql = "ADD COLUMN #{quote_column_name(o.name)} #{sql_type}"
|
10
|
-
add_column_options!(sql, column_options(o))
|
11
|
-
end
|
12
|
-
|
13
7
|
def visit_ColumnDefinition(o)
|
14
8
|
sql = super
|
15
9
|
if o.primary_key? && o.type != :primary_key
|
@@ -293,6 +287,23 @@ module ActiveRecord
|
|
293
287
|
result.rows.first.first
|
294
288
|
end
|
295
289
|
|
290
|
+
# Sets the sequence of a table's primary key to the specified value.
|
291
|
+
def set_pk_sequence!(table, value) #:nodoc:
|
292
|
+
pk, sequence = pk_and_sequence_for(table)
|
293
|
+
|
294
|
+
if pk
|
295
|
+
if sequence
|
296
|
+
quoted_sequence = quote_table_name(sequence)
|
297
|
+
|
298
|
+
select_value <<-end_sql, 'SCHEMA'
|
299
|
+
SELECT setval('#{quoted_sequence}', #{value})
|
300
|
+
end_sql
|
301
|
+
else
|
302
|
+
@logger.warn "#{table} has primary key #{pk} with no default sequence" if @logger
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
296
307
|
# Resets the sequence of a table's primary key to the maximum value.
|
297
308
|
def reset_pk_sequence!(table, pk = nil, sequence = nil) #:nodoc:
|
298
309
|
unless pk and sequence
|
@@ -394,7 +405,10 @@ module ActiveRecord
|
|
394
405
|
pk, seq = pk_and_sequence_for(new_name)
|
395
406
|
if seq && seq.identifier == "#{table_name}_#{pk}_seq"
|
396
407
|
new_seq = "#{new_name}_#{pk}_seq"
|
408
|
+
idx = "#{table_name}_pkey"
|
409
|
+
new_idx = "#{new_name}_pkey"
|
397
410
|
execute "ALTER TABLE #{quote_table_name(seq)} RENAME TO #{quote_table_name(new_seq)}"
|
411
|
+
execute "ALTER INDEX #{quote_table_name(idx)} RENAME TO #{quote_table_name(new_idx)}"
|
398
412
|
end
|
399
413
|
|
400
414
|
rename_table_indexes(table_name, new_name)
|
@@ -413,7 +427,12 @@ module ActiveRecord
|
|
413
427
|
quoted_table_name = quote_table_name(table_name)
|
414
428
|
sql_type = type_to_sql(type, options[:limit], options[:precision], options[:scale])
|
415
429
|
sql_type << "[]" if options[:array]
|
416
|
-
|
430
|
+
sql = "ALTER TABLE #{quoted_table_name} ALTER COLUMN #{quote_column_name(column_name)} TYPE #{sql_type}"
|
431
|
+
sql << " USING #{options[:using]}" if options[:using]
|
432
|
+
if options[:cast_as]
|
433
|
+
sql << " USING CAST(#{quote_column_name(column_name)} AS #{type_to_sql(options[:cast_as], options[:limit], options[:precision], options[:scale])})"
|
434
|
+
end
|
435
|
+
execute sql
|
417
436
|
|
418
437
|
change_column_default(table_name, column_name, options[:default]) if options_include_default?(options)
|
419
438
|
change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
|
@@ -461,6 +480,9 @@ module ActiveRecord
|
|
461
480
|
end
|
462
481
|
|
463
482
|
def rename_index(table_name, old_name, new_name)
|
483
|
+
if new_name.length > allowed_index_name_length
|
484
|
+
raise ArgumentError, "Index name '#{new_name}' on table '#{table_name}' is too long; the limit is #{allowed_index_name_length} characters"
|
485
|
+
end
|
464
486
|
execute "ALTER INDEX #{quote_column_name(old_name)} RENAME TO #{quote_table_name(new_name)}"
|
465
487
|
end
|
466
488
|
|
@@ -18,7 +18,11 @@ module ActiveRecord
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def quoted
|
21
|
-
|
21
|
+
if schema
|
22
|
+
PGconn.quote_ident(schema) << SEPARATOR << PGconn.quote_ident(identifier)
|
23
|
+
else
|
24
|
+
PGconn.quote_ident(identifier)
|
25
|
+
end
|
22
26
|
end
|
23
27
|
|
24
28
|
def ==(o)
|
@@ -32,8 +36,11 @@ module ActiveRecord
|
|
32
36
|
|
33
37
|
protected
|
34
38
|
def unquote(part)
|
35
|
-
|
36
|
-
|
39
|
+
if part && part.start_with?('"')
|
40
|
+
part[1..-2]
|
41
|
+
else
|
42
|
+
part
|
43
|
+
end
|
37
44
|
end
|
38
45
|
|
39
46
|
def parts
|
@@ -57,7 +64,11 @@ module ActiveRecord
|
|
57
64
|
# * <tt>"schema_name".table_name</tt>
|
58
65
|
# * <tt>"schema.name"."table name"</tt>
|
59
66
|
def extract_schema_qualified_name(string)
|
60
|
-
|
67
|
+
schema, table = string.scan(/[^".\s]+|"[^"]*"/)
|
68
|
+
if table.nil?
|
69
|
+
table = schema
|
70
|
+
schema = nil
|
71
|
+
end
|
61
72
|
PostgreSQL::Name.new(schema, table)
|
62
73
|
end
|
63
74
|
end
|
@@ -13,7 +13,7 @@ require 'active_record/connection_adapters/postgresql/database_statements'
|
|
13
13
|
require 'arel/visitors/bind_visitor'
|
14
14
|
|
15
15
|
# Make sure we're using pg high enough for PGResult#values
|
16
|
-
gem 'pg', '~> 0.
|
16
|
+
gem 'pg', '~> 0.15'
|
17
17
|
require 'pg'
|
18
18
|
|
19
19
|
require 'ipaddr'
|
@@ -104,6 +104,7 @@ module ActiveRecord
|
|
104
104
|
macaddr: { name: "macaddr" },
|
105
105
|
uuid: { name: "uuid" },
|
106
106
|
json: { name: "json" },
|
107
|
+
jsonb: { name: "jsonb" },
|
107
108
|
ltree: { name: "ltree" },
|
108
109
|
citext: { name: "citext" },
|
109
110
|
point: { name: "point" },
|
@@ -124,7 +125,7 @@ module ActiveRecord
|
|
124
125
|
PostgreSQL::SchemaCreation.new self
|
125
126
|
end
|
126
127
|
|
127
|
-
# Adds
|
128
|
+
# Adds +:array+ option to the default set provided by the
|
128
129
|
# AbstractAdapter
|
129
130
|
def prepare_column_options(column, types) # :nodoc:
|
130
131
|
spec = super
|
@@ -133,7 +134,7 @@ module ActiveRecord
|
|
133
134
|
spec
|
134
135
|
end
|
135
136
|
|
136
|
-
# Adds
|
137
|
+
# Adds +:array+ as a valid migration key
|
137
138
|
def migration_keys
|
138
139
|
super + [:array]
|
139
140
|
end
|
@@ -393,6 +394,16 @@ module ActiveRecord
|
|
393
394
|
super(oid)
|
394
395
|
end
|
395
396
|
|
397
|
+
def column_name_for_operation(operation, node) # :nodoc:
|
398
|
+
OPERATION_ALIASES.fetch(operation) { operation.downcase }
|
399
|
+
end
|
400
|
+
|
401
|
+
OPERATION_ALIASES = { # :nodoc:
|
402
|
+
"maximum" => "max",
|
403
|
+
"minimum" => "min",
|
404
|
+
"average" => "avg",
|
405
|
+
}
|
406
|
+
|
396
407
|
protected
|
397
408
|
|
398
409
|
# Returns the version of the connected PostgreSQL server.
|
@@ -585,9 +596,7 @@ module ActiveRecord
|
|
585
596
|
}
|
586
597
|
|
587
598
|
log(sql, name, type_casted_binds, stmt_key) do
|
588
|
-
@connection.
|
589
|
-
@connection.block
|
590
|
-
@connection.get_last_result
|
599
|
+
@connection.exec_prepared(stmt_key, type_casted_binds.map { |_, val| val })
|
591
600
|
end
|
592
601
|
rescue ActiveRecord::StatementInvalid => e
|
593
602
|
pgerror = e.original_exception
|