Esempio n. 1
0
File: tsearch2.c Progetto: 50wu/gpdb
/* headline(text, text, tsquery [,text]) */
Datum
tsa_headline_byname(PG_FUNCTION_ARGS)
{
	Datum		arg0 = PG_GETARG_DATUM(0);
	Datum		arg1 = PG_GETARG_DATUM(1);
	Datum		arg2 = PG_GETARG_DATUM(2);
	Datum		result;
	Oid			config_oid;

	/* first parameter has to be converted to oid */
	config_oid = DatumGetObjectId(DirectFunctionCall1(regconfigin,
										DirectFunctionCall1(textout, arg0)));

	if (PG_NARGS() == 3)
		result = DirectFunctionCall3(ts_headline_byid,
								   ObjectIdGetDatum(config_oid), arg1, arg2);
	else
	{
		Datum		arg3 = PG_GETARG_DATUM(3);

		result = DirectFunctionCall4(ts_headline_byid_opt,
									 ObjectIdGetDatum(config_oid),
									 arg1, arg2, arg3);
	}

	return result;
}
Esempio n. 2
0
Datum
ora_to_date(PG_FUNCTION_ARGS)
{
	text *date_txt = PG_GETARG_TEXT_PP(0);
	Timestamp result;

	if(nls_date_format && strlen(nls_date_format))
	{
		Datum newDate;

		/* it will return timestamp at GMT */
		newDate = DirectFunctionCall2(to_timestamp,
							CStringGetDatum(date_txt),
							CStringGetDatum(cstring_to_text(nls_date_format)));

		/* convert to local timestamp */
		result = DatumGetTimestamp(DirectFunctionCall1(timestamptz_timestamp, newDate));
	}
	else
		result = DatumGetTimestamp(DirectFunctionCall3(timestamp_in,
									CStringGetDatum(text_to_cstring(date_txt)),
									ObjectIdGetDatum(InvalidOid),
									Int32GetDatum(-1)));

	PG_RETURN_TIMESTAMP(result);
}
Esempio n. 3
0
/*
** The GiST Consistent method for _intments
** Should return false if for all data items x below entry,
** the predicate x op query == FALSE, where op is the oper
** corresponding to strategy in the pg_amop table.
*/
Datum
g_int_consistent(PG_FUNCTION_ARGS)
{
	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
	ArrayType  *query = (ArrayType *) PG_DETOAST_DATUM_COPY(PG_GETARG_POINTER(1));
	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
	bool		retval;

	if (strategy == BooleanSearchStrategy) {
		 retval =execconsistent((QUERYTYPE *) query,
							   (ArrayType *) DatumGetPointer(entry->key),
				  ISLEAFKEY((ArrayType *) DatumGetPointer(entry->key)));
		pfree( query );

		PG_RETURN_BOOL(retval);
	}

	/* sort query for fast search, key is already sorted */
	if (ARRISVOID(query)) {
		pfree( query );
		PG_RETURN_BOOL(false);
	}
	PREPAREARR(query);

	switch (strategy)
	{
		case RTOverlapStrategyNumber:
			retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key),
									   query);
			break;
		case RTSameStrategyNumber:
			if (GIST_LEAF(entry))
				DirectFunctionCall3(
									g_int_same,
									entry->key,
									PointerGetDatum(query),
									PointerGetDatum(&retval)
					);
			else
				retval = inner_int_contains((ArrayType *) DatumGetPointer(entry->key),
											query);
			break;
		case RTContainsStrategyNumber:
			retval = inner_int_contains((ArrayType *) DatumGetPointer(entry->key),
										query);
			break;
		case RTContainedByStrategyNumber:
			if (GIST_LEAF(entry))
				retval = inner_int_contains(query,
							  (ArrayType *) DatumGetPointer(entry->key));
			else
				retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key),
										   query);
			break;
		default:
			retval = FALSE;
	}
	pfree( query );
	PG_RETURN_BOOL(retval);
}
Esempio n. 4
0
/*
 * build_regexp_split_result - build output string for current match
 *
 * We return the string between the current match and the previous one,
 * or the string after the last match when next_match == nmatches.
 */
static Datum
build_regexp_split_result(regexp_matches_ctx *splitctx)
{
	int			startpos;
	int			endpos;

	if (splitctx->next_match > 0)
		startpos = splitctx->match_locs[splitctx->next_match * 2 - 1];
	else
		startpos = 0;
	if (startpos < 0)
		elog(ERROR, "invalid match ending position");

	if (splitctx->next_match < splitctx->nmatches)
	{
		endpos = splitctx->match_locs[splitctx->next_match * 2];
		if (endpos < startpos)
			elog(ERROR, "invalid match starting position");
		return DirectFunctionCall3(text_substr,
								   PointerGetDatum(splitctx->orig_str),
								   Int32GetDatum(startpos + 1),
								   Int32GetDatum(endpos - startpos));
	}
	else
	{
		/* no more matches, return rest of string */
		return DirectFunctionCall2(text_substr_no_len,
								   PointerGetDatum(splitctx->orig_str),
								   Int32GetDatum(startpos + 1));
	}
}
Datum ST_LocateBetween(PG_FUNCTION_ARGS)
{
	GSERIALIZED *geom_in = PG_GETARG_GSERIALIZED_P(0);
	double from = PG_GETARG_FLOAT8(1);
	double to = PG_GETARG_FLOAT8(2);
	double offset = PG_GETARG_FLOAT8(3);
	LWCOLLECTION *geom_out = NULL;
	LWGEOM *line_in = NULL;
	static char ordinate = 'M'; /* M */

	if ( ! gserialized_has_m(geom_in) )
	{
		elog(ERROR,"This function only accepts geometries that have an M dimension.");
		PG_RETURN_NULL();
	}

	/* This should be a call to ST_LocateAlong! */
	if ( to == from )
	{
		PG_RETURN_DATUM(DirectFunctionCall3(ST_LocateAlong, PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), PG_GETARG_DATUM(3)));
	}

	line_in = lwgeom_from_gserialized(geom_in);
	geom_out = lwgeom_clip_to_ordinate_range(line_in,  ordinate, from, to, offset);	
	lwgeom_free(line_in);
	PG_FREE_IF_COPY(geom_in, 0);

	if ( ! geom_out )
	{
		elog(ERROR,"lwline_clip_to_ordinate_range returned null");
		PG_RETURN_NULL();
	}

	PG_RETURN_POINTER(geometry_serialize((LWGEOM*)geom_out));
}
Esempio n. 6
0
/*
 * len < 0 means "length is not specified".
 */
static text *
ora_substr(Datum str, int start, int len)
{
	if (start == 0)
		start = 1;	/* 0 is interpreted as 1 */
	else if (start < 0)
	{
		text   *t;
		int32	n;

		t = DatumGetTextPP(str);
		n = pg_mbstrlen_with_len(VARDATA_ANY(t), VARSIZE_ANY_EXHDR(t));
		start = n + start + 1;
		if (start <= 0)
			return cstring_to_text("");
		str = PointerGetDatum(t);	/* save detoasted text */
	}

	if (len < 0)
		return DatumGetTextP(DirectFunctionCall2(text_substr_no_len,
			str, Int32GetDatum(start)));
	else
		return DatumGetTextP(DirectFunctionCall3(text_substr,
			str, Int32GetDatum(start), Int32GetDatum(len)));
}
Esempio n. 7
0
Datum
pgstrom_numeric_var_accum(PG_FUNCTION_ARGS)
{
	int32			nrows = PG_GETARG_INT32(1);
	MemoryContext	aggcxt;
	MemoryContext	oldcxt;
	numeric_agg_state *state;

	if (!AggCheckCallContext(fcinfo, &aggcxt))
		elog(ERROR, "aggregate function called in non-aggregate context");

	if (PG_ARGISNULL(1))
		nrows = 0;
	else if (nrows < 0)
		elog(ERROR, "Bug? negative nrows were given");

	/* make a state object and update it */
	oldcxt = MemoryContextSwitchTo(aggcxt);
	state = PG_ARGISNULL(0) ? NULL : (numeric_agg_state *)PG_GETARG_POINTER(0);
	if (!state)
	{
		state = palloc0(sizeof(numeric_agg_state));
		state->N = 0;
		state->sumX = DirectFunctionCall3(numeric_in,
										  CStringGetDatum("0"),
										  ObjectIdGetDatum(0),
										  Int32GetDatum(-1));
		state->sumX2 = DirectFunctionCall3(numeric_in,
										   CStringGetDatum("0"),
										   ObjectIdGetDatum(0),
										   Int32GetDatum(-1));
	}

	if (nrows > 0 && !PG_ARGISNULL(2) && !PG_ARGISNULL(3))
	{
		state->N += nrows;
		state->sumX = DirectFunctionCall2(numeric_add,
										  state->sumX,
										  PG_GETARG_DATUM(2));
		state->sumX2 = DirectFunctionCall2(numeric_add,
										   state->sumX2,
										   PG_GETARG_DATUM(3));
	}
	MemoryContextSwitchTo(oldcxt);

	PG_RETURN_POINTER(state);
}
Esempio n. 8
0
/*
 * Returns start time of an online exclusive backup.
 *
 * When there's no exclusive backup in progress, the function
 * returns NULL.
 */
Datum
pg_backup_start_time(PG_FUNCTION_ARGS)
{
	Datum		xtime;
	FILE	   *lfp;
	char		fline[MAXPGPATH];
	char		backup_start_time[30];

	/*
	 * See if label file is present
	 */
	lfp = AllocateFile(BACKUP_LABEL_FILE, "r");
	if (lfp == NULL)
	{
		if (errno != ENOENT)
			ereport(ERROR,
					(errcode_for_file_access(),
					 errmsg("could not read file \"%s\": %m",
							BACKUP_LABEL_FILE)));
		PG_RETURN_NULL();
	}

	/*
	 * Parse the file to find the START TIME line.
	 */
	backup_start_time[0] = '\0';
	while (fgets(fline, sizeof(fline), lfp) != NULL)
	{
		if (sscanf(fline, "START TIME: %25[^\n]\n", backup_start_time) == 1)
			break;
	}

	/* Check for a read error. */
	if (ferror(lfp))
		ereport(ERROR,
				(errcode_for_file_access(),
			   errmsg("could not read file \"%s\": %m", BACKUP_LABEL_FILE)));

	/* Close the backup label file. */
	if (FreeFile(lfp))
		ereport(ERROR,
				(errcode_for_file_access(),
			  errmsg("could not close file \"%s\": %m", BACKUP_LABEL_FILE)));

	if (strlen(backup_start_time) == 0)
		ereport(ERROR,
				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
				 errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));

	/*
	 * Convert the time string read from file to TimestampTz form.
	 */
	xtime = DirectFunctionCall3(timestamptz_in,
								CStringGetDatum(backup_start_time),
								ObjectIdGetDatum(InvalidOid),
								Int32GetDatum(-1));

	PG_RETURN_DATUM(xtime);
}
Esempio n. 9
0
static Datum
leftmostvalue_varbit(void)
{
	return DirectFunctionCall3(varbit_in,
							   CStringGetDatum(""),
							   ObjectIdGetDatum(0),
							   Int32GetDatum(-1));
}
Esempio n. 10
0
Datum
ginqueryarrayextract(PG_FUNCTION_ARGS)
{
	PG_RETURN_DATUM(DirectFunctionCall3(ginarrayextract,
										PG_GETARG_DATUM(0),
										PG_GETARG_DATUM(1),
										PG_GETARG_DATUM(2)));
}
Esempio n. 11
0
static Datum
leftmostvalue_inet(void)
{
	return DirectFunctionCall3(inet_in,
							   CStringGetDatum("0.0.0.0/0"),
							   ObjectIdGetDatum(0),
							   Int32GetDatum(-1));
}
Esempio n. 12
0
Datum
ts_headline_byid(PG_FUNCTION_ARGS)
{
	PG_RETURN_DATUM(DirectFunctionCall3(ts_headline_byid_opt,
										PG_GETARG_DATUM(0),
										PG_GETARG_DATUM(1),
										PG_GETARG_DATUM(2)));
}
Esempio n. 13
0
Datum
ts_headline(PG_FUNCTION_ARGS)
{
	PG_RETURN_DATUM(DirectFunctionCall3(ts_headline_byid_opt,
								  ObjectIdGetDatum(getTSCurrentConfig(true)),
										PG_GETARG_DATUM(0),
										PG_GETARG_DATUM(1)));
}
Esempio n. 14
0
Datum
spheretrans_from_float8_and_type(PG_FUNCTION_ARGS)
{
	SEuler	   *se;
	Datum		d[3];
	int			i;
	char	   *c = PG_GETARG_CSTRING(3);
	unsigned char t = 0;

	d[0] = PG_GETARG_DATUM(0);
	d[1] = PG_GETARG_DATUM(1);
	d[2] = PG_GETARG_DATUM(2);
	se = (SEuler *) DatumGetPointer(
						DirectFunctionCall3(spheretrans_from_float8,
											d[0], d[1], d[2]));

	for (i = 0; i < 3; i++)
	{
		switch (c[i])
		{
			case 'x':
			case 'X':
				t = EULER_AXIS_X;
				break;
			case 'y':
			case 'Y':
				t = EULER_AXIS_Y;
				break;
			case 'z':
			case 'Z':
				t = EULER_AXIS_Z;
				break;
			default:
				t = 0;
		}

		if (t == 0)
		{
			pfree(se);
			elog(ERROR, "invalid axis format");
		}
		switch (i)
		{
			case 0:
				se->phi_a = t;
				break;
			case 1:
				se->theta_a = t;
				break;
			case 2:
				se->psi_a = t;
				break;
		}
	}
	PG_RETURN_POINTER(se);

}
Esempio n. 15
0
Datum
tsquery_phrase(PG_FUNCTION_ARGS)
{
	PG_RETURN_POINTER(DirectFunctionCall3(
										  tsquery_phrase_distance,
										  PG_GETARG_DATUM(0),
										  PG_GETARG_DATUM(1),
										  Int32GetDatum(1)));
}
Esempio n. 16
0
/*
** The GiST Consistent method for _intments
** Should return false if for all data items x below entry,
** the predicate x op query == FALSE, where op is the oper
** corresponding to strategy in the pg_amop table.
*/
Datum
g_int_consistent(PG_FUNCTION_ARGS)
{
    GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
    ArrayType  *query = (ArrayType *) PG_GETARG_POINTER(1);
    StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
    bool		retval;

    if (strategy == BooleanSearchStrategy)
        PG_RETURN_BOOL(execconsistent((QUERYTYPE *) query,
                                      (ArrayType *) DatumGetPointer(entry->key),
                                      ISLEAFKEY((ArrayType *) DatumGetPointer(entry->key))));

    /* XXX are we sure it's safe to scribble on the query object here? */
    /* XXX what about toasted input? */
    /* sort query for fast search, key is already sorted */
    if (ARRISVOID(query))
        PG_RETURN_BOOL(false);
    PREPAREARR(query);

    switch (strategy)
    {
    case RTOverlapStrategyNumber:
        retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key),
                                   query);
        break;
    case RTSameStrategyNumber:
        if (GIST_LEAF(entry))
            DirectFunctionCall3(
                g_int_same,
                entry->key,
                PointerGetDatum(query),
                PointerGetDatum(&retval)
            );
        else
            retval = inner_int_contains((ArrayType *) DatumGetPointer(entry->key),
                                        query);
        break;
    case RTContainsStrategyNumber:
        retval = inner_int_contains((ArrayType *) DatumGetPointer(entry->key),
                                    query);
        break;
    case RTContainedByStrategyNumber:
        if (GIST_LEAF(entry))
            retval = inner_int_contains(query,
                                        (ArrayType *) DatumGetPointer(entry->key));
        else
            retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key),
                                       query);
        break;
    default:
        retval = FALSE;
    }
    PG_RETURN_BOOL(retval);
}
Esempio n. 17
0
Datum decimal64_numeric(PG_FUNCTION_ARGS)
{
        PGDecimal64 a = PG_GETARG_DECIMAL64(0);
        Datum ret;
        char s[DECDOUBLE_String];

        decDoubleToString(&a, s);
        ret = DirectFunctionCall3(numeric_in, 
                        CStringGetDatum(s), Int32GetDatum(0), Int32GetDatum(-1));
        PG_RETURN_DATUM(ret);
}
Esempio n. 18
0
Datum geography_from_text(PG_FUNCTION_ARGS)
{
	text *wkt_text = PG_GETARG_TEXT_P(0);
	/* Extract the cstring from the varlena */
	char *wkt = text2cstring(wkt_text);
	/* Pass the cstring to the input parser, and magic occurs! */
	Datum rv = DirectFunctionCall3(geography_in, PointerGetDatum(wkt), Int32GetDatum(0), Int32GetDatum(-1));
	/* Clean up and return */
	pfree(wkt);
	PG_RETURN_DATUM(rv);
}
Esempio n. 19
0
Datum
to_tsvector_current(PG_FUNCTION_ARGS)
{
	Datum		res = DirectFunctionCall3(
										  to_tsvector,
										  Int32GetDatum(get_currcfg()),
										  PG_GETARG_DATUM(0),
										  (Datum) 0
	);

	PG_RETURN_DATUM(res);
}
Esempio n. 20
0
/* Invokes a compression constructor */
CompressionState *
callCompressionConstructor(PGFunction constructor,
						   TupleDesc tupledesc,
						   StorageAttributes *sa,
						   bool is_compress)
{
  return DatumGetPointer(DirectFunctionCall3(constructor,
											 PointerGetDatum(tupledesc),
											 PointerGetDatum(sa),
											 BoolGetDatum(is_compress)));

}
Esempio n. 21
0
/*
 * textregexsubstr()
 *		Return a substring matched by a regular expression.
 */
Datum
textregexsubstr(PG_FUNCTION_ARGS)
{
	text	   *s = PG_GETARG_TEXT_PP(0);
	text	   *p = PG_GETARG_TEXT_PP(1);
	regex_t    *re;
	regmatch_t	pmatch[2];
	int			so,
				eo;

	/* Compile RE */
	re = RE_compile_and_cache(p, REG_ADVANCED, PG_GET_COLLATION());

	/*
	 * We pass two regmatch_t structs to get info about the overall match and
	 * the match for the first parenthesized subexpression (if any). If there
	 * is a parenthesized subexpression, we return what it matched; else
	 * return what the whole regexp matched.
	 */
	if (!RE_execute(re,
					VARDATA_ANY(s), VARSIZE_ANY_EXHDR(s),
					2, pmatch))
		PG_RETURN_NULL();		/* definitely no match */

	if (re->re_nsub > 0)
	{
		/* has parenthesized subexpressions, use the first one */
		so = pmatch[1].rm_so;
		eo = pmatch[1].rm_eo;
	}
	else
	{
		/* no parenthesized subexpression, use whole match */
		so = pmatch[0].rm_so;
		eo = pmatch[0].rm_eo;
	}

	/*
	 * It is possible to have a match to the whole pattern but no match for a
	 * subexpression; for example 'foo(bar)?' is considered to match 'foo' but
	 * there is no subexpression match.  So this extra test for match failure
	 * is not redundant.
	 */
	if (so < 0 || eo < 0)
		PG_RETURN_NULL();

	return DirectFunctionCall3(text_substr,
							   PointerGetDatum(s),
							   Int32GetDatum(so + 1),
							   Int32GetDatum(eo - so));
}
Esempio n. 22
0
/*
 * build_regexp_matches_result - build output array for current match
 */
static ArrayType *
build_regexp_matches_result(regexp_matches_ctx *matchctx)
{
	char	   *buf = matchctx->conv_buf;
	int			bufsiz PG_USED_FOR_ASSERTS_ONLY = matchctx->conv_bufsiz;
	Datum	   *elems = matchctx->elems;
	bool	   *nulls = matchctx->nulls;
	int			dims[1];
	int			lbs[1];
	int			loc;
	int			i;

	/* Extract matching substrings from the original string */
	loc = matchctx->next_match * matchctx->npatterns * 2;
	for (i = 0; i < matchctx->npatterns; i++)
	{
		int			so = matchctx->match_locs[loc++];
		int			eo = matchctx->match_locs[loc++];

		if (so < 0 || eo < 0)
		{
			elems[i] = (Datum) 0;
			nulls[i] = true;
		}
		else if (buf)
		{
			int		len = pg_wchar2mb_with_len(matchctx->wide_str + so,
											   buf,
											   eo - so);
			Assert(len < bufsiz);
			elems[i] = PointerGetDatum(cstring_to_text_with_len(buf, len));
			nulls[i] = false;
		}
		else
		{
			elems[i] = DirectFunctionCall3(text_substr,
										 PointerGetDatum(matchctx->orig_str),
										   Int32GetDatum(so + 1),
										   Int32GetDatum(eo - so));
			nulls[i] = false;
		}
	}

	/* And form an array */
	dims[0] = matchctx->npatterns;
	lbs[0] = 1;
	/* XXX: this hardcodes assumptions about the text type */
	return construct_md_array(elems, nulls, 1, dims, lbs,
							  TEXTOID, -1, false, 'i');
}
Esempio n. 23
0
/*
 * pgstrom.psum_x2(numeric)
 */
Datum
pgstrom_partial_sum_x2_numeric(PG_FUNCTION_ARGS)
{
	Datum		value;

	if (!PG_ARGISNULL(0))
		value = PG_GETARG_DATUM(0);	/* a valid numeric value */
	else
		value = DirectFunctionCall3(numeric_in,
									CStringGetDatum("0"),
									ObjectIdGetDatum(InvalidOid),
									Int32GetDatum(-1));
	return DirectFunctionCall2(numeric_mul, value, value);
}
Esempio n. 24
0
Datum
to_tsvector_name(PG_FUNCTION_ARGS)
{
	text	   *cfg = PG_GETARG_TEXT_P(0);
	Datum		res = DirectFunctionCall3(
										  to_tsvector,
										  Int32GetDatum(name2id_cfg(cfg)),
										  PG_GETARG_DATUM(1),
										  (Datum) 0
	);

	PG_FREE_IF_COPY(cfg, 0);
	PG_RETURN_DATUM(res);
}
Esempio n. 25
0
File: cdbsreh.c Progetto: LJoNe/gpdb
/*
 * Utility to convert PGresult cell in text to Datum
 */
static Datum
ResultToDatum(PGresult *result, int row, AttrNumber attnum, PGFunction func, bool *isnull)
{
	if (PQgetisnull(result, row, attnum))
	{
		*isnull = true;
		return (Datum) 0;
	}
	else
	{
		*isnull = false;
		return DirectFunctionCall3(func,
				CStringGetDatum(PQgetvalue(result, row, attnum)),
				ObjectIdGetDatum(InvalidOid), Int32GetDatum(-1));
	}
}
Esempio n. 26
0
/*
 * Convert string using encoding_nanme. We assume that string's
 * encoding is same as DB encoding.
 *
 * TEXT convert(TEXT string, NAME encoding_name) */
Datum
pg_convert(PG_FUNCTION_ARGS)
{
	Datum		string = PG_GETARG_DATUM(0);
	Datum		dest_encoding_name = PG_GETARG_DATUM(1);
	Datum		src_encoding_name = DirectFunctionCall1(
						namein, CStringGetDatum(DatabaseEncoding->name));
	Datum		result;

	result = DirectFunctionCall3(
			 pg_convert2, string, src_encoding_name, dest_encoding_name);

	/* free memory allocated by namein */
	pfree((void *) src_encoding_name);

	PG_RETURN_TEXT_P(result);
}
Esempio n. 27
0
Datum
setval3_mirror(PG_FUNCTION_ARGS)
{
	Oid			relid = PG_GETARG_OID(0);
	int64		next = PG_GETARG_INT64(1);
	bool		iscalled = PG_GETARG_BOOL(2);
	int64		result;

	result = DatumGetInt64(DirectFunctionCall3(setval3_oid,
											   ObjectIdGetDatum(relid),
											   Int64GetDatum(next),
											   BoolGetDatum(iscalled)));

	saveSequenceUpdate(relid, result, iscalled);

	PG_RETURN_INT64(result);
}
Esempio n. 28
0
/*
 * textregexsubstr()
 *		Return a substring matched by a regular expression.
 */
Datum
textregexsubstr(PG_FUNCTION_ARGS)
{
	text	   *s = PG_GETARG_TEXT_P(0);
	text	   *p = PG_GETARG_TEXT_P(1);
	bool		match;
	regmatch_t	pmatch[2];

	/*
	 * We pass two regmatch_t structs to get info about the overall match and
	 * the match for the first parenthesized subexpression (if any). If there
	 * is a parenthesized subexpression, we return what it matched; else
	 * return what the whole regexp matched.
	 */
	match = RE_compile_and_execute(p,
								   VARDATA(s),
								   VARSIZE(s) - VARHDRSZ,
								   regex_flavor,
								   2, pmatch);

	/* match? then return the substring matching the pattern */
	if (match)
	{
		int			so,
					eo;

		so = pmatch[1].rm_so;
		eo = pmatch[1].rm_eo;
		if (so < 0 || eo < 0)
		{
			/* no parenthesized subexpression */
			so = pmatch[0].rm_so;
			eo = pmatch[0].rm_eo;
		}

		return DirectFunctionCall3(text_substr,
								   PointerGetDatum(s),
								   Int32GetDatum(so + 1),
								   Int32GetDatum(eo - so));
	}

	PG_RETURN_NULL();
}
Esempio n. 29
0
Datum geography_from_binary(PG_FUNCTION_ARGS)
{
	char *wkb_cstring = NULL;
	text *wkb_hex = NULL;
	char *wkb_bytea = (char*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
	char *hexarg = palloc(4 + VARHDRSZ);

	/* Create our second argument to binary_encode */
	SET_VARSIZE(hexarg, 4 + VARHDRSZ);
	memcpy(VARDATA(hexarg), "hex", 4);

	/* Convert the bytea into a hex representation cstring */
	wkb_hex = (text*)DatumGetPointer(DirectFunctionCall2(binary_encode, PointerGetDatum(wkb_bytea), PointerGetDatum(hexarg)));
	wkb_cstring = text2cstring(wkb_hex);
	pfree(hexarg);

	/* Pass the cstring to the input parser, and magic occurs! */
	PG_RETURN_DATUM(DirectFunctionCall3(geography_in, PointerGetDatum(wkb_cstring), Int32GetDatum(0), Int32GetDatum(-1)));
}
Esempio n. 30
0
/*
 * Convert string using encoding_name. The source
 * encoding is the DB encoding.
 *
 * BYTEA convert_to(TEXT string, NAME encoding_name) */
Datum
pg_convert_to(PG_FUNCTION_ARGS)
{
	Datum		string = PG_GETARG_DATUM(0);
	Datum		dest_encoding_name = PG_GETARG_DATUM(1);
	Datum		src_encoding_name = DirectFunctionCall1(namein,
									CStringGetDatum(DatabaseEncoding->name));
	Datum		result;

	/*
	 * pg_convert expects a bytea as its first argument. We're passing it a
	 * text argument here, relying on the fact that they are both in fact
	 * varlena types, and thus structurally identical.
	 */
	result = DirectFunctionCall3(pg_convert, string,
								 src_encoding_name, dest_encoding_name);

	PG_RETURN_DATUM(result);
}