1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-05 07:21:24 +03:00

Throw a useful error message if an extension script file is fed to psql.

We have seen one too many reports of people trying to use 9.1 extension
files in the old-fashioned way of sourcing them in psql.  Not only does
that usually not work (due to failure to substitute for MODULE_PATHNAME
and/or @extschema@), but if it did work they'd get a collection of loose
objects not an extension.  To prevent this, insert an \echo ... \quit
line that prints a suitable error message into each extension script file,
and teach commands/extension.c to ignore lines starting with \echo.
That should not only prevent any adverse consequences of loading a script
file the wrong way, but make it crystal clear to users that they need to
do it differently now.

Tom Lane, following an idea of Andrew Dunstan's.  Back-patch into 9.1
... there is not going to be much value in this if we wait till 9.2.
This commit is contained in:
Tom Lane
2011-10-12 15:45:03 -04:00
parent e0d273500a
commit 458857cc9d
78 changed files with 274 additions and 17 deletions

View File

@ -33,6 +33,7 @@
#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"
@ -855,26 +856,39 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
CurrentExtensionObject = extensionOid;
PG_TRY();
{
char *sql = read_extension_script_file(control, filename);
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 just run the script as-is. There
* cannot be any need for @extschema@, else it wouldn't be
* relocatable.
* 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);
sql = text_to_cstring(
DatumGetTextPP(
DirectFunctionCall3(replace_text,
CStringGetTextDatum(sql),
CStringGetTextDatum("@extschema@"),
CStringGetTextDatum(qSchemaName))));
t_sql = DirectFunctionCall3(replace_text,
t_sql,
CStringGetTextDatum("@extschema@"),
CStringGetTextDatum(qSchemaName));
}
/*
@ -883,15 +897,16 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
*/
if (control->module_pathname)
{
sql = text_to_cstring(
DatumGetTextPP(
DirectFunctionCall3(replace_text,
CStringGetTextDatum(sql),
CStringGetTextDatum("MODULE_PATHNAME"),
CStringGetTextDatum(control->module_pathname))));
t_sql = DirectFunctionCall3(replace_text,
t_sql,
CStringGetTextDatum("MODULE_PATHNAME"),
CStringGetTextDatum(control->module_pathname));
}
execute_sql_string(sql, filename);
/* And now back to C string */
c_sql = text_to_cstring(DatumGetTextPP(t_sql));
execute_sql_string(c_sql, filename);
}
PG_CATCH();
{