diff options
author | Tom Lane | 2011-10-12 19:45:03 +0000 |
---|---|---|
committer | Tom Lane | 2011-10-12 19:45:03 +0000 |
commit | 458857cc9d7d00711b272a0dabbcb591b506d6b8 (patch) | |
tree | 2b4acca78ee2fba19273d10aa01eccc4bc111d4b /src/backend/commands/extension.c | |
parent | e0d273500a84ab94c69cbfa10ea0537604fbdda3 (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.c | 49 |
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(); { |