On Sun, Dec 4, 2011 at 18:07, Tom Lane <t...@sss.pgh.pa.us> wrote:
> Andrew Dunstan <and...@dunslane.net> writes:
>> On 12/04/2011 11:41 AM, Tom Lane wrote:
>>> Hm, how portable is symlink-reading?  If we can actually do that
>>> without big headaches, then +1.
>
>> I wondered that, specifically about Windows junction points, but we seem
>> to have support for it already in dirmod.c::pgreadlink(). Surely there's
>> no other currently supported platform where it would even be a question?
>
> readlink is required by Single Unix Spec v2 (1997), which is what we've
> been treating as our baseline expectation for Unix-oid platforms for
> awhile now.  Given that we dealt with the Windows side already, I don't
> see a problem with making this assumption.  At worst we'd end up needing
> a couple more emulations in src/port, since surely there's *some* way to
> do it on any platform with symlinks.

AFAICT, it should be as simple as the attached.

Doesn't include the required fixes for pg_upgrade, I'll get on those next.

-- 
 Magnus Hagander
 Me: http://www.hagander.net/
 Work: http://www.redpill-linpro.com/
*** a/doc/src/sgml/catalogs.sgml
--- b/doc/src/sgml/catalogs.sgml
***************
*** 5392,5404 ****
       </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>
        <entry></entry>
--- 5392,5397 ----
*** a/doc/src/sgml/func.sgml
--- b/doc/src/sgml/func.sgml
***************
*** 13612,13617 **** SELECT pg_type_is_visible('myschema.widget'::regtype);
--- 13612,13621 ----
     </indexterm>
  
     <indexterm>
+     <primary>pg_tablespace_location</primary>
+    </indexterm>
+ 
+    <indexterm>
      <primary>pg_typeof</primary>
     </indexterm>
  
***************
*** 13759,13764 **** SELECT pg_type_is_visible('myschema.widget'::regtype);
--- 13763,13773 ----
         <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>
         <entry>get the data type of any value</entry>
*** a/doc/src/sgml/xaggr.sgml
--- b/doc/src/sgml/xaggr.sgml
***************
*** 154,160 **** SELECT attrelid::regclass, array_accum(attname)
  
     attrelid    |              array_accum              
  ---------------+---------------------------------------
!  pg_tablespace | {spcname,spcowner,spclocation,spcacl}
  (1 row)
  
  SELECT attrelid::regclass, array_accum(atttypid::regtype)
--- 154,160 ----
  
     attrelid    |              array_accum              
  ---------------+---------------------------------------
!  pg_tablespace | {spcname,spcowner,spcacl,spcoptions}
  (1 row)
  
  SELECT attrelid::regclass, array_accum(atttypid::regtype)
***************
*** 164,170 **** SELECT attrelid::regclass, array_accum(atttypid::regtype)
  
     attrelid    |        array_accum        
  ---------------+---------------------------
!  pg_tablespace | {name,oid,text,aclitem[]}
  (1 row)
  </programlisting>
    </para>
--- 164,170 ----
  
     attrelid    |        array_accum        
  ---------------+---------------------------
!  pg_tablespace | {name,oid,aclitem[],text[]}
  (1 row)
  </programlisting>
    </para>
*** a/src/backend/commands/tablespace.c
--- b/src/backend/commands/tablespace.c
***************
*** 314,321 **** 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;
  
--- 314,319 ----
*** a/src/backend/utils/adt/misc.c
--- b/src/backend/utils/adt/misc.c
***************
*** 18,23 ****
--- 18,24 ----
  #include <signal.h>
  #include <dirent.h>
  #include <math.h>
+ #include <unistd.h>
  
  #include "catalog/catalog.h"
  #include "catalog/pg_tablespace.h"
***************
*** 262,267 **** pg_tablespace_databases(PG_FUNCTION_ARGS)
--- 263,298 ----
  
  
  /*
+  * 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];
+ 
+ 	/*
+ 	 * Return empty string for our two default tablespace
+ 	 */
+ 	if (tablespaceOid == DEFAULTTABLESPACE_OID ||
+ 		tablespaceOid == GLOBALTABLESPACE_OID)
+ 		PG_RETURN_TEXT_P(cstring_to_text(""));
+ 
+ 	/*
+ 	 * Find the location of the tablespace by reading the symbolic link that is
+ 	 * in pg_tblspc/<oid>.
+ 	 */
+ 	snprintf(sourcepath, sizeof(sourcepath), "pg_tblspc/%d", tablespaceOid);
+ 	MemSet(targetpath, 0, sizeof(targetpath));
+ 	if (readlink(sourcepath, targetpath, sizeof(targetpath)) == -1)
+ 		ereport(ERROR,
+ 				(errmsg("could not read symbolic link \"%s\": %m", sourcepath)));
+ 
+ 	PG_RETURN_TEXT_P(cstring_to_text(targetpath));
+ }
+ 
+ /*
   * pg_sleep - delay for N seconds
   */
  Datum
*** a/src/bin/pg_dump/pg_dumpall.c
--- b/src/bin/pg_dump/pg_dumpall.c
***************
*** 997,1003 **** dumpTablespaces(PGconn *conn)
  	 * Get all tablespaces except built-in ones (which we assume are named
  	 * pg_xxx)
  	 */
! 	if (server_version >= 90000)
  		res = executeQuery(conn, "SELECT oid, spcname, "
  						 "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
  						   "spclocation, spcacl, "
--- 997,1012 ----
  	 * Get all tablespaces except built-in ones (which we assume are named
  	 * pg_xxx)
  	 */
! 	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, "
*** a/src/bin/psql/describe.c
--- b/src/bin/psql/describe.c
***************
*** 139,151 **** 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 (verbose)
  	{
--- 139,160 ----
  
  	initPQExpBuffer(&buf);
  
! 	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)
  	{
*** a/src/include/catalog/pg_proc.h
--- b/src/include/catalog/pg_proc.h
***************
*** 2670,2675 **** DESCR("statistics: reset collected statistics for a single table or index in the
--- 2670,2678 ----
  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_ ));
*** a/src/include/catalog/pg_tablespace.h
--- b/src/include/catalog/pg_tablespace.h
***************
*** 32,38 **** 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;
--- 32,37 ----
***************
*** 49,63 **** typedef FormData_pg_tablespace *Form_pg_tablespace;
   * ----------------
   */
  
! #define Natts_pg_tablespace				5
  #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
  
! 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
--- 48,61 ----
   * ----------------
   */
  
! #define Natts_pg_tablespace				4
  #define Anum_pg_tablespace_spcname		1
  #define Anum_pg_tablespace_spcowner		2
! #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_ ));
  
  #define DEFAULTTABLESPACE_OID 1663
  #define GLOBALTABLESPACE_OID 1664
*** a/src/include/utils/builtins.h
--- b/src/include/utils/builtins.h
***************
*** 456,461 **** extern Datum pg_cancel_backend(PG_FUNCTION_ARGS);
--- 456,462 ----
  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);
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to