PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
version.c File Reference
#include "postgres_fe.h"
#include "pg_upgrade.h"
#include "fe_utils/string_utils.h"
Include dependency graph for version.c:

Go to the source code of this file.

Functions

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)
 
void old_9_6_check_for_unknown_data_type_usage (ClusterInfo *cluster)
 

Function Documentation

void new_9_0_populate_pg_largeobject_metadata ( ClusterInfo cluster,
bool  check_mode 
)

Definition at line 23 of file version.c.

References appendPsqlMetaConnect(), check_ok(), conn, connectToServer(), PQExpBufferData::data, DbInfo::db_name, ClusterInfo::dbarr, DbInfoArr::dbs, executeQueryOrDie(), fopen_priv(), initPQExpBuffer(), MAXPGPATH, DbInfoArr::ndbs, NULL, pg_fatal(), pg_log(), PG_WARNING, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), prep_status(), report_status(), snprintf(), strerror(), and termPQExpBuffer().

Referenced by check_and_dump_old_cluster(), and issue_warnings().

24 {
25  int dbnum;
26  FILE *script = NULL;
27  bool found = false;
28  char output_path[MAXPGPATH];
29 
30  prep_status("Checking for large objects");
31 
32  snprintf(output_path, sizeof(output_path), "pg_largeobject.sql");
33 
34  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
35  {
36  PGresult *res;
37  int i_count;
38  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
39  PGconn *conn = connectToServer(cluster, active_db->db_name);
40 
41  /* find if there are any large objects */
42  res = executeQueryOrDie(conn,
43  "SELECT count(*) "
44  "FROM pg_catalog.pg_largeobject ");
45 
46  i_count = PQfnumber(res, "count");
47  if (atoi(PQgetvalue(res, 0, i_count)) != 0)
48  {
49  found = true;
50  if (!check_mode)
51  {
52  PQExpBufferData connectbuf;
53 
54  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
55  pg_fatal("could not open file \"%s\": %s\n", output_path,
56  strerror(errno));
57 
58  initPQExpBuffer(&connectbuf);
59  appendPsqlMetaConnect(&connectbuf, active_db->db_name);
60  fputs(connectbuf.data, script);
61  termPQExpBuffer(&connectbuf);
62 
63  fprintf(script,
64  "SELECT pg_catalog.lo_create(t.loid)\n"
65  "FROM (SELECT DISTINCT loid FROM pg_catalog.pg_largeobject) AS t;\n");
66  }
67  }
68 
69  PQclear(res);
70  PQfinish(conn);
71  }
72 
73  if (script)
74  fclose(script);
75 
76  if (found)
77  {
78  report_status(PG_WARNING, "warning");
79  if (check_mode)
80  pg_log(PG_WARNING, "\n"
81  "Your installation contains large objects. The new database has an\n"
82  "additional large object permission table. After upgrading, you will be\n"
83  "given a command to populate the pg_largeobject permission table with\n"
84  "default permissions.\n\n");
85  else
86  pg_log(PG_WARNING, "\n"
87  "Your installation contains large objects. The new database has an\n"
88  "additional large object permission table, so default permissions must be\n"
89  "defined for all large objects. The file\n"
90  " %s\n"
91  "when executed by psql by the database superuser will set the default\n"
92  "permissions.\n\n",
93  output_path);
94  }
95  else
96  check_ok();
97 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3516
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
FILE * fopen_priv(const char *path, const char *mode)
Definition: file.c:321
void appendPsqlMetaConnect(PQExpBuffer buf, const char *dbname)
Definition: string_utils.c:581
PGconn * conn
Definition: streamutil.c:42
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void check_ok(void)
Definition: initdb.c:1987
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:2781
void PQclear(PGresult *res)
Definition: fe-exec.c:650
DbInfoArr dbarr
Definition: pg_upgrade.h:265
#define NULL
Definition: c.h:226
const char * strerror(int errnum)
Definition: strerror.c:19
void report_status(eLogType type, const char *fmt,...) pg_attribute_printf(2
char * db_name
Definition: pg_upgrade.h:187
DbInfo * dbs
Definition: pg_upgrade.h:198
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
void old_9_3_check_for_line_data_type_usage ( ClusterInfo cluster)

Definition at line 109 of file version.c.

References check_ok(), conn, connectToServer(), DbInfo::db_name, ClusterInfo::dbarr, DbInfoArr::dbs, executeQueryOrDie(), fopen_priv(), MAXPGPATH, DbInfoArr::ndbs, NULL, pg_fatal(), pg_log(), PG_REPORT, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), prep_status(), snprintf(), and strerror().

Referenced by check_and_dump_old_cluster().

110 {
111  int dbnum;
112  FILE *script = NULL;
113  bool found = false;
114  char output_path[MAXPGPATH];
115 
116  prep_status("Checking for invalid \"line\" user columns");
117 
118  snprintf(output_path, sizeof(output_path), "tables_using_line.txt");
119 
120  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
121  {
122  PGresult *res;
123  bool db_used = false;
124  int ntups;
125  int rowno;
126  int i_nspname,
127  i_relname,
128  i_attname;
129  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
130  PGconn *conn = connectToServer(cluster, active_db->db_name);
131 
132  res = executeQueryOrDie(conn,
133  "SELECT n.nspname, c.relname, a.attname "
134  "FROM pg_catalog.pg_class c, "
135  " pg_catalog.pg_namespace n, "
136  " pg_catalog.pg_attribute a "
137  "WHERE c.oid = a.attrelid AND "
138  " NOT a.attisdropped AND "
139  " a.atttypid = 'pg_catalog.line'::pg_catalog.regtype AND "
140  " c.relnamespace = n.oid AND "
141  /* exclude possible orphaned temp tables */
142  " n.nspname !~ '^pg_temp_' AND "
143  " n.nspname !~ '^pg_toast_temp_' AND "
144  " n.nspname NOT IN ('pg_catalog', 'information_schema')");
145 
146  ntups = PQntuples(res);
147  i_nspname = PQfnumber(res, "nspname");
148  i_relname = PQfnumber(res, "relname");
149  i_attname = PQfnumber(res, "attname");
150  for (rowno = 0; rowno < ntups; rowno++)
151  {
152  found = true;
153  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
154  pg_fatal("could not open file \"%s\": %s\n", output_path,
155  strerror(errno));
156  if (!db_used)
157  {
158  fprintf(script, "Database: %s\n", active_db->db_name);
159  db_used = true;
160  }
161  fprintf(script, " %s.%s.%s\n",
162  PQgetvalue(res, rowno, i_nspname),
163  PQgetvalue(res, rowno, i_relname),
164  PQgetvalue(res, rowno, i_attname));
165  }
166 
167  PQclear(res);
168 
169  PQfinish(conn);
170  }
171 
172  if (script)
173  fclose(script);
174 
175  if (found)
176  {
177  pg_log(PG_REPORT, "fatal\n");
178  pg_fatal("Your installation contains the \"line\" data type in user tables. This\n"
179  "data type changed its internal and input/output format between your old\n"
180  "and new clusters so this cluster cannot currently be upgraded. You can\n"
181  "remove the problem tables and restart the upgrade. A list of the problem\n"
182  "columns is in the file:\n"
183  " %s\n\n", output_path);
184  }
185  else
186  check_ok();
187 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3516
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
FILE * fopen_priv(const char *path, const char *mode)
Definition: file.c:321
PGconn * conn
Definition: streamutil.c:42
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void check_ok(void)
Definition: initdb.c:1987
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:2781
void PQclear(PGresult *res)
Definition: fe-exec.c:650
DbInfoArr dbarr
Definition: pg_upgrade.h:265
#define NULL
Definition: c.h:226
const char * strerror(int errnum)
Definition: strerror.c:19
char * db_name
Definition: pg_upgrade.h:187
DbInfo * dbs
Definition: pg_upgrade.h:198
void old_9_6_check_for_unknown_data_type_usage ( ClusterInfo cluster)

Definition at line 206 of file version.c.

References check_ok(), conn, connectToServer(), DbInfo::db_name, ClusterInfo::dbarr, DbInfoArr::dbs, executeQueryOrDie(), fopen_priv(), MAXPGPATH, DbInfoArr::ndbs, NULL, pg_fatal(), pg_log(), PG_REPORT, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), prep_status(), snprintf(), and strerror().

Referenced by check_and_dump_old_cluster().

207 {
208  int dbnum;
209  FILE *script = NULL;
210  bool found = false;
211  char output_path[MAXPGPATH];
212 
213  prep_status("Checking for invalid \"unknown\" user columns");
214 
215  snprintf(output_path, sizeof(output_path), "tables_using_unknown.txt");
216 
217  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
218  {
219  PGresult *res;
220  bool db_used = false;
221  int ntups;
222  int rowno;
223  int i_nspname,
224  i_relname,
225  i_attname;
226  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
227  PGconn *conn = connectToServer(cluster, active_db->db_name);
228 
229  res = executeQueryOrDie(conn,
230  "SELECT n.nspname, c.relname, a.attname "
231  "FROM pg_catalog.pg_class c, "
232  " pg_catalog.pg_namespace n, "
233  " pg_catalog.pg_attribute a "
234  "WHERE c.oid = a.attrelid AND "
235  " NOT a.attisdropped AND "
236  " a.atttypid = 'pg_catalog.unknown'::pg_catalog.regtype AND "
237  " c.relkind IN ('r', 'c', 'm') AND "
238  " c.relnamespace = n.oid AND "
239  /* exclude possible orphaned temp tables */
240  " n.nspname !~ '^pg_temp_' AND "
241  " n.nspname !~ '^pg_toast_temp_' AND "
242  " n.nspname NOT IN ('pg_catalog', 'information_schema')");
243 
244  ntups = PQntuples(res);
245  i_nspname = PQfnumber(res, "nspname");
246  i_relname = PQfnumber(res, "relname");
247  i_attname = PQfnumber(res, "attname");
248  for (rowno = 0; rowno < ntups; rowno++)
249  {
250  found = true;
251  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
252  pg_fatal("could not open file \"%s\": %s\n", output_path,
253  strerror(errno));
254  if (!db_used)
255  {
256  fprintf(script, "Database: %s\n", active_db->db_name);
257  db_used = true;
258  }
259  fprintf(script, " %s.%s.%s\n",
260  PQgetvalue(res, rowno, i_nspname),
261  PQgetvalue(res, rowno, i_relname),
262  PQgetvalue(res, rowno, i_attname));
263  }
264 
265  PQclear(res);
266 
267  PQfinish(conn);
268  }
269 
270  if (script)
271  fclose(script);
272 
273  if (found)
274  {
275  pg_log(PG_REPORT, "fatal\n");
276  pg_fatal("Your installation contains the \"unknown\" data type in user tables. This\n"
277  "data type is no longer allowed in tables, so this cluster cannot currently\n"
278  "be upgraded. You can remove the problem tables and restart the upgrade.\n"
279  "A list of the problem columns is in the file:\n"
280  " %s\n\n", output_path);
281  }
282  else
283  check_ok();
284 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3516
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
FILE * fopen_priv(const char *path, const char *mode)
Definition: file.c:321
PGconn * conn
Definition: streamutil.c:42
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void check_ok(void)
Definition: initdb.c:1987
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:2781
void PQclear(PGresult *res)
Definition: fe-exec.c:650
DbInfoArr dbarr
Definition: pg_upgrade.h:265
#define NULL
Definition: c.h:226
const char * strerror(int errnum)
Definition: strerror.c:19
char * db_name
Definition: pg_upgrade.h:187
DbInfo * dbs
Definition: pg_upgrade.h:198