From a3b355eda1ae3da40357d2230dfe4094a3391570 Mon Sep 17 00:00:00 2001 From: Xavier Shay Date: Mon, 29 Jul 2019 13:54:39 +1000 Subject: [PATCH] Postgres: allow enabling prepared statements for specific queries when disabled globally. There is no way to do this otherwise. --- .../connection_adapters/postgresql_adapter.rb | 9 +++++---- .../test/cases/adapters/postgresql/connection_test.rb | 11 +++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 0a7c6d8ac4b56..9e586376dac86 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -642,13 +642,14 @@ def execute_and_clear(sql, name, binds, prepare: false) raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}" end - if without_prepared_statement?(binds) + if prepare + result = exec_cache(sql, name, binds) + elsif without_prepared_statement?(binds) result = exec_no_cache(sql, name, []) - elsif !prepare - result = exec_no_cache(sql, name, binds) else - result = exec_cache(sql, name, binds) + result = exec_no_cache(sql, name, binds) end + ret = yield result result.clear ret diff --git a/activerecord/test/cases/adapters/postgresql/connection_test.rb b/activerecord/test/cases/adapters/postgresql/connection_test.rb index dcee4fd22d869..c364244333525 100644 --- a/activerecord/test/cases/adapters/postgresql/connection_test.rb +++ b/activerecord/test/cases/adapters/postgresql/connection_test.rb @@ -138,6 +138,17 @@ def test_statement_key_is_logged end end + def test_force_prepare_statement + @connection.unprepared_statement do + @connection.exec_query("SELECT 1::integer", "SQL", [], prepare: true) + name = @subscriber.payloads.last[:statement_name] + assert name + res = @connection.exec_query("EXPLAIN (FORMAT JSON) EXECUTE #{name}(1)") + plan = res.column_types["QUERY PLAN"].deserialize res.rows.first.first + assert_operator plan.length, :>, 0 + end + end + def test_reconnection_after_actual_disconnection_with_verify original_connection_pid = @connection.query("select pg_backend_pid()")