예제 #1
0
파일: plvstr.c 프로젝트: protodef/orafce
Datum
plvstr_betwn_i(PG_FUNCTION_ARGS)
{
	text *string_in = PG_GETARG_TEXT_P(0);
	int start_in = PG_GETARG_INT32(1);
	int end_in = PG_GETARG_INT32(2);
	bool inclusive = PG_GETARG_BOOL(3);

	if ((start_in < 0 && end_in > 0) ||
		(start_in > 0 && end_in < 0) ||
		(start_in > end_in))
		PARAMETER_ERROR("Wrong positions.");

	if (start_in < 0)
	{
		int v_len =  ora_mb_strlen1(string_in);
		start_in = v_len + start_in + 1;
		end_in = v_len + start_in + 1;
	}

	if (!inclusive)
	{
		start_in += 1;
		end_in -= 1;

		if (start_in > end_in)
			PG_RETURN_TEXT_P(cstring_to_text(""));
	}

	PG_RETURN_TEXT_P(ora_substr_text(string_in,
									 start_in,
									 end_in - start_in + 1));
}
예제 #2
0
파일: plvstr.c 프로젝트: protodef/orafce
Datum
plvstr_swap(PG_FUNCTION_ARGS)
{
	text *string_in;
	text *replace_in;
	int start_in = 1;
	int oldlen_in;
	int v_len;

	if (PG_ARGISNULL(0))
		PG_RETURN_NULL();
	else
		string_in = PG_GETARG_TEXT_P(0);

	if (PG_ARGISNULL(1))
		PG_RETURN_NULL();
	else
		replace_in = PG_GETARG_TEXT_P(1);

	if (!PG_ARGISNULL(2))
		start_in = PG_GETARG_INT32(2);

	if (PG_ARGISNULL(3))
		oldlen_in = ora_mb_strlen1(replace_in);
	else
		oldlen_in = PG_GETARG_INT32(3);

	v_len =  ora_mb_strlen1(string_in);

	start_in = start_in > 0 ? start_in : v_len + start_in + 1;

	if (start_in == 0 || start_in > v_len)
		PG_RETURN_TEXT_P(TextPCopy(string_in));
	else if (start_in == 1)
		PG_RETURN_TEXT_P(ora_concat2(
			replace_in, ora_substr_text(string_in, oldlen_in+1, -1)));
	else
		PG_RETURN_TEXT_P(ora_concat3(
			ora_substr_text(string_in, 1, start_in - 1),
			replace_in,
			ora_substr_text(string_in, start_in + oldlen_in, -1)));
}
예제 #3
0
파일: plvstr.c 프로젝트: protodef/orafce
Datum
plvstr_right (PG_FUNCTION_ARGS)
{
	text *str = PG_GETARG_TEXT_P(0);
	int n = PG_GETARG_INT32(1);
	if (n < 0)
		n = ora_mb_strlen1(str) + n;
	n = (n < 0) ? 0 : n;

	PG_RETURN_TEXT_P(ora_substr_text(str, -n, -1));
}
예제 #4
0
파일: plvstr.c 프로젝트: protodef/orafce
Datum
plvstr_betwn_c(PG_FUNCTION_ARGS)
{
	text *string_in;
	text *start_in;
	text *end_in;
	int startnth_in;
	int endnth_in;
	bool inclusive;
	bool gotoend;

	int v_start;
	int v_end;

	if (PG_ARGISNULL(0) || PG_ARGISNULL(1) ||
		PG_ARGISNULL(3) || PG_ARGISNULL(4) ||
		PG_ARGISNULL(5) || PG_ARGISNULL(6))
		PG_RETURN_NULL();


	string_in = PG_GETARG_TEXT_P(0);
	start_in = PG_GETARG_TEXT_P(1);
	end_in = PG_ARGISNULL(2) ? start_in : PG_GETARG_TEXT_P(2);
	startnth_in = PG_GETARG_INT32(3);
	endnth_in = PG_GETARG_INT32(4);
	inclusive = PG_GETARG_BOOL(5);
	gotoend = PG_GETARG_BOOL(6);

	if (startnth_in == 0)
	{
		v_start = 1;
		v_end = ora_instr(string_in, end_in, 1, endnth_in);
	}
	else
	{
		v_start = ora_instr(string_in, start_in, 1, startnth_in);
		v_end = ora_instr(string_in, end_in, v_start + 1, endnth_in);
	}

	if (v_start == 0)
		PG_RETURN_NULL();

	if (!inclusive)
	{
		if (startnth_in > 0)
			v_start += ora_mb_strlen1(start_in);

		v_end -= 1;
	}
	else
		v_end += (ora_mb_strlen1(end_in) - 1);

	if (((v_start > v_end) && (v_end > 0)) ||
		(v_end <= 0 && !gotoend))
		PG_RETURN_NULL();

	if (v_end <= 0)
		v_end = ora_mb_strlen1(string_in);

	PG_RETURN_TEXT_P(ora_substr_text(string_in,
									 v_start,
									 v_end - v_start + 1));
}
예제 #5
0
파일: plvsubst.c 프로젝트: 50wu/gpdb
static text*
plvsubst_string(text *template_in, ArrayType *vals_in, text *c_subst, FunctionCallInfo fcinfo)
{
	ArrayType	   *v = vals_in;
	int				nitems,
				   *dims,
					ndims;
	char		   *p;
	int16			typlen;
	bool			typbyval;
	char			typalign;
	char			typdelim;
	Oid				typelem;
	Oid				typiofunc;
	FmgrInfo		proc;
	int				i = 0, items = 0;
	StringInfo		sinfo;
	const char	   *template_str;
	int				template_len;
	char		   *sizes;
	int			   *positions;
	int				subst_mb_len;
	int				subst_len;
	const bits8	   *bitmap;
	int				bitmask;

	if (v != NULL && (ndims = ARR_NDIM(v)) > 0)
	{
		if (ndims != 1)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("invalid parameter"),
					 errdetail("Array of arguments has wrong dimension: %d", ndims)));

		p = ARR_DATA_PTR(v);
		dims = ARR_DIMS(v);
		nitems = ArrayGetNItems(ndims, dims);
		bitmap = ARR_NULLBITMAP(v);
		get_type_io_data(ARR_ELEMTYPE(v), IOFunc_output,
							&typlen, &typbyval,
							&typalign, &typdelim,
							&typelem, &typiofunc);
		fmgr_info_cxt(typiofunc, &proc, fcinfo->flinfo->fn_mcxt);
	}
	else
	{
		nitems = 0;
		p = NULL;
		bitmap = NULL;
	}

	template_str = VARDATA(template_in);
	template_len = ora_mb_strlen(template_in, &sizes, &positions);
	subst_mb_len = ora_mb_strlen1(c_subst);
	subst_len = VARSIZE_ANY_EXHDR(c_subst);
	sinfo = makeStringInfo();

	bitmask = 1;
	for (i = 0; i < template_len; i++)
	{
		if (strncmp(&template_str[positions[i]], VARDATA(c_subst), subst_len) == 0)
		{
			Datum    itemvalue;
			char     *value;

			if (items++ < nitems)
			{
				if (bitmap && (*bitmap & bitmask) == 0)
					value = pstrdup("NULL");
				else
				{
					itemvalue = fetch_att(p, typbyval, typlen);
					value = DatumGetCString(FunctionCall3(&proc,
								itemvalue,
								ObjectIdGetDatum(typelem),
								Int32GetDatum(-1)));

					p = att_addlength_pointer(p, typlen, p);
					p = (char *) att_align_nominal(p, typalign);
				}
				appendStringInfoString(sinfo, value);
				pfree(value);

				if (bitmap)
				{
					bitmask <<= 1;
					if (bitmask == 0x100)
					{
						bitmap++;
						bitmask = 1;
					}
				}
			}
			else
				ereport(ERROR,
						(errcode(ERRCODE_SYNTAX_ERROR),
						 errmsg("too few parameters specified for template string")));

			i += subst_mb_len - 1;
		}
		else
			appendBinaryStringInfo(sinfo, &template_str[positions[i]], sizes[i]);
	}

	return cstring_to_text(sinfo->data);
}