Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit8e4ef32

Browse files
committed
Handle arrays and ranges in pg_upgrade's test for non-upgradable types.
pg_upgrade needs to check whether certain non-upgradable data typesappear anywhere on-disk in the source cluster. It knew that it hasto check for these types being contained inside domains and compositetypes; but it somehow overlooked that they could be contained inarrays and ranges, too. Extend the existing recursive-containmentquery to handle those cases.We probably should have noticed this oversight while working oncommit0ccfc28 and follow-ups, but we failed to :-(. The wholething's possibly a bit overdesigned, since we don't really expectthat any of these types will appear on disk; but if we're going tothe effort of doing a recursive search then it's silly not to coverall the possibilities.While at it, refactor so that we have only one copy of the searchlogic, not three-and-counting. Also, to keep the branches lookingmore alike, back-patch the output wording change of commit1634d36.Back-patch to all supported branches.Discussion:https://postgr.es/m/31473.1573412838@sss.pgh.pa.us
1 parent34f805c commit8e4ef32

File tree

1 file changed

+99
-146
lines changed

1 file changed

+99
-146
lines changed

‎src/bin/pg_upgrade/version.c

Lines changed: 99 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -100,78 +100,96 @@ new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster, bool check_mode)
100100

101101

102102
/*
103-
* old_9_3_check_for_line_data_type_usage()
104-
*9.3 -> 9.4
105-
*Fully implement the 'line' data type in 9.4, which previously returned
106-
*"not enabled" by default and was only functionally enabled with a
107-
*compile-time switch; 9.4 "line" has different binary and text
108-
*representation formats; checks tables and indexes.
103+
* check_for_data_type_usage
104+
*Detect whether there are any stored columns depending on the given type
105+
*
106+
* If so, write a report to the given file name, and return true.
107+
*
108+
* We check for the type in tables, matviews, and indexes, but not views;
109+
* there's no storage involved in a view.
109110
*/
110-
void
111-
old_9_3_check_for_line_data_type_usage(ClusterInfo*cluster)
111+
staticbool
112+
check_for_data_type_usage(ClusterInfo*cluster,constchar*typename,
113+
char*output_path)
112114
{
113-
intdbnum;
114-
FILE*script=NULL;
115115
boolfound= false;
116-
charoutput_path[MAXPGPATH];
117-
118-
prep_status("Checking for incompatible \"line\" data type");
119-
120-
snprintf(output_path,sizeof(output_path),"tables_using_line.txt");
116+
FILE*script=NULL;
117+
intdbnum;
121118

122119
for (dbnum=0;dbnum<cluster->dbarr.ndbs;dbnum++)
123120
{
121+
DbInfo*active_db=&cluster->dbarr.dbs[dbnum];
122+
PGconn*conn=connectToServer(cluster,active_db->db_name);
123+
PQExpBufferDataquerybuf;
124124
PGresult*res;
125125
booldb_used= false;
126126
intntups;
127127
introwno;
128128
inti_nspname,
129129
i_relname,
130130
i_attname;
131-
DbInfo*active_db=&cluster->dbarr.dbs[dbnum];
132-
PGconn*conn=connectToServer(cluster,active_db->db_name);
133131

134132
/*
135-
* Thepg_catalog.linetypemaybe wrapped in a domain or composite
136-
*type, orboth (9.3 did not allow domains on composite types, but
137-
*there may be multi-level composite type). To detect these cases
138-
* we need a recursive CTE.
133+
* The typeof interest mightbe wrapped in a domain, array,
134+
*composite, orrange, and these container types can be nested (to
135+
*varying extents depending on server version, but that's not of
136+
*concern here). To handle all these caseswe need a recursive CTE.
139137
*/
140-
res=executeQueryOrDie(conn,
141-
"WITH RECURSIVE oids AS ( "
142-
/* the pg_catalog.line type itself */
143-
"SELECT 'pg_catalog.line'::pg_catalog.regtype AS oid "
144-
"UNION ALL "
145-
"SELECT * FROM ( "
146-
/* domains on the type */
147-
"WITH x AS (SELECT oid FROM oids) "
148-
"SELECT t.oid FROM pg_catalog.pg_type t, x WHERE typbasetype = x.oid AND typtype = 'd' "
149-
"UNION "
150-
/* composite types containing the type */
151-
"SELECT t.oid FROM pg_catalog.pg_type t, pg_catalog.pg_class c, pg_catalog.pg_attribute a, x "
152-
"WHERE t.typtype = 'c' AND "
153-
" t.oid = c.reltype AND "
154-
" c.oid = a.attrelid AND "
155-
" NOT a.attisdropped AND "
156-
" a.atttypid = x.oid "
157-
") foo "
158-
") "
159-
"SELECT n.nspname, c.relname, a.attname "
160-
"FROMpg_catalog.pg_class c, "
161-
"pg_catalog.pg_namespace n, "
162-
"pg_catalog.pg_attribute a "
163-
"WHEREc.oid = a.attrelid AND "
164-
"NOT a.attisdropped AND "
165-
"a.atttypid IN (SELECT oid FROM oids) AND "
166-
"c.relkind IN ("
167-
CppAsString2(RELKIND_RELATION) ", "
168-
CppAsString2(RELKIND_MATVIEW)", "
169-
CppAsString2(RELKIND_INDEX)") AND "
170-
"c.relnamespace = n.oid AND "
138+
initPQExpBuffer(&querybuf);
139+
appendPQExpBuffer(&querybuf,
140+
"WITH RECURSIVE oids AS ( "
141+
/* the target type itself */
142+
"SELECT '%s'::pg_catalog.regtype AS oid "
143+
"UNION ALL "
144+
"SELECT * FROM ( "
145+
/* inner WITH because we can only reference the CTE once */
146+
"WITH x AS (SELECT oid FROM oids) "
147+
/* domains on any type selected so far */
148+
"SELECT t.oid FROM pg_catalog.pg_type t, x WHERE typbasetype = x.oid AND typtype = 'd' "
149+
"UNION ALL "
150+
/* arrays over any type selected so far */
151+
"SELECT t.oid FROM pg_catalog.pg_type t, x WHERE typelem = x.oid AND typtype = 'b' "
152+
"UNION ALL "
153+
/* composite types containing any type selected so far */
154+
"SELECT t.oid FROM pg_catalog.pg_type t, pg_catalog.pg_class c, pg_catalog.pg_attribute a, x "
155+
"WHERE t.typtype = 'c' AND "
156+
" t.oid = c.reltype AND "
157+
" c.oid = a.attrelid AND "
158+
" NOT a.attisdropped AND "
159+
" a.atttypid = x.oid ",
160+
typename);
161+
162+
/* Ranges came in in 9.2 */
163+
if (GET_MAJOR_VERSION(cluster->major_version) >=902)
164+
appendPQExpBuffer(&querybuf,
165+
"UNION ALL "
166+
/* ranges containing any type selected so far */
167+
"SELECT t.oid FROM pg_catalog.pg_type t, pg_catalog.pg_range r, x "
168+
"WHERE t.typtype = 'r' AND r.rngtypid = t.oid AND r.rngsubtype = x.oid");
169+
170+
appendPQExpBuffer(&querybuf,
171+
") foo "
172+
") "
173+
/* now look for stored columns of any such type */
174+
"SELECT n.nspname, c.relname, a.attname "
175+
"FROMpg_catalog.pg_class c, "
176+
"pg_catalog.pg_namespace n, "
177+
"pg_catalog.pg_attribute a "
178+
"WHEREc.oid = a.attrelid AND "
179+
"NOT a.attisdropped AND "
180+
"a.atttypid IN (SELECT oid FROM oids) AND "
181+
"c.relkind IN ("
182+
CppAsString2(RELKIND_RELATION) ", "
183+
CppAsString2(RELKIND_MATVIEW)", "
184+
CppAsString2(RELKIND_INDEX)") AND "
185+
"c.relnamespace = n.oid AND "
171186
/* exclude possible orphaned temp tables */
172-
"n.nspname !~ '^pg_temp_' AND "
173-
"n.nspname !~ '^pg_toast_temp_' AND "
174-
"n.nspname NOT IN ('pg_catalog', 'information_schema')");
187+
"n.nspname !~ '^pg_temp_' AND "
188+
"n.nspname !~ '^pg_toast_temp_' AND "
189+
/* exclude system catalogs, too */
190+
"n.nspname NOT IN ('pg_catalog', 'information_schema')");
191+
192+
res=executeQueryOrDie(conn,"%s",querybuf.data);
175193

176194
ntups=PQntuples(res);
177195
i_nspname=PQfnumber(res,"nspname");
@@ -185,7 +203,7 @@ old_9_3_check_for_line_data_type_usage(ClusterInfo *cluster)
185203
strerror(errno));
186204
if (!db_used)
187205
{
188-
fprintf(script,"Database: %s\n",active_db->db_name);
206+
fprintf(script,"In database: %s\n",active_db->db_name);
189207
db_used= true;
190208
}
191209
fprintf(script," %s.%s.%s\n",
@@ -196,13 +214,36 @@ old_9_3_check_for_line_data_type_usage(ClusterInfo *cluster)
196214

197215
PQclear(res);
198216

217+
termPQExpBuffer(&querybuf);
218+
199219
PQfinish(conn);
200220
}
201221

202222
if (script)
203223
fclose(script);
204224

205-
if (found)
225+
returnfound;
226+
}
227+
228+
229+
/*
230+
* old_9_3_check_for_line_data_type_usage()
231+
*9.3 -> 9.4
232+
*Fully implement the 'line' data type in 9.4, which previously returned
233+
*"not enabled" by default and was only functionally enabled with a
234+
*compile-time switch; as of 9.4 "line" has a different on-disk
235+
*representation format.
236+
*/
237+
void
238+
old_9_3_check_for_line_data_type_usage(ClusterInfo*cluster)
239+
{
240+
charoutput_path[MAXPGPATH];
241+
242+
prep_status("Checking for incompatible \"line\" data type");
243+
244+
snprintf(output_path,sizeof(output_path),"tables_using_line.txt");
245+
246+
if (check_for_data_type_usage(cluster,"pg_catalog.line",output_path))
206247
{
207248
pg_log(PG_REPORT,"fatal\n");
208249
pg_fatal("Your installation contains the \"line\" data type in user tables. This\n"
@@ -229,105 +270,17 @@ old_9_3_check_for_line_data_type_usage(ClusterInfo *cluster)
229270
*mid-upgrade. Worse, if there's a matview with such a column, the
230271
*DDL reload will silently change it to "text" which won't match the
231272
*on-disk storage (which is like "cstring"). So we *must* reject that.
232-
*Also check composite types and domains on the "unknwown" type (even
233-
*combinations of both), in case they are used for table columns.
234-
*We needn't check indexes, because "unknown" has no opclasses.
235273
*/
236274
void
237275
old_9_6_check_for_unknown_data_type_usage(ClusterInfo*cluster)
238276
{
239-
intdbnum;
240-
FILE*script=NULL;
241-
boolfound= false;
242277
charoutput_path[MAXPGPATH];
243278

244279
prep_status("Checking for invalid \"unknown\" user columns");
245280

246281
snprintf(output_path,sizeof(output_path),"tables_using_unknown.txt");
247282

248-
for (dbnum=0;dbnum<cluster->dbarr.ndbs;dbnum++)
249-
{
250-
PGresult*res;
251-
booldb_used= false;
252-
intntups;
253-
introwno;
254-
inti_nspname,
255-
i_relname,
256-
i_attname;
257-
DbInfo*active_db=&cluster->dbarr.dbs[dbnum];
258-
PGconn*conn=connectToServer(cluster,active_db->db_name);
259-
260-
/*
261-
* The pg_catalog.unknown type may be wrapped in a domain or composite
262-
* type, or both (9.3 did not allow domains on composite types, but
263-
* there may be multi-level composite type). To detect these cases
264-
* we need a recursive CTE.
265-
*/
266-
res=executeQueryOrDie(conn,
267-
"WITH RECURSIVE oids AS ( "
268-
/* the pg_catalog.unknown type itself */
269-
"SELECT 'pg_catalog.unknown'::pg_catalog.regtype AS oid "
270-
"UNION ALL "
271-
"SELECT * FROM ( "
272-
/* domains on the type */
273-
"WITH x AS (SELECT oid FROM oids) "
274-
"SELECT t.oid FROM pg_catalog.pg_type t, x WHERE typbasetype = x.oid AND typtype = 'd' "
275-
"UNION "
276-
/* composite types containing the type */
277-
"SELECT t.oid FROM pg_catalog.pg_type t, pg_catalog.pg_class c, pg_catalog.pg_attribute a, x "
278-
"WHERE t.typtype = 'c' AND "
279-
" t.oid = c.reltype AND "
280-
" c.oid = a.attrelid AND "
281-
" NOT a.attisdropped AND "
282-
" a.atttypid = x.oid "
283-
") foo "
284-
") "
285-
"SELECT n.nspname, c.relname, a.attname "
286-
"FROMpg_catalog.pg_class c, "
287-
"pg_catalog.pg_namespace n, "
288-
"pg_catalog.pg_attribute a "
289-
"WHEREc.oid = a.attrelid AND "
290-
"NOT a.attisdropped AND "
291-
"a.atttypid IN (SELECT oid FROM oids) AND "
292-
"c.relkind IN ("
293-
CppAsString2(RELKIND_RELATION) ", "
294-
CppAsString2(RELKIND_MATVIEW)") AND "
295-
"c.relnamespace = n.oid AND "
296-
/* exclude possible orphaned temp tables */
297-
"n.nspname !~ '^pg_temp_' AND "
298-
"n.nspname !~ '^pg_toast_temp_' AND "
299-
"n.nspname NOT IN ('pg_catalog', 'information_schema')");
300-
301-
ntups=PQntuples(res);
302-
i_nspname=PQfnumber(res,"nspname");
303-
i_relname=PQfnumber(res,"relname");
304-
i_attname=PQfnumber(res,"attname");
305-
for (rowno=0;rowno<ntups;rowno++)
306-
{
307-
found= true;
308-
if (script==NULL&& (script=fopen_priv(output_path,"w"))==NULL)
309-
pg_fatal("could not open file \"%s\": %s\n",output_path,
310-
strerror(errno));
311-
if (!db_used)
312-
{
313-
fprintf(script,"Database: %s\n",active_db->db_name);
314-
db_used= true;
315-
}
316-
fprintf(script," %s.%s.%s\n",
317-
PQgetvalue(res,rowno,i_nspname),
318-
PQgetvalue(res,rowno,i_relname),
319-
PQgetvalue(res,rowno,i_attname));
320-
}
321-
322-
PQclear(res);
323-
324-
PQfinish(conn);
325-
}
326-
327-
if (script)
328-
fclose(script);
329-
330-
if (found)
283+
if (check_for_data_type_usage(cluster,"pg_catalog.unknown",output_path))
331284
{
332285
pg_log(PG_REPORT,"fatal\n");
333286
pg_fatal("Your installation contains the \"unknown\" data type in user tables. This\n"

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp