提交 a5b7640b 编写于 作者: T Tom Lane

Fix concat_ws() to not insert a separator after leading NULL argument(s).

Per bug #6181 from Itagaki Takahiro.  Also do some marginal code cleanup
and improve error handling.
上级 be1e8053
...@@ -3622,11 +3622,19 @@ string_agg_finalfn(PG_FUNCTION_ARGS) ...@@ -3622,11 +3622,19 @@ string_agg_finalfn(PG_FUNCTION_ARGS)
PG_RETURN_NULL(); PG_RETURN_NULL();
} }
/*
* Implementation of both concat() and concat_ws().
*
* sepstr/seplen describe the separator. argidx is the first argument
* to concatenate (counting from zero).
*/
static text * static text *
concat_internal(const char *sepstr, int seplen, int argidx, FunctionCallInfo fcinfo) concat_internal(const char *sepstr, int seplen, int argidx,
FunctionCallInfo fcinfo)
{ {
StringInfoData str;
text *result; text *result;
StringInfoData str;
bool first_arg = true;
int i; int i;
initStringInfo(&str); initStringInfo(&str);
...@@ -3635,17 +3643,21 @@ concat_internal(const char *sepstr, int seplen, int argidx, FunctionCallInfo fci ...@@ -3635,17 +3643,21 @@ concat_internal(const char *sepstr, int seplen, int argidx, FunctionCallInfo fci
{ {
if (!PG_ARGISNULL(i)) if (!PG_ARGISNULL(i))
{ {
Datum value = PG_GETARG_DATUM(i);
Oid valtype; Oid valtype;
Datum value;
Oid typOutput; Oid typOutput;
bool typIsVarlena; bool typIsVarlena;
if (i > argidx) /* add separator if appropriate */
if (first_arg)
first_arg = false;
else
appendBinaryStringInfo(&str, sepstr, seplen); appendBinaryStringInfo(&str, sepstr, seplen);
/* append n-th value */ /* call the appropriate type output function, append the result */
value = PG_GETARG_DATUM(i);
valtype = get_fn_expr_argtype(fcinfo->flinfo, i); valtype = get_fn_expr_argtype(fcinfo->flinfo, i);
if (!OidIsValid(valtype))
elog(ERROR, "could not determine data type of concat() input");
getTypeOutputInfo(valtype, &typOutput, &typIsVarlena); getTypeOutputInfo(valtype, &typOutput, &typIsVarlena);
appendStringInfoString(&str, appendStringInfoString(&str,
OidOutputFunctionCall(typOutput, value)); OidOutputFunctionCall(typOutput, value));
...@@ -3664,12 +3676,12 @@ concat_internal(const char *sepstr, int seplen, int argidx, FunctionCallInfo fci ...@@ -3664,12 +3676,12 @@ concat_internal(const char *sepstr, int seplen, int argidx, FunctionCallInfo fci
Datum Datum
text_concat(PG_FUNCTION_ARGS) text_concat(PG_FUNCTION_ARGS)
{ {
PG_RETURN_TEXT_P(concat_internal(NULL, 0, 0, fcinfo)); PG_RETURN_TEXT_P(concat_internal("", 0, 0, fcinfo));
} }
/* /*
* Concatenate all but first argument values with separators. The first * Concatenate all but first argument value with separators. The first
* parameter is used as a separator. NULL arguments are ignored. * parameter is used as the separator. NULL arguments are ignored.
*/ */
Datum Datum
text_concat_ws(PG_FUNCTION_ARGS) text_concat_ws(PG_FUNCTION_ARGS)
...@@ -3682,8 +3694,8 @@ text_concat_ws(PG_FUNCTION_ARGS) ...@@ -3682,8 +3694,8 @@ text_concat_ws(PG_FUNCTION_ARGS)
sep = PG_GETARG_TEXT_PP(0); sep = PG_GETARG_TEXT_PP(0);
PG_RETURN_TEXT_P(concat_internal( PG_RETURN_TEXT_P(concat_internal(VARDATA_ANY(sep), VARSIZE_ANY_EXHDR(sep),
VARDATA_ANY(sep), VARSIZE_ANY_EXHDR(sep), 1, fcinfo)); 1, fcinfo));
} }
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册