Stephen Frost <[email protected]> writes:
> Yeah, default_version was the other one that looked like it might be
> possible to include, but folks might decide to try and use 'comment' in
> that way too. Basically, there's a chance that they'd want to use any
> string in there.
Actually, I think that $default_value is the only other serious enough
candidate that we should support, and I think we should support it both
from the directory and module_pathname parameters.
Also, it seems to me that while the $directory macro should still be
found only at the beginning of the module_pathname value, the
$default_value should be substituted from wherever it is found.
Please find attached a v1 version of the patch implementing that.
doc/src/sgml/extend.sgml | 18 ++++++++
src/backend/commands/extension.c | 79 +++++++++++++++++++++++++++++---
2 files changed, 91 insertions(+), 6 deletions(-)
Regards,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support
*** a/doc/src/sgml/extend.sgml
--- b/doc/src/sgml/extend.sgml
***************
*** 412,417 ****
--- 412,423 ----
default behavior is equivalent to specifying
<literal>directory = 'extension'</>.
</para>
+ <para>
+ The macro <literal>$default_value</literal> is supported for this
+ parameter. When used <literal>$default_value</literal> is then
+ substituted with the <literal>default_value</literal> control
+ parameter value.
+ </para>
</listitem>
</varlistentry>
***************
*** 462,467 ****
--- 468,485 ----
FUNCTION</> commands for C-language functions, so that the script
files do not need to hard-wire the name of the shared library.
</para>
+ <para>
+ The macro <literal>$default_value</literal> is supported for this
+ parameter. When used <literal>$default_value</literal> is then
+ substituted with the <literal>default_value</literal> control
+ parameter value.
+ </para>
+ <para>
+ The macro <literal>$directory</literal> is also supported for this
+ parameter, only when found at the very start of the value for this
+ parameter. When used <literal>$directory</literal> is then substituted
+ with the <literal>directory</literal> control parameter value.
+ </para>
</listitem>
</varlistentry>
*** a/src/backend/commands/extension.c
--- b/src/backend/commands/extension.c
***************
*** 369,374 **** get_extension_control_filename(const char *extname)
--- 369,377 ----
return result;
}
+ /*
+ * In the control file, the directory entry supports $default_version macro.
+ */
static char *
get_extension_script_directory(ExtensionControlFile *control)
{
***************
*** 383,393 **** get_extension_script_directory(ExtensionControlFile *control)
return get_extension_control_directory();
if (is_absolute_path(control->directory))
! return pstrdup(control->directory);
! get_share_path(my_exec_path, sharepath);
! result = (char *) palloc(MAXPGPATH);
! snprintf(result, MAXPGPATH, "%s/%s", sharepath, control->directory);
return result;
}
--- 386,406 ----
return get_extension_control_directory();
if (is_absolute_path(control->directory))
! result = pstrdup(control->directory);
! else
! {
! get_share_path(my_exec_path, sharepath);
! result = (char *) palloc(MAXPGPATH);
! snprintf(result, MAXPGPATH, "%s/%s", sharepath, control->directory);
! }
! /* see about replacing the $default_version macro if present. */
! result = text_to_cstring(
! DatumGetTextPP(
! DirectFunctionCall3(replace_text,
! CStringGetTextDatum(result),
! CStringGetTextDatum("$default_version"),
! CStringGetTextDatum(control->default_version))));
return result;
}
***************
*** 432,437 **** get_extension_script_filename(ExtensionControlFile *control,
--- 445,499 ----
return result;
}
+ /*
+ * Substitute for any macros appearing in the given string.
+ * Result is always freshly palloc'd.
+ *
+ * Supported macros are:
+ * - $directory
+ * - $default_version
+ *
+ * The $directory macro must be used at the very start of the module_pathname.
+ */
+ static char *
+ substitute_module_macros(const char *module_pathname,
+ const char *directory,
+ const char *default_version)
+ {
+ Datum t_result;
+ const char *sep_ptr;
+
+ if (module_pathname == NULL)
+ return NULL;
+
+ /* Currently, we only recognize $directory at the start of the string */
+ if (module_pathname[0] != '$')
+ return pstrdup(module_pathname);
+
+ if ((sep_ptr = first_dir_separator(module_pathname)) == NULL)
+ sep_ptr = module_pathname + strlen(module_pathname);
+
+ /* Accept $libdir, just return module_pathname as is then */
+ if (strlen("$libdir") == sep_ptr - module_pathname &&
+ strncmp(module_pathname, "$libdir", strlen("$libdir")) == 0)
+ return pstrdup(module_pathname);
+
+ if (strlen("$directory") != sep_ptr - module_pathname ||
+ strncmp(module_pathname, "$directory", strlen("$directory")) != 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_NAME),
+ errmsg("invalid macro module_pathname in: %s",
+ module_pathname)));
+
+ t_result = CStringGetTextDatum(psprintf("%s%s", directory, sep_ptr));
+ t_result = DirectFunctionCall3(replace_text,
+ t_result,
+ CStringGetTextDatum("$default_version"),
+ CStringGetTextDatum(default_version));
+
+ return text_to_cstring(DatumGetTextPP(t_result));
+ }
+
/*
* Parse contents of primary or auxiliary control file, and fill in
***************
*** 895,904 **** execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
*/
if (control->module_pathname)
{
t_sql = DirectFunctionCall3(replace_text,
t_sql,
! CStringGetTextDatum("MODULE_PATHNAME"),
! CStringGetTextDatum(control->module_pathname));
}
/* And now back to C string */
--- 957,971 ----
*/
if (control->module_pathname)
{
+ char *directory = get_extension_script_directory(control);
+ char *module_pathname =
+ substitute_module_macros(control->module_pathname,
+ directory, control->default_version);
+
t_sql = DirectFunctionCall3(replace_text,
t_sql,
! CStringGetTextDatum("MODULE_PATHNAME"),
! CStringGetTextDatum(module_pathname));
}
/* And now back to C string */
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers