Esempio n. 1
0
/*
 * regexp_split_to_array()
 *		Split the string at matches of the pattern, returning the
 *		split-out substrings as an array.
 */
Datum
regexp_split_to_array(PG_FUNCTION_ARGS)
{
	ArrayBuildState *astate = NULL;
	regexp_matches_ctx *splitctx;

	splitctx = setup_regexp_matches(PG_GETARG_TEXT_PP(0),
									PG_GETARG_TEXT_PP(1),
									PG_GETARG_TEXT_PP_IF_EXISTS(2),
									PG_GET_COLLATION(),
									true, false, true);

	while (splitctx->next_match <= splitctx->nmatches)
	{
		astate = accumArrayResult(astate,
								  build_regexp_split_result(splitctx),
								  false,
								  TEXTOID,
								  CurrentMemoryContext);
		splitctx->next_match++;
	}

	/*
	 * We don't call cleanup_regexp_matches here; it would try to pfree the
	 * input string, which we didn't copy.  The space is not in a long-lived
	 * memory context anyway.
	 */

	PG_RETURN_ARRAYTYPE_P(makeArrayResult(astate, CurrentMemoryContext));
}
Esempio n. 2
0
/*
 * regexp_matches()
 *		Return a table of matches of a pattern within a string.
 */
Datum
regexp_matches(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcctx;
	regexp_matches_ctx *matchctx;

	if (SRF_IS_FIRSTCALL())
	{
		text	   *pattern = PG_GETARG_TEXT_PP(1);
		text	   *flags = PG_GETARG_TEXT_PP_IF_EXISTS(2);
		MemoryContext oldcontext;

		funcctx = SRF_FIRSTCALL_INIT();
		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);

		/* be sure to copy the input string into the multi-call ctx */
		matchctx = setup_regexp_matches(PG_GETARG_TEXT_P_COPY(0), pattern,
										flags,
										PG_GET_COLLATION(),
										false, true, false);

		/* Pre-create workspace that build_regexp_matches_result needs */
		matchctx->elems = (Datum *) palloc(sizeof(Datum) * matchctx->npatterns);
		matchctx->nulls = (bool *) palloc(sizeof(bool) * matchctx->npatterns);

		MemoryContextSwitchTo(oldcontext);
		funcctx->user_fctx = (void *) matchctx;
	}

	funcctx = SRF_PERCALL_SETUP();
	matchctx = (regexp_matches_ctx *) funcctx->user_fctx;

	if (matchctx->next_match < matchctx->nmatches)
	{
		ArrayType  *result_ary;

		result_ary = build_regexp_matches_result(matchctx);
		matchctx->next_match++;
		SRF_RETURN_NEXT(funcctx, PointerGetDatum(result_ary));
	}

	/* release space in multi-call ctx to avoid intraquery memory leak */
	cleanup_regexp_matches(matchctx);

	SRF_RETURN_DONE(funcctx);
}
Esempio n. 3
0
/*
 * regexp_split_to_table()
 *		Split the string at matches of the pattern, returning the
 *		split-out substrings as a table.
 */
Datum
regexp_split_to_table(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcctx;
	regexp_matches_ctx *splitctx;

	if (SRF_IS_FIRSTCALL())
	{
		text	   *pattern = PG_GETARG_TEXT_PP(1);
		text	   *flags = PG_GETARG_TEXT_PP_IF_EXISTS(2);
		MemoryContext oldcontext;

		funcctx = SRF_FIRSTCALL_INIT();
		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);

		/* be sure to copy the input string into the multi-call ctx */
		splitctx = setup_regexp_matches(PG_GETARG_TEXT_P_COPY(0), pattern,
										flags,
										PG_GET_COLLATION(),
										true, false, true);

		MemoryContextSwitchTo(oldcontext);
		funcctx->user_fctx = (void *) splitctx;
	}

	funcctx = SRF_PERCALL_SETUP();
	splitctx = (regexp_matches_ctx *) funcctx->user_fctx;

	if (splitctx->next_match <= splitctx->nmatches)
	{
		Datum		result = build_regexp_split_result(splitctx);

		splitctx->next_match++;
		SRF_RETURN_NEXT(funcctx, result);
	}

	/* release space in multi-call ctx to avoid intraquery memory leak */
	cleanup_regexp_matches(splitctx);

	SRF_RETURN_DONE(funcctx);
}
Esempio n. 4
0
/*
 * regexp_matches()
 *		Return a table of matches of a pattern within a string.
 */
datum_t regexp_matches(PG_FUNC_ARGS)
{
	struct fcall_ctx *funcctx;
	regexp_matches_ctx *matchctx;

	if (SRF_IS_FIRSTCALL()) {
		text *pattern = ARG_TEXT_PP(1);
		text *flags = ARG_TEXT_PP_IF_EXISTS(2);
		struct mctx * oldcontext;

		funcctx = SRF_FIRSTCALL_INIT();
		oldcontext = mctx_switch(funcctx->multi_call_memory_ctx);

		/* be sure to copy the input string into the multi-call ctx */
		matchctx = setup_regexp_matches(ARG_TEXT_P_COPY(0), pattern,
			flags, PG_COLLATION(), false, true, false);

		/* Pre-create workspace that build_regexp_matches_result needs */
		matchctx->elems = (datum_t *) palloc(sizeof(datum_t) * matchctx->npatterns);
		matchctx->nulls = (bool *) palloc(sizeof(bool) * matchctx->npatterns);

		mctx_switch(oldcontext);
		funcctx->user_fctx = (void *)matchctx;
	}

	funcctx = SRF_PERCALL_SETUP();
	matchctx = (regexp_matches_ctx *) funcctx->user_fctx;

	if (matchctx->next_match < matchctx->nmatches) {
		array_s *result_ary;

		result_ary = build_regexp_matches_result(matchctx);
		matchctx->next_match++;
		SRF_RETURN_NEXT(funcctx, PTR_TO_D(result_ary));
	}

	/* release space in multi-call ctx to avoid intraquery memory leak */
	cleanup_regexp_matches(matchctx);

	SRF_RETURN_DONE(funcctx);
}
Esempio n. 5
0
/*
 * regexp_split_to_array()
 *		Split the string at matches of the pattern, returning the
 *		split-out substrings as an array.
 */
datum_t regexp_split_to_array(PG_FUNC_ARGS)
{
	array_build_s *astate = NULL;
	regexp_matches_ctx *splitctx;

	splitctx = setup_regexp_matches(ARG_TEXT_PP(0), ARG_TEXT_PP(1),
		ARG_TEXT_PP_IF_EXISTS(2), PG_COLLATION(), true, false, true);

	while (splitctx->next_match <= splitctx->nmatches) {
		astate = accum_array_result(astate,
			build_regexp_split_result(splitctx),
			false, TEXTOID, current_mctx);
		splitctx->next_match++;
	}

	/*
	 * We don't call cleanup_regexp_matches here; it would try to pfree the
	 * input string, which we didn't copy.  The space is not in a long-lived
	 * memory context anyway.
	 */

	RET_ARRAY_P(make_array_result(astate, current_mctx));
}
Esempio n. 6
0
/*
 * regexp_split_to_array()
 *		Split the string at matches of the pattern, returning the
 *		split-out substrings as an array.
 */
Datum
regexp_split_to_array(PG_FUNCTION_ARGS)
{
	ArrayBuildState *astate = NULL;
	regexp_matches_ctx *splitctx;

	splitctx = setup_regexp_matches(PG_GETARG_TEXT_PP(0),
									PG_GETARG_TEXT_PP(1),
									PG_GETARG_TEXT_PP_IF_EXISTS(2),
									PG_GET_COLLATION(),
									true, false, true, true);

	while (splitctx->next_match <= splitctx->nmatches)
	{
		astate = accumArrayResult(astate,
								  build_regexp_split_result(splitctx),
								  false,
								  TEXTOID,
								  CurrentMemoryContext);
		splitctx->next_match++;
	}

	PG_RETURN_ARRAYTYPE_P(makeArrayResult(astate, CurrentMemoryContext));
}