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 "catalog/pg_class.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 25 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().

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

Definition at line 111 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().

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

Definition at line 208 of file version.c.

References check_ok(), conn, connectToServer(), CppAsString2, 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(), RELKIND_COMPOSITE_TYPE, RELKIND_MATVIEW, RELKIND_RELATION, snprintf(), and strerror().

Referenced by check_and_dump_old_cluster().

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