activerecord 7.1.5.1 → 8.0.2

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 (206) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +369 -2484
  3. data/README.rdoc +15 -15
  4. data/examples/performance.rb +2 -2
  5. data/lib/active_record/association_relation.rb +2 -1
  6. data/lib/active_record/associations/alias_tracker.rb +31 -23
  7. data/lib/active_record/associations/association.rb +43 -12
  8. data/lib/active_record/associations/belongs_to_association.rb +21 -8
  9. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
  10. data/lib/active_record/associations/builder/association.rb +7 -6
  11. data/lib/active_record/associations/builder/belongs_to.rb +1 -0
  12. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +2 -2
  13. data/lib/active_record/associations/builder/has_many.rb +3 -4
  14. data/lib/active_record/associations/builder/has_one.rb +3 -4
  15. data/lib/active_record/associations/collection_association.rb +17 -9
  16. data/lib/active_record/associations/collection_proxy.rb +14 -1
  17. data/lib/active_record/associations/disable_joins_association_scope.rb +1 -1
  18. data/lib/active_record/associations/errors.rb +265 -0
  19. data/lib/active_record/associations/has_many_association.rb +1 -1
  20. data/lib/active_record/associations/has_many_through_association.rb +10 -3
  21. data/lib/active_record/associations/join_dependency/join_association.rb +1 -1
  22. data/lib/active_record/associations/nested_error.rb +47 -0
  23. data/lib/active_record/associations/preloader/association.rb +4 -3
  24. data/lib/active_record/associations/preloader/branch.rb +7 -1
  25. data/lib/active_record/associations/preloader/through_association.rb +1 -3
  26. data/lib/active_record/associations/singular_association.rb +14 -3
  27. data/lib/active_record/associations/through_association.rb +1 -1
  28. data/lib/active_record/associations.rb +92 -295
  29. data/lib/active_record/asynchronous_queries_tracker.rb +28 -24
  30. data/lib/active_record/attribute_assignment.rb +0 -2
  31. data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
  32. data/lib/active_record/attribute_methods/primary_key.rb +25 -61
  33. data/lib/active_record/attribute_methods/read.rb +1 -13
  34. data/lib/active_record/attribute_methods/serialization.rb +4 -24
  35. data/lib/active_record/attribute_methods/time_zone_conversion.rb +9 -18
  36. data/lib/active_record/attribute_methods.rb +71 -75
  37. data/lib/active_record/attributes.rb +63 -49
  38. data/lib/active_record/autosave_association.rb +92 -57
  39. data/lib/active_record/base.rb +2 -3
  40. data/lib/active_record/callbacks.rb +1 -1
  41. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +48 -122
  42. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +0 -1
  43. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +1 -1
  44. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +286 -77
  45. data/lib/active_record/connection_adapters/abstract/database_statements.rb +119 -55
  46. data/lib/active_record/connection_adapters/abstract/query_cache.rb +197 -76
  47. data/lib/active_record/connection_adapters/abstract/quoting.rb +66 -92
  48. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -5
  49. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +12 -3
  50. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +48 -12
  51. data/lib/active_record/connection_adapters/abstract/transaction.rb +140 -67
  52. data/lib/active_record/connection_adapters/abstract_adapter.rb +85 -90
  53. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +71 -52
  54. data/lib/active_record/connection_adapters/mysql/database_statements.rb +9 -1
  55. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -57
  56. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +2 -8
  57. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +56 -45
  58. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +92 -101
  59. data/lib/active_record/connection_adapters/mysql2_adapter.rb +13 -31
  60. data/lib/active_record/connection_adapters/pool_config.rb +14 -13
  61. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +86 -41
  62. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  63. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
  64. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +10 -0
  65. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
  66. data/lib/active_record/connection_adapters/postgresql/quoting.rb +58 -58
  67. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -4
  68. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +1 -11
  69. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +36 -20
  70. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +3 -2
  71. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +75 -28
  72. data/lib/active_record/connection_adapters/postgresql_adapter.rb +73 -113
  73. data/lib/active_record/connection_adapters/schema_cache.rb +124 -131
  74. data/lib/active_record/connection_adapters/sqlite3/column.rb +14 -1
  75. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +81 -97
  76. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +57 -46
  77. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +16 -0
  78. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +13 -0
  79. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +29 -0
  80. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +35 -3
  81. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +183 -87
  82. data/lib/active_record/connection_adapters/statement_pool.rb +4 -2
  83. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +39 -69
  84. data/lib/active_record/connection_adapters/trilogy_adapter.rb +19 -65
  85. data/lib/active_record/connection_adapters.rb +65 -0
  86. data/lib/active_record/connection_handling.rb +74 -37
  87. data/lib/active_record/core.rb +132 -51
  88. data/lib/active_record/counter_cache.rb +19 -10
  89. data/lib/active_record/database_configurations/connection_url_resolver.rb +9 -2
  90. data/lib/active_record/database_configurations/database_config.rb +23 -4
  91. data/lib/active_record/database_configurations/hash_config.rb +46 -34
  92. data/lib/active_record/database_configurations/url_config.rb +20 -1
  93. data/lib/active_record/database_configurations.rb +1 -1
  94. data/lib/active_record/delegated_type.rb +41 -17
  95. data/lib/active_record/dynamic_matchers.rb +2 -2
  96. data/lib/active_record/encryption/config.rb +3 -1
  97. data/lib/active_record/encryption/encryptable_record.rb +7 -7
  98. data/lib/active_record/encryption/encrypted_attribute_type.rb +33 -4
  99. data/lib/active_record/encryption/encryptor.rb +28 -6
  100. data/lib/active_record/encryption/extended_deterministic_queries.rb +4 -2
  101. data/lib/active_record/encryption/key_provider.rb +1 -1
  102. data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
  103. data/lib/active_record/encryption/message_serializer.rb +4 -0
  104. data/lib/active_record/encryption/null_encryptor.rb +4 -0
  105. data/lib/active_record/encryption/read_only_null_encryptor.rb +4 -0
  106. data/lib/active_record/encryption/scheme.rb +8 -1
  107. data/lib/active_record/enum.rb +20 -16
  108. data/lib/active_record/errors.rb +54 -20
  109. data/lib/active_record/explain.rb +13 -24
  110. data/lib/active_record/fixtures.rb +37 -33
  111. data/lib/active_record/future_result.rb +21 -13
  112. data/lib/active_record/gem_version.rb +4 -4
  113. data/lib/active_record/inheritance.rb +4 -2
  114. data/lib/active_record/insert_all.rb +19 -16
  115. data/lib/active_record/integration.rb +4 -1
  116. data/lib/active_record/internal_metadata.rb +48 -34
  117. data/lib/active_record/locking/optimistic.rb +8 -7
  118. data/lib/active_record/log_subscriber.rb +5 -32
  119. data/lib/active_record/message_pack.rb +1 -1
  120. data/lib/active_record/migration/command_recorder.rb +33 -14
  121. data/lib/active_record/migration/compatibility.rb +8 -3
  122. data/lib/active_record/migration/default_strategy.rb +4 -5
  123. data/lib/active_record/migration/pending_migration_connection.rb +2 -2
  124. data/lib/active_record/migration.rb +104 -98
  125. data/lib/active_record/model_schema.rb +32 -70
  126. data/lib/active_record/nested_attributes.rb +15 -9
  127. data/lib/active_record/normalization.rb +3 -7
  128. data/lib/active_record/persistence.rb +127 -451
  129. data/lib/active_record/query_cache.rb +19 -8
  130. data/lib/active_record/query_logs.rb +104 -37
  131. data/lib/active_record/query_logs_formatter.rb +17 -28
  132. data/lib/active_record/querying.rb +24 -12
  133. data/lib/active_record/railtie.rb +26 -68
  134. data/lib/active_record/railties/controller_runtime.rb +13 -4
  135. data/lib/active_record/railties/databases.rake +43 -61
  136. data/lib/active_record/reflection.rb +112 -53
  137. data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
  138. data/lib/active_record/relation/batches.rb +138 -72
  139. data/lib/active_record/relation/calculations.rb +122 -82
  140. data/lib/active_record/relation/delegation.rb +30 -22
  141. data/lib/active_record/relation/finder_methods.rb +32 -18
  142. data/lib/active_record/relation/merger.rb +12 -14
  143. data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
  144. data/lib/active_record/relation/predicate_builder/association_query_value.rb +10 -2
  145. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -1
  146. data/lib/active_record/relation/predicate_builder/relation_handler.rb +4 -3
  147. data/lib/active_record/relation/predicate_builder.rb +16 -3
  148. data/lib/active_record/relation/query_attribute.rb +1 -1
  149. data/lib/active_record/relation/query_methods.rb +317 -101
  150. data/lib/active_record/relation/spawn_methods.rb +3 -19
  151. data/lib/active_record/relation/where_clause.rb +7 -19
  152. data/lib/active_record/relation.rb +561 -119
  153. data/lib/active_record/result.rb +95 -46
  154. data/lib/active_record/runtime_registry.rb +39 -0
  155. data/lib/active_record/sanitization.rb +31 -25
  156. data/lib/active_record/schema.rb +8 -6
  157. data/lib/active_record/schema_dumper.rb +53 -20
  158. data/lib/active_record/schema_migration.rb +31 -14
  159. data/lib/active_record/scoping/named.rb +6 -2
  160. data/lib/active_record/signed_id.rb +24 -4
  161. data/lib/active_record/statement_cache.rb +19 -19
  162. data/lib/active_record/store.rb +7 -3
  163. data/lib/active_record/table_metadata.rb +2 -13
  164. data/lib/active_record/tasks/database_tasks.rb +87 -58
  165. data/lib/active_record/tasks/mysql_database_tasks.rb +1 -3
  166. data/lib/active_record/tasks/postgresql_database_tasks.rb +1 -1
  167. data/lib/active_record/tasks/sqlite_database_tasks.rb +4 -3
  168. data/lib/active_record/test_fixtures.rb +98 -89
  169. data/lib/active_record/testing/query_assertions.rb +121 -0
  170. data/lib/active_record/timestamp.rb +2 -2
  171. data/lib/active_record/token_for.rb +22 -12
  172. data/lib/active_record/touch_later.rb +1 -1
  173. data/lib/active_record/transaction.rb +132 -0
  174. data/lib/active_record/transactions.rb +72 -17
  175. data/lib/active_record/translation.rb +0 -2
  176. data/lib/active_record/type/serialized.rb +1 -3
  177. data/lib/active_record/type_caster/connection.rb +4 -4
  178. data/lib/active_record/validations/associated.rb +9 -3
  179. data/lib/active_record/validations/uniqueness.rb +23 -18
  180. data/lib/active_record/validations.rb +4 -1
  181. data/lib/active_record.rb +138 -57
  182. data/lib/arel/alias_predication.rb +1 -1
  183. data/lib/arel/collectors/bind.rb +4 -2
  184. data/lib/arel/collectors/composite.rb +7 -0
  185. data/lib/arel/collectors/sql_string.rb +2 -2
  186. data/lib/arel/collectors/substitute_binds.rb +3 -3
  187. data/lib/arel/nodes/binary.rb +1 -7
  188. data/lib/arel/nodes/bound_sql_literal.rb +9 -5
  189. data/lib/arel/nodes/{and.rb → nary.rb} +5 -2
  190. data/lib/arel/nodes/node.rb +5 -4
  191. data/lib/arel/nodes/sql_literal.rb +8 -1
  192. data/lib/arel/nodes.rb +2 -2
  193. data/lib/arel/predications.rb +1 -1
  194. data/lib/arel/select_manager.rb +1 -1
  195. data/lib/arel/table.rb +3 -7
  196. data/lib/arel/tree_manager.rb +3 -2
  197. data/lib/arel/update_manager.rb +2 -1
  198. data/lib/arel/visitors/dot.rb +1 -0
  199. data/lib/arel/visitors/mysql.rb +9 -4
  200. data/lib/arel/visitors/postgresql.rb +1 -12
  201. data/lib/arel/visitors/sqlite.rb +25 -0
  202. data/lib/arel/visitors/to_sql.rb +29 -16
  203. data/lib/arel.rb +7 -3
  204. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
  205. metadata +18 -16
  206. data/lib/active_record/relation/record_fetch_warning.rb +0 -49
@@ -20,17 +20,6 @@ require "active_record/connection_adapters/postgresql/type_metadata"
20
20
  require "active_record/connection_adapters/postgresql/utils"
21
21
 
22
22
  module ActiveRecord
23
- module ConnectionHandling # :nodoc:
24
- def postgresql_adapter_class
25
- ConnectionAdapters::PostgreSQLAdapter
26
- end
27
-
28
- # Establishes a connection to the database that's used by all Active Record objects
29
- def postgresql_connection(config)
30
- postgresql_adapter_class.new(config)
31
- end
32
- end
33
-
34
23
  module ConnectionAdapters
35
24
  # = Active Record PostgreSQL Adapter
36
25
  #
@@ -97,7 +86,7 @@ module ActiveRecord
97
86
  "-c #{name}=#{value.to_s.gsub(/[ \\]/, '\\\\\0')}" unless value == ":default" || value == :default
98
87
  end.join(" ")
99
88
  end
100
- find_cmd_and_exec("psql", config.database)
89
+ find_cmd_and_exec(ActiveRecord.database_cli[:postgresql], config.database)
101
90
  end
102
91
  end
103
92
 
@@ -133,6 +122,15 @@ module ActiveRecord
133
122
  # setting, you should immediately run <tt>bin/rails db:migrate</tt> to update the types in your schema.rb.
134
123
  class_attribute :datetime_type, default: :timestamp
135
124
 
125
+ ##
126
+ # :singleton-method:
127
+ # Toggles automatic decoding of date columns.
128
+ #
129
+ # ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.select_value("select '2024-01-01'::date").class #=> String
130
+ # ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.decode_dates = true
131
+ # ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.select_value("select '2024-01-01'::date").class #=> Date
132
+ class_attribute :decode_dates, default: false
133
+
136
134
  NATIVE_DATABASE_TYPES = {
137
135
  primary_key: "bigserial primary key",
138
136
  string: { name: "character varying" },
@@ -286,12 +284,12 @@ module ActiveRecord
286
284
  database_version >= 15_00_00 # >= 15.0
287
285
  end
288
286
 
289
- def index_algorithms
290
- { concurrently: "CONCURRENTLY" }
287
+ def supports_native_partitioning? # :nodoc:
288
+ database_version >= 10_00_00 # >= 10.0
291
289
  end
292
290
 
293
- def return_value_after_insert?(column) # :nodoc:
294
- column.auto_populated?
291
+ def index_algorithms
292
+ { concurrently: "CONCURRENTLY" }
295
293
  end
296
294
 
297
295
  class StatementPool < ConnectionAdapters::StatementPool # :nodoc:
@@ -342,11 +340,16 @@ module ActiveRecord
342
340
  @use_insert_returning = @config.key?(:insert_returning) ? self.class.type_cast_config_to_boolean(@config[:insert_returning]) : true
343
341
  end
344
342
 
343
+ def connected?
344
+ !(@raw_connection.nil? || @raw_connection.finished?)
345
+ end
346
+
345
347
  # Is this connection alive and ready for queries?
346
348
  def active?
347
349
  @lock.synchronize do
348
350
  return false unless @raw_connection
349
351
  @raw_connection.query ";"
352
+ verified!
350
353
  end
351
354
  true
352
355
  rescue PG::Error
@@ -407,7 +410,7 @@ module ActiveRecord
407
410
  end
408
411
 
409
412
  def set_standard_conforming_strings
410
- internal_execute("SET standard_conforming_strings = on")
413
+ internal_execute("SET standard_conforming_strings = on", "SCHEMA")
411
414
  end
412
415
 
413
416
  def supports_ddl_transactions?
@@ -481,6 +484,7 @@ module ActiveRecord
481
484
  # Set to +:cascade+ to drop dependent objects as well.
482
485
  # Defaults to false.
483
486
  def disable_extension(name, force: false)
487
+ _schema, name = name.to_s.split(".").values_at(-2, -1)
484
488
  internal_exec_query("DROP EXTENSION IF EXISTS \"#{name}\"#{' CASCADE' if force == :cascade}").tap {
485
489
  reload_type_map
486
490
  }
@@ -495,7 +499,19 @@ module ActiveRecord
495
499
  end
496
500
 
497
501
  def extensions
498
- internal_exec_query("SELECT extname FROM pg_extension", "SCHEMA", allow_retry: true, materialize_transactions: false).cast_values
502
+ query = <<~SQL
503
+ SELECT
504
+ pg_extension.extname,
505
+ n.nspname AS schema
506
+ FROM pg_extension
507
+ JOIN pg_namespace n ON pg_extension.extnamespace = n.oid
508
+ SQL
509
+
510
+ internal_exec_query(query, "SCHEMA", allow_retry: true, materialize_transactions: false).cast_values.map do |row|
511
+ name, schema = row[0], row[1]
512
+ schema = nil if schema == current_schema
513
+ [schema, name].compact.join(".")
514
+ end
499
515
  end
500
516
 
501
517
  # Returns a list of defined enum types, and their values.
@@ -505,7 +521,7 @@ module ActiveRecord
505
521
  type.typname AS name,
506
522
  type.OID AS oid,
507
523
  n.nspname AS schema,
508
- string_agg(enum.enumlabel, ',' ORDER BY enum.enumsortorder) AS value
524
+ array_agg(enum.enumlabel ORDER BY enum.enumsortorder) AS value
509
525
  FROM pg_enum AS enum
510
526
  JOIN pg_type AS type ON (type.oid = enum.enumtypid)
511
527
  JOIN pg_namespace n ON type.typnamespace = n.oid
@@ -560,30 +576,34 @@ module ActiveRecord
560
576
  end
561
577
 
562
578
  # Rename an existing enum type to something else.
563
- def rename_enum(name, options = {})
564
- to = options.fetch(:to) { raise ArgumentError, ":to is required" }
579
+ def rename_enum(name, new_name = nil, **options)
580
+ new_name ||= options.fetch(:to) do
581
+ raise ArgumentError, "rename_enum requires two from/to name positional arguments."
582
+ end
565
583
 
566
- exec_query("ALTER TYPE #{quote_table_name(name)} RENAME TO #{to}").tap { reload_type_map }
584
+ exec_query("ALTER TYPE #{quote_table_name(name)} RENAME TO #{quote_table_name(new_name)}").tap { reload_type_map }
567
585
  end
568
586
 
569
587
  # Add enum value to an existing enum type.
570
- def add_enum_value(type_name, value, options = {})
588
+ def add_enum_value(type_name, value, **options)
571
589
  before, after = options.values_at(:before, :after)
572
- sql = +"ALTER TYPE #{quote_table_name(type_name)} ADD VALUE '#{value}'"
590
+ sql = +"ALTER TYPE #{quote_table_name(type_name)} ADD VALUE"
591
+ sql << " IF NOT EXISTS" if options[:if_not_exists]
592
+ sql << " #{quote(value)}"
573
593
 
574
594
  if before && after
575
595
  raise ArgumentError, "Cannot have both :before and :after at the same time"
576
596
  elsif before
577
- sql << " BEFORE '#{before}'"
597
+ sql << " BEFORE #{quote(before)}"
578
598
  elsif after
579
- sql << " AFTER '#{after}'"
599
+ sql << " AFTER #{quote(after)}"
580
600
  end
581
601
 
582
602
  execute(sql).tap { reload_type_map }
583
603
  end
584
604
 
585
605
  # Rename enum value on an existing enum type.
586
- def rename_enum_value(type_name, options = {})
606
+ def rename_enum_value(type_name, **options)
587
607
  unless database_version >= 10_00_00 # >= 10.0
588
608
  raise ArgumentError, "Renaming enum values is only supported in PostgreSQL 10 or later"
589
609
  end
@@ -591,7 +611,7 @@ module ActiveRecord
591
611
  from = options.fetch(:from) { raise ArgumentError, ":from is required" }
592
612
  to = options.fetch(:to) { raise ArgumentError, ":to is required" }
593
613
 
594
- execute("ALTER TYPE #{quote_table_name(type_name)} RENAME VALUE '#{from}' TO '#{to}'").tap {
614
+ execute("ALTER TYPE #{quote_table_name(type_name)} RENAME VALUE #{quote(from)} TO #{quote(to)}").tap {
595
615
  reload_type_map
596
616
  }
597
617
  end
@@ -613,7 +633,13 @@ module ActiveRecord
613
633
 
614
634
  # Returns the version of the connected PostgreSQL server.
615
635
  def get_database_version # :nodoc:
616
- valid_raw_connection.server_version
636
+ with_raw_connection do |conn|
637
+ version = conn.server_version
638
+ if version == 0
639
+ raise ActiveRecord::ConnectionFailed, "Could not determine PostgreSQL version"
640
+ end
641
+ version
642
+ end
617
643
  end
618
644
  alias :postgresql_version :database_version
619
645
 
@@ -652,8 +678,8 @@ module ActiveRecord
652
678
  m.register_type "int4", Type::Integer.new(limit: 4)
653
679
  m.register_type "int8", Type::Integer.new(limit: 8)
654
680
  m.register_type "oid", OID::Oid.new
655
- m.register_type "float4", Type::Float.new
656
- m.alias_type "float8", "float4"
681
+ m.register_type "float4", Type::Float.new(limit: 24)
682
+ m.register_type "float8", Type::Float.new
657
683
  m.register_type "text", Type::Text.new
658
684
  register_class_with_limit m, "varchar", Type::String
659
685
  m.alias_type "char", "varchar"
@@ -777,7 +803,7 @@ module ActiveRecord
777
803
 
778
804
  case exception.result.try(:error_field, PG::PG_DIAG_SQLSTATE)
779
805
  when nil
780
- if exception.message.match?(/connection is closed/i)
806
+ if exception.message.match?(/connection is closed/i) || exception.message.match?(/no connection to the server/i)
781
807
  ConnectionNotEstablished.new(exception, connection_pool: @pool)
782
808
  elsif exception.is_a?(PG::ConnectionBad)
783
809
  # libpq message style always ends with a newline; the pg gem's internal
@@ -841,9 +867,8 @@ module ActiveRecord
841
867
  def load_additional_types(oids = nil)
842
868
  initializer = OID::TypeMapInitializer.new(type_map)
843
869
  load_types_queries(initializer, oids) do |query|
844
- execute_and_clear(query, "SCHEMA", [], allow_retry: true, materialize_transactions: false) do |records|
845
- initializer.run(records)
846
- end
870
+ records = internal_execute(query, "SCHEMA", [], allow_retry: true, materialize_transactions: false)
871
+ initializer.run(records)
847
872
  end
848
873
  end
849
874
 
@@ -864,71 +889,6 @@ module ActiveRecord
864
889
 
865
890
  FEATURE_NOT_SUPPORTED = "0A000" # :nodoc:
866
891
 
867
- def execute_and_clear(sql, name, binds, prepare: false, async: false, allow_retry: false, materialize_transactions: true)
868
- sql = transform_query(sql)
869
- check_if_write_query(sql)
870
-
871
- if !prepare || without_prepared_statement?(binds)
872
- result = exec_no_cache(sql, name, binds, async: async, allow_retry: allow_retry, materialize_transactions: materialize_transactions)
873
- else
874
- result = exec_cache(sql, name, binds, async: async, allow_retry: allow_retry, materialize_transactions: materialize_transactions)
875
- end
876
- begin
877
- ret = yield result
878
- ensure
879
- result.clear
880
- end
881
- ret
882
- end
883
-
884
- def exec_no_cache(sql, name, binds, async:, allow_retry:, materialize_transactions:)
885
- mark_transaction_written_if_write(sql)
886
-
887
- # make sure we carry over any changes to ActiveRecord.default_timezone that have been
888
- # made since we established the connection
889
- update_typemap_for_default_timezone
890
-
891
- type_casted_binds = type_casted_binds(binds)
892
- log(sql, name, binds, type_casted_binds, async: async) do
893
- with_raw_connection do |conn|
894
- result = conn.exec_params(sql, type_casted_binds)
895
- verified!
896
- result
897
- end
898
- end
899
- end
900
-
901
- def exec_cache(sql, name, binds, async:, allow_retry:, materialize_transactions:)
902
- mark_transaction_written_if_write(sql)
903
-
904
- update_typemap_for_default_timezone
905
-
906
- with_raw_connection do |conn|
907
- stmt_key = prepare_statement(sql, binds, conn)
908
- type_casted_binds = type_casted_binds(binds)
909
-
910
- log(sql, name, binds, type_casted_binds, stmt_key, async: async) do
911
- result = conn.exec_prepared(stmt_key, type_casted_binds)
912
- verified!
913
- result
914
- end
915
- end
916
- rescue ActiveRecord::StatementInvalid => e
917
- raise unless is_cached_plan_failure?(e)
918
-
919
- # Nothing we can do if we are in a transaction because all commands
920
- # will raise InFailedSQLTransaction
921
- if in_transaction?
922
- raise ActiveRecord::PreparedStatementCacheExpired.new(e.cause.message)
923
- else
924
- @lock.synchronize do
925
- # outside of transactions we can simply flush this query and retry
926
- @statements.delete sql_key(sql)
927
- end
928
- retry
929
- end
930
- end
931
-
932
892
  # Annoyingly, the code for prepared statements whose return value may
933
893
  # have changed is FEATURE_NOT_SUPPORTED.
934
894
  #
@@ -938,8 +898,7 @@ module ActiveRecord
938
898
  #
939
899
  # Check here for more details:
940
900
  # https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/utils/cache/plancache.c#l573
941
- def is_cached_plan_failure?(e)
942
- pgerror = e.cause
901
+ def is_cached_plan_failure?(pgerror)
943
902
  pgerror.result.result_error_field(PG::PG_DIAG_SQLSTATE) == FEATURE_NOT_SUPPORTED &&
944
903
  pgerror.result.result_error_field(PG::PG_DIAG_SOURCE_FUNCTION) == "RevalidateCachedQuery"
945
904
  rescue
@@ -995,6 +954,8 @@ module ActiveRecord
995
954
  # Configures the encoding, verbosity, schema search path, and time zone of the connection.
996
955
  # This is called by #connect and should not be called manually.
997
956
  def configure_connection
957
+ super
958
+
998
959
  if @config[:encoding]
999
960
  @raw_connection.set_client_encoding(@config[:encoding])
1000
961
  end
@@ -1016,16 +977,16 @@ module ActiveRecord
1016
977
  variables = @config.fetch(:variables, {}).stringify_keys
1017
978
 
1018
979
  # Set interval output format to ISO 8601 for ease of parsing by ActiveSupport::Duration.parse
1019
- internal_execute("SET intervalstyle = iso_8601")
980
+ internal_execute("SET intervalstyle = iso_8601", "SCHEMA")
1020
981
 
1021
982
  # SET statements from :variables config hash
1022
983
  # https://www.postgresql.org/docs/current/static/sql-set.html
1023
984
  variables.map do |k, v|
1024
985
  if v == ":default" || v == :default
1025
986
  # Sets the value to the global or compile default
1026
- internal_execute("SET SESSION #{k} TO DEFAULT")
987
+ internal_execute("SET SESSION #{k} TO DEFAULT", "SCHEMA")
1027
988
  elsif !v.nil?
1028
- internal_execute("SET SESSION #{k} TO #{quote(v)}")
989
+ internal_execute("SET SESSION #{k} TO #{quote(v)}", "SCHEMA")
1029
990
  end
1030
991
  end
1031
992
 
@@ -1046,9 +1007,9 @@ module ActiveRecord
1046
1007
  # If using Active Record's time zone support configure the connection
1047
1008
  # to return TIMESTAMP WITH ZONE types in UTC.
1048
1009
  if default_timezone == :utc
1049
- internal_execute("SET SESSION timezone TO 'UTC'")
1010
+ raw_execute("SET SESSION timezone TO 'UTC'", "SCHEMA")
1050
1011
  else
1051
- internal_execute("SET SESSION timezone TO DEFAULT")
1012
+ raw_execute("SET SESSION timezone TO DEFAULT", "SCHEMA")
1052
1013
  end
1053
1014
  end
1054
1015
 
@@ -1115,9 +1076,8 @@ module ActiveRecord
1115
1076
  AND castsource = #{quote column.sql_type}::regtype
1116
1077
  )
1117
1078
  SQL
1118
- execute_and_clear(sql, "SCHEMA", [], allow_retry: true, materialize_transactions: false) do |result|
1119
- result.getvalue(0, 0)
1120
- end
1079
+ result = internal_execute(sql, "SCHEMA", [], allow_retry: true, materialize_transactions: false)
1080
+ result.getvalue(0, 0)
1121
1081
  end
1122
1082
  end
1123
1083
  end
@@ -1165,6 +1125,7 @@ module ActiveRecord
1165
1125
  "timestamp" => PG::TextDecoder::TimestampUtc,
1166
1126
  "timestamptz" => PG::TextDecoder::TimestampWithTimeZone,
1167
1127
  }
1128
+ coders_by_name["date"] = PG::TextDecoder::Date if decode_dates
1168
1129
 
1169
1130
  known_coder_types = coders_by_name.keys.map { |n| quote(n) }
1170
1131
  query = <<~SQL % known_coder_types.join(", ")
@@ -1172,9 +1133,8 @@ module ActiveRecord
1172
1133
  FROM pg_type as t
1173
1134
  WHERE t.typname IN (%s)
1174
1135
  SQL
1175
- coders = execute_and_clear(query, "SCHEMA", [], allow_retry: true, materialize_transactions: false) do |result|
1176
- result.filter_map { |row| construct_coder(row, coders_by_name[row["typname"]]) }
1177
- end
1136
+ result = internal_execute(query, "SCHEMA", [], allow_retry: true, materialize_transactions: false)
1137
+ coders = result.filter_map { |row| construct_coder(row, coders_by_name[row["typname"]]) }
1178
1138
 
1179
1139
  map = PG::TypeMapByOid.new
1180
1140
  coders.each { |coder| map.add_coder(coder) }