PG_RETURN_TEXT_P(cstring_to_text_with_len(str, nbytes));
}
+#ifdef XCP
+Datum
+json_agg_state_in(PG_FUNCTION_ARGS)
+{
+ char *str = pstrdup(PG_GETARG_CSTRING(0));
+ JsonAggState *state;
+ char *token, *freestr;
+
+ state = (JsonAggState *) palloc0(sizeof (JsonAggState));
+ state->str = makeStringInfo();
+
+ freestr = str;
+
+ token = strsep(&str, ":");
+ state->val_category = atoi(token);
+ appendStringInfoString(state->str, str);
+
+ pfree(freestr);
+
+ PG_RETURN_POINTER(state);
+}
+
+/*
+ * json_agg_collectfn only needs the 'val_category' for formatting purposes. So
+ * only output that along with the json string
+ */
+Datum
+json_agg_state_out(PG_FUNCTION_ARGS)
+{
+ JsonAggState *state = (JsonAggState *) PG_GETARG_POINTER(0);
+ char *result;
+ int len = 15 + strlen(state->str->data);
+
+ result = (char *) palloc0(len);
+ sprintf(result, "%d:%s", state->val_category, state->str->data);
+
+ PG_RETURN_CSTRING(result);
+}
+#endif
/*
* makeJsonLexContext
*
state->str = makeStringInfo();
MemoryContextSwitchTo(oldcontext);
+#ifndef XCP
+ /*
+ * Do not add the start marker. It will be done by the
+ * json_agg_collectfn on receiving the first result
+ */
appendStringInfoChar(state->str, '[');
+#endif
json_categorize_type(arg_type, &state->val_category,
&state->val_output_func);
}
PG_RETURN_POINTER(state);
}
+#ifdef XCP
+/*
+ * json_agg collection function
+ */
+Datum
+json_agg_collectfn(PG_FUNCTION_ARGS)
+{
+ MemoryContext aggcontext,
+ oldcontext;
+ JsonAggState *collectstate;
+ JsonAggState *transstate;
+
+ if (!AggCheckCallContext(fcinfo, &aggcontext))
+ {
+ /* cannot be called directly because of internal-type argument */
+ elog(ERROR, "json_agg_collectfn called in non-aggregate context");
+ }
+
+
+ /* cannot be called directly because of internal-type argument */
+ Assert(AggCheckCallContext(fcinfo, NULL));
+
+ if (PG_ARGISNULL(0))
+ {
+ /*
+ * Make this state object in a context where it will persist for the
+ * duration of the aggregate call. MemoryContextSwitchTo is only
+ * needed the first time, as the StringInfo routines make sure they
+ * use the right context to enlarge the object if necessary.
+ */
+ oldcontext = MemoryContextSwitchTo(aggcontext);
+ collectstate = (JsonAggState *) palloc(sizeof(JsonAggState));
+ collectstate->str = makeStringInfo();
+ MemoryContextSwitchTo(oldcontext);
+
+ appendStringInfoChar(collectstate->str, '[');
+ }
+ else
+ {
+ collectstate = (JsonAggState *) PG_GETARG_POINTER(0);
+ if (!PG_ARGISNULL(1))
+ appendStringInfoString(collectstate->str, ", ");
+ }
+
+ /* fast path for NULLs */
+ if (PG_ARGISNULL(1))
+ PG_RETURN_POINTER(collectstate);
+
+ transstate = (JsonAggState *) PG_GETARG_POINTER(1);
+
+ /* add some whitespace if structured type and not first item */
+ if (!PG_ARGISNULL(0) &&
+ (transstate->val_category == JSONTYPE_ARRAY ||
+ transstate->val_category == JSONTYPE_COMPOSITE))
+ {
+ appendStringInfoString(collectstate->str, "\n ");
+ }
+
+ appendStringInfoString(collectstate->str, transstate->str->data);
+
+ PG_RETURN_POINTER(collectstate);
+}
+#endif
+
/*
* json_agg final function
*/
DESCR("map row to json");
DATA(insert OID = 3156 ( row_to_json PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 114 "2249 16" _null_ _null_ _null_ _null_ _null_ row_to_json_pretty _null_ _null_ _null_ ));
DESCR("map row to json with optional pretty printing");
-DATA(insert OID = 3173 ( json_agg_transfn PGNSP PGUID 12 1 0 0 0 f f f f f f s 2 0 2281 "2281 2283" _null_ _null_ _null_ _null_ _null_ json_agg_transfn _null_ _null_ _null_ ));
+DATA(insert OID = 3173 ( json_agg_transfn PGNSP PGUID 12 1 0 0 0 f f f f f f s 2 0 7028 "7028 2283" _null_ _null_ _null_ _null_ _null_ json_agg_transfn _null_ _null_ _null_ ));
DESCR("json aggregate transition function");
-DATA(insert OID = 3174 ( json_agg_finalfn PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 114 "2281" _null_ _null_ _null_ _null_ _null_ json_agg_finalfn _null_ _null_ _null_ ));
+DATA(insert OID = 7029 ( json_agg_collectfn PGNSP PGUID 12 1 0 0 0 f f f f f f s 2 0 7028 "7028 7028" _null_ _null_ _null_ _null_ _null_ json_agg_collectfn _null_ _null_ _null_ ));
+DESCR("json aggregate collection function");
+DATA(insert OID = 3174 ( json_agg_finalfn PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 114 "7028" _null_ _null_ _null_ _null_ _null_ json_agg_finalfn _null_ _null_ _null_ ));
DESCR("json aggregate final function");
DATA(insert OID = 3175 ( json_agg PGNSP PGUID 12 1 0 0 0 t f f f f f s 1 0 114 "2283" _null_ _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ ));
DESCR("aggregate input into json");
DESCR("I/O");
DATA(insert OID = 7023 ( numeric_poly_agg_state_send PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 17 "7019" _null_ _null_ _null_ _null_ _null_ numeric_poly_agg_state_send _null_ _null_ _null_ ));
DESCR("I/O");
+DATA(insert OID = 7030 ( json_agg_state_in PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 7028 "2275" _null_ _null_ _null_ _null_ _null_ json_agg_state_in _null_ _null_ _null_ ));
+DESCR("I/O");
+DATA(insert OID = 7025 ( json_agg_state_out PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2275 "7028" _null_ _null_ _null_ _null_ _null_ json_agg_state_out _null_ _null_ _null_ ));
+DESCR("I/O");
#endif
/* pg_upgrade support */
DATA(insert OID = 3582 ( binary_upgrade_set_next_pg_type_oid PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 2278 "26" _null_ _null_ _null_ _null_ _null_ binary_upgrade_set_next_pg_type_oid _null_ _null_ _null_ ));