aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/varlena.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/varlena.c')
-rw-r--r--src/backend/utils/adt/varlena.c40
1 files changed, 18 insertions, 22 deletions
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index 096ca75bf93..652e1e6add4 100644
--- a/src/backend/utils/adt/varlena.c
+++ b/src/backend/utils/adt/varlena.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.175 2010/02/01 03:14:43 itagaki Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.176 2010/02/08 20:39:51 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,7 +21,6 @@
#include "libpq/md5.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
-#include "nodes/execnodes.h"
#include "parser/scansup.h"
#include "regex/regex.h"
#include "utils/builtins.h"
@@ -74,7 +73,7 @@ static bytea *bytea_substring(Datum str,
int L,
bool length_not_specified);
static bytea *bytea_overlay(bytea *t1, bytea *t2, int sp, int sl);
-static StringInfo makeStringAggState(fmNodePtr context);
+static StringInfo makeStringAggState(FunctionCallInfo fcinfo);
/*****************************************************************************
@@ -3327,25 +3326,25 @@ pg_column_size(PG_FUNCTION_ARGS)
* actually used at all, and on subsequent calls the delimiter precedes
* the associated value.
*/
+
+/* subroutine to initialize state */
static StringInfo
-makeStringAggState(fmNodePtr context)
+makeStringAggState(FunctionCallInfo fcinfo)
{
StringInfo state;
MemoryContext aggcontext;
MemoryContext oldcontext;
- if (context && IsA(context, AggState))
- aggcontext = ((AggState *) context)->aggcontext;
- else if (context && IsA(context, WindowAggState))
- aggcontext = ((WindowAggState *) context)->wincontext;
- else
+ if (!AggCheckCallContext(fcinfo, &aggcontext))
{
/* cannot be called directly because of internal-type argument */
elog(ERROR, "string_agg_transfn called in non-aggregate context");
- aggcontext = NULL; /* keep compiler quiet */
}
- /* Create state in aggregate context */
+ /*
+ * Create state in aggregate context. It'll stay there across subsequent
+ * calls.
+ */
oldcontext = MemoryContextSwitchTo(aggcontext);
state = makeStringInfo();
MemoryContextSwitchTo(oldcontext);
@@ -3360,11 +3359,11 @@ string_agg_transfn(PG_FUNCTION_ARGS)
state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
- /* Append the element unless not null. */
+ /* Append the element unless null. */
if (!PG_ARGISNULL(1))
{
if (state == NULL)
- state = makeStringAggState(fcinfo->context);
+ state = makeStringAggState(fcinfo);
appendStringInfoText(state, PG_GETARG_TEXT_PP(1)); /* value */
}
@@ -3382,11 +3381,12 @@ string_agg_delim_transfn(PG_FUNCTION_ARGS)
state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
- /* Append the value unless not null. */
+ /* Append the value unless null. */
if (!PG_ARGISNULL(1))
{
+ /* On the first time through, we ignore the delimiter. */
if (state == NULL)
- state = makeStringAggState(fcinfo->context);
+ state = makeStringAggState(fcinfo);
else if (!PG_ARGISNULL(2))
appendStringInfoText(state, PG_GETARG_TEXT_PP(2)); /* delimiter */
@@ -3405,15 +3405,11 @@ string_agg_finalfn(PG_FUNCTION_ARGS)
{
StringInfo state;
- if (PG_ARGISNULL(0))
- PG_RETURN_NULL();
-
/* cannot be called directly because of internal-type argument */
- Assert(fcinfo->context &&
- (IsA(fcinfo->context, AggState) ||
- IsA(fcinfo->context, WindowAggState)));
+ Assert(AggCheckCallContext(fcinfo, NULL));
+
+ state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
- state = (StringInfo) PG_GETARG_POINTER(0);
if (state != NULL)
PG_RETURN_TEXT_P(cstring_to_text(state->data));
else