summaryrefslogtreecommitdiff
path: root/src/backend/commands/extension.c
diff options
context:
space:
mode:
authorTom Lane2011-10-12 19:45:03 +0000
committerTom Lane2011-10-12 19:45:03 +0000
commit458857cc9d7d00711b272a0dabbcb591b506d6b8 (patch)
tree2b4acca78ee2fba19273d10aa01eccc4bc111d4b /src/backend/commands/extension.c
parente0d273500a84ab94c69cbfa10ea0537604fbdda3 (diff)
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.
Diffstat (limited to 'src/backend/commands/extension.c')
-rw-r--r--src/backend/commands/extension.c49
1 files changed, 32 insertions, 17 deletions
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index 3af15dd38bb..ba1e2c45cd9 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -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();
{