Stephen Frost <sfr...@snowman.net> 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 (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers