On Tue, 28 Aug 2018 11:49:26 +0900 (Tokyo Standard Time) Kyotaro HORIGUCHI <horiguchi.kyot...@lab.ntt.co.jp> wrote:
> At Fri, 24 Aug 2018 20:44:12 +0900, Yugo Nagata <nag...@sraoss.co.jp> wrote > in <20180824204412.150979ae6b283ddb639f9...@sraoss.co.jp> > > When working on other patch[1], I found there are almost same > > functions, texttoQualifiedNameList() and stringToQualifiedNameList(). > > The only difference is the argument type, text or char*. I don't know > > why these functions are defined seperately, but I think the former > > function can be rewritten using the latter code as the attached patch. > > Is this reasonable fix? > > The functions were introduced within a month for different > objectives in March and April, 2002. I supppose that they are > intentionally added as separate functions for simplicitly since > the second one is apparent CnP'ed from the first one. > > commit 5f4745adf4fb2a1f933b25d7a2bc72b39fa9edfd > commit 52200befd04b9fa71da83231c808764867079226 Thank you for your comments. I also looked at the commit history. stringToQNL is added after textToQNL as a static function originally, but this is now public and reffered from other modules, too. So, I propose to mote this from regproc.c to verlena.c and rewrite textToQNL to call stringToQNL. This is just for reducing redundancy of the code. Attached is the updated patch. > Returning to the patch, the downside of it is that textToQNL > makes an extra and unused copy of the parameter string. (It's a > kind of bug that it is forgetting to free rawname.) I also fixed to free rawname in the texttoQNL. Regards, -- Yugo Nagata <nag...@sraoss.co.jp>
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c index a0079821fe..ebc087ed3f 100644 --- a/src/backend/utils/adt/regproc.c +++ b/src/backend/utils/adt/regproc.c @@ -1680,43 +1680,6 @@ text_regclass(PG_FUNCTION_ARGS) } -/* - * Given a C string, parse it into a qualified-name list. - */ -List * -stringToQualifiedNameList(const char *string) -{ - char *rawname; - List *result = NIL; - List *namelist; - ListCell *l; - - /* We need a modifiable copy of the input string. */ - rawname = pstrdup(string); - - if (!SplitIdentifierString(rawname, '.', &namelist)) - ereport(ERROR, - (errcode(ERRCODE_INVALID_NAME), - errmsg("invalid name syntax"))); - - if (namelist == NIL) - ereport(ERROR, - (errcode(ERRCODE_INVALID_NAME), - errmsg("invalid name syntax"))); - - foreach(l, namelist) - { - char *curname = (char *) lfirst(l); - - result = lappend(result, makeString(pstrdup(curname))); - } - - pfree(rawname); - list_free(namelist); - - return result; -} - /***************************************************************************** * SUPPORT ROUTINES * *****************************************************************************/ diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c index a5e812d026..1846ddcae8 100644 --- a/src/backend/utils/adt/varlena.c +++ b/src/backend/utils/adt/varlena.c @@ -3219,26 +3219,19 @@ name_text(PG_FUNCTION_ARGS) PG_RETURN_TEXT_P(cstring_to_text(NameStr(*s))); } - /* - * textToQualifiedNameList - convert a text object to list of names - * - * This implements the input parsing needed by nextval() and other - * functions that take a text parameter representing a qualified name. - * We split the name at dots, downcase if not double-quoted, and - * truncate names if they're too long. + * Given a C string, parse it into a qualified-name list. */ List * -textToQualifiedNameList(text *textval) +stringToQualifiedNameList(const char *string) { char *rawname; List *result = NIL; List *namelist; ListCell *l; - /* Convert to C string (handles possible detoasting). */ - /* Note we rely on being able to modify rawname below. */ - rawname = text_to_cstring(textval); + /* We need a modifiable copy of the input string. */ + rawname = pstrdup(string); if (!SplitIdentifierString(rawname, '.', &namelist)) ereport(ERROR, @@ -3263,6 +3256,31 @@ textToQualifiedNameList(text *textval) return result; } + +/* + * textToQualifiedNameList - convert a text object to list of names + * + * This implements the input parsing needed by nextval() and other + * functions that take a text parameter representing a qualified name. + * We split the name at dots, downcase if not double-quoted, and + * truncate names if they're too long. + */ +List * +textToQualifiedNameList(text *textval) +{ + char *rawname; + List *result = NIL; + + /* Convert to C string (handles possible detoasting). */ + /* Note we rely on being able to modify rawname below. */ + rawname = text_to_cstring(textval); + + result = stringToQualifiedNameList(rawname); + pfree(rawname); + + return result; +} + /* * SplitIdentifierString --- parse a string containing identifiers * diff --git a/src/include/utils/regproc.h b/src/include/utils/regproc.h index 5b9a8cbee8..ace74ed49f 100644 --- a/src/include/utils/regproc.h +++ b/src/include/utils/regproc.h @@ -15,7 +15,6 @@ #include "nodes/pg_list.h" -extern List *stringToQualifiedNameList(const char *string); extern char *format_procedure(Oid procedure_oid); extern char *format_procedure_qualified(Oid procedure_oid); extern void format_procedure_parts(Oid operator_oid, List **objnames, diff --git a/src/include/utils/varlena.h b/src/include/utils/varlena.h index c776931bc4..a51c84beb3 100644 --- a/src/include/utils/varlena.h +++ b/src/include/utils/varlena.h @@ -26,6 +26,7 @@ extern int varstr_levenshtein_less_equal(const char *source, int slen, const char *target, int tlen, int ins_c, int del_c, int sub_c, int max_d, bool trusted); +extern List *stringToQualifiedNameList(const char *string); extern List *textToQualifiedNameList(text *textval); extern bool SplitIdentifierString(char *rawstring, char separator, List **namelist);