From 6e6bee987ff4b6d650eec9f20fd477269d95e295 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Sat, 1 Jan 2011 12:06:36 -0500 Subject: [PATCH] In pg_upgrade, remove use of whichCluster, and just pass old/new cluster pointers, which simplifies the code. This was not possible in 9.0 because everything was in a single nested struct, but is possible now. Per suggestion from Tom. --- contrib/pg_upgrade/check.c | 80 ++++++++++++-------------- contrib/pg_upgrade/exec.c | 10 ++-- contrib/pg_upgrade/function.c | 17 +++--- contrib/pg_upgrade/info.c | 86 +++++++++++++--------------- contrib/pg_upgrade/pg_upgrade.c | 19 +++--- contrib/pg_upgrade/pg_upgrade.h | 54 ++++++----------- contrib/pg_upgrade/relfilenode.c | 7 +-- contrib/pg_upgrade/server.c | 42 ++++++-------- contrib/pg_upgrade/tablespace.c | 25 ++++---- contrib/pg_upgrade/version.c | 10 ++-- contrib/pg_upgrade/version_old_8_3.c | 58 ++++++++----------- 11 files changed, 181 insertions(+), 227 deletions(-) diff --git a/contrib/pg_upgrade/check.c b/contrib/pg_upgrade/check.c index 6d5111caf8..839a3c9267 100644 --- a/contrib/pg_upgrade/check.c +++ b/contrib/pg_upgrade/check.c @@ -10,13 +10,12 @@ #include "pg_upgrade.h" -static void set_locale_and_encoding(Cluster whichCluster); +static void set_locale_and_encoding(ClusterInfo *cluster); static void check_new_db_is_empty(void); static void check_locale_and_encoding(ControlData *oldctrl, ControlData *newctrl); -static void check_for_isn_and_int8_passing_mismatch( - Cluster whichCluster); -static void check_for_reg_data_type_usage(Cluster whichCluster); +static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster); +static void check_for_reg_data_type_usage(ClusterInfo *cluster); void @@ -46,14 +45,14 @@ check_old_cluster(bool live_check, /* -- OLD -- */ if (!live_check) - start_postmaster(CLUSTER_OLD, false); + start_postmaster(&old_cluster, false); - set_locale_and_encoding(CLUSTER_OLD); + set_locale_and_encoding(&old_cluster); - get_pg_database_relfilenode(CLUSTER_OLD); + get_pg_database_relfilenode(&old_cluster); /* Extract a list of databases and tables from the old cluster */ - get_db_and_rel_infos(&old_cluster.dbarr, CLUSTER_OLD); + get_db_and_rel_infos(&old_cluster); init_tablespaces(); @@ -64,19 +63,19 @@ check_old_cluster(bool live_check, * Check for various failure cases */ - check_for_reg_data_type_usage(CLUSTER_OLD); - check_for_isn_and_int8_passing_mismatch(CLUSTER_OLD); + 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(CLUSTER_OLD); - old_8_3_check_for_tsquery_usage(CLUSTER_OLD); + old_8_3_check_for_name_data_type_usage(&old_cluster); + old_8_3_check_for_tsquery_usage(&old_cluster); if (user_opts.check) { - old_8_3_rebuild_tsvector_tables(true, CLUSTER_OLD); - old_8_3_invalidate_hash_gin_indexes(true, CLUSTER_OLD); - old_8_3_invalidate_bpchar_pattern_ops_indexes(true, CLUSTER_OLD); + 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 @@ -86,12 +85,12 @@ check_old_cluster(bool live_check, * end. */ *sequence_script_file_name = - old_8_3_create_sequence_script(CLUSTER_OLD); + old_8_3_create_sequence_script(&old_cluster); } /* Pre-PG 9.0 had no large object permissions */ if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804) - new_9_0_populate_pg_largeobject_metadata(true, CLUSTER_OLD); + new_9_0_populate_pg_largeobject_metadata(&old_cluster, true); /* * While not a check option, we do this now because this is the only time @@ -111,7 +110,7 @@ check_old_cluster(bool live_check, void check_new_cluster(void) { - set_locale_and_encoding(CLUSTER_NEW); + set_locale_and_encoding(&new_cluster); check_new_db_is_empty(); @@ -149,7 +148,7 @@ issue_warnings(char *sequence_script_file_name) /* old = PG 8.3 warnings? */ if (GET_MAJOR_VERSION(old_cluster.major_version) <= 803) { - start_postmaster(CLUSTER_NEW, true); + start_postmaster(&new_cluster, true); /* restore proper sequence values using file created from old server */ if (sequence_script_file_name) @@ -165,17 +164,17 @@ issue_warnings(char *sequence_script_file_name) check_ok(); } - old_8_3_rebuild_tsvector_tables(false, CLUSTER_NEW); - old_8_3_invalidate_hash_gin_indexes(false, CLUSTER_NEW); - old_8_3_invalidate_bpchar_pattern_ops_indexes(false, CLUSTER_NEW); + 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, true); } /* Create dummy large object permissions for old < PG 9.0? */ if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804) { - start_postmaster(CLUSTER_NEW, true); - new_9_0_populate_pg_largeobject_metadata(false, CLUSTER_NEW); + start_postmaster(&new_cluster, true); + new_9_0_populate_pg_largeobject_metadata(&new_cluster, false); stop_postmaster(false, true); } } @@ -210,8 +209,8 @@ void check_cluster_versions(void) { /* get old and new cluster versions */ - old_cluster.major_version = get_major_server_version(&old_cluster.major_version_str, CLUSTER_OLD); - new_cluster.major_version = get_major_server_version(&new_cluster.major_version_str, CLUSTER_NEW); + old_cluster.major_version = get_major_server_version(&old_cluster, &old_cluster.major_version_str); + new_cluster.major_version = get_major_server_version(&new_cluster, &new_cluster.major_version_str); /* We allow upgrades from/to the same major version for alpha/beta upgrades */ @@ -270,16 +269,15 @@ check_cluster_compatibility(bool live_check) * query the database to get the template0 locale */ static void -set_locale_and_encoding(Cluster whichCluster) +set_locale_and_encoding(ClusterInfo *cluster) { - ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster); - ControlData *ctrl = &active_cluster->controldata; + ControlData *ctrl = &cluster->controldata; PGconn *conn; PGresult *res; int i_encoding; - int cluster_version = active_cluster->major_version; + int cluster_version = cluster->major_version; - conn = connectToServer("template1", whichCluster); + conn = connectToServer(cluster, "template1"); /* for pg < 80400, we got the values from pg_controldata */ if (cluster_version >= 80400) @@ -345,7 +343,7 @@ check_new_db_is_empty(void) int dbnum; bool found = false; - get_db_and_rel_infos(&new_cluster.dbarr, CLUSTER_NEW); + get_db_and_rel_infos(&new_cluster); for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++) { @@ -457,9 +455,8 @@ create_script_for_old_cluster_deletion( * it must match for the old and new servers. */ void -check_for_isn_and_int8_passing_mismatch(Cluster whichCluster) +check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster) { - ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster); int dbnum; FILE *script = NULL; bool found = false; @@ -478,7 +475,7 @@ check_for_isn_and_int8_passing_mismatch(Cluster whichCluster) snprintf(output_path, sizeof(output_path), "%s/contrib_isn_and_int8_pass_by_value.txt", os_info.cwd); - for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++) + for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) { PGresult *res; bool db_used = false; @@ -486,8 +483,8 @@ check_for_isn_and_int8_passing_mismatch(Cluster whichCluster) int rowno; int i_nspname, i_proname; - DbInfo *active_db = &active_cluster->dbarr.dbs[dbnum]; - PGconn *conn = connectToServer(active_db->db_name, whichCluster); + DbInfo *active_db = &cluster->dbarr.dbs[dbnum]; + PGconn *conn = connectToServer(cluster, active_db->db_name); /* Find any functions coming from contrib/isn */ res = executeQueryOrDie(conn, @@ -552,9 +549,8 @@ check_for_isn_and_int8_passing_mismatch(Cluster whichCluster) * tables upgraded by pg_upgrade. */ void -check_for_reg_data_type_usage(Cluster whichCluster) +check_for_reg_data_type_usage(ClusterInfo *cluster) { - ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster); int dbnum; FILE *script = NULL; bool found = false; @@ -565,7 +561,7 @@ check_for_reg_data_type_usage(Cluster whichCluster) snprintf(output_path, sizeof(output_path), "%s/tables_using_reg.txt", os_info.cwd); - for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++) + for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) { PGresult *res; bool db_used = false; @@ -574,8 +570,8 @@ check_for_reg_data_type_usage(Cluster whichCluster) int i_nspname, i_relname, i_attname; - DbInfo *active_db = &active_cluster->dbarr.dbs[dbnum]; - PGconn *conn = connectToServer(active_db->db_name, whichCluster); + DbInfo *active_db = &cluster->dbarr.dbs[dbnum]; + PGconn *conn = connectToServer(cluster, active_db->db_name); res = executeQueryOrDie(conn, "SELECT n.nspname, c.relname, a.attname " diff --git a/contrib/pg_upgrade/exec.c b/contrib/pg_upgrade/exec.c index af0fcf93a9..1959b8aa94 100644 --- a/contrib/pg_upgrade/exec.c +++ b/contrib/pg_upgrade/exec.c @@ -14,7 +14,7 @@ static void check_data_dir(const char *pg_data); -static void check_bin_dir(ClusterInfo *cluster, Cluster whichCluster); +static void check_bin_dir(ClusterInfo *cluster); static int check_exec(const char *dir, const char *cmdName); static const char *validate_exec(const char *path); @@ -99,7 +99,7 @@ verify_directories(void) check_ok(); prep_status("Checking old bin directory (%s)", old_cluster.bindir); - check_bin_dir(&old_cluster, CLUSTER_OLD); + check_bin_dir(&old_cluster); check_ok(); prep_status("Checking new data directory (%s)", new_cluster.pgdata); @@ -107,7 +107,7 @@ verify_directories(void) check_ok(); prep_status("Checking new bin directory (%s)", new_cluster.bindir); - check_bin_dir(&new_cluster, CLUSTER_NEW); + check_bin_dir(&new_cluster); check_ok(); } @@ -158,12 +158,12 @@ check_data_dir(const char *pg_data) * exit(). */ static void -check_bin_dir(ClusterInfo *cluster, Cluster whichCluster) +check_bin_dir(ClusterInfo *cluster) { check_exec(cluster->bindir, "postgres"); check_exec(cluster->bindir, "pg_ctl"); check_exec(cluster->bindir, "pg_resetxlog"); - if (whichCluster == CLUSTER_NEW) + if (cluster == &new_cluster) { /* these are only needed in the new cluster */ check_exec(cluster->bindir, "pg_config"); diff --git a/contrib/pg_upgrade/function.c b/contrib/pg_upgrade/function.c index c76aaeb090..877b0041ce 100644 --- a/contrib/pg_upgrade/function.c +++ b/contrib/pg_upgrade/function.c @@ -28,7 +28,7 @@ install_support_functions(void) for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++) { DbInfo *newdb = &new_cluster.dbarr.dbs[dbnum]; - PGconn *conn = connectToServer(newdb->db_name, CLUSTER_NEW); + PGconn *conn = connectToServer(&new_cluster, newdb->db_name); /* suppress NOTICE of dropped objects */ PQclear(executeQueryOrDie(conn, @@ -99,7 +99,7 @@ uninstall_support_functions(void) for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++) { DbInfo *newdb = &new_cluster.dbarr.dbs[dbnum]; - PGconn *conn = connectToServer(newdb->db_name, CLUSTER_NEW); + PGconn *conn = connectToServer(&new_cluster, newdb->db_name); /* suppress NOTICE of dropped objects */ PQclear(executeQueryOrDie(conn, @@ -123,20 +123,19 @@ uninstall_support_functions(void) void get_loadable_libraries(void) { - ClusterInfo *active_cluster = &old_cluster; PGresult **ress; int totaltups; int dbnum; ress = (PGresult **) - pg_malloc(active_cluster->dbarr.ndbs * sizeof(PGresult *)); + pg_malloc(old_cluster.dbarr.ndbs * sizeof(PGresult *)); totaltups = 0; /* Fetch all library names, removing duplicates within each DB */ - for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++) + for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++) { - DbInfo *active_db = &active_cluster->dbarr.dbs[dbnum]; - PGconn *conn = connectToServer(active_db->db_name, CLUSTER_OLD); + DbInfo *active_db = &old_cluster.dbarr.dbs[dbnum]; + PGconn *conn = connectToServer(&old_cluster, active_db->db_name); /* Fetch all libraries referenced in this DB */ ress[dbnum] = executeQueryOrDie(conn, @@ -163,7 +162,7 @@ get_loadable_libraries(void) */ totaltups = 0; - for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++) + for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++) { PGresult *res = ress[dbnum]; int ntups; @@ -207,7 +206,7 @@ get_loadable_libraries(void) void check_loadable_libraries(void) { - PGconn *conn = connectToServer("template1", CLUSTER_NEW); + PGconn *conn = connectToServer(&new_cluster, "template1"); int libnum; FILE *script = NULL; bool found = false; diff --git a/contrib/pg_upgrade/info.c b/contrib/pg_upgrade/info.c index 99a1548a58..e44798a817 100644 --- a/contrib/pg_upgrade/info.c +++ b/contrib/pg_upgrade/info.c @@ -12,13 +12,11 @@ #include "access/transam.h" -static void get_db_infos(DbInfoArr *dbinfos, - Cluster whichCluster); -static void dbarr_print(DbInfoArr *arr, - Cluster whichCluster); +static void get_db_infos(ClusterInfo *cluster); +static void dbarr_print(ClusterInfo *cluster); static void relarr_print(RelInfoArr *arr); -static void get_rel_infos(const DbInfo *dbinfo, - RelInfoArr *relarr, Cluster whichCluster); +static void get_rel_infos(ClusterInfo *cluster, const DbInfo *dbinfo, + RelInfoArr *relarr); static void relarr_free(RelInfoArr *rel_arr); static void map_rel(const RelInfo *oldrel, const RelInfo *newrel, const DbInfo *old_db, @@ -30,11 +28,10 @@ static void map_rel_by_id(Oid oldid, Oid newid, const char *old_tablespace, const DbInfo *old_db, const DbInfo *new_db, const char *olddata, const char *newdata, FileNameMap *map); -static RelInfo *relarr_lookup_reloid(RelInfoArr *rel_arr, - Oid oid, Cluster whichCluster); -static RelInfo *relarr_lookup_rel(RelInfoArr *rel_arr, - const char *nspname, const char *relname, - Cluster whichCluster); +static RelInfo *relarr_lookup_reloid(ClusterInfo *cluster, RelInfoArr *rel_arr, + Oid oid); +static RelInfo *relarr_lookup_rel(ClusterInfo *cluster, RelInfoArr *rel_arr, + const char *nspname, const char *relname); /* @@ -66,8 +63,8 @@ gen_db_file_maps(DbInfo *old_db, DbInfo *new_db, if (strcmp(newrel->nspname, "pg_toast") == 0) continue; - oldrel = relarr_lookup_rel(&old_db->rel_arr, newrel->nspname, - newrel->relname, CLUSTER_OLD); + oldrel = relarr_lookup_rel(&old_cluster, &old_db->rel_arr, + newrel->nspname, newrel->relname); map_rel(oldrel, newrel, old_db, new_db, old_pgdata, new_pgdata, maps + num_maps); @@ -91,10 +88,10 @@ gen_db_file_maps(DbInfo *old_db, DbInfo *new_db, newrel->reloid); /* look them up in their respective arrays */ - old_toast = relarr_lookup_reloid(&old_db->rel_arr, - oldrel->toastrelid, CLUSTER_OLD); - new_toast = relarr_lookup_rel(&new_db->rel_arr, - "pg_toast", new_name, CLUSTER_NEW); + old_toast = relarr_lookup_reloid(&old_cluster, &old_db->rel_arr, + oldrel->toastrelid); + new_toast = relarr_lookup_rel(&new_cluster, &new_db->rel_arr, + "pg_toast", new_name); /* finally create a mapping for them */ map_rel(old_toast, new_toast, old_db, new_db, old_pgdata, new_pgdata, @@ -118,10 +115,10 @@ gen_db_file_maps(DbInfo *old_db, DbInfo *new_db, /* look them up in their respective arrays */ /* we lose our cache location here */ - old_toast = relarr_lookup_rel(&old_db->rel_arr, - "pg_toast", old_name, CLUSTER_OLD); - new_toast = relarr_lookup_rel(&new_db->rel_arr, - "pg_toast", new_name, CLUSTER_NEW); + old_toast = relarr_lookup_rel(&old_cluster, &old_db->rel_arr, + "pg_toast", old_name); + new_toast = relarr_lookup_rel(&new_cluster, &new_db->rel_arr, + "pg_toast", new_name); /* finally create a mapping for them */ map_rel(old_toast, new_toast, old_db, new_db, old_pgdata, @@ -214,13 +211,13 @@ print_maps(FileNameMap *maps, int n, const char *dbName) /* * get_db_infos() * - * Scans pg_database system catalog and returns (in dbinfs_arr) all user + * Scans pg_database system catalog and populates all user * databases. */ static void -get_db_infos(DbInfoArr *dbinfs_arr, Cluster whichCluster) +get_db_infos(ClusterInfo *cluster) { - PGconn *conn = connectToServer("template1", whichCluster); + PGconn *conn = connectToServer(cluster, "template1"); PGresult *res; int ntups; int tupnum; @@ -256,8 +253,8 @@ get_db_infos(DbInfoArr *dbinfs_arr, Cluster whichCluster) PQfinish(conn); - dbinfs_arr->dbs = dbinfos; - dbinfs_arr->ndbs = ntups; + cluster->dbarr.dbs = dbinfos; + cluster->dbarr.ndbs = ntups; } @@ -268,18 +265,18 @@ get_db_infos(DbInfoArr *dbinfs_arr, Cluster whichCluster) * on the given "port". Assumes that server is already running. */ void -get_db_and_rel_infos(DbInfoArr *db_arr, Cluster whichCluster) +get_db_and_rel_infos(ClusterInfo *cluster) { int dbnum; - get_db_infos(db_arr, whichCluster); + get_db_infos(cluster); - for (dbnum = 0; dbnum < db_arr->ndbs; dbnum++) - get_rel_infos(&db_arr->dbs[dbnum], - &db_arr->dbs[dbnum].rel_arr, whichCluster); + for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) + get_rel_infos(cluster, &cluster->dbarr.dbs[dbnum], + &cluster->dbarr.dbs[dbnum].rel_arr); if (log_opts.debug) - dbarr_print(db_arr, whichCluster); + dbarr_print(cluster); } @@ -293,9 +290,9 @@ get_db_and_rel_infos(DbInfoArr *db_arr, Cluster whichCluster) * FirstNormalObjectId belongs to the user */ static void -get_rel_infos(const DbInfo *dbinfo, RelInfoArr *relarr, Cluster whichCluster) +get_rel_infos(ClusterInfo *cluster, const DbInfo *dbinfo, RelInfoArr *relarr) { - PGconn *conn = connectToServer(dbinfo->db_name, whichCluster); + PGconn *conn = connectToServer(cluster, dbinfo->db_name); PGresult *res; RelInfo *relinfos; int ntups; @@ -417,8 +414,8 @@ dbarr_lookup_db(DbInfoArr *db_arr, const char *db_name) * RelInfo structure. */ static RelInfo * -relarr_lookup_rel(RelInfoArr *rel_arr, const char *nspname, - const char *relname, Cluster whichCluster) +relarr_lookup_rel(ClusterInfo *cluster, RelInfoArr *rel_arr, + const char *nspname, const char *relname) { int relnum; @@ -441,7 +438,7 @@ relarr_lookup_rel(RelInfoArr *rel_arr, const char *nspname, } } pg_log(PG_FATAL, "Could not find %s.%s in %s cluster\n", - nspname, relname, CLUSTER_NAME(whichCluster)); + nspname, relname, CLUSTER_NAME(cluster)); return NULL; } @@ -454,8 +451,7 @@ relarr_lookup_rel(RelInfoArr *rel_arr, const char *nspname, * found. */ static RelInfo * -relarr_lookup_reloid(RelInfoArr *rel_arr, Oid oid, - Cluster whichCluster) +relarr_lookup_reloid(ClusterInfo *cluster, RelInfoArr *rel_arr, Oid oid) { int relnum; @@ -465,7 +461,7 @@ relarr_lookup_reloid(RelInfoArr *rel_arr, Oid oid, return &rel_arr->rels[relnum]; } pg_log(PG_FATAL, "Could not find %d in %s cluster\n", - oid, CLUSTER_NAME(whichCluster)); + oid, CLUSTER_NAME(cluster)); return NULL; } @@ -491,16 +487,16 @@ dbarr_free(DbInfoArr *db_arr) static void -dbarr_print(DbInfoArr *arr, Cluster whichCluster) +dbarr_print(ClusterInfo *cluster) { int dbnum; - pg_log(PG_DEBUG, "%s databases\n", CLUSTER_NAME(whichCluster)); + pg_log(PG_DEBUG, "%s databases\n", CLUSTER_NAME(cluster)); - for (dbnum = 0; dbnum < arr->ndbs; dbnum++) + for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) { - pg_log(PG_DEBUG, "Database: %s\n", arr->dbs[dbnum].db_name); - relarr_print(&arr->dbs[dbnum].rel_arr); + pg_log(PG_DEBUG, "Database: %s\n", cluster->dbarr.dbs[dbnum].db_name); + relarr_print(&cluster->dbarr.dbs[dbnum].rel_arr); pg_log(PG_DEBUG, "\n\n"); } } diff --git a/contrib/pg_upgrade/pg_upgrade.c b/contrib/pg_upgrade/pg_upgrade.c index bfd2defbb0..d2ca08bb0b 100644 --- a/contrib/pg_upgrade/pg_upgrade.c +++ b/contrib/pg_upgrade/pg_upgrade.c @@ -22,8 +22,7 @@ static void set_frozenxids(void); static void setup(char *argv0, bool live_check); static void cleanup(void); -ClusterInfo old_cluster, - new_cluster; +ClusterInfo old_cluster, new_cluster; OSInfo os_info; int @@ -46,7 +45,7 @@ main(int argc, char **argv) /* -- NEW -- */ - start_postmaster(CLUSTER_NEW, false); + start_postmaster(&new_cluster, false); check_new_cluster(); report_clusters_compatible(); @@ -178,7 +177,7 @@ prepare_new_cluster(void) new_cluster.bindir, new_cluster.port, os_info.user, log_opts.filename); check_ok(); - get_pg_database_relfilenode(CLUSTER_NEW); + get_pg_database_relfilenode(&new_cluster); } @@ -186,7 +185,7 @@ static void prepare_new_databases(void) { /* -- NEW -- */ - start_postmaster(CLUSTER_NEW, false); + start_postmaster(&new_cluster, false); /* * We set autovacuum_freeze_max_age to its maximum value so autovacuum @@ -210,7 +209,7 @@ prepare_new_databases(void) GLOBALS_DUMP_FILE, log_opts.filename); check_ok(); - get_db_and_rel_infos(&new_cluster.dbarr, CLUSTER_NEW); + get_db_and_rel_infos(&new_cluster); stop_postmaster(false, false); } @@ -220,7 +219,7 @@ static void create_new_objects(void) { /* -- NEW -- */ - start_postmaster(CLUSTER_NEW, false); + start_postmaster(&new_cluster, false); install_support_functions(); @@ -235,7 +234,7 @@ create_new_objects(void) /* regenerate now that we have db schemas */ dbarr_free(&new_cluster.dbarr); - get_db_and_rel_infos(&new_cluster.dbarr, CLUSTER_NEW); + get_db_and_rel_infos(&new_cluster); uninstall_support_functions(); @@ -309,7 +308,7 @@ set_frozenxids(void) prep_status("Setting frozenxid counters in new cluster"); - conn_template1 = connectToServer("template1", CLUSTER_NEW); + conn_template1 = connectToServer(&new_cluster, "template1"); /* set pg_database.datfrozenxid */ PQclear(executeQueryOrDie(conn_template1, @@ -344,7 +343,7 @@ set_frozenxids(void) "SET datallowconn = true " "WHERE datname = '%s'", datname)); - conn = connectToServer(datname, CLUSTER_NEW); + conn = connectToServer(&new_cluster, datname); /* set pg_class.relfrozenxid */ PQclear(executeQueryOrDie(conn, diff --git a/contrib/pg_upgrade/pg_upgrade.h b/contrib/pg_upgrade/pg_upgrade.h index c53f935a78..b6ce965731 100644 --- a/contrib/pg_upgrade/pg_upgrade.h +++ b/contrib/pg_upgrade/pg_upgrade.h @@ -52,9 +52,8 @@ #define EXE_EXT ".exe" #endif -#define CLUSTER_NAME(cluster) ((cluster) == CLUSTER_OLD ? "old" : "new") -#define ACTIVE_CLUSTER(cluster) (((cluster) == CLUSTER_OLD) ? \ - &old_cluster : &new_cluster) +#define CLUSTER_NAME(cluster) ((cluster) == &old_cluster ? "old" : \ + (cluster) == &new_cluster ? "new" : "none") #define atooid(x) ((Oid) strtoul((x), NULL, 10)) @@ -163,15 +162,6 @@ typedef enum PG_DEBUG } eLogType; -/* - * Enumeration to distinguish between old cluster and new cluster - */ -typedef enum -{ - NONE = 0, /* used for no running servers */ - CLUSTER_OLD, - CLUSTER_NEW -} Cluster; typedef long pgpid_t; @@ -234,7 +224,7 @@ typedef struct char **libraries; /* loadable libraries */ int num_libraries; pgpid_t postmasterPID; /* PID of currently running postmaster */ - Cluster running_cluster; + ClusterInfo *running_cluster; } OSInfo; @@ -243,8 +233,7 @@ typedef struct */ extern LogOpts log_opts; extern UserOpts user_opts; -extern ClusterInfo old_cluster, - new_cluster; +extern ClusterInfo old_cluster, new_cluster; extern OSInfo os_info; extern char scandir_file_pattern[]; @@ -339,8 +328,7 @@ void check_loadable_libraries(void); FileNameMap *gen_db_file_maps(DbInfo *old_db, DbInfo *new_db, int *nmaps, const char *old_pgdata, const char *new_pgdata); -void get_db_and_rel_infos(DbInfoArr *db_arr, - Cluster whichCluster); +void get_db_and_rel_infos(ClusterInfo *cluster); DbInfo *dbarr_lookup_db(DbInfoArr *db_arr, const char *db_name); void dbarr_free(DbInfoArr *db_arr); void print_maps(FileNameMap *maps, int n, @@ -352,7 +340,7 @@ void parseCommandLine(int argc, char *argv[]); /* relfilenode.c */ -void get_pg_database_relfilenode(Cluster whichCluster); +void get_pg_database_relfilenode(ClusterInfo *cluster); const char *transfer_all_new_dbs(DbInfoArr *olddb_arr, DbInfoArr *newdb_arr, char *old_pgdata, char *new_pgdata); @@ -364,14 +352,12 @@ void init_tablespaces(void); /* server.c */ -PGconn *connectToServer(const char *db_name, - Cluster whichCluster); -PGresult *executeQueryOrDie(PGconn *conn, - const char *fmt,...); +PGconn *connectToServer(ClusterInfo *cluster, const char *db_name); +PGresult *executeQueryOrDie(PGconn *conn, const char *fmt,...); -void start_postmaster(Cluster whichCluster, bool quiet); +void start_postmaster(ClusterInfo *cluster, bool quiet); void stop_postmaster(bool fast, bool quiet); -uint32 get_major_server_version(char **verstr, Cluster whichCluster); +uint32 get_major_server_version(ClusterInfo *cluster, char **verstr); void check_for_libpq_envvars(void); @@ -394,17 +380,15 @@ unsigned int str2uint(const char *str); /* version.c */ -void new_9_0_populate_pg_largeobject_metadata( - bool check_mode, Cluster whichCluster); +void new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster, + bool check_mode); /* version_old_8_3.c */ -void old_8_3_check_for_name_data_type_usage(Cluster whichCluster); -void old_8_3_check_for_tsquery_usage(Cluster whichCluster); -void old_8_3_rebuild_tsvector_tables(bool check_mode, - Cluster whichCluster); -void old_8_3_invalidate_hash_gin_indexes(bool check_mode, - Cluster whichCluster); -void old_8_3_invalidate_bpchar_pattern_ops_indexes(bool check_mode, - Cluster whichCluster); -char *old_8_3_create_sequence_script(Cluster whichCluster); +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_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); diff --git a/contrib/pg_upgrade/relfilenode.c b/contrib/pg_upgrade/relfilenode.c index da7531e314..b23ce2f37d 100644 --- a/contrib/pg_upgrade/relfilenode.c +++ b/contrib/pg_upgrade/relfilenode.c @@ -77,10 +77,9 @@ transfer_all_new_dbs(DbInfoArr *olddb_arr, * relfilenodes later in the upgrade process. */ void -get_pg_database_relfilenode(Cluster whichCluster) +get_pg_database_relfilenode(ClusterInfo *cluster) { - PGconn *conn = connectToServer("template1", whichCluster); - ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster); + PGconn *conn = connectToServer(cluster, "template1"); PGresult *res; int i_relfile; @@ -94,7 +93,7 @@ get_pg_database_relfilenode(Cluster whichCluster) "ORDER BY c.relname"); i_relfile = PQfnumber(res, "relfilenode"); - active_cluster->pg_database_oid = atooid(PQgetvalue(res, 0, i_relfile)); + cluster->pg_database_oid = atooid(PQgetvalue(res, 0, i_relfile)); PQclear(res); PQfinish(conn); diff --git a/contrib/pg_upgrade/server.c b/contrib/pg_upgrade/server.c index 127f9c4fc0..56dcb10a5e 100644 --- a/contrib/pg_upgrade/server.c +++ b/contrib/pg_upgrade/server.c @@ -15,8 +15,7 @@ static pgpid_t get_postmaster_pid(const char *datadir); -static bool test_server_conn(int timeout, - Cluster whichCluster); +static bool test_server_conn(ClusterInfo *cluster, int timeout); /* @@ -27,11 +26,9 @@ static bool test_server_conn(int timeout, * message and calls exit_nicely() to kill the program. */ PGconn * -connectToServer(const char *db_name, - Cluster whichCluster) +connectToServer(ClusterInfo *cluster, const char *db_name) { - ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster); - unsigned short port = active_cluster->port; + unsigned short port = cluster->port; char connectString[MAXPGPATH]; PGconn *conn; @@ -132,10 +129,9 @@ get_postmaster_pid(const char *datadir) * is retrieved by reading the PG_VERSION file. */ uint32 -get_major_server_version(char **verstr, Cluster whichCluster) +get_major_server_version(ClusterInfo *cluster, char **verstr) { - ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster); - const char *datadir = active_cluster->pgdata; + const char *datadir = cluster->pgdata; FILE *version_fd; char ver_file[MAXPGPATH]; int integer_version = 0; @@ -160,17 +156,16 @@ get_major_server_version(char **verstr, Cluster whichCluster) void -start_postmaster(Cluster whichCluster, bool quiet) +start_postmaster(ClusterInfo *cluster, bool quiet) { - ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster); char cmd[MAXPGPATH]; const char *bindir; const char *datadir; unsigned short port; - bindir = active_cluster->bindir; - datadir = active_cluster->pgdata; - port = active_cluster->port; + bindir = cluster->bindir; + datadir = cluster->pgdata; + port = cluster->port; /* * On Win32, we can't send both pg_upgrade output and pg_ctl output to the @@ -193,13 +188,13 @@ start_postmaster(Cluster whichCluster, bool quiet) /* wait for the server to start properly */ - if (test_server_conn(POSTMASTER_UPTIME, whichCluster) == false) + if (test_server_conn(cluster, POSTMASTER_UPTIME) == false) pg_log(PG_FATAL, " Unable to start %s postmaster with the command: %s\nPerhaps pg_hba.conf was not set to \"trust\".", - CLUSTER_NAME(whichCluster), cmd); + CLUSTER_NAME(cluster), cmd); if ((os_info.postmasterPID = get_postmaster_pid(datadir)) == 0) pg_log(PG_FATAL, " Unable to get postmaster pid\n"); - os_info.running_cluster = whichCluster; + os_info.running_cluster = cluster; } @@ -210,12 +205,12 @@ stop_postmaster(bool fast, bool quiet) const char *bindir; const char *datadir; - if (os_info.running_cluster == CLUSTER_OLD) + if (os_info.running_cluster == &old_cluster) { bindir = old_cluster.bindir; datadir = old_cluster.pgdata; } - else if (os_info.running_cluster == CLUSTER_NEW) + else if (os_info.running_cluster == &new_cluster) { bindir = new_cluster.bindir; datadir = new_cluster.pgdata; @@ -236,7 +231,7 @@ stop_postmaster(bool fast, bool quiet) exec_prog(fast ? false : true, "%s", cmd); os_info.postmasterPID = 0; - os_info.running_cluster = NONE; + os_info.running_cluster = NULL; } @@ -250,10 +245,9 @@ stop_postmaster(bool fast, bool quiet) * Returns true if the connection attempt was successfull, false otherwise. */ static bool -test_server_conn(int timeout, Cluster whichCluster) +test_server_conn(ClusterInfo *cluster, int timeout) { - ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster); - unsigned short port = active_cluster->port; + unsigned short port = cluster->port; PGconn *conn = NULL; char con_opts[MAX_STRING]; int tries; @@ -275,7 +269,7 @@ test_server_conn(int timeout, Cluster whichCluster) if (tries == STARTUP_WARNING_TRIES) prep_status("Trying to start %s server ", - CLUSTER_NAME(whichCluster)); + CLUSTER_NAME(cluster)); else if (tries > STARTUP_WARNING_TRIES) pg_log(PG_REPORT, "."); } diff --git a/contrib/pg_upgrade/tablespace.c b/contrib/pg_upgrade/tablespace.c index 4930d5dc3b..70fe0578fd 100644 --- a/contrib/pg_upgrade/tablespace.c +++ b/contrib/pg_upgrade/tablespace.c @@ -10,8 +10,7 @@ #include "pg_upgrade.h" static void get_tablespace_paths(void); -static void set_tablespace_directory_suffix( - Cluster whichCluster); +static void set_tablespace_directory_suffix(ClusterInfo *cluster); void @@ -19,8 +18,8 @@ init_tablespaces(void) { get_tablespace_paths(); - set_tablespace_directory_suffix(CLUSTER_OLD); - set_tablespace_directory_suffix(CLUSTER_NEW); + set_tablespace_directory_suffix(&old_cluster); + set_tablespace_directory_suffix(&new_cluster); if (os_info.num_tablespaces > 0 && strcmp(old_cluster.tablespace_suffix, new_cluster.tablespace_suffix) == 0) @@ -39,7 +38,7 @@ init_tablespaces(void) static void get_tablespace_paths(void) { - PGconn *conn = connectToServer("template1", CLUSTER_OLD); + PGconn *conn = connectToServer(&old_cluster, "template1"); PGresult *res; int tblnum; int i_spclocation; @@ -71,21 +70,19 @@ get_tablespace_paths(void) static void -set_tablespace_directory_suffix(Cluster whichCluster) +set_tablespace_directory_suffix(ClusterInfo *cluster) { - ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster); - - if (GET_MAJOR_VERSION(active_cluster->major_version) <= 804) - active_cluster->tablespace_suffix = pg_strdup(""); + if (GET_MAJOR_VERSION(cluster->major_version) <= 804) + cluster->tablespace_suffix = pg_strdup(""); else { /* This cluster has a version-specific subdirectory */ - active_cluster->tablespace_suffix = pg_malloc(4 + - strlen(active_cluster->major_version_str) + + cluster->tablespace_suffix = pg_malloc(4 + + strlen(cluster->major_version_str) + 10 /* OIDCHARS */ + 1); /* The leading slash is needed to start a new directory. */ - sprintf(active_cluster->tablespace_suffix, "/PG_%s_%d", active_cluster->major_version_str, - active_cluster->controldata.cat_ver); + sprintf(cluster->tablespace_suffix, "/PG_%s_%d", cluster->major_version_str, + cluster->controldata.cat_ver); } } diff --git a/contrib/pg_upgrade/version.c b/contrib/pg_upgrade/version.c index b85b8148f5..cdda741552 100644 --- a/contrib/pg_upgrade/version.c +++ b/contrib/pg_upgrade/version.c @@ -18,10 +18,8 @@ * 9.0 has a new pg_largeobject permission table */ void -new_9_0_populate_pg_largeobject_metadata(bool check_mode, - Cluster whichCluster) +new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster, bool check_mode) { - ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster); int dbnum; FILE *script = NULL; bool found = false; @@ -32,12 +30,12 @@ new_9_0_populate_pg_largeobject_metadata(bool check_mode, snprintf(output_path, sizeof(output_path), "%s/pg_largeobject.sql", os_info.cwd); - for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++) + for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) { PGresult *res; int i_count; - DbInfo *active_db = &active_cluster->dbarr.dbs[dbnum]; - PGconn *conn = connectToServer(active_db->db_name, whichCluster); + DbInfo *active_db = &cluster->dbarr.dbs[dbnum]; + PGconn *conn = connectToServer(cluster, active_db->db_name); /* find if there are any large objects */ res = executeQueryOrDie(conn, diff --git a/contrib/pg_upgrade/version_old_8_3.c b/contrib/pg_upgrade/version_old_8_3.c index 5a396ded14..c342cd99a7 100644 --- a/contrib/pg_upgrade/version_old_8_3.c +++ b/contrib/pg_upgrade/version_old_8_3.c @@ -19,9 +19,8 @@ * checks tables and indexes. */ void -old_8_3_check_for_name_data_type_usage(Cluster whichCluster) +old_8_3_check_for_name_data_type_usage(ClusterInfo *cluster) { - ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster); int dbnum; FILE *script = NULL; bool found = false; @@ -32,7 +31,7 @@ old_8_3_check_for_name_data_type_usage(Cluster whichCluster) snprintf(output_path, sizeof(output_path), "%s/tables_using_name.txt", os_info.cwd); - for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++) + for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) { PGresult *res; bool db_used = false; @@ -41,8 +40,8 @@ old_8_3_check_for_name_data_type_usage(Cluster whichCluster) int i_nspname, i_relname, i_attname; - DbInfo *active_db = &active_cluster->dbarr.dbs[dbnum]; - PGconn *conn = connectToServer(active_db->db_name, whichCluster); + 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 @@ -113,9 +112,8 @@ old_8_3_check_for_name_data_type_usage(Cluster whichCluster) * so upgrading of such fields is impossible. */ void -old_8_3_check_for_tsquery_usage(Cluster whichCluster) +old_8_3_check_for_tsquery_usage(ClusterInfo *cluster) { - ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster); int dbnum; FILE *script = NULL; bool found = false; @@ -126,7 +124,7 @@ old_8_3_check_for_tsquery_usage(Cluster whichCluster) snprintf(output_path, sizeof(output_path), "%s/tables_using_tsquery.txt", os_info.cwd); - for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++) + for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) { PGresult *res; bool db_used = false; @@ -135,8 +133,8 @@ old_8_3_check_for_tsquery_usage(Cluster whichCluster) int i_nspname, i_relname, i_attname; - DbInfo *active_db = &active_cluster->dbarr.dbs[dbnum]; - PGconn *conn = connectToServer(active_db->db_name, whichCluster); + DbInfo *active_db = &cluster->dbarr.dbs[dbnum]; + PGconn *conn = connectToServer(cluster, active_db->db_name); /* Find any user-defined tsquery columns */ res = executeQueryOrDie(conn, @@ -208,10 +206,8 @@ old_8_3_check_for_tsquery_usage(Cluster whichCluster) * 'c' 'bb' 'aaa' -- 8.3 */ void -old_8_3_rebuild_tsvector_tables(bool check_mode, - Cluster whichCluster) +old_8_3_rebuild_tsvector_tables(ClusterInfo *cluster, bool check_mode) { - ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster); int dbnum; FILE *script = NULL; bool found = false; @@ -222,7 +218,7 @@ old_8_3_rebuild_tsvector_tables(bool check_mode, snprintf(output_path, sizeof(output_path), "%s/rebuild_tsvector_tables.sql", os_info.cwd); - for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++) + for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) { PGresult *res; bool db_used = false; @@ -233,8 +229,8 @@ old_8_3_rebuild_tsvector_tables(bool check_mode, int i_nspname, i_relname, i_attname; - DbInfo *active_db = &active_cluster->dbarr.dbs[dbnum]; - PGconn *conn = connectToServer(active_db->db_name, whichCluster); + DbInfo *active_db = &cluster->dbarr.dbs[dbnum]; + PGconn *conn = connectToServer(cluster, active_db->db_name); /* Find any user-defined tsvector columns */ res = executeQueryOrDie(conn, @@ -352,10 +348,8 @@ old_8_3_rebuild_tsvector_tables(bool check_mode, * Hash, Gin, and GiST index binary format has changes from 8.3->8.4 */ void -old_8_3_invalidate_hash_gin_indexes(bool check_mode, - Cluster whichCluster) +old_8_3_invalidate_hash_gin_indexes(ClusterInfo *cluster, bool check_mode) { - ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster); int dbnum; FILE *script = NULL; bool found = false; @@ -366,7 +360,7 @@ old_8_3_invalidate_hash_gin_indexes(bool check_mode, snprintf(output_path, sizeof(output_path), "%s/reindex_hash_and_gin.sql", os_info.cwd); - for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++) + for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) { PGresult *res; bool db_used = false; @@ -374,8 +368,8 @@ old_8_3_invalidate_hash_gin_indexes(bool check_mode, int rowno; int i_nspname, i_relname; - DbInfo *active_db = &active_cluster->dbarr.dbs[dbnum]; - PGconn *conn = connectToServer(active_db->db_name, whichCluster); + DbInfo *active_db = &cluster->dbarr.dbs[dbnum]; + PGconn *conn = connectToServer(cluster, active_db->db_name); /* find hash and gin indexes */ res = executeQueryOrDie(conn, @@ -467,10 +461,9 @@ old_8_3_invalidate_hash_gin_indexes(bool check_mode, * 8.4 bpchar_pattern_ops no longer sorts based on trailing spaces */ void -old_8_3_invalidate_bpchar_pattern_ops_indexes(bool check_mode, - Cluster whichCluster) +old_8_3_invalidate_bpchar_pattern_ops_indexes(ClusterInfo *cluster, + bool check_mode) { - ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster); int dbnum; FILE *script = NULL; bool found = false; @@ -481,7 +474,7 @@ old_8_3_invalidate_bpchar_pattern_ops_indexes(bool check_mode, snprintf(output_path, sizeof(output_path), "%s/reindex_bpchar_ops.sql", os_info.cwd); - for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++) + for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) { PGresult *res; bool db_used = false; @@ -489,8 +482,8 @@ old_8_3_invalidate_bpchar_pattern_ops_indexes(bool check_mode, int rowno; int i_nspname, i_relname; - DbInfo *active_db = &active_cluster->dbarr.dbs[dbnum]; - PGconn *conn = connectToServer(active_db->db_name, whichCluster); + DbInfo *active_db = &cluster->dbarr.dbs[dbnum]; + PGconn *conn = connectToServer(cluster, active_db->db_name); /* find bpchar_pattern_ops indexes */ @@ -602,9 +595,8 @@ old_8_3_invalidate_bpchar_pattern_ops_indexes(bool check_mode, * server, even in link mode. */ char * -old_8_3_create_sequence_script(Cluster whichCluster) +old_8_3_create_sequence_script(ClusterInfo *cluster) { - ClusterInfo *active_cluster = ACTIVE_CLUSTER(whichCluster); int dbnum; FILE *script = NULL; bool found = false; @@ -614,7 +606,7 @@ old_8_3_create_sequence_script(Cluster whichCluster) prep_status("Creating script to adjust sequences"); - for (dbnum = 0; dbnum < active_cluster->dbarr.ndbs; dbnum++) + for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) { PGresult *res; bool db_used = false; @@ -622,8 +614,8 @@ old_8_3_create_sequence_script(Cluster whichCluster) int rowno; int i_nspname, i_relname; - DbInfo *active_db = &active_cluster->dbarr.dbs[dbnum]; - PGconn *conn = connectToServer(active_db->db_name, whichCluster); + DbInfo *active_db = &cluster->dbarr.dbs[dbnum]; + PGconn *conn = connectToServer(cluster, active_db->db_name); /* Find any sequences */ res = executeQueryOrDie(conn, -- 2.40.0