From: Bruce Momjian Date: Tue, 26 Aug 2014 00:05:07 +0000 (-0400) Subject: pg_upgrade: remove support for 8.3 old clusters X-Git-Tag: REL9_5_ALPHA1~1568 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2209b3923a7afe0b6033ecfea972219df252ca8e;p=postgresql pg_upgrade: remove support for 8.3 old clusters This trims down the code, and is in preparation for hardening pg_upgrade against auto-oid assignment. --- diff --git a/contrib/pg_upgrade/Makefile b/contrib/pg_upgrade/Makefile index 150a9b4770..87da4b8e83 100644 --- a/contrib/pg_upgrade/Makefile +++ b/contrib/pg_upgrade/Makefile @@ -6,7 +6,7 @@ PGAPPICON = win32 PROGRAM = pg_upgrade OBJS = check.o controldata.o dump.o exec.o file.o function.o info.o \ option.o page.o parallel.o pg_upgrade.o relfilenode.o server.o \ - tablespace.o util.o version.o version_old_8_3.o $(WIN32RES) + tablespace.o util.o version.o $(WIN32RES) PG_CPPFLAGS = -DFRONTEND -DDLSUFFIX=\"$(DLSUFFIX)\" -I$(srcdir) -I$(libpq_srcdir) PG_LIBS = $(libpq_pgport) diff --git a/contrib/pg_upgrade/check.c b/contrib/pg_upgrade/check.c index b216e61a4e..88fe12db01 100644 --- a/contrib/pg_upgrade/check.c +++ b/contrib/pg_upgrade/check.c @@ -73,7 +73,7 @@ output_check_banner(bool live_check) void -check_and_dump_old_cluster(bool live_check, char **sequence_script_file_name) +check_and_dump_old_cluster(bool live_check) { /* -- OLD -- */ @@ -100,29 +100,6 @@ check_and_dump_old_cluster(bool live_check, char **sequence_script_file_name) check_for_reg_data_type_usage(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); - /* old = PG 8.3 checks? */ - if (GET_MAJOR_VERSION(old_cluster.major_version) <= 803) - { - old_8_3_check_for_name_data_type_usage(&old_cluster); - old_8_3_check_for_tsquery_usage(&old_cluster); - old_8_3_check_ltree_usage(&old_cluster); - if (user_opts.check) - { - old_8_3_rebuild_tsvector_tables(&old_cluster, true); - old_8_3_invalidate_hash_gin_indexes(&old_cluster, true); - old_8_3_invalidate_bpchar_pattern_ops_indexes(&old_cluster, true); - } - else - - /* - * While we have the old server running, create the script to - * properly restore its sequence values but we report this at the - * end. - */ - *sequence_script_file_name = - old_8_3_create_sequence_script(&old_cluster); - } - /* Pre-PG 9.4 had a different 'line' data type internal format */ if (GET_MAJOR_VERSION(old_cluster.major_version) <= 903) old_9_3_check_for_line_data_type_usage(&old_cluster); @@ -183,31 +160,8 @@ report_clusters_compatible(void) void -issue_warnings(char *sequence_script_file_name) +issue_warnings(void) { - /* old = PG 8.3 warnings? */ - if (GET_MAJOR_VERSION(old_cluster.major_version) <= 803) - { - start_postmaster(&new_cluster, true); - - /* restore proper sequence values using file created from old server */ - if (sequence_script_file_name) - { - prep_status("Adjusting sequences"); - exec_prog(UTILITY_LOG_FILE, NULL, true, - "\"%s/psql\" " EXEC_PSQL_ARGS " %s -f \"%s\"", - new_cluster.bindir, cluster_conn_opts(&new_cluster), - sequence_script_file_name); - unlink(sequence_script_file_name); - check_ok(); - } - - old_8_3_rebuild_tsvector_tables(&new_cluster, false); - old_8_3_invalidate_hash_gin_indexes(&new_cluster, false); - old_8_3_invalidate_bpchar_pattern_ops_indexes(&new_cluster, false); - stop_postmaster(false); - } - /* Create dummy large object permissions for old < PG 9.0? */ if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804) { @@ -262,8 +216,8 @@ check_cluster_versions(void) * upgrades */ - if (GET_MAJOR_VERSION(old_cluster.major_version) < 803) - pg_fatal("This utility can only upgrade from PostgreSQL version 8.3 and later.\n"); + if (GET_MAJOR_VERSION(old_cluster.major_version) < 804) + pg_fatal("This utility can only upgrade from PostgreSQL version 8.4 and later.\n"); /* Only current PG version is supported as a target */ if (GET_MAJOR_VERSION(new_cluster.major_version) != GET_MAJOR_VERSION(PG_VERSION_NUM)) diff --git a/contrib/pg_upgrade/controldata.c b/contrib/pg_upgrade/controldata.c index 13c95a2e2e..cce44ba783 100644 --- a/contrib/pg_upgrade/controldata.c +++ b/contrib/pg_upgrade/controldata.c @@ -125,13 +125,6 @@ get_control_data(ClusterInfo *cluster, bool live_check) cluster->controldata.lc_collate = NULL; cluster->controldata.lc_ctype = NULL; - /* Only in <= 8.3 */ - if (GET_MAJOR_VERSION(cluster->major_version) <= 803) - { - cluster->controldata.float8_pass_by_value = false; - got_float8_pass_by_value = true; - } - /* Only in <= 9.2 */ if (GET_MAJOR_VERSION(cluster->major_version) <= 902) { @@ -144,23 +137,6 @@ get_control_data(ClusterInfo *cluster, bool live_check) { pg_log(PG_VERBOSE, "%s", bufin); -#ifdef WIN32 - - /* - * Due to an installer bug, LANG=C doesn't work for PG 8.3.3, but does - * work 8.2.6 and 8.3.7, so check for non-ASCII output and suggest a - * minor upgrade. - */ - if (GET_MAJOR_VERSION(cluster->major_version) <= 803) - { - for (p = bufin; *p; p++) - if (!isascii((unsigned char) *p)) - pg_fatal("The 8.3 cluster's pg_controldata is incapable of outputting ASCII, even\n" - "with LANG=C. You must upgrade this cluster to a newer version of PostgreSQL\n" - "8.3 to fix this bug. PostgreSQL 8.3.7 and later are known to work properly.\n"); - } -#endif - if ((p = strstr(bufin, "pg_control version number:")) != NULL) { p = strchr(p, ':'); @@ -550,7 +526,6 @@ get_control_data(ClusterInfo *cluster, bool live_check) if (!got_date_is_int) pg_log(PG_REPORT, " dates/times are integers?\n"); - /* value added in Postgres 8.4 */ if (!got_float8_pass_by_value) pg_log(PG_REPORT, " float8 argument passing method\n"); @@ -598,17 +573,7 @@ check_control_data(ControlData *oldctrl, pg_fatal("old and new pg_controldata maximum TOAST chunk sizes are invalid or do not match\n"); if (oldctrl->date_is_int != newctrl->date_is_int) - { - pg_log(PG_WARNING, - "\nOld and new pg_controldata date/time storage types do not match.\n"); - - /* - * This is a common 8.3 -> 8.4 upgrade problem, so we are more verbose - */ - pg_fatal("You will need to rebuild the new server with configure option\n" - "--disable-integer-datetimes or get server binaries built with those\n" - "options.\n"); - } + pg_fatal("old and new pg_controldata date/time storage types do not match\n"); /* * We might eventually allow upgrades from checksum to no-checksum diff --git a/contrib/pg_upgrade/info.c b/contrib/pg_upgrade/info.c index 93ea2667bc..3d31c2791a 100644 --- a/contrib/pg_upgrade/info.c +++ b/contrib/pg_upgrade/info.c @@ -325,7 +325,7 @@ get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo) " ON c.relnamespace = n.oid " "LEFT OUTER JOIN pg_catalog.pg_index i " " ON c.oid = i.indexrelid " - "WHERE relkind IN ('r', 'm', 'i'%s) AND " + "WHERE relkind IN ('r', 'm', 'i', 'S') AND " /* * pg_dump only dumps valid indexes; testing indisready is necessary in @@ -342,9 +342,6 @@ get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo) " c.oid >= %u) " " OR (n.nspname = 'pg_catalog' AND " " relname IN ('pg_largeobject', 'pg_largeobject_loid_pn_index'%s) ));", - /* see the comment at the top of old_8_3_create_sequence_script() */ - (GET_MAJOR_VERSION(old_cluster.major_version) <= 803) ? - "" : ", 'S'", FirstNormalObjectId, /* does pg_largeobject_metadata need to be migrated? */ (GET_MAJOR_VERSION(old_cluster.major_version) <= 804) ? diff --git a/contrib/pg_upgrade/pg_upgrade.c b/contrib/pg_upgrade/pg_upgrade.c index 49ea873099..b6f370f1d2 100644 --- a/contrib/pg_upgrade/pg_upgrade.c +++ b/contrib/pg_upgrade/pg_upgrade.c @@ -69,7 +69,6 @@ char *output_files[] = { int main(int argc, char **argv) { - char *sequence_script_file_name = NULL; char *analyze_script_file_name = NULL; char *deletion_script_file_name = NULL; bool live_check = false; @@ -90,7 +89,7 @@ main(int argc, char **argv) check_cluster_compatibility(live_check); - check_and_dump_old_cluster(live_check, &sequence_script_file_name); + check_and_dump_old_cluster(live_check); /* -- NEW -- */ @@ -157,7 +156,7 @@ main(int argc, char **argv) create_script_for_cluster_analyze(&analyze_script_file_name); create_script_for_old_cluster_deletion(&deletion_script_file_name); - issue_warnings(sequence_script_file_name); + issue_warnings(); pg_log(PG_REPORT, "\nUpgrade Complete\n"); pg_log(PG_REPORT, "----------------\n"); @@ -167,7 +166,6 @@ main(int argc, char **argv) pg_free(analyze_script_file_name); pg_free(deletion_script_file_name); - pg_free(sequence_script_file_name); cleanup(); diff --git a/contrib/pg_upgrade/pg_upgrade.h b/contrib/pg_upgrade/pg_upgrade.h index 1175604e37..4b8facf5ce 100644 --- a/contrib/pg_upgrade/pg_upgrade.h +++ b/contrib/pg_upgrade/pg_upgrade.h @@ -313,11 +313,10 @@ extern OSInfo os_info; /* check.c */ void output_check_banner(bool live_check); -void check_and_dump_old_cluster(bool live_check, - char **sequence_script_file_name); +void check_and_dump_old_cluster(bool live_check); void check_new_cluster(void); void report_clusters_compatible(void); -void issue_warnings(char *sequence_script_file_name); +void issue_warnings(void); void output_completion_banner(char *analyze_script_file_name, char *deletion_script_file_name); void check_cluster_versions(void); @@ -471,17 +470,6 @@ void new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster, bool check_mode); void old_9_3_check_for_line_data_type_usage(ClusterInfo *cluster); -/* version_old_8_3.c */ - -void old_8_3_check_for_name_data_type_usage(ClusterInfo *cluster); -void old_8_3_check_for_tsquery_usage(ClusterInfo *cluster); -void old_8_3_check_ltree_usage(ClusterInfo *cluster); -void old_8_3_rebuild_tsvector_tables(ClusterInfo *cluster, bool check_mode); -void old_8_3_invalidate_hash_gin_indexes(ClusterInfo *cluster, bool check_mode); -void old_8_3_invalidate_bpchar_pattern_ops_indexes(ClusterInfo *cluster, - bool check_mode); -char *old_8_3_create_sequence_script(ClusterInfo *cluster); - /* parallel.c */ void parallel_exec_prog(const char *log_file, const char *opt_log_file, diff --git a/contrib/pg_upgrade/version_old_8_3.c b/contrib/pg_upgrade/version_old_8_3.c deleted file mode 100644 index 07e79bd609..0000000000 --- a/contrib/pg_upgrade/version_old_8_3.c +++ /dev/null @@ -1,769 +0,0 @@ -/* - * version.c - * - * Postgres-version-specific routines - * - * Copyright (c) 2010-2014, PostgreSQL Global Development Group - * contrib/pg_upgrade/version_old_8_3.c - */ - -#include "postgres_fe.h" - -#include "pg_upgrade.h" - -#include "access/transam.h" - - -/* - * old_8_3_check_for_name_data_type_usage() - * 8.3 -> 8.4 - * Alignment for the 'name' data type changed to 'char' in 8.4; - * checks tables and indexes. - */ -void -old_8_3_check_for_name_data_type_usage(ClusterInfo *cluster) -{ - int dbnum; - FILE *script = NULL; - bool found = false; - char output_path[MAXPGPATH]; - - prep_status("Checking for invalid \"name\" user columns"); - - snprintf(output_path, sizeof(output_path), "tables_using_name.txt"); - - for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) - { - PGresult *res; - bool db_used = false; - int ntups; - int rowno; - int i_nspname, - i_relname, - i_attname; - DbInfo *active_db = &cluster->dbarr.dbs[dbnum]; - PGconn *conn = connectToServer(cluster, active_db->db_name); - - /* - * With a smaller alignment in 8.4, 'name' cannot be used in a - * non-pg_catalog table, except as the first column. (We could tighten - * that condition with enough analysis, but it seems not worth the - * trouble.) - */ - res = executeQueryOrDie(conn, - "SELECT n.nspname, c.relname, a.attname " - "FROM pg_catalog.pg_class c, " - " pg_catalog.pg_namespace n, " - " pg_catalog.pg_attribute a " - "WHERE c.oid = a.attrelid AND " - " a.attnum > 1 AND " - " NOT a.attisdropped AND " - " a.atttypid = 'pg_catalog.name'::pg_catalog.regtype AND " - " c.relnamespace = n.oid AND " - /* exclude possible orphaned temp tables */ - " n.nspname !~ '^pg_temp_' AND " - " n.nspname !~ '^pg_toast_temp_' AND " - " n.nspname NOT IN ('pg_catalog', 'information_schema')"); - - ntups = PQntuples(res); - i_nspname = PQfnumber(res, "nspname"); - i_relname = PQfnumber(res, "relname"); - i_attname = PQfnumber(res, "attname"); - for (rowno = 0; rowno < ntups; rowno++) - { - found = true; - if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL) - pg_fatal("could not open file \"%s\": %s\n", output_path, getErrorText(errno)); - if (!db_used) - { - fprintf(script, "Database: %s\n", active_db->db_name); - db_used = true; - } - fprintf(script, " %s.%s.%s\n", - PQgetvalue(res, rowno, i_nspname), - PQgetvalue(res, rowno, i_relname), - PQgetvalue(res, rowno, i_attname)); - } - - PQclear(res); - - PQfinish(conn); - } - - if (script) - fclose(script); - - if (found) - { - pg_log(PG_REPORT, "fatal\n"); - pg_fatal("Your installation contains the \"name\" data type in user tables. This\n" - "data type changed its internal alignment between your old and new\n" - "clusters so this cluster cannot currently be upgraded. You can remove\n" - "the problem tables and restart the upgrade. A list of the problem\n" - "columns is in the file:\n" - " %s\n\n", output_path); - } - else - check_ok(); -} - - -/* - * old_8_3_check_for_tsquery_usage() - * 8.3 -> 8.4 - * A new 'prefix' field was added to the 'tsquery' data type in 8.4 - * so upgrading of such fields is impossible. - */ -void -old_8_3_check_for_tsquery_usage(ClusterInfo *cluster) -{ - int dbnum; - FILE *script = NULL; - bool found = false; - char output_path[MAXPGPATH]; - - prep_status("Checking for tsquery user columns"); - - snprintf(output_path, sizeof(output_path), "tables_using_tsquery.txt"); - - for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) - { - PGresult *res; - bool db_used = false; - int ntups; - int rowno; - int i_nspname, - i_relname, - i_attname; - DbInfo *active_db = &cluster->dbarr.dbs[dbnum]; - PGconn *conn = connectToServer(cluster, active_db->db_name); - - /* Find any user-defined tsquery columns */ - res = executeQueryOrDie(conn, - "SELECT n.nspname, c.relname, a.attname " - "FROM pg_catalog.pg_class c, " - " pg_catalog.pg_namespace n, " - " pg_catalog.pg_attribute a " - /* materialized views didn't exist in 8.3, so no need to check 'm' */ - "WHERE c.relkind = 'r' AND " - " c.oid = a.attrelid AND " - " NOT a.attisdropped AND " - " a.atttypid = 'pg_catalog.tsquery'::pg_catalog.regtype AND " - " c.relnamespace = n.oid AND " - /* exclude possible orphaned temp tables */ - " n.nspname !~ '^pg_temp_' AND " - " n.nspname !~ '^pg_toast_temp_' AND " - " n.nspname NOT IN ('pg_catalog', 'information_schema')"); - - ntups = PQntuples(res); - i_nspname = PQfnumber(res, "nspname"); - i_relname = PQfnumber(res, "relname"); - i_attname = PQfnumber(res, "attname"); - for (rowno = 0; rowno < ntups; rowno++) - { - found = true; - if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL) - pg_fatal("could not open file \"%s\": %s\n", output_path, getErrorText(errno)); - if (!db_used) - { - fprintf(script, "Database: %s\n", active_db->db_name); - db_used = true; - } - fprintf(script, " %s.%s.%s\n", - PQgetvalue(res, rowno, i_nspname), - PQgetvalue(res, rowno, i_relname), - PQgetvalue(res, rowno, i_attname)); - } - - PQclear(res); - - PQfinish(conn); - } - - if (script) - fclose(script); - - if (found) - { - pg_log(PG_REPORT, "fatal\n"); - pg_fatal("Your installation contains the \"tsquery\" data type. This data type\n" - "added a new internal field between your old and new clusters so this\n" - "cluster cannot currently be upgraded. You can remove the problem\n" - "columns and restart the upgrade. A list of the problem columns is in the\n" - "file:\n" - " %s\n\n", output_path); - } - else - check_ok(); -} - - -/* - * old_8_3_check_ltree_usage() - * 8.3 -> 8.4 - * The internal ltree structure was changed in 8.4 so upgrading is impossible. - */ -void -old_8_3_check_ltree_usage(ClusterInfo *cluster) -{ - int dbnum; - FILE *script = NULL; - bool found = false; - char output_path[MAXPGPATH]; - - prep_status("Checking for contrib/ltree"); - - snprintf(output_path, sizeof(output_path), "contrib_ltree.txt"); - - for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) - { - PGresult *res; - bool db_used = false; - int ntups; - int rowno; - int i_nspname, - i_proname; - DbInfo *active_db = &cluster->dbarr.dbs[dbnum]; - PGconn *conn = connectToServer(cluster, active_db->db_name); - - /* Find any functions coming from contrib/ltree */ - res = executeQueryOrDie(conn, - "SELECT n.nspname, p.proname " - "FROM pg_catalog.pg_proc p, " - " pg_catalog.pg_namespace n " - "WHERE p.pronamespace = n.oid AND " - " p.probin = '$libdir/ltree'"); - - ntups = PQntuples(res); - i_nspname = PQfnumber(res, "nspname"); - i_proname = PQfnumber(res, "proname"); - for (rowno = 0; rowno < ntups; rowno++) - { - found = true; - if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL) - pg_fatal("Could not open file \"%s\": %s\n", - output_path, getErrorText(errno)); - if (!db_used) - { - fprintf(script, "Database: %s\n", active_db->db_name); - db_used = true; - } - fprintf(script, " %s.%s\n", - PQgetvalue(res, rowno, i_nspname), - PQgetvalue(res, rowno, i_proname)); - } - - PQclear(res); - - PQfinish(conn); - } - - if (script) - fclose(script); - - if (found) - { - pg_log(PG_REPORT, "fatal\n"); - pg_fatal("Your installation contains the \"ltree\" data type. This data type\n" - "changed its internal storage format between your old and new clusters so this\n" - "cluster cannot currently be upgraded. You can manually upgrade databases\n" - "that use \"contrib/ltree\" facilities and remove \"contrib/ltree\" from the old\n" - "cluster and restart the upgrade. A list of the problem functions is in the\n" - "file:\n" - " %s\n\n", output_path); - } - else - check_ok(); -} - - -/* - * old_8_3_rebuild_tsvector_tables() - * 8.3 -> 8.4 - * 8.3 sorts lexemes by its length and if lengths are the same then it uses - * alphabetic order; 8.4 sorts lexemes in lexicographical order, e.g. - * - * => SELECT 'c bb aaa'::tsvector; - * tsvector - * ---------------- - * 'aaa' 'bb' 'c' -- 8.4 - * 'c' 'bb' 'aaa' -- 8.3 - */ -void -old_8_3_rebuild_tsvector_tables(ClusterInfo *cluster, bool check_mode) -{ - int dbnum; - FILE *script = NULL; - bool found = false; - char output_path[MAXPGPATH]; - - prep_status("Checking for tsvector user columns"); - - snprintf(output_path, sizeof(output_path), "rebuild_tsvector_tables.sql"); - - for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) - { - PGresult *res; - bool db_used = false; - char nspname[NAMEDATALEN] = "", - relname[NAMEDATALEN] = ""; - int ntups; - int rowno; - int i_nspname, - i_relname, - i_attname; - DbInfo *active_db = &cluster->dbarr.dbs[dbnum]; - PGconn *conn = connectToServer(cluster, active_db->db_name); - - /* Find any user-defined tsvector columns */ - res = executeQueryOrDie(conn, - "SELECT n.nspname, c.relname, a.attname " - "FROM pg_catalog.pg_class c, " - " pg_catalog.pg_namespace n, " - " pg_catalog.pg_attribute a " - /* materialized views didn't exist in 8.3, so no need to check 'm' */ - "WHERE c.relkind = 'r' AND " - " c.oid = a.attrelid AND " - " NOT a.attisdropped AND " - /* child attribute changes are processed by the parent */ - " a.attinhcount = 0 AND " - " a.atttypid = 'pg_catalog.tsvector'::pg_catalog.regtype AND " - " c.relnamespace = n.oid AND " - /* exclude possible orphaned temp tables */ - " n.nspname !~ '^pg_temp_' AND " - " n.nspname !~ '^pg_toast_temp_' AND " - " n.nspname NOT IN ('pg_catalog', 'information_schema')"); - -/* - * This macro is used below to avoid reindexing indexes already rebuilt - * because of tsvector columns. - */ -#define SKIP_TSVECTOR_TABLES \ - "i.indrelid NOT IN ( " \ - "SELECT DISTINCT c.oid " \ - "FROM pg_catalog.pg_class c, " \ - " pg_catalog.pg_namespace n, " \ - " pg_catalog.pg_attribute a " \ - /* materialized views didn't exist in 8.3, so no need to check 'm' */ \ - "WHERE c.relkind = 'r' AND " \ - " c.oid = a.attrelid AND " \ - " NOT a.attisdropped AND " \ - /* child attribute changes are processed by the parent */ \ - " a.attinhcount = 0 AND " \ - " a.atttypid = 'pg_catalog.tsvector'::pg_catalog.regtype AND " \ - " c.relnamespace = n.oid AND " \ - " n.nspname !~ '^pg_' AND " \ - " n.nspname != 'information_schema') " - - ntups = PQntuples(res); - i_nspname = PQfnumber(res, "nspname"); - i_relname = PQfnumber(res, "relname"); - i_attname = PQfnumber(res, "attname"); - for (rowno = 0; rowno < ntups; rowno++) - { - found = true; - if (!check_mode) - { - if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL) - pg_fatal("could not open file \"%s\": %s\n", output_path, getErrorText(errno)); - if (!db_used) - { - fprintf(script, "\\connect %s\n\n", - quote_identifier(active_db->db_name)); - db_used = true; - } - - /* Rebuild all tsvector collumns with one ALTER TABLE command */ - if (strcmp(PQgetvalue(res, rowno, i_nspname), nspname) != 0 || - strcmp(PQgetvalue(res, rowno, i_relname), relname) != 0) - { - if (strlen(nspname) != 0 || strlen(relname) != 0) - fprintf(script, ";\n\n"); - fprintf(script, "ALTER TABLE %s.%s\n", - quote_identifier(PQgetvalue(res, rowno, i_nspname)), - quote_identifier(PQgetvalue(res, rowno, i_relname))); - } - else - fprintf(script, ",\n"); - strlcpy(nspname, PQgetvalue(res, rowno, i_nspname), sizeof(nspname)); - strlcpy(relname, PQgetvalue(res, rowno, i_relname), sizeof(relname)); - - fprintf(script, "ALTER COLUMN %s " - /* This could have been a custom conversion function call. */ - "TYPE pg_catalog.tsvector USING %s::pg_catalog.text::pg_catalog.tsvector", - quote_identifier(PQgetvalue(res, rowno, i_attname)), - quote_identifier(PQgetvalue(res, rowno, i_attname))); - } - } - if (strlen(nspname) != 0 || strlen(relname) != 0) - fprintf(script, ";\n\n"); - - PQclear(res); - - /* XXX Mark tables as not accessible somehow */ - - PQfinish(conn); - } - - if (script) - fclose(script); - - if (found) - { - report_status(PG_WARNING, "warning"); - if (check_mode) - pg_log(PG_WARNING, "\n" - "Your installation contains tsvector columns. The tsvector internal\n" - "storage format changed between your old and new clusters so the tables\n" - "must be rebuilt. After upgrading, you will be given instructions.\n\n"); - else - pg_log(PG_WARNING, "\n" - "Your installation contains tsvector columns. The tsvector internal\n" - "storage format changed between your old and new clusters so the tables\n" - "must be rebuilt. The file:\n" - " %s\n" - "when executed by psql by the database superuser will rebuild all tables\n" - "with tsvector columns.\n\n", - output_path); - } - else - check_ok(); -} - - -/* - * old_8_3_invalidate_hash_gin_indexes() - * 8.3 -> 8.4 - * Hash and GIN index binary format changed from 8.3->8.4 - */ -void -old_8_3_invalidate_hash_gin_indexes(ClusterInfo *cluster, bool check_mode) -{ - int dbnum; - FILE *script = NULL; - bool found = false; - char output_path[MAXPGPATH]; - - prep_status("Checking for hash and GIN indexes"); - - snprintf(output_path, sizeof(output_path), "reindex_hash_and_gin.sql"); - - for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) - { - PGresult *res; - bool db_used = false; - int ntups; - int rowno; - int i_nspname, - i_relname; - DbInfo *active_db = &cluster->dbarr.dbs[dbnum]; - PGconn *conn = connectToServer(cluster, active_db->db_name); - - /* find hash and gin indexes */ - res = executeQueryOrDie(conn, - "SELECT n.nspname, c.relname " - "FROM pg_catalog.pg_class c, " - " pg_catalog.pg_index i, " - " pg_catalog.pg_am a, " - " pg_catalog.pg_namespace n " - "WHERE i.indexrelid = c.oid AND " - " c.relam = a.oid AND " - " c.relnamespace = n.oid AND " - " a.amname IN ('hash', 'gin') AND " - SKIP_TSVECTOR_TABLES); - - ntups = PQntuples(res); - i_nspname = PQfnumber(res, "nspname"); - i_relname = PQfnumber(res, "relname"); - for (rowno = 0; rowno < ntups; rowno++) - { - found = true; - if (!check_mode) - { - if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL) - pg_fatal("could not open file \"%s\": %s\n", output_path, getErrorText(errno)); - if (!db_used) - { - fprintf(script, "\\connect %s\n", - quote_identifier(active_db->db_name)); - db_used = true; - } - fprintf(script, "REINDEX INDEX %s.%s;\n", - quote_identifier(PQgetvalue(res, rowno, i_nspname)), - quote_identifier(PQgetvalue(res, rowno, i_relname))); - } - } - - PQclear(res); - - if (!check_mode && found) - /* mark hash and gin indexes as invalid */ - PQclear(executeQueryOrDie(conn, - "UPDATE pg_catalog.pg_index i " - "SET indisvalid = false " - "FROM pg_catalog.pg_class c, " - " pg_catalog.pg_am a, " - " pg_catalog.pg_namespace n " - "WHERE i.indexrelid = c.oid AND " - " c.relam = a.oid AND " - " c.relnamespace = n.oid AND " - " a.amname IN ('hash', 'gin')")); - - PQfinish(conn); - } - - if (script) - fclose(script); - - if (found) - { - report_status(PG_WARNING, "warning"); - if (check_mode) - pg_log(PG_WARNING, "\n" - "Your installation contains hash and/or GIN indexes. These indexes have\n" - "different internal formats between your old and new clusters, so they\n" - "must be reindexed with the REINDEX command. After upgrading, you will\n" - "be given REINDEX instructions.\n\n"); - else - pg_log(PG_WARNING, "\n" - "Your installation contains hash and/or GIN indexes. These indexes have\n" - "different internal formats between your old and new clusters, so they\n" - "must be reindexed with the REINDEX command. The file:\n" - " %s\n" - "when executed by psql by the database superuser will recreate all invalid\n" - "indexes; until then, none of these indexes will be used.\n\n", - output_path); - } - else - check_ok(); -} - - -/* - * old_8_3_invalidate_bpchar_pattern_ops_indexes() - * 8.3 -> 8.4 - * 8.4 bpchar_pattern_ops no longer sorts based on trailing spaces - */ -void -old_8_3_invalidate_bpchar_pattern_ops_indexes(ClusterInfo *cluster, - bool check_mode) -{ - int dbnum; - FILE *script = NULL; - bool found = false; - char output_path[MAXPGPATH]; - - prep_status("Checking for bpchar_pattern_ops indexes"); - - snprintf(output_path, sizeof(output_path), "reindex_bpchar_ops.sql"); - - for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) - { - PGresult *res; - bool db_used = false; - int ntups; - int rowno; - int i_nspname, - i_relname; - DbInfo *active_db = &cluster->dbarr.dbs[dbnum]; - PGconn *conn = connectToServer(cluster, active_db->db_name); - - /* find bpchar_pattern_ops indexes */ - - /* - * Do only non-hash, non-gin indexees; we already invalidated them - * above; no need to reindex twice - */ - res = executeQueryOrDie(conn, - "SELECT n.nspname, c.relname " - "FROM pg_catalog.pg_index i, " - " pg_catalog.pg_class c, " - " pg_catalog.pg_namespace n " - "WHERE indexrelid = c.oid AND " - " c.relnamespace = n.oid AND " - " ( " - " SELECT o.oid " - " FROM pg_catalog.pg_opclass o, " - " pg_catalog.pg_am a" - " WHERE a.amname NOT IN ('hash', 'gin') AND " - " a.oid = o.opcmethod AND " - " o.opcname = 'bpchar_pattern_ops') " - " = ANY (i.indclass) AND " - SKIP_TSVECTOR_TABLES); - - ntups = PQntuples(res); - i_nspname = PQfnumber(res, "nspname"); - i_relname = PQfnumber(res, "relname"); - for (rowno = 0; rowno < ntups; rowno++) - { - found = true; - if (!check_mode) - { - if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL) - pg_fatal("could not open file \"%s\": %s\n", output_path, getErrorText(errno)); - if (!db_used) - { - fprintf(script, "\\connect %s\n", - quote_identifier(active_db->db_name)); - db_used = true; - } - fprintf(script, "REINDEX INDEX %s.%s;\n", - quote_identifier(PQgetvalue(res, rowno, i_nspname)), - quote_identifier(PQgetvalue(res, rowno, i_relname))); - } - } - - PQclear(res); - - if (!check_mode && found) - /* mark bpchar_pattern_ops indexes as invalid */ - PQclear(executeQueryOrDie(conn, - "UPDATE pg_catalog.pg_index i " - "SET indisvalid = false " - "FROM pg_catalog.pg_class c, " - " pg_catalog.pg_namespace n " - "WHERE indexrelid = c.oid AND " - " c.relnamespace = n.oid AND " - " ( " - " SELECT o.oid " - " FROM pg_catalog.pg_opclass o, " - " pg_catalog.pg_am a" - " WHERE a.amname NOT IN ('hash', 'gin') AND " - " a.oid = o.opcmethod AND " - " o.opcname = 'bpchar_pattern_ops') " - " = ANY (i.indclass)")); - - PQfinish(conn); - } - - if (script) - fclose(script); - - if (found) - { - report_status(PG_WARNING, "warning"); - if (check_mode) - pg_log(PG_WARNING, "\n" - "Your installation contains indexes using \"bpchar_pattern_ops\". These\n" - "indexes have different internal formats between your old and new clusters\n" - "so they must be reindexed with the REINDEX command. After upgrading, you\n" - "will be given REINDEX instructions.\n\n"); - else - pg_log(PG_WARNING, "\n" - "Your installation contains indexes using \"bpchar_pattern_ops\". These\n" - "indexes have different internal formats between your old and new clusters\n" - "so they must be reindexed with the REINDEX command. The file:\n" - " %s\n" - "when executed by psql by the database superuser will recreate all invalid\n" - "indexes; until then, none of these indexes will be used.\n\n", - output_path); - } - else - check_ok(); -} - - -/* - * old_8_3_create_sequence_script() - * 8.3 -> 8.4 - * 8.4 added the column "start_value" to all sequences. For this reason, - * we don't transfer sequence files but instead use the CREATE SEQUENCE - * command from the schema dump, and use setval() to restore the sequence - * value and 'is_called' from the old database. This is safe to run - * by pg_upgrade because sequence files are not transferred from the old - * server, even in link mode. - */ -char * -old_8_3_create_sequence_script(ClusterInfo *cluster) -{ - int dbnum; - FILE *script = NULL; - bool found = false; - char *output_path; - - output_path = pg_strdup("adjust_sequences.sql"); - - prep_status("Creating script to adjust sequences"); - - for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) - { - PGresult *res; - bool db_used = false; - int ntups; - int rowno; - int i_nspname, - i_relname; - DbInfo *active_db = &cluster->dbarr.dbs[dbnum]; - PGconn *conn = connectToServer(cluster, active_db->db_name); - - /* Find any sequences */ - res = executeQueryOrDie(conn, - "SELECT n.nspname, c.relname " - "FROM pg_catalog.pg_class c, " - " pg_catalog.pg_namespace n " - "WHERE c.relkind = 'S' AND " - " c.relnamespace = n.oid AND " - /* exclude possible orphaned temp tables */ - " n.nspname !~ '^pg_temp_' AND " - " n.nspname !~ '^pg_toast_temp_' AND " - " n.nspname NOT IN ('pg_catalog', 'information_schema')"); - - ntups = PQntuples(res); - i_nspname = PQfnumber(res, "nspname"); - i_relname = PQfnumber(res, "relname"); - for (rowno = 0; rowno < ntups; rowno++) - { - PGresult *seq_res; - int i_last_value, - i_is_called; - const char *nspname = PQgetvalue(res, rowno, i_nspname); - const char *relname = PQgetvalue(res, rowno, i_relname); - - found = true; - - if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL) - pg_fatal("could not open file \"%s\": %s\n", output_path, getErrorText(errno)); - if (!db_used) - { - fprintf(script, "\\connect %s\n\n", - quote_identifier(active_db->db_name)); - db_used = true; - } - - /* Find the desired sequence */ - seq_res = executeQueryOrDie(conn, - "SELECT s.last_value, s.is_called " - "FROM %s.%s s", - quote_identifier(nspname), - quote_identifier(relname)); - - assert(PQntuples(seq_res) == 1); - i_last_value = PQfnumber(seq_res, "last_value"); - i_is_called = PQfnumber(seq_res, "is_called"); - - fprintf(script, "SELECT setval('%s.%s', %s, '%s');\n", - quote_identifier(nspname), quote_identifier(relname), - PQgetvalue(seq_res, 0, i_last_value), PQgetvalue(seq_res, 0, i_is_called)); - PQclear(seq_res); - } - if (db_used) - fprintf(script, "\n"); - - PQclear(res); - - PQfinish(conn); - } - - if (script) - fclose(script); - - check_ok(); - - if (found) - return output_path; - else - { - pg_free(output_path); - return NULL; - } -}