Branch data Line data Source code
1 : : /*
2 : : * version.c
3 : : *
4 : : * Postgres-version-specific routines
5 : : *
6 : : * Copyright (c) 2010-2026, PostgreSQL Global Development Group
7 : : * src/bin/pg_upgrade/version.c
8 : : */
9 : :
10 : : #include "postgres_fe.h"
11 : :
12 : : #include "fe_utils/string_utils.h"
13 : : #include "pg_upgrade.h"
14 : :
15 : : /*
16 : : * Older servers can't support newer protocol versions, so their connection
17 : : * strings will need to lock max_protocol_version to 3.0.
18 : : */
19 : : bool
20 : 729 : protocol_negotiation_supported(const ClusterInfo *cluster)
21 : : {
22 : : /*
23 : : * The February 2018 patch release (9.3.21, 9.4.16, 9.5.11, 9.6.7, and
24 : : * 10.2) added support for NegotiateProtocolVersion. But ClusterInfo only
25 : : * has information about the major version number. To ensure we can still
26 : : * upgrade older unpatched servers, just assume anything prior to PG11
27 : : * can't negotiate. It's not possible for those servers to make use of
28 : : * newer protocols anyway, so nothing is lost.
29 : : */
30 : 729 : return (GET_MAJOR_VERSION(cluster->major_version) >= 1100);
31 : : }
32 : :
33 : : /*
34 : : * Callback function for processing results of query for
35 : : * report_extension_updates()'s UpgradeTask. If the query returned any rows,
36 : : * write the details to the report file.
37 : : */
38 : : static void
39 : 32 : process_extension_updates(DbInfo *dbinfo, PGresult *res, void *arg)
40 : : {
41 : 32 : int ntups = PQntuples(res);
42 : 32 : int i_name = PQfnumber(res, "name");
43 : 32 : UpgradeTaskReport *report = (UpgradeTaskReport *) arg;
44 : : PQExpBufferData connectbuf;
45 : :
46 [ + - ]: 32 : if (ntups == 0)
47 : 32 : return;
48 : :
49 [ # # ]: 0 : if (report->file == NULL &&
50 [ # # ]: 0 : (report->file = fopen_priv(report->path, "w")) == NULL)
51 : 0 : pg_fatal("could not open file \"%s\": %m", report->path);
52 : :
53 : 0 : initPQExpBuffer(&connectbuf);
54 : 0 : appendPsqlMetaConnect(&connectbuf, dbinfo->db_name);
55 : 0 : fputs(connectbuf.data, report->file);
56 : 0 : termPQExpBuffer(&connectbuf);
57 : :
58 [ # # ]: 0 : for (int rowno = 0; rowno < ntups; rowno++)
59 : 0 : fprintf(report->file, "ALTER EXTENSION %s UPDATE;\n",
60 : 0 : quote_identifier(PQgetvalue(res, rowno, i_name)));
61 : : }
62 : :
63 : : /*
64 : : * report_extension_updates()
65 : : * Report extensions that should be updated.
66 : : */
67 : : void
68 : 10 : report_extension_updates(ClusterInfo *cluster)
69 : : {
70 : : UpgradeTaskReport report;
71 : 10 : UpgradeTask *task = upgrade_task_create();
72 : 10 : const char *query = "SELECT name "
73 : : "FROM pg_available_extensions "
74 : : "WHERE installed_version != default_version";
75 : :
76 : 10 : prep_status("Checking for extension updates");
77 : :
78 : 10 : report.file = NULL;
79 : 10 : strcpy(report.path, "update_extensions.sql");
80 : :
81 : 10 : upgrade_task_add_step(task, query, process_extension_updates,
82 : : true, &report);
83 : :
84 : 10 : upgrade_task_run(task, cluster);
85 : 10 : upgrade_task_free(task);
86 : :
87 [ - + ]: 10 : if (report.file)
88 : : {
89 : 0 : fclose(report.file);
90 : 0 : report_status(PG_REPORT, "notice");
91 : 0 : pg_log(PG_REPORT, "\n"
92 : : "Your installation contains extensions that should be updated\n"
93 : : "with the ALTER EXTENSION command. The file\n"
94 : : " %s\n"
95 : : "when executed by psql by the database superuser will update\n"
96 : : "these extensions.",
97 : : report.path);
98 : : }
99 : : else
100 : 10 : check_ok();
101 : 10 : }
|