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:
@ -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();
|
||||
{
|
||||
|
Reference in New Issue
Block a user