diff --git a/integration_test/pg/explain_test.exs b/integration_test/pg/explain_test.exs index 0e87af29..957a792f 100644 --- a/integration_test/pg/explain_test.exs +++ b/integration_test/pg/explain_test.exs @@ -37,6 +37,9 @@ defmodule Ecto.Integration.ExplainTest do assert explain =~ "p0.visits = $1" assert explain =~ "(p0.title)::text = $2" + + # Works when no parameters are given + TestRepo.explain(:all, Post, plan: :fallback_generic, verbose: true, timeout: 20000) end test "explain with fallback generic plan cannot use analyze" do diff --git a/lib/ecto/adapters/postgres/connection.ex b/lib/ecto/adapters/postgres/connection.ex index a99fecb8..1203fcaa 100644 --- a/lib/ecto/adapters/postgres/connection.ex +++ b/lib/ecto/adapters/postgres/connection.ex @@ -397,28 +397,35 @@ if Code.ensure_loaded?(Postgrex) do end def build_fallback_generic_queries(query, num_params, opts) do + prepare_args = + if num_params > 0, + do: ["( ", Enum.map_intersperse(1..num_params, ", ", fn _ -> "unknown" end), " )"], + else: [] + prepare = [ "PREPARE ", @explain_prepared_statement_name, - "(", - Enum.map_intersperse(1..num_params, ", ", fn _ -> "unknown" end), - ") AS ", + prepare_args, + " AS ", query ] |> IO.iodata_to_binary() set = "SET LOCAL plan_cache_mode = force_generic_plan" + execute_args = + if num_params > 0, + do: ["( ", Enum.map_intersperse(1..num_params, ", ", fn _ -> "NULL" end), " )"], + else: [] + execute = [ "EXPLAIN ", build_explain_opts(opts), "EXECUTE ", @explain_prepared_statement_name, - "(", - Enum.map_intersperse(1..num_params, ", ", fn _ -> "NULL" end), - ")" + execute_args ] |> IO.iodata_to_binary()