Magnus Hagander <mag...@hagander.net> writes:
> On Wed, Oct 12, 2011 at 17:40, Tom Lane <t...@sss.pgh.pa.us> wrote:
>> The only thing the \echo approach will cost us is a few more lines of C
>> code in execute_extension_script(), and I think it's more than worth
>> that given the evident scope of the problem.

> +1.

PFA, a sample patch for this --- I've only bothered to change one script
file here, but will of course do the rest if there are no further
objections.  The technique actually works even better than I expected,
because of the seemingly nowhere documented fact that \quit in a script
file doesn't terminate psql, only processing of the script.  So what
I get is

regression=# \i ~/postgres/share/extension/cube--1.0.sql
Use "CREATE EXTENSION cube" to load this file.
regression=# 

which is about as good as one could hope for.

(Looks like a patch to the psql docs is upcoming, too.)

                        regards, tom lane


diff --git a/contrib/cube/cube--1.0.sql b/contrib/cube/cube--1.0.sql
index ee9febe005315bf13e93a9ef216a7411fc13a445..0d259c0969d9df4a00f160bf1fc00407273e2b1d 100644
*** a/contrib/cube/cube--1.0.sql
--- b/contrib/cube/cube--1.0.sql
***************
*** 1,5 ****
--- 1,7 ----
  /* contrib/cube/cube--1.0.sql */
  
+ \echo Use "CREATE EXTENSION cube" to load this file. \quit
+ 
  -- Create the user-defined type for N-dimensional boxes
  
  CREATE FUNCTION cube_in(cstring)
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index 3af15dd38bb7044ec6f733787cad6897b204ccd3..ba1e2c45cd97c89265912d338a98f52bf48ea4b0 100644
*** a/src/backend/commands/extension.c
--- b/src/backend/commands/extension.c
***************
*** 33,38 ****
--- 33,39 ----
  #include "catalog/indexing.h"
  #include "catalog/namespace.h"
  #include "catalog/objectaccess.h"
+ #include "catalog/pg_collation.h"
  #include "catalog/pg_depend.h"
  #include "catalog/pg_extension.h"
  #include "catalog/pg_namespace.h"
*************** execute_extension_script(Oid extensionOi
*** 855,880 ****
  	CurrentExtensionObject = extensionOid;
  	PG_TRY();
  	{
! 		char	   *sql = read_extension_script_file(control, filename);
  
  		/*
  		 * If it's not relocatable, substitute the target schema name for
  		 * occcurrences of @extschema@.
  		 *
! 		 * For a relocatable extension, we just run the script as-is. There
! 		 * cannot be any need for @extschema@, else it wouldn't be
! 		 * relocatable.
  		 */
  		if (!control->relocatable)
  		{
  			const char *qSchemaName = quote_identifier(schemaName);
  
! 			sql = text_to_cstring(
! 								  DatumGetTextPP(
! 											DirectFunctionCall3(replace_text,
! 													CStringGetTextDatum(sql),
! 										  CStringGetTextDatum("@extschema@"),
! 										 CStringGetTextDatum(qSchemaName))));
  		}
  
  		/*
--- 856,894 ----
  	CurrentExtensionObject = extensionOid;
  	PG_TRY();
  	{
! 		char	   *c_sql = read_extension_script_file(control, filename);
! 		Datum		t_sql;
! 
! 		/* We use various functions that want to operate on text datums */
! 		t_sql = CStringGetTextDatum(c_sql);
! 
! 		/*
! 		 * Reduce any lines beginning with "\echo" to empty.  This allows
! 		 * scripts to contain messages telling people not to run them via
! 		 * psql, which has been found to be necessary due to old habits.
! 		 */
! 		t_sql = DirectFunctionCall4Coll(textregexreplace,
! 										C_COLLATION_OID,
! 										t_sql,
! 										CStringGetTextDatum("^\\\\echo.*$"),
! 										CStringGetTextDatum(""),
! 										CStringGetTextDatum("ng"));
  
  		/*
  		 * If it's not relocatable, substitute the target schema name for
  		 * occcurrences of @extschema@.
  		 *
! 		 * For a relocatable extension, we needn't do this.  There cannot be
! 		 * any need for @extschema@, else it wouldn't be relocatable.
  		 */
  		if (!control->relocatable)
  		{
  			const char *qSchemaName = quote_identifier(schemaName);
  
! 			t_sql = DirectFunctionCall3(replace_text,
! 										t_sql,
! 										CStringGetTextDatum("@extschema@"),
! 										CStringGetTextDatum(qSchemaName));
  		}
  
  		/*
*************** execute_extension_script(Oid extensionOi
*** 883,897 ****
  		 */
  		if (control->module_pathname)
  		{
! 			sql = text_to_cstring(
! 								  DatumGetTextPP(
! 											DirectFunctionCall3(replace_text,
! 													CStringGetTextDatum(sql),
! 									  CStringGetTextDatum("MODULE_PATHNAME"),
! 							CStringGetTextDatum(control->module_pathname))));
  		}
  
! 		execute_sql_string(sql, filename);
  	}
  	PG_CATCH();
  	{
--- 897,912 ----
  		 */
  		if (control->module_pathname)
  		{
! 			t_sql = DirectFunctionCall3(replace_text,
! 										t_sql,
! 										CStringGetTextDatum("MODULE_PATHNAME"),
! 							CStringGetTextDatum(control->module_pathname));
  		}
  
! 		/* And now back to C string */
! 		c_sql = text_to_cstring(DatumGetTextPP(t_sql));
! 
! 		execute_sql_string(c_sql, filename);
  	}
  	PG_CATCH();
  	{
-- 
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