PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
info.c
Go to the documentation of this file.
1 /*
2  * info.c
3  *
4  * information support functions
5  *
6  * Copyright (c) 2010-2017, PostgreSQL Global Development Group
7  * src/bin/pg_upgrade/info.c
8  */
9 
10 #include "postgres_fe.h"
11 
12 #include "pg_upgrade.h"
13 
14 #include "access/transam.h"
15 
16 
17 static void create_rel_filename_map(const char *old_data, const char *new_data,
18  const DbInfo *old_db, const DbInfo *new_db,
19  const RelInfo *old_rel, const RelInfo *new_rel,
20  FileNameMap *map);
21 static void report_unmatched_relation(const RelInfo *rel, const DbInfo *db,
22  bool is_new_db);
23 static void free_db_and_rel_infos(DbInfoArr *db_arr);
24 static void get_db_infos(ClusterInfo *cluster);
25 static void get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo);
26 static void free_rel_infos(RelInfoArr *rel_arr);
27 static void print_db_infos(DbInfoArr *dbinfo);
28 static void print_rel_infos(RelInfoArr *rel_arr);
29 
30 
31 /*
32  * gen_db_file_maps()
33  *
34  * generates a database mapping from "old_db" to "new_db".
35  *
36  * Returns a malloc'ed array of mappings. The length of the array
37  * is returned into *nmaps.
38  */
40 gen_db_file_maps(DbInfo *old_db, DbInfo *new_db,
41  int *nmaps,
42  const char *old_pgdata, const char *new_pgdata)
43 {
45  int old_relnum,
46  new_relnum;
47  int num_maps = 0;
48  bool all_matched = true;
49 
50  /* There will certainly not be more mappings than there are old rels */
51  maps = (FileNameMap *) pg_malloc(sizeof(FileNameMap) *
52  old_db->rel_arr.nrels);
53 
54  /*
55  * Each of the RelInfo arrays should be sorted by OID. Scan through them
56  * and match them up. If we fail to match everything, we'll abort, but
57  * first print as much info as we can about mismatches.
58  */
59  old_relnum = new_relnum = 0;
60  while (old_relnum < old_db->rel_arr.nrels ||
61  new_relnum < new_db->rel_arr.nrels)
62  {
63  RelInfo *old_rel = (old_relnum < old_db->rel_arr.nrels) ?
64  &old_db->rel_arr.rels[old_relnum] : NULL;
65  RelInfo *new_rel = (new_relnum < new_db->rel_arr.nrels) ?
66  &new_db->rel_arr.rels[new_relnum] : NULL;
67 
68  /* handle running off one array before the other */
69  if (!new_rel)
70  {
71  /*
72  * old_rel is unmatched. This should never happen, because we
73  * force new rels to have TOAST tables if the old one did.
74  */
75  report_unmatched_relation(old_rel, old_db, false);
76  all_matched = false;
77  old_relnum++;
78  continue;
79  }
80  if (!old_rel)
81  {
82  /*
83  * new_rel is unmatched. This shouldn't really happen either, but
84  * if it's a TOAST table, we can ignore it and continue
85  * processing, assuming that the new server made a TOAST table
86  * that wasn't needed.
87  */
88  if (strcmp(new_rel->nspname, "pg_toast") != 0)
89  {
90  report_unmatched_relation(new_rel, new_db, true);
91  all_matched = false;
92  }
93  new_relnum++;
94  continue;
95  }
96 
97  /* check for mismatched OID */
98  if (old_rel->reloid < new_rel->reloid)
99  {
100  /* old_rel is unmatched, see comment above */
101  report_unmatched_relation(old_rel, old_db, false);
102  all_matched = false;
103  old_relnum++;
104  continue;
105  }
106  else if (old_rel->reloid > new_rel->reloid)
107  {
108  /* new_rel is unmatched, see comment above */
109  if (strcmp(new_rel->nspname, "pg_toast") != 0)
110  {
111  report_unmatched_relation(new_rel, new_db, true);
112  all_matched = false;
113  }
114  new_relnum++;
115  continue;
116  }
117 
118  /*
119  * Verify that rels of same OID have same name. The namespace name
120  * should always match, but the relname might not match for TOAST
121  * tables (and, therefore, their indexes).
122  *
123  * TOAST table names initially match the heap pg_class oid, but
124  * pre-9.0 they can change during certain commands such as CLUSTER, so
125  * don't insist on a match if old cluster is < 9.0.
126  */
127  if (strcmp(old_rel->nspname, new_rel->nspname) != 0 ||
128  (strcmp(old_rel->relname, new_rel->relname) != 0 &&
130  strcmp(old_rel->nspname, "pg_toast") != 0)))
131  {
132  pg_log(PG_WARNING, "Relation names for OID %u in database \"%s\" do not match: "
133  "old name \"%s.%s\", new name \"%s.%s\"\n",
134  old_rel->reloid, old_db->db_name,
135  old_rel->nspname, old_rel->relname,
136  new_rel->nspname, new_rel->relname);
137  all_matched = false;
138  old_relnum++;
139  new_relnum++;
140  continue;
141  }
142 
143  /* OK, create a mapping entry */
144  create_rel_filename_map(old_pgdata, new_pgdata, old_db, new_db,
145  old_rel, new_rel, maps + num_maps);
146  num_maps++;
147  old_relnum++;
148  new_relnum++;
149  }
150 
151  if (!all_matched)
152  pg_fatal("Failed to match up old and new tables in database \"%s\"\n",
153  old_db->db_name);
154 
155  *nmaps = num_maps;
156  return maps;
157 }
158 
159 
160 /*
161  * create_rel_filename_map()
162  *
163  * fills a file node map structure and returns it in "map".
164  */
165 static void
166 create_rel_filename_map(const char *old_data, const char *new_data,
167  const DbInfo *old_db, const DbInfo *new_db,
168  const RelInfo *old_rel, const RelInfo *new_rel,
169  FileNameMap *map)
170 {
171  /* In case old/new tablespaces don't match, do them separately. */
172  if (strlen(old_rel->tablespace) == 0)
173  {
174  /*
175  * relation belongs to the default tablespace, hence relfiles should
176  * exist in the data directories.
177  */
178  map->old_tablespace = old_data;
179  map->old_tablespace_suffix = "/base";
180  }
181  else
182  {
183  /* relation belongs to a tablespace, so use the tablespace location */
184  map->old_tablespace = old_rel->tablespace;
186  }
187 
188  /* Do the same for new tablespaces */
189  if (strlen(new_rel->tablespace) == 0)
190  {
191  map->new_tablespace = new_data;
192  map->new_tablespace_suffix = "/base";
193  }
194  else
195  {
196  map->new_tablespace = new_rel->tablespace;
198  }
199 
200  map->old_db_oid = old_db->db_oid;
201  map->new_db_oid = new_db->db_oid;
202 
203  /*
204  * old_relfilenode might differ from pg_class.oid (and hence
205  * new_relfilenode) because of CLUSTER, REINDEX, or VACUUM FULL.
206  */
207  map->old_relfilenode = old_rel->relfilenode;
208 
209  /* new_relfilenode will match old and new pg_class.oid */
210  map->new_relfilenode = new_rel->relfilenode;
211 
212  /* used only for logging and error reporing, old/new are identical */
213  map->nspname = old_rel->nspname;
214  map->relname = old_rel->relname;
215 }
216 
217 
218 /*
219  * Complain about a relation we couldn't match to the other database,
220  * identifying it as best we can.
221  */
222 static void
223 report_unmatched_relation(const RelInfo *rel, const DbInfo *db, bool is_new_db)
224 {
225  Oid reloid = rel->reloid; /* we might change rel below */
226  char reldesc[1000];
227  int i;
228 
229  snprintf(reldesc, sizeof(reldesc), "\"%s.%s\"",
230  rel->nspname, rel->relname);
231  if (rel->indtable)
232  {
233  for (i = 0; i < db->rel_arr.nrels; i++)
234  {
235  const RelInfo *hrel = &db->rel_arr.rels[i];
236 
237  if (hrel->reloid == rel->indtable)
238  {
239  snprintf(reldesc + strlen(reldesc),
240  sizeof(reldesc) - strlen(reldesc),
241  _(" which is an index on \"%s.%s\""),
242  hrel->nspname, hrel->relname);
243  /* Shift attention to index's table for toast check */
244  rel = hrel;
245  break;
246  }
247  }
248  if (i >= db->rel_arr.nrels)
249  snprintf(reldesc + strlen(reldesc),
250  sizeof(reldesc) - strlen(reldesc),
251  _(" which is an index on OID %u"), rel->indtable);
252  }
253  if (rel->toastheap)
254  {
255  for (i = 0; i < db->rel_arr.nrels; i++)
256  {
257  const RelInfo *brel = &db->rel_arr.rels[i];
258 
259  if (brel->reloid == rel->toastheap)
260  {
261  snprintf(reldesc + strlen(reldesc),
262  sizeof(reldesc) - strlen(reldesc),
263  _(" which is the TOAST table for \"%s.%s\""),
264  brel->nspname, brel->relname);
265  break;
266  }
267  }
268  if (i >= db->rel_arr.nrels)
269  snprintf(reldesc + strlen(reldesc),
270  sizeof(reldesc) - strlen(reldesc),
271  _(" which is the TOAST table for OID %u"), rel->toastheap);
272  }
273 
274  if (is_new_db)
275  pg_log(PG_WARNING, "No match found in old cluster for new relation with OID %u in database \"%s\": %s\n",
276  reloid, db->db_name, reldesc);
277  else
278  pg_log(PG_WARNING, "No match found in new cluster for old relation with OID %u in database \"%s\": %s\n",
279  reloid, db->db_name, reldesc);
280 }
281 
282 
283 void
284 print_maps(FileNameMap *maps, int n_maps, const char *db_name)
285 {
286  if (log_opts.verbose)
287  {
288  int mapnum;
289 
290  pg_log(PG_VERBOSE, "mappings for database \"%s\":\n", db_name);
291 
292  for (mapnum = 0; mapnum < n_maps; mapnum++)
293  pg_log(PG_VERBOSE, "%s.%s: %u to %u\n",
294  maps[mapnum].nspname, maps[mapnum].relname,
295  maps[mapnum].old_relfilenode,
296  maps[mapnum].new_relfilenode);
297 
298  pg_log(PG_VERBOSE, "\n\n");
299  }
300 }
301 
302 
303 /*
304  * get_db_and_rel_infos()
305  *
306  * higher level routine to generate dbinfos for the database running
307  * on the given "port". Assumes that server is already running.
308  */
309 void
311 {
312  int dbnum;
313 
314  if (cluster->dbarr.dbs != NULL)
315  free_db_and_rel_infos(&cluster->dbarr);
316 
317  get_db_infos(cluster);
318 
319  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
320  get_rel_infos(cluster, &cluster->dbarr.dbs[dbnum]);
321 
322  pg_log(PG_VERBOSE, "\n%s databases:\n", CLUSTER_NAME(cluster));
323  if (log_opts.verbose)
324  print_db_infos(&cluster->dbarr);
325 }
326 
327 
328 /*
329  * get_db_infos()
330  *
331  * Scans pg_database system catalog and populates all user
332  * databases.
333  */
334 static void
336 {
337  PGconn *conn = connectToServer(cluster, "template1");
338  PGresult *res;
339  int ntups;
340  int tupnum;
341  DbInfo *dbinfos;
342  int i_datname,
343  i_oid,
344  i_encoding,
345  i_datcollate,
346  i_datctype,
347  i_spclocation;
348  char query[QUERY_ALLOC];
349 
350  snprintf(query, sizeof(query),
351  "SELECT d.oid, d.datname, d.encoding, d.datcollate, d.datctype, "
352  "%s AS spclocation "
353  "FROM pg_catalog.pg_database d "
354  " LEFT OUTER JOIN pg_catalog.pg_tablespace t "
355  " ON d.dattablespace = t.oid "
356  "WHERE d.datallowconn = true "
357  /* we don't preserve pg_database.oid so we sort by name */
358  "ORDER BY 2",
359  /* 9.2 removed the spclocation column */
360  (GET_MAJOR_VERSION(cluster->major_version) <= 901) ?
361  "t.spclocation" : "pg_catalog.pg_tablespace_location(t.oid)");
362 
363  res = executeQueryOrDie(conn, "%s", query);
364 
365  i_oid = PQfnumber(res, "oid");
366  i_datname = PQfnumber(res, "datname");
367  i_encoding = PQfnumber(res, "encoding");
368  i_datcollate = PQfnumber(res, "datcollate");
369  i_datctype = PQfnumber(res, "datctype");
370  i_spclocation = PQfnumber(res, "spclocation");
371 
372  ntups = PQntuples(res);
373  dbinfos = (DbInfo *) pg_malloc(sizeof(DbInfo) * ntups);
374 
375  for (tupnum = 0; tupnum < ntups; tupnum++)
376  {
377  dbinfos[tupnum].db_oid = atooid(PQgetvalue(res, tupnum, i_oid));
378  dbinfos[tupnum].db_name = pg_strdup(PQgetvalue(res, tupnum, i_datname));
379  dbinfos[tupnum].db_encoding = atoi(PQgetvalue(res, tupnum, i_encoding));
380  dbinfos[tupnum].db_collate = pg_strdup(PQgetvalue(res, tupnum, i_datcollate));
381  dbinfos[tupnum].db_ctype = pg_strdup(PQgetvalue(res, tupnum, i_datctype));
382  snprintf(dbinfos[tupnum].db_tablespace, sizeof(dbinfos[tupnum].db_tablespace), "%s",
383  PQgetvalue(res, tupnum, i_spclocation));
384  }
385  PQclear(res);
386 
387  PQfinish(conn);
388 
389  cluster->dbarr.dbs = dbinfos;
390  cluster->dbarr.ndbs = ntups;
391 }
392 
393 
394 /*
395  * get_rel_infos()
396  *
397  * gets the relinfos for all the user tables and indexes of the database
398  * referred to by "dbinfo".
399  *
400  * Note: the resulting RelInfo array is assumed to be sorted by OID.
401  * This allows later processing to match up old and new databases efficiently.
402  */
403 static void
405 {
406  PGconn *conn = connectToServer(cluster,
407  dbinfo->db_name);
408  PGresult *res;
409  RelInfo *relinfos;
410  int ntups;
411  int relnum;
412  int num_rels = 0;
413  char *nspname = NULL;
414  char *relname = NULL;
415  char *tablespace = NULL;
416  int i_spclocation,
417  i_nspname,
418  i_relname,
419  i_reloid,
420  i_indtable,
421  i_toastheap,
422  i_relfilenode,
423  i_reltablespace;
424  char query[QUERY_ALLOC];
425  char *last_namespace = NULL,
426  *last_tablespace = NULL;
427 
428  query[0] = '\0'; /* initialize query string to empty */
429 
430  /*
431  * Create a CTE that collects OIDs of regular user tables, including
432  * matviews and sequences, but excluding toast tables and indexes. We
433  * assume that relations with OIDs >= FirstNormalObjectId belong to the
434  * user. (That's probably redundant with the namespace-name exclusions,
435  * but let's be safe.)
436  *
437  * pg_largeobject contains user data that does not appear in pg_dump
438  * output, so we have to copy that system table. It's easiest to do that
439  * by treating it as a user table. Likewise for pg_largeobject_metadata,
440  * if it exists.
441  */
442  snprintf(query + strlen(query), sizeof(query) - strlen(query),
443  "WITH regular_heap (reloid, indtable, toastheap) AS ( "
444  " SELECT c.oid, 0::oid, 0::oid "
445  " FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n "
446  " ON c.relnamespace = n.oid "
447  " WHERE relkind IN ('r', 'm') AND "
448  /* exclude possible orphaned temp tables */
449  " ((n.nspname !~ '^pg_temp_' AND "
450  " n.nspname !~ '^pg_toast_temp_' AND "
451  " n.nspname NOT IN ('pg_catalog', 'information_schema', "
452  " 'binary_upgrade', 'pg_toast') AND "
453  " c.oid >= %u::pg_catalog.oid) OR "
454  " (n.nspname = 'pg_catalog' AND "
455  " relname IN ('pg_largeobject'%s) ))), ",
458  ", 'pg_largeobject_metadata'" : "");
459 
460  /*
461  * Add a CTE that collects OIDs of toast tables belonging to the tables
462  * selected by the regular_heap CTE. (We have to do this separately
463  * because the namespace-name rules above don't work for toast tables.)
464  */
465  snprintf(query + strlen(query), sizeof(query) - strlen(query),
466  " toast_heap (reloid, indtable, toastheap) AS ( "
467  " SELECT c.reltoastrelid, 0::oid, c.oid "
468  " FROM regular_heap JOIN pg_catalog.pg_class c "
469  " ON regular_heap.reloid = c.oid "
470  " WHERE c.reltoastrelid != 0), ");
471 
472  /*
473  * Add a CTE that collects OIDs of all valid indexes on the previously
474  * selected tables. We can ignore invalid indexes since pg_dump does.
475  * Testing indisready is necessary in 9.2, and harmless in earlier/later
476  * versions.
477  */
478  snprintf(query + strlen(query), sizeof(query) - strlen(query),
479  " all_index (reloid, indtable, toastheap) AS ( "
480  " SELECT indexrelid, indrelid, 0::oid "
481  " FROM pg_catalog.pg_index "
482  " WHERE indisvalid AND indisready "
483  " AND indrelid IN "
484  " (SELECT reloid FROM regular_heap "
485  " UNION ALL "
486  " SELECT reloid FROM toast_heap)) ");
487 
488  /*
489  * And now we can write the query that retrieves the data we want for each
490  * heap and index relation. Make sure result is sorted by OID.
491  */
492  snprintf(query + strlen(query), sizeof(query) - strlen(query),
493  "SELECT all_rels.*, n.nspname, c.relname, "
494  " c.relfilenode, c.reltablespace, %s "
495  "FROM (SELECT * FROM regular_heap "
496  " UNION ALL "
497  " SELECT * FROM toast_heap "
498  " UNION ALL "
499  " SELECT * FROM all_index) all_rels "
500  " JOIN pg_catalog.pg_class c "
501  " ON all_rels.reloid = c.oid "
502  " JOIN pg_catalog.pg_namespace n "
503  " ON c.relnamespace = n.oid "
504  " LEFT OUTER JOIN pg_catalog.pg_tablespace t "
505  " ON c.reltablespace = t.oid "
506  "ORDER BY 1;",
507  /* 9.2 removed the pg_tablespace.spclocation column */
508  (GET_MAJOR_VERSION(cluster->major_version) >= 902) ?
509  "pg_catalog.pg_tablespace_location(t.oid) AS spclocation" :
510  "t.spclocation");
511 
512  res = executeQueryOrDie(conn, "%s", query);
513 
514  ntups = PQntuples(res);
515 
516  relinfos = (RelInfo *) pg_malloc(sizeof(RelInfo) * ntups);
517 
518  i_reloid = PQfnumber(res, "reloid");
519  i_indtable = PQfnumber(res, "indtable");
520  i_toastheap = PQfnumber(res, "toastheap");
521  i_nspname = PQfnumber(res, "nspname");
522  i_relname = PQfnumber(res, "relname");
523  i_relfilenode = PQfnumber(res, "relfilenode");
524  i_reltablespace = PQfnumber(res, "reltablespace");
525  i_spclocation = PQfnumber(res, "spclocation");
526 
527  for (relnum = 0; relnum < ntups; relnum++)
528  {
529  RelInfo *curr = &relinfos[num_rels++];
530 
531  curr->reloid = atooid(PQgetvalue(res, relnum, i_reloid));
532  curr->indtable = atooid(PQgetvalue(res, relnum, i_indtable));
533  curr->toastheap = atooid(PQgetvalue(res, relnum, i_toastheap));
534 
535  nspname = PQgetvalue(res, relnum, i_nspname);
536  curr->nsp_alloc = false;
537 
538  /*
539  * Many of the namespace and tablespace strings are identical, so we
540  * try to reuse the allocated string pointers where possible to reduce
541  * memory consumption.
542  */
543  /* Can we reuse the previous string allocation? */
544  if (last_namespace && strcmp(nspname, last_namespace) == 0)
545  curr->nspname = last_namespace;
546  else
547  {
548  last_namespace = curr->nspname = pg_strdup(nspname);
549  curr->nsp_alloc = true;
550  }
551 
552  relname = PQgetvalue(res, relnum, i_relname);
553  curr->relname = pg_strdup(relname);
554 
555  curr->relfilenode = atooid(PQgetvalue(res, relnum, i_relfilenode));
556  curr->tblsp_alloc = false;
557 
558  /* Is the tablespace oid non-default? */
559  if (atooid(PQgetvalue(res, relnum, i_reltablespace)) != 0)
560  {
561  /*
562  * The tablespace location might be "", meaning the cluster
563  * default location, i.e. pg_default or pg_global.
564  */
565  tablespace = PQgetvalue(res, relnum, i_spclocation);
566 
567  /* Can we reuse the previous string allocation? */
568  if (last_tablespace && strcmp(tablespace, last_tablespace) == 0)
569  curr->tablespace = last_tablespace;
570  else
571  {
572  last_tablespace = curr->tablespace = pg_strdup(tablespace);
573  curr->tblsp_alloc = true;
574  }
575  }
576  else
577  /* A zero reltablespace oid indicates the database tablespace. */
578  curr->tablespace = dbinfo->db_tablespace;
579  }
580  PQclear(res);
581 
582  PQfinish(conn);
583 
584  dbinfo->rel_arr.rels = relinfos;
585  dbinfo->rel_arr.nrels = num_rels;
586 }
587 
588 
589 static void
591 {
592  int dbnum;
593 
594  for (dbnum = 0; dbnum < db_arr->ndbs; dbnum++)
595  {
596  free_rel_infos(&db_arr->dbs[dbnum].rel_arr);
597  pg_free(db_arr->dbs[dbnum].db_name);
598  }
599  pg_free(db_arr->dbs);
600  db_arr->dbs = NULL;
601  db_arr->ndbs = 0;
602 }
603 
604 
605 static void
607 {
608  int relnum;
609 
610  for (relnum = 0; relnum < rel_arr->nrels; relnum++)
611  {
612  if (rel_arr->rels[relnum].nsp_alloc)
613  pg_free(rel_arr->rels[relnum].nspname);
614  pg_free(rel_arr->rels[relnum].relname);
615  if (rel_arr->rels[relnum].tblsp_alloc)
616  pg_free(rel_arr->rels[relnum].tablespace);
617  }
618  pg_free(rel_arr->rels);
619  rel_arr->nrels = 0;
620 }
621 
622 
623 static void
625 {
626  int dbnum;
627 
628  for (dbnum = 0; dbnum < db_arr->ndbs; dbnum++)
629  {
630  pg_log(PG_VERBOSE, "Database: %s\n", db_arr->dbs[dbnum].db_name);
631  print_rel_infos(&db_arr->dbs[dbnum].rel_arr);
632  pg_log(PG_VERBOSE, "\n\n");
633  }
634 }
635 
636 
637 static void
639 {
640  int relnum;
641 
642  for (relnum = 0; relnum < rel_arr->nrels; relnum++)
643  pg_log(PG_VERBOSE, "relname: %s.%s: reloid: %u reltblspace: %s\n",
644  rel_arr->rels[relnum].nspname,
645  rel_arr->rels[relnum].relname,
646  rel_arr->rels[relnum].reloid,
647  rel_arr->rels[relnum].tablespace);
648 }
Oid old_relfilenode
Definition: pg_upgrade.h:174
uint32 major_version
Definition: pg_upgrade.h:274
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
static void get_db_infos(ClusterInfo *cluster)
Definition: info.c:335
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
char * relname
Definition: pg_upgrade.h:142
FileNameMap * gen_db_file_maps(DbInfo *old_db, DbInfo *new_db, int *nmaps, const char *old_pgdata, const char *new_pgdata)
Definition: info.c:40
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3517
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
bool tblsp_alloc
Definition: pg_upgrade.h:149
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
LogOpts log_opts
Definition: util.c:18
Oid new_db_oid
Definition: pg_upgrade.h:168
unsigned int Oid
Definition: postgres_ext.h:31
Oid reloid
Definition: pg_upgrade.h:143
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
#define QUERY_ALLOC
Definition: logging.c:26
char * nspname
Definition: pg_upgrade.h:141
static void get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo)
Definition: info.c:404
Oid db_oid
Definition: pg_upgrade.h:186
#define FirstNormalObjectId
Definition: transam.h:94
char db_tablespace[MAXPGPATH]
Definition: pg_upgrade.h:188
static void free_rel_infos(RelInfoArr *rel_arr)
Definition: info.c:606
ClusterInfo new_cluster
Definition: pg_upgrade.c:55
char * db_ctype
Definition: pg_upgrade.h:191
void print_maps(FileNameMap *maps, int n_maps, const char *db_name)
Definition: info.c:284
const char * old_tablespace
Definition: pg_upgrade.h:163
Oid new_relfilenode
Definition: pg_upgrade.h:175
PGconn * conn
Definition: streamutil.c:45
RelInfo * rels
Definition: pg_upgrade.h:154
Oid relfilenode
Definition: pg_upgrade.h:144
#define CLUSTER_NAME(cluster)
Definition: pg_upgrade.h:97
char * tablespace
Definition: pgbench.c:146
ClusterInfo old_cluster
Definition: pg_upgrade.c:55
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void cluster(ClusterStmt *stmt, bool isTopLevel)
Definition: cluster.c:106
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void print_db_infos(DbInfoArr *dbinfo)
Definition: info.c:624
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
const char * old_tablespace_suffix
Definition: pg_upgrade.h:165
Oid indtable
Definition: pg_upgrade.h:145
bool verbose
Definition: pg_upgrade.h:287
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:2781
static void report_unmatched_relation(const RelInfo *rel, const DbInfo *db, bool is_new_db)
Definition: info.c:223
const char * tablespace_suffix
Definition: pg_upgrade.h:277
void PQclear(PGresult *res)
Definition: fe-exec.c:650
DbInfoArr dbarr
Definition: pg_upgrade.h:265
Oid old_db_oid
Definition: pg_upgrade.h:167
#define NULL
Definition: c.h:226
RelInfoArr rel_arr
Definition: pg_upgrade.h:193
void get_db_and_rel_infos(ClusterInfo *cluster)
Definition: info.c:310
static const pg_conv_map maps[]
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)
Definition: info.c:166
void pg_free(void *ptr)
Definition: fe_memutils.c:105
char * nspname
Definition: pg_upgrade.h:177
int db_encoding
Definition: pg_upgrade.h:192
static void print_rel_infos(RelInfoArr *rel_arr)
Definition: info.c:638
static void free_db_and_rel_infos(DbInfoArr *db_arr)
Definition: info.c:590
#define atooid(x)
Definition: lo.c:17
int i
char * tablespace
Definition: pg_upgrade.h:147
bool nsp_alloc
Definition: pg_upgrade.h:148
char * db_name
Definition: pg_upgrade.h:187
char * db_collate
Definition: pg_upgrade.h:190
DbInfo * dbs
Definition: pg_upgrade.h:198
const char * new_tablespace
Definition: pg_upgrade.h:164
#define _(x)
Definition: elog.c:84
const char * new_tablespace_suffix
Definition: pg_upgrade.h:166
char * relname
Definition: pg_upgrade.h:178
Oid toastheap
Definition: pg_upgrade.h:146