Skip to content

Commit a5b7640

Browse files
committed
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.
1 parent be1e805 commit a5b7640

File tree

1 file changed

+23
-11
lines changed

1 file changed

+23
-11
lines changed

src/backend/utils/adt/varlena.c

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3622,11 +3622,19 @@ string_agg_finalfn(PG_FUNCTION_ARGS)
36223622
PG_RETURN_NULL();
36233623
}
36243624

3625+
/*
3626+
* Implementation of both concat() and concat_ws().
3627+
*
3628+
* sepstr/seplen describe the separator. argidx is the first argument
3629+
* to concatenate (counting from zero).
3630+
*/
36253631
static text *
3626-
concat_internal(const char *sepstr, int seplen, int argidx, FunctionCallInfo fcinfo)
3632+
concat_internal(const char *sepstr, int seplen, int argidx,
3633+
FunctionCallInfo fcinfo)
36273634
{
3628-
StringInfoData str;
36293635
text *result;
3636+
StringInfoData str;
3637+
bool first_arg = true;
36303638
int i;
36313639

36323640
initStringInfo(&str);
@@ -3635,17 +3643,21 @@ concat_internal(const char *sepstr, int seplen, int argidx, FunctionCallInfo fci
36353643
{
36363644
if (!PG_ARGISNULL(i))
36373645
{
3646+
Datum value = PG_GETARG_DATUM(i);
36383647
Oid valtype;
3639-
Datum value;
36403648
Oid typOutput;
36413649
bool typIsVarlena;
36423650

3643-
if (i > argidx)
3651+
/* add separator if appropriate */
3652+
if (first_arg)
3653+
first_arg = false;
3654+
else
36443655
appendBinaryStringInfo(&str, sepstr, seplen);
36453656

3646-
/* append n-th value */
3647-
value = PG_GETARG_DATUM(i);
3657+
/* call the appropriate type output function, append the result */
36483658
valtype = get_fn_expr_argtype(fcinfo->flinfo, i);
3659+
if (!OidIsValid(valtype))
3660+
elog(ERROR, "could not determine data type of concat() input");
36493661
getTypeOutputInfo(valtype, &typOutput, &typIsVarlena);
36503662
appendStringInfoString(&str,
36513663
OidOutputFunctionCall(typOutput, value));
@@ -3664,12 +3676,12 @@ concat_internal(const char *sepstr, int seplen, int argidx, FunctionCallInfo fci
36643676
Datum
36653677
text_concat(PG_FUNCTION_ARGS)
36663678
{
3667-
PG_RETURN_TEXT_P(concat_internal(NULL, 0, 0, fcinfo));
3679+
PG_RETURN_TEXT_P(concat_internal("", 0, 0, fcinfo));
36683680
}
36693681

36703682
/*
3671-
* Concatenate all but first argument values with separators. The first
3672-
* parameter is used as a separator. NULL arguments are ignored.
3683+
* Concatenate all but first argument value with separators. The first
3684+
* parameter is used as the separator. NULL arguments are ignored.
36733685
*/
36743686
Datum
36753687
text_concat_ws(PG_FUNCTION_ARGS)
@@ -3682,8 +3694,8 @@ text_concat_ws(PG_FUNCTION_ARGS)
36823694

36833695
sep = PG_GETARG_TEXT_PP(0);
36843696

3685-
PG_RETURN_TEXT_P(concat_internal(
3686-
VARDATA_ANY(sep), VARSIZE_ANY_EXHDR(sep), 1, fcinfo));
3697+
PG_RETURN_TEXT_P(concat_internal(VARDATA_ANY(sep), VARSIZE_ANY_EXHDR(sep),
3698+
1, fcinfo));
36873699
}
36883700

36893701
/*

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy