@@ -3622,11 +3622,19 @@ string_agg_finalfn(PG_FUNCTION_ARGS)
36223622PG_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+ */
36253631static 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 ;
36293635text * result ;
3636+ StringInfoData str ;
3637+ bool first_arg = true;
36303638int i ;
36313639
36323640initStringInfo (& str );
@@ -3635,17 +3643,21 @@ concat_internal(const char *sepstr, int seplen, int argidx, FunctionCallInfo fci
36353643{
36363644if (!PG_ARGISNULL (i ))
36373645{
3646+ Datum value = PG_GETARG_DATUM (i );
36383647Oid valtype ;
3639- Datum value ;
36403648Oid typOutput ;
36413649bool typIsVarlena ;
36423650
3643- if (i > argidx )
3651+ /* add separator if appropriate */
3652+ if (first_arg )
3653+ first_arg = false;
3654+ else
36443655appendBinaryStringInfo (& 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 */
36483658valtype = get_fn_expr_argtype (fcinfo -> flinfo ,i );
3659+ if (!OidIsValid (valtype ))
3660+ elog (ERROR ,"could not determine data type of concat() input" );
36493661getTypeOutputInfo (valtype ,& typOutput ,& typIsVarlena );
36503662appendStringInfoString (& str ,
36513663OidOutputFunctionCall (typOutput ,value ));
@@ -3664,12 +3676,12 @@ concat_internal(const char *sepstr, int seplen, int argidx, FunctionCallInfo fci
36643676Datum
36653677text_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 argumentvalues with separators. The first
3672- * parameter is used asa separator. NULL arguments are ignored.
3683+ * Concatenate all but first argumentvalue with separators. The first
3684+ * parameter is used asthe separator. NULL arguments are ignored.
36733685 */
36743686Datum
36753687text_concat_ws (PG_FUNCTION_ARGS )
@@ -3682,8 +3694,8 @@ text_concat_ws(PG_FUNCTION_ARGS)
36823694
36833695sep = 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/*