PostgreSQL Source Code git master
Loading...
Searching...
No Matches
version.c
Go to the documentation of this file.
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
13#include "pg_upgrade.h"
14
15/*
16 * version_hook functions for check_for_data_types_usage in order to determine
17 * whether a data type check should be executed for the cluster in question or
18 * not.
19 */
20bool
22{
23 /* JSONB changed its storage format during 9.4 beta */
24 if (GET_MAJOR_VERSION(cluster->major_version) == 904 &&
25 cluster->controldata.cat_ver < JSONB_FORMAT_CHANGE_CAT_VER)
26 return true;
27
28 return false;
29}
30
31/*
32 * Older servers can't support newer protocol versions, so their connection
33 * strings will need to lock max_protocol_version to 3.0.
34 */
35bool
37{
38 /*
39 * The February 2018 patch release (9.3.21, 9.4.16, 9.5.11, 9.6.7, and
40 * 10.2) added support for NegotiateProtocolVersion. But ClusterInfo only
41 * has information about the major version number. To ensure we can still
42 * upgrade older unpatched servers, just assume anything prior to PG11
43 * can't negotiate. It's not possible for those servers to make use of
44 * newer protocols anyway, so nothing is lost.
45 */
46 return (GET_MAJOR_VERSION(cluster->major_version) >= 1100);
47}
48
49/*
50 * old_9_6_invalidate_hash_indexes()
51 * 9.6 -> 10
52 * Hash index binary format has changed from 9.6->10.0
53 */
54void
56{
57 int dbnum;
58 FILE *script = NULL;
59 bool found = false;
60 char *output_path = "reindex_hash.sql";
61
62 prep_status("Checking for hash indexes");
63
64 for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
65 {
66 PGresult *res;
67 bool db_used = false;
68 int ntups;
69 int rowno;
70 int i_nspname,
72 DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
74
75 /* find hash indexes */
77 "SELECT n.nspname, c.relname "
78 "FROM pg_catalog.pg_class c, "
79 " pg_catalog.pg_index i, "
80 " pg_catalog.pg_am a, "
81 " pg_catalog.pg_namespace n "
82 "WHERE i.indexrelid = c.oid AND "
83 " c.relam = a.oid AND "
84 " c.relnamespace = n.oid AND "
85 " a.amname = 'hash'"
86 );
87
88 ntups = PQntuples(res);
89 i_nspname = PQfnumber(res, "nspname");
90 i_relname = PQfnumber(res, "relname");
91 for (rowno = 0; rowno < ntups; rowno++)
92 {
93 found = true;
94 if (!check_mode)
95 {
96 if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
97 pg_fatal("could not open file \"%s\": %m", output_path);
98 if (!db_used)
99 {
101
104 fputs(connectbuf.data, script);
106 db_used = true;
107 }
108 fprintf(script, "REINDEX INDEX %s.%s;\n",
111 }
112 }
113
114 PQclear(res);
115
116 if (!check_mode && db_used)
117 {
118 /* mark hash indexes as invalid */
120 "UPDATE pg_catalog.pg_index i "
121 "SET indisvalid = false "
122 "FROM pg_catalog.pg_class c, "
123 " pg_catalog.pg_am a, "
124 " pg_catalog.pg_namespace n "
125 "WHERE i.indexrelid = c.oid AND "
126 " c.relam = a.oid AND "
127 " c.relnamespace = n.oid AND "
128 " a.amname = 'hash'"));
129 }
130
131 PQfinish(conn);
132 }
133
134 if (script)
135 fclose(script);
136
137 if (found)
138 {
139 report_status(PG_WARNING, "warning");
140 if (check_mode)
141 pg_log(PG_WARNING, "\n"
142 "Your installation contains hash indexes. These indexes have different\n"
143 "internal formats between your old and new clusters, so they must be\n"
144 "reindexed with the REINDEX command. After upgrading, you will be given\n"
145 "REINDEX instructions.");
146 else
147 pg_log(PG_WARNING, "\n"
148 "Your installation contains hash indexes. These indexes have different\n"
149 "internal formats between your old and new clusters, so they must be\n"
150 "reindexed with the REINDEX command. The file\n"
151 " %s\n"
152 "when executed by psql by the database superuser will recreate all invalid\n"
153 "indexes; until then, none of these indexes will be used.",
155 }
156 else
157 check_ok();
158}
159
160/*
161 * Callback function for processing results of query for
162 * report_extension_updates()'s UpgradeTask. If the query returned any rows,
163 * write the details to the report file.
164 */
165static void
167{
168 int ntups = PQntuples(res);
169 int i_name = PQfnumber(res, "name");
172
173 if (ntups == 0)
174 return;
175
176 if (report->file == NULL &&
177 (report->file = fopen_priv(report->path, "w")) == NULL)
178 pg_fatal("could not open file \"%s\": %m", report->path);
179
182 fputs(connectbuf.data, report->file);
184
185 for (int rowno = 0; rowno < ntups; rowno++)
186 fprintf(report->file, "ALTER EXTENSION %s UPDATE;\n",
188}
189
190/*
191 * report_extension_updates()
192 * Report extensions that should be updated.
193 */
194void
196{
197 UpgradeTaskReport report;
199 const char *query = "SELECT name "
200 "FROM pg_available_extensions "
201 "WHERE installed_version != default_version";
202
203 prep_status("Checking for extension updates");
204
205 report.file = NULL;
206 strcpy(report.path, "update_extensions.sql");
207
209 true, &report);
210
213
214 if (report.file)
215 {
216 fclose(report.file);
217 report_status(PG_REPORT, "notice");
218 pg_log(PG_REPORT, "\n"
219 "Your installation contains extensions that should be updated\n"
220 "with the ALTER EXTENSION command. The file\n"
221 " %s\n"
222 "when executed by psql by the database superuser will update\n"
223 "these extensions.",
224 report.path);
225 }
226 else
227 check_ok();
228}
bool jsonb_9_4_check_applicable(ClusterInfo *cluster)
Definition version.c:21
void report_extension_updates(ClusterInfo *cluster)
Definition version.c:195
static void process_extension_updates(DbInfo *dbinfo, PGresult *res, void *arg)
Definition version.c:166
bool protocol_negotiation_supported(const ClusterInfo *cluster)
Definition version.c:36
void old_9_6_invalidate_hash_indexes(ClusterInfo *cluster, bool check_mode)
Definition version.c:55
#define fprintf(file, fmt, msg)
Definition cubescan.l:21
Datum arg
Definition elog.c:1322
void PQfinish(PGconn *conn)
int PQfnumber(const PGresult *res, const char *field_name)
Definition fe-exec.c:3606
static void check_ok(void)
Definition initdb.c:2123
#define PQgetvalue
#define PQclear
#define PQntuples
#define pg_fatal(...)
UpgradeTask * upgrade_task_create(void)
Definition task.c:117
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition server.c:28
void upgrade_task_run(const UpgradeTask *task, const ClusterInfo *cluster)
Definition task.c:421
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
void upgrade_task_free(UpgradeTask *task)
Definition task.c:133
#define fopen_priv(path, mode)
Definition pg_upgrade.h:439
@ PG_WARNING
Definition pg_upgrade.h:284
@ PG_REPORT
Definition pg_upgrade.h:283
#define GET_MAJOR_VERSION(v)
Definition pg_upgrade.h:27
void prep_status(const char *fmt,...) pg_attribute_printf(1
void report_status(eLogType type, const char *fmt,...) pg_attribute_printf(2
void upgrade_task_add_step(UpgradeTask *task, const char *query, UpgradeTaskProcessCB process_cb, bool free_result, void *arg)
Definition task.c:151
#define JSONB_FORMAT_CHANGE_CAT_VER
Definition pg_upgrade.h:133
void initPQExpBuffer(PQExpBuffer str)
Definition pqexpbuffer.c:90
void termPQExpBuffer(PQExpBuffer str)
static int fb(int x)
const char * quote_identifier(const char *ident)
PGconn * conn
Definition streamutil.c:52
void appendPsqlMetaConnect(PQExpBuffer buf, const char *dbname)
char * db_name
Definition pg_upgrade.h:206
char path[MAXPGPATH]
Definition pg_upgrade.h:539