Age Owner Branch data TLA Line data Source code
1 : : /*
2 : : * version.c
3 : : *
4 : : * Postgres-version-specific routines
5 : : *
6 : : * Copyright (c) 2010-2024, 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 : : * 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 : : */
20 : : bool
26 dgustafsson@postgres 21 :GNC 20 : jsonb_9_4_check_applicable(ClusterInfo *cluster)
22 : : {
23 : : /* JSONB changed its storage format during 9.4 beta */
24 [ - + ]: 20 : if (GET_MAJOR_VERSION(cluster->major_version) == 904 &&
26 dgustafsson@postgres 25 [ # # ]:UNC 0 : cluster->controldata.cat_ver < JSONB_FORMAT_CHANGE_CAT_VER)
26 : 0 : return true;
27 : :
26 dgustafsson@postgres 28 :GNC 20 : return false;
2636 tgl@sss.pgh.pa.us 29 :EUB : }
30 : :
31 : : /*
32 : : * old_9_6_invalidate_hash_indexes()
33 : : * 9.6 -> 10
34 : : * Hash index binary format has changed from 9.6->10.0
35 : : */
36 : : void
2522 rhaas@postgresql.org 37 :UBC 0 : old_9_6_invalidate_hash_indexes(ClusterInfo *cluster, bool check_mode)
38 : : {
39 : : int dbnum;
40 : 0 : FILE *script = NULL;
41 : 0 : bool found = false;
42 : 0 : char *output_path = "reindex_hash.sql";
43 : :
44 : 0 : prep_status("Checking for hash indexes");
45 : :
46 [ # # ]: 0 : for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
47 : : {
48 : : PGresult *res;
49 : 0 : bool db_used = false;
50 : : int ntups;
51 : : int rowno;
52 : : int i_nspname,
53 : : i_relname;
54 : 0 : DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
55 : 0 : PGconn *conn = connectToServer(cluster, active_db->db_name);
56 : :
57 : : /* find hash indexes */
58 : 0 : res = executeQueryOrDie(conn,
59 : : "SELECT n.nspname, c.relname "
60 : : "FROM pg_catalog.pg_class c, "
61 : : " pg_catalog.pg_index i, "
62 : : " pg_catalog.pg_am a, "
63 : : " pg_catalog.pg_namespace n "
64 : : "WHERE i.indexrelid = c.oid AND "
65 : : " c.relam = a.oid AND "
66 : : " c.relnamespace = n.oid AND "
67 : : " a.amname = 'hash'"
68 : : );
69 : :
70 : 0 : ntups = PQntuples(res);
71 : 0 : i_nspname = PQfnumber(res, "nspname");
72 : 0 : i_relname = PQfnumber(res, "relname");
73 [ # # ]: 0 : for (rowno = 0; rowno < ntups; rowno++)
74 : : {
75 : 0 : found = true;
76 [ # # ]: 0 : if (!check_mode)
77 : : {
78 [ # # # # ]: 0 : if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
33 michael@paquier.xyz 79 :UNC 0 : pg_fatal("could not open file \"%s\": %m", output_path);
2522 rhaas@postgresql.org 80 [ # # ]:UBC 0 : if (!db_used)
81 : : {
82 : : PQExpBufferData connectbuf;
83 : :
84 : 0 : initPQExpBuffer(&connectbuf);
85 : 0 : appendPsqlMetaConnect(&connectbuf, active_db->db_name);
86 : 0 : fputs(connectbuf.data, script);
87 : 0 : termPQExpBuffer(&connectbuf);
88 : 0 : db_used = true;
89 : : }
90 : 0 : fprintf(script, "REINDEX INDEX %s.%s;\n",
91 : 0 : quote_identifier(PQgetvalue(res, rowno, i_nspname)),
92 : 0 : quote_identifier(PQgetvalue(res, rowno, i_relname)));
93 : : }
94 : : }
95 : :
96 : 0 : PQclear(res);
97 : :
98 [ # # # # ]: 0 : if (!check_mode && db_used)
99 : : {
100 : : /* mark hash indexes as invalid */
101 : 0 : PQclear(executeQueryOrDie(conn,
102 : : "UPDATE pg_catalog.pg_index i "
103 : : "SET indisvalid = false "
104 : : "FROM pg_catalog.pg_class c, "
105 : : " pg_catalog.pg_am a, "
106 : : " pg_catalog.pg_namespace n "
107 : : "WHERE i.indexrelid = c.oid AND "
108 : : " c.relam = a.oid AND "
109 : : " c.relnamespace = n.oid AND "
110 : : " a.amname = 'hash'"));
111 : : }
112 : :
113 : 0 : PQfinish(conn);
114 : : }
115 : :
116 [ # # ]: 0 : if (script)
117 : 0 : fclose(script);
118 : :
119 [ # # ]: 0 : if (found)
120 : : {
121 : 0 : report_status(PG_WARNING, "warning");
122 [ # # ]: 0 : if (check_mode)
123 : 0 : pg_log(PG_WARNING, "\n"
124 : : "Your installation contains hash indexes. These indexes have different\n"
125 : : "internal formats between your old and new clusters, so they must be\n"
126 : : "reindexed with the REINDEX command. After upgrading, you will be given\n"
127 : : "REINDEX instructions.");
128 : : else
129 : 0 : pg_log(PG_WARNING, "\n"
130 : : "Your installation contains hash indexes. These indexes have different\n"
131 : : "internal formats between your old and new clusters, so they must be\n"
132 : : "reindexed with the REINDEX command. The file\n"
133 : : " %s\n"
134 : : "when executed by psql by the database superuser will recreate all invalid\n"
135 : : "indexes; until then, none of these indexes will be used.",
136 : : output_path);
137 : : }
138 : : else
139 : 0 : check_ok();
140 : 0 : }
141 : :
142 : : /*
143 : : * report_extension_updates()
144 : : * Report extensions that should be updated.
145 : : */
146 : : void
985 bruce@momjian.us 147 :CBC 3 : report_extension_updates(ClusterInfo *cluster)
148 : : {
149 : : int dbnum;
150 : 3 : FILE *script = NULL;
151 : 3 : char *output_path = "update_extensions.sql";
152 : :
153 : 3 : prep_status("Checking for extension updates");
154 : :
155 [ + + ]: 13 : for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
156 : : {
157 : : PGresult *res;
158 : 10 : bool db_used = false;
159 : : int ntups;
160 : : int rowno;
161 : : int i_name;
162 : 10 : DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
163 : 10 : PGconn *conn = connectToServer(cluster, active_db->db_name);
164 : :
165 : : /* find extensions needing updates */
166 : 10 : res = executeQueryOrDie(conn,
167 : : "SELECT name "
168 : : "FROM pg_available_extensions "
169 : : "WHERE installed_version != default_version"
170 : : );
171 : :
172 : 10 : ntups = PQntuples(res);
173 : 10 : i_name = PQfnumber(res, "name");
174 [ - + ]: 10 : for (rowno = 0; rowno < ntups; rowno++)
175 : : {
985 bruce@momjian.us 176 [ # # # # ]:UBC 0 : if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
33 michael@paquier.xyz 177 :UNC 0 : pg_fatal("could not open file \"%s\": %m", output_path);
985 bruce@momjian.us 178 [ # # ]:UBC 0 : if (!db_used)
179 : : {
180 : : PQExpBufferData connectbuf;
181 : :
182 : 0 : initPQExpBuffer(&connectbuf);
183 : 0 : appendPsqlMetaConnect(&connectbuf, active_db->db_name);
184 : 0 : fputs(connectbuf.data, script);
185 : 0 : termPQExpBuffer(&connectbuf);
186 : 0 : db_used = true;
187 : : }
188 : 0 : fprintf(script, "ALTER EXTENSION %s UPDATE;\n",
189 : 0 : quote_identifier(PQgetvalue(res, rowno, i_name)));
190 : : }
191 : :
985 bruce@momjian.us 192 :CBC 10 : PQclear(res);
193 : :
194 : 10 : PQfinish(conn);
195 : : }
196 : :
197 [ - + ]: 3 : if (script)
198 : : {
592 dgustafsson@postgres 199 :UBC 0 : fclose(script);
985 bruce@momjian.us 200 : 0 : report_status(PG_REPORT, "notice");
201 : 0 : pg_log(PG_REPORT, "\n"
202 : : "Your installation contains extensions that should be updated\n"
203 : : "with the ALTER EXTENSION command. The file\n"
204 : : " %s\n"
205 : : "when executed by psql by the database superuser will update\n"
206 : : "these extensions.",
207 : : output_path);
208 : : }
209 : : else
985 bruce@momjian.us 210 :CBC 3 : check_ok();
211 : 3 : }
|