diff --git a/contrib/pg_upgrade/info.c b/contrib/pg_upgrade/info.c index b55bd6d23c2b5808a59e2abe04ea18a569ed5556..c33e13a6704a511043925d8614cce0a500ff3762 100644 --- a/contrib/pg_upgrade/info.c +++ b/contrib/pg_upgrade/info.c @@ -193,15 +193,21 @@ get_db_infos(ClusterInfo *cluster) int i_datname, i_oid, i_spclocation; + char query[QUERY_ALLOC]; - res = executeQueryOrDie(conn, - "SELECT d.oid, d.datname, t.spclocation " - "FROM pg_catalog.pg_database d " - " LEFT OUTER JOIN pg_catalog.pg_tablespace t " - " ON d.dattablespace = t.oid " - "WHERE d.datallowconn = true " + snprintf(query, sizeof(query), + "SELECT d.oid, d.datname, %s " + "FROM pg_catalog.pg_database d " + " LEFT OUTER JOIN pg_catalog.pg_tablespace t " + " ON d.dattablespace = t.oid " + "WHERE d.datallowconn = true " /* we don't preserve pg_database.oid so we sort by name */ - "ORDER BY 2"); + "ORDER BY 2", + /* 9.2 removed the spclocation column */ + (GET_MAJOR_VERSION(old_cluster.major_version) <= 901) ? + "t.spclocation" : "pg_catalog.pg_tablespace_location(t.oid) AS spclocation"); + + res = executeQueryOrDie(conn, "%s", query); i_oid = PQfnumber(res, "oid"); i_datname = PQfnumber(res, "datname"); @@ -265,7 +271,7 @@ get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo) snprintf(query, sizeof(query), "SELECT c.oid, n.nspname, c.relname, " - " c.relfilenode, t.spclocation " + " c.relfilenode, %s " "FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n " " ON c.relnamespace = n.oid " " LEFT OUTER JOIN pg_catalog.pg_tablespace t " @@ -280,6 +286,9 @@ get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo) " relname IN ('pg_largeobject', 'pg_largeobject_loid_pn_index'%s) )) " /* we preserve pg_class.oid so we sort by it to match old/new */ "ORDER BY 1;", + /* 9.2 removed the spclocation column */ + (GET_MAJOR_VERSION(old_cluster.major_version) <= 901) ? + "t.spclocation" : "pg_catalog.pg_tablespace_location(t.oid) AS spclocation", /* see the comment at the top of old_8_3_create_sequence_script() */ (GET_MAJOR_VERSION(old_cluster.major_version) <= 803) ? "" : ", 'S'", diff --git a/contrib/pg_upgrade/tablespace.c b/contrib/pg_upgrade/tablespace.c index 08d227c10a011f9e2233e917759bf2fe197de6f6..df2285f36699148c0cb266e452d66b94920bf5cd 100644 --- a/contrib/pg_upgrade/tablespace.c +++ b/contrib/pg_upgrade/tablespace.c @@ -44,12 +44,18 @@ get_tablespace_paths(void) PGresult *res; int tblnum; int i_spclocation; - - res = executeQueryOrDie(conn, - "SELECT spclocation " - "FROM pg_catalog.pg_tablespace " - "WHERE spcname != 'pg_default' AND " - " spcname != 'pg_global'"); + char query[QUERY_ALLOC]; + + snprintf(query, sizeof(query), + "SELECT %s " + "FROM pg_catalog.pg_tablespace " + "WHERE spcname != 'pg_default' AND " + " spcname != 'pg_global'", + /* 9.2 removed the spclocation column */ + (GET_MAJOR_VERSION(old_cluster.major_version) <= 901) ? + "t.spclocation" : "pg_catalog.pg_tablespace_location(oid) AS spclocation"); + + res = executeQueryOrDie(conn, "%s", query); if ((os_info.num_tablespaces = PQntuples(res)) != 0) os_info.tablespaces = (char **) pg_malloc( diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index 8156c35916ac409ce87b150647d352833f421663..b8cc16f72a9268b83de14a4dddfc6f13d1fdd55f 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -5391,13 +5391,6 @@ <entry>Owner of the tablespace, usually the user who created it</entry> </row> - <row> - <entry><structfield>spclocation</structfield></entry> - <entry><type>text</type></entry> - <entry></entry> - <entry>Location (directory path) of the tablespace</entry> - </row> - <row> <entry><structfield>spcacl</structfield></entry> <entry><type>aclitem[]</type></entry> diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index ddfb29a433813684c60c545dfb124d50020df72a..e7f7fe0e889af030d1a61f720da1bab9bad74727 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -13611,6 +13611,10 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); <primary>pg_tablespace_databases</primary> </indexterm> + <indexterm> + <primary>pg_tablespace_location</primary> + </indexterm> + <indexterm> <primary>pg_typeof</primary> </indexterm> @@ -13758,6 +13762,11 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); <entry><type>setof oid</type></entry> <entry>get the set of database OIDs that have objects in the tablespace</entry> </row> + <row> + <entry><literal><function>pg_tablespace_location(<parameter>tablespace_oid</parameter>)</function></literal></entry> + <entry><type>text</type></entry> + <entry>get the path in the filesystem that this tablespace is located in</entry> + </row> <row> <entry><literal><function>pg_typeof(<parameter>any</parameter>)</function></literal></entry> <entry><type>regtype</type></entry> diff --git a/doc/src/sgml/xaggr.sgml b/doc/src/sgml/xaggr.sgml index 811934bd75bf7714944025f2456a86e792989380..1822f6d4abd026786735ebb836d120d6e5455da0 100644 --- a/doc/src/sgml/xaggr.sgml +++ b/doc/src/sgml/xaggr.sgml @@ -154,7 +154,7 @@ SELECT attrelid::regclass, array_accum(attname) attrelid | array_accum ---------------+--------------------------------------- - pg_tablespace | {spcname,spcowner,spclocation,spcacl} + pg_tablespace | {spcname,spcowner,spcacl,spcoptions} (1 row) SELECT attrelid::regclass, array_accum(atttypid::regtype) @@ -164,7 +164,7 @@ SELECT attrelid::regclass, array_accum(atttypid::regtype) attrelid | array_accum ---------------+--------------------------- - pg_tablespace | {name,oid,text,aclitem[]} + pg_tablespace | {name,oid,aclitem[],text[]} (1 row) </programlisting> </para> diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index d223f8c9649e9b6b46e03b016fb0bff2b8df0493..93592fabef1c791be6850ab16bb4ba5b56a40e86 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -314,8 +314,6 @@ CreateTableSpace(CreateTableSpaceStmt *stmt) DirectFunctionCall1(namein, CStringGetDatum(stmt->tablespacename)); values[Anum_pg_tablespace_spcowner - 1] = ObjectIdGetDatum(ownerId); - values[Anum_pg_tablespace_spclocation - 1] = - CStringGetTextDatum(location); nulls[Anum_pg_tablespace_spcacl - 1] = true; nulls[Anum_pg_tablespace_spcoptions - 1] = true; diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c index 63ec6fd9d4ea71328db6c6426050449e1bfc30ef..4453e818c0074fbfc80cfd954202f6bedab5e09a 100644 --- a/src/backend/utils/adt/misc.c +++ b/src/backend/utils/adt/misc.c @@ -18,6 +18,7 @@ #include <signal.h> #include <dirent.h> #include <math.h> +#include <unistd.h> #include "catalog/catalog.h" #include "catalog/pg_tablespace.h" @@ -261,6 +262,44 @@ pg_tablespace_databases(PG_FUNCTION_ARGS) } +/* + * pg_tablespace_location - get location for a tablespace + */ +Datum +pg_tablespace_location(PG_FUNCTION_ARGS) +{ + Oid tablespaceOid = PG_GETARG_OID(0); + char sourcepath[MAXPGPATH]; + char targetpath[MAXPGPATH]; + int rllen; + + /* + * Return empty string for our two default tablespace + */ + if (tablespaceOid == DEFAULTTABLESPACE_OID || + tablespaceOid == GLOBALTABLESPACE_OID) + PG_RETURN_TEXT_P(cstring_to_text("")); + +#if defined(HAVE_READLINK) || defined(WIN32) + /* + * Find the location of the tablespace by reading the symbolic link that is + * in pg_tblspc/<oid>. + */ + snprintf(sourcepath, sizeof(sourcepath), "pg_tblspc/%u", tablespaceOid); + rllen =readlink(sourcepath, targetpath, sizeof(targetpath)); + if (rllen < 0 || rllen >= sizeof(targetpath)) + ereport(ERROR, + (errmsg("could not read symbolic link \"%s\": %m", sourcepath))); + targetpath[rllen] = '\0'; + + PG_RETURN_TEXT_P(cstring_to_text(targetpath)); +#else + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("tablespaces are not supported on this platform"))); +#endif +} + /* * pg_sleep - delay for N seconds */ diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index 04d655a504b58a6024a1afdb1702458782de006c..f37b7514e47596f9ac257b9b4eb52aff143eed6f 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -997,7 +997,16 @@ dumpTablespaces(PGconn *conn) * Get all tablespaces except built-in ones (which we assume are named * pg_xxx) */ - if (server_version >= 90000) + if (server_version >= 90200) + res = executeQuery(conn, "SELECT oid, spcname, " + "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, " + "pg_catalog.pg_tablespace_location(oid), spcacl, " + "array_to_string(spcoptions, ', ')," + "pg_catalog.shobj_description(oid, 'pg_tablespace') " + "FROM pg_catalog.pg_tablespace " + "WHERE spcname !~ '^pg_' " + "ORDER BY 1"); + else if (server_version >= 90000) res = executeQuery(conn, "SELECT oid, spcname, " "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, " "spclocation, spcacl, " diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index 2ff6d7dc997da21141dd689f091295a48be7e630..dcafdd2c1aed1b18097f85a112b7414071f138ad 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -139,13 +139,22 @@ describeTablespaces(const char *pattern, bool verbose) initPQExpBuffer(&buf); - printfPQExpBuffer(&buf, - "SELECT spcname AS \"%s\",\n" - " pg_catalog.pg_get_userbyid(spcowner) AS \"%s\",\n" - " spclocation AS \"%s\"", - gettext_noop("Name"), - gettext_noop("Owner"), - gettext_noop("Location")); + if (pset.sversion >= 90200) + printfPQExpBuffer(&buf, + "SELECT spcname AS \"%s\",\n" + " pg_catalog.pg_get_userbyid(spcowner) AS \"%s\",\n" + " pg_catalog.pg_tablespace_location(oid) AS \"%s\"", + gettext_noop("Name"), + gettext_noop("Owner"), + gettext_noop("Location")); + else + printfPQExpBuffer(&buf, + "SELECT spcname AS \"%s\",\n" + " pg_catalog.pg_get_userbyid(spcowner) AS \"%s\",\n" + " spclocation AS \"%s\"", + gettext_noop("Name"), + gettext_noop("Owner"), + gettext_noop("Location")); if (verbose) { diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 95c424b81fa6ad22287515ee93017f9a40778095..14e177dc48279823a99c423b6c06ad9c4d65360a 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 201112061 +#define CATALOG_VERSION_NO 201112071 #endif diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 7451a12908acd29a86fa07f50194d41d354b83f7..924cb1f601c0ce8570d534305d0e05cf5dca0689 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -2686,6 +2686,9 @@ DESCR("statistics: reset collected statistics for a single table or index in the DATA(insert OID = 3777 ( pg_stat_reset_single_function_counters PGNSP PGUID 12 1 0 0 0 f f f f f v 1 0 2278 "26" _null_ _null_ _null_ _null_ pg_stat_reset_single_function_counters _null_ _null_ _null_ )); DESCR("statistics: reset collected statistics for a single function in the current database"); +DATA(insert OID = 3778 ( pg_tablespace_location PGNSP PGUID 12 1 0 0 0 f f f t f s 1 0 25 "26" _null_ _null_ _null_ _null_ pg_tablespace_location _null_ _null_ _null_ )); +DESCR("tablespace location"); + DATA(insert OID = 1946 ( encode PGNSP PGUID 12 1 0 0 0 f f f t f i 2 0 25 "17 25" _null_ _null_ _null_ _null_ binary_encode _null_ _null_ _null_ )); DESCR("convert bytea value into some ascii-only text string"); DATA(insert OID = 1947 ( decode PGNSP PGUID 12 1 0 0 0 f f f t f i 2 0 17 "25 25" _null_ _null_ _null_ _null_ binary_decode _null_ _null_ _null_ )); diff --git a/src/include/catalog/pg_tablespace.h b/src/include/catalog/pg_tablespace.h index a1f5688c464b6024614393041a9b13c779085bf5..b35e32fabf08a43dfccaa175d18609d2ab6a7e43 100644 --- a/src/include/catalog/pg_tablespace.h +++ b/src/include/catalog/pg_tablespace.h @@ -32,7 +32,6 @@ CATALOG(pg_tablespace,1213) BKI_SHARED_RELATION { NameData spcname; /* tablespace name */ Oid spcowner; /* owner of tablespace */ - text spclocation; /* physical location (VAR LENGTH) */ aclitem spcacl[1]; /* access permissions (VAR LENGTH) */ text spcoptions[1]; /* per-tablespace options */ } FormData_pg_tablespace; @@ -49,15 +48,14 @@ typedef FormData_pg_tablespace *Form_pg_tablespace; * ---------------- */ -#define Natts_pg_tablespace 5 +#define Natts_pg_tablespace 4 #define Anum_pg_tablespace_spcname 1 #define Anum_pg_tablespace_spcowner 2 -#define Anum_pg_tablespace_spclocation 3 -#define Anum_pg_tablespace_spcacl 4 -#define Anum_pg_tablespace_spcoptions 5 +#define Anum_pg_tablespace_spcacl 3 +#define Anum_pg_tablespace_spcoptions 4 -DATA(insert OID = 1663 ( pg_default PGUID "" _null_ _null_ )); -DATA(insert OID = 1664 ( pg_global PGUID "" _null_ _null_ )); +DATA(insert OID = 1663 ( pg_default PGUID _null_ _null_ )); +DATA(insert OID = 1664 ( pg_global PGUID _null_ _null_ )); #define DEFAULTTABLESPACE_OID 1663 #define GLOBALTABLESPACE_OID 1664 diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 17550e0b3fd469288a90fe6ffe7c6a85aa5c4e01..994dc5368b1176281bbc8faec96534868bbe6c77 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -469,6 +469,7 @@ extern Datum pg_cancel_backend(PG_FUNCTION_ARGS); extern Datum pg_terminate_backend(PG_FUNCTION_ARGS); extern Datum pg_reload_conf(PG_FUNCTION_ARGS); extern Datum pg_tablespace_databases(PG_FUNCTION_ARGS); +extern Datum pg_tablespace_location(PG_FUNCTION_ARGS); extern Datum pg_rotate_logfile(PG_FUNCTION_ARGS); extern Datum pg_sleep(PG_FUNCTION_ARGS); extern Datum pg_get_keywords(PG_FUNCTION_ARGS);