Header And Logo

PostgreSQL
| The world's most advanced open source database.

tablespace.c

Go to the documentation of this file.
00001 /*
00002  *  tablespace.c
00003  *
00004  *  tablespace functions
00005  *
00006  *  Copyright (c) 2010-2013, PostgreSQL Global Development Group
00007  *  contrib/pg_upgrade/tablespace.c
00008  */
00009 
00010 #include "postgres_fe.h"
00011 
00012 #include "pg_upgrade.h"
00013 
00014 static void get_tablespace_paths(void);
00015 static void set_tablespace_directory_suffix(ClusterInfo *cluster);
00016 
00017 
00018 void
00019 init_tablespaces(void)
00020 {
00021     get_tablespace_paths();
00022 
00023     set_tablespace_directory_suffix(&old_cluster);
00024     set_tablespace_directory_suffix(&new_cluster);
00025 
00026     if (os_info.num_old_tablespaces > 0 &&
00027     strcmp(old_cluster.tablespace_suffix, new_cluster.tablespace_suffix) == 0)
00028         pg_log(PG_FATAL,
00029                "Cannot upgrade to/from the same system catalog version when\n"
00030                "using tablespaces.\n");
00031 }
00032 
00033 
00034 /*
00035  * get_tablespace_paths()
00036  *
00037  * Scans pg_tablespace and returns a malloc'ed array of all tablespace
00038  * paths. Its the caller's responsibility to free the array.
00039  */
00040 static void
00041 get_tablespace_paths(void)
00042 {
00043     PGconn     *conn = connectToServer(&old_cluster, "template1");
00044     PGresult   *res;
00045     int         tblnum;
00046     int         i_spclocation;
00047     char        query[QUERY_ALLOC];
00048 
00049     snprintf(query, sizeof(query),
00050              "SELECT    %s "
00051              "FROM  pg_catalog.pg_tablespace "
00052              "WHERE spcname != 'pg_default' AND "
00053              "      spcname != 'pg_global'",
00054     /* 9.2 removed the spclocation column */
00055              (GET_MAJOR_VERSION(old_cluster.major_version) <= 901) ?
00056     "spclocation" : "pg_catalog.pg_tablespace_location(oid) AS spclocation");
00057 
00058     res = executeQueryOrDie(conn, "%s", query);
00059 
00060     if ((os_info.num_old_tablespaces = PQntuples(res)) != 0)
00061         os_info.old_tablespaces = (char **) pg_malloc(
00062                                    os_info.num_old_tablespaces * sizeof(char *));
00063     else
00064         os_info.old_tablespaces = NULL;
00065 
00066     i_spclocation = PQfnumber(res, "spclocation");
00067 
00068     for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
00069         os_info.old_tablespaces[tblnum] = pg_strdup(
00070                                      PQgetvalue(res, tblnum, i_spclocation));
00071 
00072     PQclear(res);
00073 
00074     PQfinish(conn);
00075 
00076     return;
00077 }
00078 
00079 
00080 static void
00081 set_tablespace_directory_suffix(ClusterInfo *cluster)
00082 {
00083     if (GET_MAJOR_VERSION(cluster->major_version) <= 804)
00084         cluster->tablespace_suffix = pg_strdup("");
00085     else
00086     {
00087         /* This cluster has a version-specific subdirectory */
00088         cluster->tablespace_suffix = pg_malloc(4 +
00089                                          strlen(cluster->major_version_str) +
00090                                                10 /* OIDCHARS */ + 1);
00091 
00092         /* The leading slash is needed to start a new directory. */
00093         sprintf(cluster->tablespace_suffix, "/PG_%s_%d", cluster->major_version_str,
00094                 cluster->controldata.cat_ver);
00095     }
00096 }