Skip to content

Commit 942f8ac

Browse files
Add pg 16 to CI and remove :generic explain plan option (#606)
1 parent 52e49a2 commit 942f8ac

File tree

6 files changed

+26
-48
lines changed

6 files changed

+26
-48
lines changed

.github/workflows/ci.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ jobs:
5454
elixirbase:
5555
- "1.11.4-erlang-21.3.8.24-alpine-3.13.3"
5656
postgres:
57-
- "15.0"
58-
- "11.11"
59-
- "9.6"
60-
- "9.5"
57+
- "16.2-alpine"
58+
- "11.11-alpine"
59+
- "9.6-alpine"
60+
- "9.5-alpine"
6161
steps:
6262
- uses: earthly/actions-setup@v1
6363
- uses: actions/checkout@v3

Earthfile

+11-11
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ VERSION 0.6
33
all:
44
ARG ELIXIR_BASE=1.15.6-erlang-25.3.2.6-alpine-3.18.4
55
BUILD \
6-
--build-arg POSTGRES=15.0 \
7-
--build-arg POSTGRES=11.11 \
8-
--build-arg POSTGRES=9.6 \
9-
--build-arg POSTGRES=9.5 \
6+
--build-arg POSTGRES=16.2-alpine \
7+
--build-arg POSTGRES=11.11-alpine \
8+
--build-arg POSTGRES=9.6-alpine \
9+
--build-arg POSTGRES=9.5-alpine \
1010
+integration-test-postgres
1111

1212
BUILD \
@@ -41,19 +41,19 @@ integration-test-postgres:
4141
FROM +setup-base
4242
ARG POSTGRES="11.11"
4343

44-
IF [ "$POSTGRES" = "9.5" ]
44+
IF [ "$POSTGRES" = "9.5-alpine" ]
4545
# for 9.5 we require a downgraded version of pg_dump;
4646
# and in the 3.4 version, it is not included in postgresql-client but rather in postgresql
4747
RUN echo 'http://dl-cdn.alpinelinux.org/alpine/v3.4/main' >> /etc/apk/repositories
4848
RUN apk add postgresql=9.5.13-r0
49-
ELSE IF [ "$POSTGRES" = "15.0" ]
50-
# for 15.0 we need an upgraded version of pg_dump;
51-
# alpine 3.17 does not come with the postgres 15 client by default;
49+
ELSE IF [ "$POSTGRES" = "16.2-alpine" ]
50+
# for 16 we need an upgraded version of pg_dump;
51+
# alpine 3.16 does not come with the postgres 16 client by default;
5252
# we must first update the public keys for the packages because they
5353
# might have been rotated since our image was built
54-
RUN apk add -X https://dl-cdn.alpinelinux.org/alpine/v3.17/main -u alpine-keys
55-
RUN echo 'http://dl-cdn.alpinelinux.org/alpine/v3.17/main' >> /etc/apk/repositories
56-
RUN apk add postgresql15-client
54+
RUN apk add -X https://dl-cdn.alpinelinux.org/alpine/v3.19/main -u alpine-keys
55+
RUN echo 'http://dl-cdn.alpinelinux.org/alpine/v3.19/main' >> /etc/apk/repositories
56+
RUN apk add postgresql16-client
5757
ELSE
5858
RUN apk add postgresql-client
5959
END

integration_test/pg/explain_test.exs

-12
Original file line numberDiff line numberDiff line change
@@ -63,18 +63,6 @@ defmodule Ecto.Integration.ExplainTest do
6363
assert explain =~ "(p0.title)::text = 'title'"
6464
end
6565

66-
@tag :explain_generic
67-
test "explain with generic plan" do
68-
# when using generic plan, placeholders are used instead of values. i.e. $1 instead of 1
69-
query = from p in Post, where: p.visits == ^1 and p.title == ^"title"
70-
71-
explain =
72-
TestRepo.explain(:all, query, plan: :generic, analyze: true, verbose: true, timeout: 20000)
73-
74-
assert explain =~ "p0.visits = $1"
75-
assert explain =~ "(p0.title)::text = $2"
76-
end
77-
7866
test "explain MAP format" do
7967
[explain] =
8068
TestRepo.explain(:all, Post, analyze: true, verbose: true, timeout: 20000, format: :map)

integration_test/pg/test_helper.exs

+3-7
Original file line numberDiff line numberDiff line change
@@ -102,22 +102,18 @@ excludes_above_9_5 = [:without_conflict_target]
102102
excludes_below_9_6 = [:add_column_if_not_exists, :no_error_on_conditional_column_migration]
103103
excludes_below_12_0 = [:plan_cache_mode]
104104
excludes_below_15_0 = [:on_delete_nilify_column_list]
105-
excludes_below_16_0 = [:explain_generic]
106105

107106
exclude_list = excludes ++ excludes_above_9_5
108107

109108
cond do
110109
Version.match?(version, "< 9.6.0") ->
111-
ExUnit.configure(exclude: exclude_list ++ excludes_below_9_6 ++ excludes_below_12_0 ++ excludes_below_15_0 ++ excludes_below_16_0)
110+
ExUnit.configure(exclude: exclude_list ++ excludes_below_9_6 ++ excludes_below_12_0 ++ excludes_below_15_0)
112111

113112
Version.match?(version, "< 12.0.0") ->
114-
ExUnit.configure(exclude: exclude_list ++ excludes_below_12_0 ++ excludes_below_15_0 ++ excludes_below_16_0)
113+
ExUnit.configure(exclude: exclude_list ++ excludes_below_12_0 ++ excludes_below_15_0)
115114

116115
Version.match?(version, "< 15.0.0") ->
117-
ExUnit.configure(exclude: exclude_list ++ excludes_below_15_0 ++ excludes_below_16_0)
118-
119-
Version.match?(version, "< 16.0.0") ->
120-
ExUnit.configure(exclude: exclude_list ++ excludes_below_16_0)
116+
ExUnit.configure(exclude: exclude_list ++ excludes_below_15_0)
121117

122118
true ->
123119
ExUnit.configure(exclude: exclude_list)

lib/ecto/adapters/postgres/connection.ex

+2-8
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,8 @@ if Code.ensure_loaded?(Postgrex) do
363363
~w[analyze verbose costs settings buffers timing summary format plan]a
364364
)
365365

366-
fallback_generic? = explain_opts[:plan] == :fallback_generic
366+
{plan_type, explain_opts} = Keyword.pop(explain_opts, :plan)
367+
fallback_generic? = plan_type == :fallback_generic
367368

368369
result =
369370
cond do
@@ -374,7 +375,6 @@ if Code.ensure_loaded?(Postgrex) do
374375
"You may either change the plan type to `:custom` or remove the `:analyze` option."
375376

376377
fallback_generic? ->
377-
explain_opts = Keyword.delete(explain_opts, :plan)
378378
explain_queries = build_fallback_generic_queries(query, length(params), explain_opts)
379379
fallback_generic_query(conn, explain_queries, opts)
380380

@@ -465,12 +465,6 @@ if Code.ensure_loaded?(Postgrex) do
465465
{:format, value}, acc ->
466466
[String.upcase("#{format_to_sql(value)}") | acc]
467467

468-
{:plan, :generic}, acc ->
469-
["GENERIC" | acc]
470-
471-
{:plan, _}, acc ->
472-
acc
473-
474468
{opt, value}, acc ->
475469
[String.upcase("#{opt} #{quote_boolean(value)}") | acc]
476470
end)

lib/ecto/adapters/sql.ex

+6-6
Original file line numberDiff line numberDiff line change
@@ -400,12 +400,12 @@ defmodule Ecto.Adapters.SQL do
400400
* Postgrex: `:map`, `:yaml` and `:text`
401401
* MyXQL: `:map` and `:text`
402402
403-
The `:plan` option in Postgres can take the values `:custom`, `:generic` or `:fallback_generic`.
404-
When `:custom` is specified, the explain plan generated by Postgres will consider the specific values
405-
of the query parameters that are supplied. When using `:generic` or `:fallback_generic`, the specific
406-
values of the query parameters will be ignored. The difference between the two is that `:generic`
407-
utilizes Postgres's built-in functionality (available since Postgres 16) and `:fallback_generic` is
408-
a special implementation for earlier Postgres versions. Defaults to `:custom`.
403+
The `:plan` option in Postgrex can take the values `:custom` or `:fallback_generic`. When `:custom`
404+
is specified, the explain plan generated will consider the specific values of the query parameters
405+
that are supplied. When using `:fallback_generic`, the specific values of the query parameters will
406+
be ignored. `:fallback_generic` does not use PostgreSQL's built-in support for a generic explain
407+
plan (available as of PostgreSQL 16), but instead uses a special implementation that works for PostgreSQL
408+
versions 12 and above. Defaults to `:custom`.
409409
410410
Any other value passed to `opts` will be forwarded to the underlying adapter query function, including
411411
shared Repo options such as `:timeout`. Non built-in adapters may have specific behaviour and you should

0 commit comments

Comments
 (0)