Skip to content

Commit 35419ae

Browse files
committed
pg_upgrade: have pg_upgrade fail for old 9.4 JSONB format
Backpatch through 9.4
1 parent 445d262 commit 35419ae

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed

contrib/pg_upgrade/check.c

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ static void check_is_install_user(ClusterInfo *cluster);
2424
static void check_for_prepared_transactions(ClusterInfo *cluster);
2525
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster);
2626
static void check_for_reg_data_type_usage(ClusterInfo *cluster);
27+
static void check_for_jsonb_9_4_usage(ClusterInfo *cluster);
2728
static void get_bin_version(ClusterInfo *cluster);
2829
static char *get_canonical_locale_name(int category, const char *locale);
2930

@@ -99,6 +100,9 @@ check_and_dump_old_cluster(bool live_check)
99100
check_for_prepared_transactions(&old_cluster);
100101
check_for_reg_data_type_usage(&old_cluster);
101102
check_for_isn_and_int8_passing_mismatch(&old_cluster);
103+
if (GET_MAJOR_VERSION(old_cluster.major_version) == 904 &&
104+
old_cluster.controldata.cat_ver < JSONB_FORMAT_CHANGE_CAT_VER)
105+
check_for_jsonb_9_4_usage(&old_cluster);
102106

103107
/* Pre-PG 9.4 had a different 'line' data type internal format */
104108
if (GET_MAJOR_VERSION(old_cluster.major_version) <= 903)
@@ -915,6 +919,96 @@ check_for_reg_data_type_usage(ClusterInfo *cluster)
915919
}
916920

917921

922+
/*
923+
* check_for_jsonb_9_4_usage()
924+
*
925+
* JSONB changed its storage format during 9.4 beta, so check for it.
926+
*/
927+
static void
928+
check_for_jsonb_9_4_usage(ClusterInfo *cluster)
929+
{
930+
int dbnum;
931+
FILE *script = NULL;
932+
bool found = false;
933+
char output_path[MAXPGPATH];
934+
935+
prep_status("Checking for JSONB user data types");
936+
937+
snprintf(output_path, sizeof(output_path), "tables_using_jsonb.txt");
938+
939+
for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
940+
{
941+
PGresult *res;
942+
bool db_used = false;
943+
int ntups;
944+
int rowno;
945+
int i_nspname,
946+
i_relname,
947+
i_attname;
948+
DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
949+
PGconn *conn = connectToServer(cluster, active_db->db_name);
950+
951+
/*
952+
* While several relkinds don't store any data, e.g. views, they can
953+
* be used to define data types of other columns, so we check all
954+
* relkinds.
955+
*/
956+
res = executeQueryOrDie(conn,
957+
"SELECT n.nspname, c.relname, a.attname "
958+
"FROM pg_catalog.pg_class c, "
959+
" pg_catalog.pg_namespace n, "
960+
" pg_catalog.pg_attribute a "
961+
"WHERE c.oid = a.attrelid AND "
962+
" NOT a.attisdropped AND "
963+
" a.atttypid = 'pg_catalog.jsonb'::pg_catalog.regtype AND "
964+
" c.relnamespace = n.oid AND "
965+
/* exclude possible orphaned temp tables */
966+
" n.nspname !~ '^pg_temp_' AND "
967+
" n.nspname NOT IN ('pg_catalog', 'information_schema')");
968+
969+
ntups = PQntuples(res);
970+
i_nspname = PQfnumber(res, "nspname");
971+
i_relname = PQfnumber(res, "relname");
972+
i_attname = PQfnumber(res, "attname");
973+
for (rowno = 0; rowno < ntups; rowno++)
974+
{
975+
found = true;
976+
if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
977+
pg_fatal("Could not open file \"%s\": %s\n",
978+
output_path, getErrorText(errno));
979+
if (!db_used)
980+
{
981+
fprintf(script, "Database: %s\n", active_db->db_name);
982+
db_used = true;
983+
}
984+
fprintf(script, " %s.%s.%s\n",
985+
PQgetvalue(res, rowno, i_nspname),
986+
PQgetvalue(res, rowno, i_relname),
987+
PQgetvalue(res, rowno, i_attname));
988+
}
989+
990+
PQclear(res);
991+
992+
PQfinish(conn);
993+
}
994+
995+
if (script)
996+
fclose(script);
997+
998+
if (found)
999+
{
1000+
pg_log(PG_REPORT, "fatal\n");
1001+
pg_fatal("Your installation contains one of the JSONB data types in user tables.\n"
1002+
"The internal format of JSONB changed during 9.4 beta so this cluster cannot currently\n"
1003+
"be upgraded. You can remove the problem tables and restart the upgrade. A list\n"
1004+
"of the problem columns is in the file:\n"
1005+
" %s\n\n", output_path);
1006+
}
1007+
else
1008+
check_ok();
1009+
}
1010+
1011+
9181012
static void
9191013
get_bin_version(ClusterInfo *cluster)
9201014
{

contrib/pg_upgrade/pg_upgrade.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@ extern char *output_files[];
121121
*/
122122
#define LARGE_OBJECT_SIZE_PG_CONTROL_VER 942
123123

124+
/*
125+
* change in JSONB format during 9.4 beta
126+
*/
127+
#define JSONB_FORMAT_CHANGE_CAT_VER 201409291
128+
124129
/*
125130
* Each relation is represented by a relinfo structure.
126131
*/

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy