activerecord 5.0.0.beta3 → 5.0.0.beta4

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.

Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +225 -8
  3. data/examples/performance.rb +0 -1
  4. data/examples/simple.rb +0 -1
  5. data/lib/active_record.rb +0 -1
  6. data/lib/active_record/associations.rb +10 -6
  7. data/lib/active_record/associations/association.rb +1 -1
  8. data/lib/active_record/associations/builder/collection_association.rb +5 -1
  9. data/lib/active_record/associations/join_dependency.rb +1 -1
  10. data/lib/active_record/associations/preloader.rb +1 -0
  11. data/lib/active_record/associations/preloader/through_association.rb +15 -8
  12. data/lib/active_record/attribute/user_provided_default.rb +10 -5
  13. data/lib/active_record/attribute_methods/time_zone_conversion.rb +1 -1
  14. data/lib/active_record/attributes.rb +3 -3
  15. data/lib/active_record/autosave_association.rb +1 -1
  16. data/lib/active_record/base.rb +2 -1
  17. data/lib/active_record/collection_cache_key.rb +1 -1
  18. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +0 -19
  19. data/lib/active_record/connection_adapters/abstract/database_statements.rb +7 -8
  20. data/lib/active_record/connection_adapters/abstract/query_cache.rb +1 -1
  21. data/lib/active_record/connection_adapters/abstract/quoting.rb +7 -1
  22. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  23. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +16 -2
  24. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +9 -4
  25. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +20 -10
  26. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +85 -20
  27. data/lib/active_record/connection_adapters/abstract/transaction.rb +13 -1
  28. data/lib/active_record/connection_adapters/abstract_adapter.rb +37 -16
  29. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +119 -108
  30. data/lib/active_record/connection_adapters/column.rb +5 -6
  31. data/lib/active_record/connection_adapters/mysql/database_statements.rb +125 -0
  32. data/lib/active_record/connection_adapters/mysql/quoting.rb +51 -0
  33. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +27 -6
  34. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -13
  35. data/lib/active_record/connection_adapters/mysql2_adapter.rb +18 -55
  36. data/lib/active_record/connection_adapters/postgresql/column.rb +0 -1
  37. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
  38. data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
  39. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +7 -10
  40. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +65 -25
  41. data/lib/active_record/connection_adapters/postgresql_adapter.rb +59 -30
  42. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +48 -0
  43. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +7 -0
  44. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +19 -56
  45. data/lib/active_record/connection_adapters/statement_pool.rb +6 -4
  46. data/lib/active_record/core.rb +13 -4
  47. data/lib/active_record/enum.rb +1 -1
  48. data/lib/active_record/errors.rb +9 -0
  49. data/lib/active_record/fixture_set/file.rb +7 -1
  50. data/lib/active_record/gem_version.rb +1 -1
  51. data/lib/active_record/locking/optimistic.rb +4 -0
  52. data/lib/active_record/log_subscriber.rb +1 -1
  53. data/lib/active_record/migration.rb +4 -4
  54. data/lib/active_record/migration/compatibility.rb +1 -1
  55. data/lib/active_record/model_schema.rb +12 -0
  56. data/lib/active_record/nested_attributes.rb +1 -1
  57. data/lib/active_record/persistence.rb +1 -1
  58. data/lib/active_record/query_cache.rb +13 -16
  59. data/lib/active_record/querying.rb +1 -1
  60. data/lib/active_record/railtie.rb +8 -11
  61. data/lib/active_record/railties/databases.rake +5 -5
  62. data/lib/active_record/reflection.rb +21 -4
  63. data/lib/active_record/relation.rb +10 -10
  64. data/lib/active_record/relation/batches.rb +29 -9
  65. data/lib/active_record/relation/delegation.rb +0 -1
  66. data/lib/active_record/relation/finder_methods.rb +27 -8
  67. data/lib/active_record/relation/predicate_builder.rb +4 -2
  68. data/lib/active_record/relation/where_clause.rb +2 -1
  69. data/lib/active_record/schema_dumper.rb +39 -24
  70. data/lib/active_record/scoping/default.rb +2 -1
  71. data/lib/active_record/suppressor.rb +5 -1
  72. data/lib/active_record/tasks/database_tasks.rb +6 -4
  73. data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
  74. data/lib/active_record/type.rb +1 -1
  75. data/lib/active_record/type/internal/abstract_json.rb +1 -5
  76. data/lib/active_record/type/time.rb +12 -0
  77. data/lib/active_record/validations/uniqueness.rb +1 -4
  78. data/lib/rails/generators/active_record/model/model_generator.rb +15 -11
  79. data/lib/rails/generators/active_record/model/templates/application_record.rb +2 -0
  80. metadata +11 -8
@@ -1,3 +1,5 @@
1
+ require 'ipaddr'
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -27,8 +27,8 @@ module ActiveRecord
27
27
  # - schema_name."table.name"
28
28
  # - "schema.name".table_name
29
29
  # - "schema.name"."table.name"
30
- def quote_table_name(name)
31
- Utils.extract_schema_qualified_name(name.to_s).quoted
30
+ def quote_table_name(name) # :nodoc:
31
+ @quoted_table_names[name] ||= Utils.extract_schema_qualified_name(name.to_s).quoted
32
32
  end
33
33
 
34
34
  # Quotes schema names for use in SQL queries.
@@ -41,8 +41,8 @@ module ActiveRecord
41
41
  end
42
42
 
43
43
  # Quotes column names for use in SQL queries.
44
- def quote_column_name(name) #:nodoc:
45
- PGconn.quote_ident(name.to_s)
44
+ def quote_column_name(name) # :nodoc:
45
+ @quoted_column_names[name] ||= PGconn.quote_ident(super)
46
46
  end
47
47
 
48
48
  # Quote date/time values for use in SQL input.
@@ -3,16 +3,9 @@ module ActiveRecord
3
3
  module PostgreSQL
4
4
  module ColumnDumper
5
5
  def column_spec_for_primary_key(column)
6
- spec = {}
7
- if column.serial?
8
- return unless column.bigint?
9
- spec[:id] = ':bigserial'
10
- elsif column.type == :uuid
11
- spec[:id] = ':uuid'
12
- spec[:default] = schema_default(column) || 'nil'
13
- else
14
- spec[:id] = schema_type(column).inspect
15
- spec.merge!(prepare_column_options(column).delete_if { |key, _| [:name, :type, :null].include?(key) })
6
+ spec = super
7
+ if schema_type(column) == :uuid
8
+ spec[:default] ||= 'nil'
16
9
  end
17
10
  spec
18
11
  end
@@ -31,6 +24,10 @@ module ActiveRecord
31
24
 
32
25
  private
33
26
 
27
+ def default_primary_key?(column)
28
+ schema_type(column) == :serial
29
+ end
30
+
34
31
  def schema_type(column)
35
32
  return super unless column.serial?
36
33
 
@@ -1,3 +1,5 @@
1
+ require 'active_support/core_ext/string/strip'
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
@@ -172,7 +174,11 @@ module ActiveRecord
172
174
  table = Utils.extract_schema_qualified_name(table_name.to_s)
173
175
 
174
176
  result = query(<<-SQL, 'SCHEMA')
175
- SELECT distinct i.relname, d.indisunique, d.indkey, pg_get_indexdef(d.indexrelid), t.oid
177
+ SELECT distinct i.relname, d.indisunique, d.indkey, pg_get_indexdef(d.indexrelid), t.oid,
178
+ pg_catalog.obj_description(i.oid, 'pg_class') AS comment,
179
+ (SELECT COUNT(*) FROM pg_opclass o
180
+ JOIN (SELECT unnest(string_to_array(d.indclass::text, ' '))::int oid) c
181
+ ON o.oid = c.oid WHERE o.opcdefault = 'f')
176
182
  FROM pg_class t
177
183
  INNER JOIN pg_index d ON t.oid = d.indrelid
178
184
  INNER JOIN pg_class i ON d.indexrelid = i.oid
@@ -190,43 +196,61 @@ module ActiveRecord
190
196
  indkey = row[2].split(" ").map(&:to_i)
191
197
  inddef = row[3]
192
198
  oid = row[4]
199
+ comment = row[5]
200
+ opclass = row[6]
193
201
 
194
- columns = Hash[query(<<-SQL, "SCHEMA")]
195
- SELECT a.attnum, a.attname
196
- FROM pg_attribute a
197
- WHERE a.attrelid = #{oid}
198
- AND a.attnum IN (#{indkey.join(",")})
199
- SQL
202
+ using, expressions, where = inddef.scan(/ USING (\w+?) \((.+?)\)(?: WHERE (.+))?\z/).flatten
200
203
 
201
- column_names = columns.values_at(*indkey).compact
204
+ if indkey.include?(0) || opclass > 0
205
+ columns = expressions
206
+ else
207
+ columns = Hash[query(<<-SQL.strip_heredoc, "SCHEMA")].values_at(*indkey).compact
208
+ SELECT a.attnum, a.attname
209
+ FROM pg_attribute a
210
+ WHERE a.attrelid = #{oid}
211
+ AND a.attnum IN (#{indkey.join(",")})
212
+ SQL
202
213
 
203
- unless column_names.empty?
204
214
  # add info on sort order for columns (only desc order is explicitly specified, asc is the default)
205
- desc_order_columns = inddef.scan(/(\w+) DESC/).flatten
206
- orders = desc_order_columns.any? ? Hash[desc_order_columns.map {|order_column| [order_column, :desc]}] : {}
207
- where = inddef.scan(/WHERE (.+)$/).flatten[0]
208
- using = inddef.scan(/USING (.+?) /).flatten[0].to_sym
209
-
210
- IndexDefinition.new(table_name, index_name, unique, column_names, [], orders, where, nil, using)
215
+ orders = Hash[
216
+ expressions.scan(/(\w+) DESC/).flatten.map { |order_column| [order_column, :desc] }
217
+ ]
211
218
  end
219
+
220
+ IndexDefinition.new(table_name, index_name, unique, columns, [], orders, where, nil, using.to_sym, comment)
212
221
  end.compact
213
222
  end
214
223
 
215
224
  # Returns the list of all column definitions for a table.
216
- def columns(table_name)
217
- # Limit, precision, and scale are all handled by the superclass.
218
- column_definitions(table_name).map do |column_name, type, default, notnull, oid, fmod, collation|
225
+ def columns(table_name) # :nodoc:
226
+ table_name = table_name.to_s
227
+ column_definitions(table_name).map do |column_name, type, default, notnull, oid, fmod, collation, comment|
219
228
  oid = oid.to_i
220
229
  fmod = fmod.to_i
221
230
  type_metadata = fetch_type_metadata(column_name, type, oid, fmod)
222
231
  default_value = extract_value_from_default(default)
223
232
  default_function = extract_default_function(default_value, default)
224
- new_column(column_name, default_value, type_metadata, !notnull, default_function, collation)
233
+ new_column(column_name, default_value, type_metadata, !notnull, table_name, default_function, collation, comment: comment.presence)
225
234
  end
226
235
  end
227
236
 
228
- def new_column(name, default, sql_type_metadata = nil, null = true, default_function = nil, collation = nil) # :nodoc:
229
- PostgreSQLColumn.new(name, default, sql_type_metadata, null, default_function, collation)
237
+ def new_column(*args) # :nodoc:
238
+ PostgreSQLColumn.new(*args)
239
+ end
240
+
241
+ # Returns a comment stored in database for given table
242
+ def table_comment(table_name) # :nodoc:
243
+ name = Utils.extract_schema_qualified_name(table_name.to_s)
244
+ if name.identifier
245
+ select_value(<<-SQL.strip_heredoc, 'SCHEMA')
246
+ SELECT pg_catalog.obj_description(c.oid, 'pg_class')
247
+ FROM pg_catalog.pg_class c
248
+ LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
249
+ WHERE c.relname = #{quote(name.identifier)}
250
+ AND c.relkind IN ('r') -- (r)elation/table
251
+ AND n.nspname = #{name.schema ? quote(name.schema) : 'ANY (current_schemas(false))'}
252
+ SQL
253
+ end
230
254
  end
231
255
 
232
256
  # Returns the current database name.
@@ -325,7 +349,7 @@ module ActiveRecord
325
349
 
326
350
  select_value("SELECT setval('#{quoted_sequence}', #{value})", 'SCHEMA')
327
351
  else
328
- @logger.warn "#{table} has primary key #{pk} with no default sequence" if @logger
352
+ @logger.warn "#{table} has primary key #{pk} with no default sequence." if @logger
329
353
  end
330
354
  end
331
355
  end
@@ -340,7 +364,7 @@ module ActiveRecord
340
364
  end
341
365
 
342
366
  if @logger && pk && !sequence
343
- @logger.warn "#{table} has primary key #{pk} with no default sequence"
367
+ @logger.warn "#{table} has primary key #{pk} with no default sequence."
344
368
  end
345
369
 
346
370
  if pk && sequence
@@ -445,6 +469,7 @@ module ActiveRecord
445
469
  def add_column(table_name, column_name, type, options = {}) #:nodoc:
446
470
  clear_cache!
447
471
  super
472
+ change_column_comment(table_name, column_name, options[:comment]) if options.key?(:comment)
448
473
  end
449
474
 
450
475
  def change_column(table_name, column_name, type, options = {}) #:nodoc:
@@ -466,6 +491,7 @@ module ActiveRecord
466
491
 
467
492
  change_column_default(table_name, column_name, options[:default]) if options_include_default?(options)
468
493
  change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
494
+ change_column_comment(table_name, column_name, options[:comment]) if options.key?(:comment)
469
495
  end
470
496
 
471
497
  # Changes the default value of a table column.
@@ -494,6 +520,18 @@ module ActiveRecord
494
520
  execute("ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} #{null ? 'DROP' : 'SET'} NOT NULL")
495
521
  end
496
522
 
523
+ # Adds comment for given table column or drops it if +comment+ is a +nil+
524
+ def change_column_comment(table_name, column_name, comment) # :nodoc:
525
+ clear_cache!
526
+ execute "COMMENT ON COLUMN #{quote_table_name(table_name)}.#{quote_column_name(column_name)} IS #{quote(comment)}"
527
+ end
528
+
529
+ # Adds comment for given table or drops it if +comment+ is a +nil+
530
+ def change_table_comment(table_name, comment) # :nodoc:
531
+ clear_cache!
532
+ execute "COMMENT ON TABLE #{quote_table_name(table_name)} IS #{quote(comment)}"
533
+ end
534
+
497
535
  # Renames a column in a table.
498
536
  def rename_column(table_name, column_name, new_column_name) #:nodoc:
499
537
  clear_cache!
@@ -502,8 +540,10 @@ module ActiveRecord
502
540
  end
503
541
 
504
542
  def add_index(table_name, column_name, options = {}) #:nodoc:
505
- index_name, index_type, index_columns, index_options, index_algorithm, index_using = add_index_options(table_name, column_name, options)
506
- execute "CREATE #{index_type} INDEX #{index_algorithm} #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} #{index_using} (#{index_columns})#{index_options}"
543
+ index_name, index_type, index_columns, index_options, index_algorithm, index_using, comment = add_index_options(table_name, column_name, options)
544
+ execute("CREATE #{index_type} INDEX #{index_algorithm} #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} #{index_using} (#{index_columns})#{index_options}").tap do
545
+ execute "COMMENT ON INDEX #{quote_column_name(index_name)} IS #{quote(comment)}" if comment
546
+ end
507
547
  end
508
548
 
509
549
  def remove_index(table_name, options = {}) #:nodoc:
@@ -16,8 +16,6 @@ require "active_record/connection_adapters/postgresql/type_metadata"
16
16
  require "active_record/connection_adapters/postgresql/utils"
17
17
  require "active_record/connection_adapters/statement_pool"
18
18
 
19
- require 'ipaddr'
20
-
21
19
  module ActiveRecord
22
20
  module ConnectionHandling # :nodoc:
23
21
  # Establishes a connection to the database that's used by all Active Record objects
@@ -119,12 +117,15 @@ module ActiveRecord
119
117
  include PostgreSQL::SchemaStatements
120
118
  include PostgreSQL::DatabaseStatements
121
119
  include PostgreSQL::ColumnDumper
122
- include Savepoints
123
120
 
124
121
  def schema_creation # :nodoc:
125
122
  PostgreSQL::SchemaCreation.new self
126
123
  end
127
124
 
125
+ def arel_visitor # :nodoc:
126
+ Arel::Visitors::PostgreSQL.new(self)
127
+ end
128
+
128
129
  # Returns true, since this connection adapter supports prepared statement
129
130
  # caching.
130
131
  def supports_statement_cache?
@@ -139,6 +140,10 @@ module ActiveRecord
139
140
  true
140
141
  end
141
142
 
143
+ def supports_expression_index?
144
+ true
145
+ end
146
+
142
147
  def supports_transaction_isolation?
143
148
  true
144
149
  end
@@ -159,6 +164,18 @@ module ActiveRecord
159
164
  postgresql_version >= 90200
160
165
  end
161
166
 
167
+ def supports_comments?
168
+ true
169
+ end
170
+
171
+ def supports_comments_in_create?
172
+ false
173
+ end
174
+
175
+ def supports_savepoints?
176
+ true
177
+ end
178
+
162
179
  def index_algorithms
163
180
  { concurrently: 'CONCURRENTLY' }
164
181
  end
@@ -195,14 +212,6 @@ module ActiveRecord
195
212
  def initialize(connection, logger, connection_parameters, config)
196
213
  super(connection, logger, config)
197
214
 
198
- @visitor = Arel::Visitors::PostgreSQL.new self
199
- if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true })
200
- @prepared_statements = true
201
- @visitor.extend(DetermineIfPreparableVisitor)
202
- else
203
- @prepared_statements = false
204
- end
205
-
206
215
  @connection_parameters = connection_parameters
207
216
 
208
217
  # @local_tz is initialized as nil to avoid warnings when connect tries to use it
@@ -212,7 +221,7 @@ module ActiveRecord
212
221
  connect
213
222
  add_pg_encoders
214
223
  @statements = StatementPool.new @connection,
215
- self.class.type_cast_config_to_integer(config.fetch(:statement_limit) { 1000 })
224
+ self.class.type_cast_config_to_integer(config[:statement_limit])
216
225
 
217
226
  if postgresql_version < 90100
218
227
  raise "Your version of PostgreSQL (#{postgresql_version}) is too old. Active Record supports PostgreSQL >= 9.1."
@@ -398,6 +407,7 @@ module ActiveRecord
398
407
  protected
399
408
 
400
409
  # See http://www.postgresql.org/docs/current/static/errcodes-appendix.html
410
+ VALUE_LIMIT_VIOLATION = "22001"
401
411
  FOREIGN_KEY_VIOLATION = "23503"
402
412
  UNIQUE_VIOLATION = "23505"
403
413
 
@@ -409,6 +419,8 @@ module ActiveRecord
409
419
  RecordNotUnique.new(message)
410
420
  when FOREIGN_KEY_VIOLATION
411
421
  InvalidForeignKey.new(message)
422
+ when VALUE_LIMIT_VIOLATION
423
+ ValueTooLong.new(message)
412
424
  else
413
425
  super
414
426
  end
@@ -598,25 +610,41 @@ module ActiveRecord
598
610
  @connection.exec_prepared(stmt_key, type_casted_binds)
599
611
  end
600
612
  rescue ActiveRecord::StatementInvalid => e
601
- pgerror = e.cause
613
+ raise unless is_cached_plan_failure?(e)
602
614
 
603
- # Get the PG code for the failure. Annoyingly, the code for
604
- # prepared statements whose return value may have changed is
605
- # FEATURE_NOT_SUPPORTED. Check here for more details:
606
- # http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/cache/plancache.c#l573
607
- begin
608
- code = pgerror.result.result_error_field(PGresult::PG_DIAG_SQLSTATE)
609
- rescue
610
- raise e
611
- end
612
- if FEATURE_NOT_SUPPORTED == code
615
+ # Nothing we can do if we are in a transaction because all commands
616
+ # will raise InFailedSQLTransaction
617
+ if in_transaction?
618
+ raise ActiveRecord::PreparedStatementCacheExpired.new(e.cause.message)
619
+ else
620
+ # outside of transactions we can simply flush this query and retry
613
621
  @statements.delete sql_key(sql)
614
622
  retry
615
- else
616
- raise e
617
623
  end
618
624
  end
619
625
 
626
+ # Annoyingly, the code for prepared statements whose return value may
627
+ # have changed is FEATURE_NOT_SUPPORTED.
628
+ #
629
+ # This covers various different error types so we need to do additional
630
+ # work to classify the exception definitively as a
631
+ # ActiveRecord::PreparedStatementCacheExpired
632
+ #
633
+ # Check here for more details:
634
+ # http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/cache/plancache.c#l573
635
+ CACHED_PLAN_HEURISTIC = 'cached plan must not change result type'.freeze
636
+ def is_cached_plan_failure?(e)
637
+ pgerror = e.cause
638
+ code = pgerror.result.result_error_field(PGresult::PG_DIAG_SQLSTATE)
639
+ code == FEATURE_NOT_SUPPORTED && pgerror.message.include?(CACHED_PLAN_HEURISTIC)
640
+ rescue
641
+ false
642
+ end
643
+
644
+ def in_transaction?
645
+ open_transactions > 0
646
+ end
647
+
620
648
  # Returns the statement identifier for the client side cache
621
649
  # of statements
622
650
  def sql_key(sql)
@@ -696,7 +724,7 @@ module ActiveRecord
696
724
  # Returns the list of a table's column names, data types, and default values.
697
725
  #
698
726
  # The underlying query is roughly:
699
- # SELECT column.name, column.type, default.value
727
+ # SELECT column.name, column.type, default.value, column.comment
700
728
  # FROM column LEFT JOIN default
701
729
  # ON column.table_id = default.table_id
702
730
  # AND column.num = default.column_num
@@ -716,7 +744,8 @@ module ActiveRecord
716
744
  SELECT a.attname, format_type(a.atttypid, a.atttypmod),
717
745
  pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod,
718
746
  (SELECT c.collname FROM pg_collation c, pg_type t
719
- WHERE c.oid = a.attcollation AND t.oid = a.atttypid AND a.attcollation <> t.typcollation)
747
+ WHERE c.oid = a.attcollation AND t.oid = a.atttypid AND a.attcollation <> t.typcollation),
748
+ col_description(a.attrelid, a.attnum) AS comment
720
749
  FROM pg_attribute a LEFT JOIN pg_attrdef d
721
750
  ON a.attrelid = d.adrelid AND a.attnum = d.adnum
722
751
  WHERE a.attrelid = '#{quote_table_name(table_name)}'::regclass
@@ -730,8 +759,8 @@ module ActiveRecord
730
759
  $1.strip if $1
731
760
  end
732
761
 
733
- def create_table_definition(name, temporary = false, options = nil, as = nil) # :nodoc:
734
- PostgreSQL::TableDefinition.new(name, temporary, options, as)
762
+ def create_table_definition(*args) # :nodoc:
763
+ PostgreSQL::TableDefinition.new(*args)
735
764
  end
736
765
 
737
766
  def can_perform_case_insensitive_comparison_for?(column)
@@ -799,7 +828,7 @@ module ActiveRecord
799
828
  ActiveRecord::Type.register(:bit_varying, OID::BitVarying, adapter: :postgresql)
800
829
  ActiveRecord::Type.register(:binary, OID::Bytea, adapter: :postgresql)
801
830
  ActiveRecord::Type.register(:cidr, OID::Cidr, adapter: :postgresql)
802
- ActiveRecord::Type.register(:date_time, OID::DateTime, adapter: :postgresql)
831
+ ActiveRecord::Type.register(:datetime, OID::DateTime, adapter: :postgresql)
803
832
  ActiveRecord::Type.register(:decimal, OID::Decimal, adapter: :postgresql)
804
833
  ActiveRecord::Type.register(:enum, OID::Enum, adapter: :postgresql)
805
834
  ActiveRecord::Type.register(:hstore, OID::Hstore, adapter: :postgresql)
@@ -0,0 +1,48 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ module SQLite3
4
+ module Quoting # :nodoc:
5
+ def quote_string(s)
6
+ @connection.class.quote(s)
7
+ end
8
+
9
+ def quote_table_name_for_assignment(table, attr)
10
+ quote_column_name(attr)
11
+ end
12
+
13
+ def quote_column_name(name)
14
+ @quoted_column_names[name] ||= %Q("#{super.gsub('"', '""')}")
15
+ end
16
+
17
+ def quoted_time(value)
18
+ quoted_date(value)
19
+ end
20
+
21
+ private
22
+
23
+ def _quote(value)
24
+ if value.is_a?(Type::Binary::Data)
25
+ "x'#{value.hex}'"
26
+ else
27
+ super
28
+ end
29
+ end
30
+
31
+ def _type_cast(value)
32
+ case value
33
+ when BigDecimal
34
+ value.to_f
35
+ when String
36
+ if value.encoding == Encoding::ASCII_8BIT
37
+ super(value.encode(Encoding::UTF_8))
38
+ else
39
+ super
40
+ end
41
+ else
42
+ super
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end