13 #include "catalog/pg_class_d.h"
41 const char *old_pgdata,
const char *new_pgdata)
47 bool all_matched =
true;
58 old_relnum = new_relnum = 0;
59 while (old_relnum < old_db->rel_arr.nrels ||
60 new_relnum < new_db->rel_arr.nrels)
64 RelInfo *new_rel = (new_relnum < new_db->rel_arr.nrels) ?
87 if (strcmp(new_rel->nspname,
"pg_toast") != 0)
97 if (old_rel->
reloid < new_rel->reloid)
105 else if (old_rel->
reloid > new_rel->reloid)
108 if (strcmp(new_rel->nspname,
"pg_toast") != 0)
122 if (strcmp(old_rel->
nspname, new_rel->nspname) != 0 ||
123 strcmp(old_rel->
relname, new_rel->relname) != 0)
125 pg_log(
PG_WARNING,
"Relation names for OID %u in database \"%s\" do not match: "
126 "old name \"%s.%s\", new name \"%s.%s\"\n",
129 new_rel->nspname, new_rel->relname);
138 old_rel, new_rel,
maps + num_maps);
145 pg_fatal(
"Failed to match up old and new tables in database \"%s\"\n",
214 snprintf(reldesc,
sizeof(reldesc),
"\"%s.%s\"",
225 sizeof(reldesc) - strlen(reldesc),
226 _(
" which is an index on \"%s.%s\""),
235 sizeof(reldesc) - strlen(reldesc),
236 _(
" which is an index on OID %u"), rel->
indtable);
247 sizeof(reldesc) - strlen(reldesc),
248 _(
" which is the TOAST table for \"%s.%s\""),
255 sizeof(reldesc) - strlen(reldesc),
256 _(
" which is the TOAST table for OID %u"), rel->
toastheap);
260 pg_log(
PG_WARNING,
"No match found in old cluster for new relation with OID %u in database \"%s\": %s\n",
263 pg_log(
PG_WARNING,
"No match found in new cluster for old relation with OID %u in database \"%s\": %s\n",
278 if (
cluster->dbarr.dbs != NULL)
283 for (dbnum = 0; dbnum <
cluster->dbarr.ndbs; dbnum++)
321 "SELECT d.oid, d.datname, d.encoding, d.datcollate, d.datctype, ");
323 snprintf(query + strlen(query),
sizeof(query) - strlen(query),
324 "'c' AS datlocprovider, NULL AS daticulocale, ");
326 snprintf(query + strlen(query),
sizeof(query) - strlen(query),
327 "datlocprovider, daticulocale, ");
328 snprintf(query + strlen(query),
sizeof(query) - strlen(query),
329 "pg_catalog.pg_tablespace_location(t.oid) AS spclocation "
330 "FROM pg_catalog.pg_database d "
331 " LEFT OUTER JOIN pg_catalog.pg_tablespace t "
332 " ON d.dattablespace = t.oid "
333 "WHERE d.datallowconn = true "
350 for (tupnum = 0; tupnum < ntups; tupnum++)
362 snprintf(dbinfos[tupnum].db_tablespace,
sizeof(dbinfos[tupnum].db_tablespace),
"%s",
393 char *nspname = NULL;
405 char *last_namespace = NULL,
406 *last_tablespace = NULL;
421 snprintf(query + strlen(query),
sizeof(query) - strlen(query),
422 "WITH regular_heap (reloid, indtable, toastheap) AS ( "
423 " SELECT c.oid, 0::oid, 0::oid "
424 " FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n "
425 " ON c.relnamespace = n.oid "
426 " WHERE relkind IN (" CppAsString2(RELKIND_RELATION)
", "
429 " ((n.nspname !~ '^pg_temp_' AND "
430 " n.nspname !~ '^pg_toast_temp_' AND "
431 " n.nspname NOT IN ('pg_catalog', 'information_schema', "
432 " 'binary_upgrade', 'pg_toast') AND "
433 " c.oid >= %u::pg_catalog.oid) OR "
434 " (n.nspname = 'pg_catalog' AND "
435 " relname IN ('pg_largeobject') ))), ",
443 snprintf(query + strlen(query),
sizeof(query) - strlen(query),
444 " toast_heap (reloid, indtable, toastheap) AS ( "
445 " SELECT c.reltoastrelid, 0::oid, c.oid "
446 " FROM regular_heap JOIN pg_catalog.pg_class c "
447 " ON regular_heap.reloid = c.oid "
448 " WHERE c.reltoastrelid != 0), ");
456 snprintf(query + strlen(query),
sizeof(query) - strlen(query),
457 " all_index (reloid, indtable, toastheap) AS ( "
458 " SELECT indexrelid, indrelid, 0::oid "
459 " FROM pg_catalog.pg_index "
460 " WHERE indisvalid AND indisready "
462 " (SELECT reloid FROM regular_heap "
464 " SELECT reloid FROM toast_heap)) ");
470 snprintf(query + strlen(query),
sizeof(query) - strlen(query),
471 "SELECT all_rels.*, n.nspname, c.relname, "
472 " c.relfilenode, c.reltablespace, "
473 " pg_catalog.pg_tablespace_location(t.oid) AS spclocation "
474 "FROM (SELECT * FROM regular_heap "
476 " SELECT * FROM toast_heap "
478 " SELECT * FROM all_index) all_rels "
479 " JOIN pg_catalog.pg_class c "
480 " ON all_rels.reloid = c.oid "
481 " JOIN pg_catalog.pg_namespace n "
482 " ON c.relnamespace = n.oid "
483 " LEFT OUTER JOIN pg_catalog.pg_tablespace t "
484 " ON c.reltablespace = t.oid "
502 for (relnum = 0; relnum < ntups; relnum++)
504 RelInfo *curr = &relinfos[num_rels++];
519 if (last_namespace && strcmp(nspname, last_namespace) == 0)
520 curr->
nspname = last_namespace;
543 if (last_tablespace && strcmp(
tablespace, last_tablespace) == 0)
569 for (dbnum = 0; dbnum < db_arr->
ndbs; dbnum++)
585 for (relnum = 0; relnum < rel_arr->
nrels; relnum++)
603 for (dbnum = 0; dbnum < db_arr->
ndbs; dbnum++)
617 for (relnum = 0; relnum < rel_arr->
nrels; relnum++)
void cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel)
static void PGresult * res
void PQfinish(PGconn *conn)
void PQclear(PGresult *res)
int PQntuples(const PGresult *res)
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
int PQfnumber(const PGresult *res, const char *field_name)
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
char * pg_strdup(const char *in)
void * pg_malloc(size_t size)
static void print_db_infos(DbInfoArr *dbinfo)
static void report_unmatched_relation(const RelInfo *rel, const DbInfo *db, bool is_new_db)
static void get_db_infos(ClusterInfo *cluster)
static void free_rel_infos(RelInfoArr *rel_arr)
static void print_rel_infos(RelInfoArr *rel_arr)
static void create_rel_filename_map(const char *old_data, const char *new_data, const DbInfo *old_db, const DbInfo *new_db, const RelInfo *old_rel, const RelInfo *new_rel, FileNameMap *map)
FileNameMap * gen_db_file_maps(DbInfo *old_db, DbInfo *new_db, int *nmaps, const char *old_pgdata, const char *new_pgdata)
static void free_db_and_rel_infos(DbInfoArr *db_arr)
void get_db_and_rel_infos(ClusterInfo *cluster)
static void get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo)
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
#define GET_MAJOR_VERSION(v)
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
const char * tablespace_suffix
char db_tablespace[MAXPGPATH]
const char * new_tablespace
const char * old_tablespace_suffix
const char * old_tablespace
const char * new_tablespace_suffix
#define FirstNormalObjectId
static const pg_conv_map maps[]