Beispiel #1
0
Datum
plvstr_lstrip (PG_FUNCTION_ARGS)
{
	text *str = PG_GETARG_TEXT_PP(0);
	text *pat = PG_GETARG_TEXT_PP(1);
	int num = PG_GETARG_INT32(2);
	int count = 0;
	int len_p, len_s, i;

	char *str_p, *aux_str_p, *pat_p;
	len_p = VARSIZE_ANY_EXHDR(pat);
	len_s = VARSIZE_ANY_EXHDR(str);

	str_p = VARDATA_ANY(str);
	while (count < num)
	{
		pat_p = VARDATA_ANY(pat);
		aux_str_p = str_p;

		if (len_s < len_p)
			break;

		for (i = 0; i < len_p; i++)
			if (*aux_str_p++ != *pat_p++)
				break;

		if (i >= len_p)
		{
			count++;
			/* found */
			str_p = aux_str_p;
			len_s -= len_p;
			continue;
		}
		break;
	}

	PG_RETURN_TEXT_P(cstring_to_text_with_len(str_p,len_s));
}
Beispiel #2
0
/* set_curcfg(text) */
Datum
tsa_set_curcfg_byname(PG_FUNCTION_ARGS)
{
	text	   *arg0 = PG_GETARG_TEXT_PP(0);
	char	   *name;

	name = text_to_cstring(arg0);

	SetConfigOption("default_text_search_config", name,
					PGC_USERSET, PGC_S_SESSION);

	PG_RETURN_VOID();
}
/*
 * As of pgstattuple version 1.5, we no longer need to check if the user
 * is a superuser because we REVOKE EXECUTE on the function from PUBLIC.
 * Users can then grant access to it based on their policies.
 *
 * Otherwise identical to pgstattuple (above).
 */
Datum
pgstattuple_v1_5(PG_FUNCTION_ARGS)
{
	text	   *relname = PG_GETARG_TEXT_PP(0);
	RangeVar   *relrv;
	Relation	rel;

	/* open relation */
	relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
	rel = relation_openrv(relrv, AccessShareLock);

	PG_RETURN_DATUM(pgstat_relation(rel, fcinfo));
}
Beispiel #4
0
/*
 * dblink_connect(server text) : boolean
 */
Datum
dblink_connect(PG_FUNCTION_ARGS)
{
	text   *name = PG_GETARG_TEXT_PP(0);
	Conn   *conn;
	bool	isNew;

	conn = doConnect(name, name, &isNew);
	conn->use_xa = PG_GETARG_BOOL(1);
	conn->keep = true;

	PG_RETURN_BOOL(isNew);
}
Beispiel #5
0
Datum
nameregexne(PG_FUNCTION_ARGS)
{
	Name		n = PG_GETARG_NAME(0);
	text	   *p = PG_GETARG_TEXT_PP(1);

	PG_RETURN_BOOL(!RE_compile_and_execute(p,
										   NameStr(*n),
										   strlen(NameStr(*n)),
										   REG_ADVANCED,
										   PG_GET_COLLATION(),
										   0, NULL));
}
Beispiel #6
0
/*
 * Test property of an index column specified by index OID and column number
 */
Datum
pg_index_column_has_property(PG_FUNCTION_ARGS)
{
	Oid			relid = PG_GETARG_OID(0);
	int32		attno = PG_GETARG_INT32(1);
	char	   *propname = text_to_cstring(PG_GETARG_TEXT_PP(2));

	/* Reject attno 0 immediately, so that attno > 0 identifies this case */
	if (attno <= 0)
		PG_RETURN_NULL();

	return indexam_property(fcinfo, propname, InvalidOid, relid, attno);
}
/*
 * lo_import -
 *	  imports a file as an (inversion) large object.
 */
Datum
lo_import(PG_FUNCTION_ARGS)
{
	text	   *filename = PG_GETARG_TEXT_PP(0);

#ifdef PGXC
	ereport(ERROR,
			(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
			 errmsg("Postgres-XC does not support large object yet"),
			 errdetail("The feature is not currently supported")));
#endif

	PG_RETURN_OID(lo_import_internal(filename, InvalidOid));
}
Beispiel #8
0
Datum
levenshtein_less_equal(PG_FUNCTION_ARGS)
{
	text	   *src = PG_GETARG_TEXT_PP(0);
	text	   *dst = PG_GETARG_TEXT_PP(1);
	int			max_d = PG_GETARG_INT32(2);
	const char *s_data;
	const char *t_data;
	int			s_bytes,
				t_bytes;

	/* Extract a pointer to the actual character data */
	s_data = VARDATA_ANY(src);
	t_data = VARDATA_ANY(dst);
	/* Determine length of each string in bytes */
	s_bytes = VARSIZE_ANY_EXHDR(src);
	t_bytes = VARSIZE_ANY_EXHDR(dst);

	PG_RETURN_INT32(varstr_levenshtein_less_equal(s_data, s_bytes,
												  t_data, t_bytes,
												  1, 1, 1,
												  max_d, false));
}
Beispiel #9
0
Datum
nameicnlike(PG_FUNCTION_ARGS)
{
	Name		str = PG_GETARG_NAME(0);
	text	   *pat = PG_GETARG_TEXT_PP(1);
	bool		result;
	text	   *strtext;

	strtext = DatumGetTextP(DirectFunctionCall1(name_text,
												NameGetDatum(str)));
	result = (Generic_Text_IC_like(strtext, pat, PG_GET_COLLATION()) != LIKE_TRUE);

	PG_RETURN_BOOL(result);
}
Beispiel #10
0
Datum
levenshtein_with_costs(PG_FUNCTION_ARGS)
{
	text	   *src = PG_GETARG_TEXT_PP(0);
	text	   *dst = PG_GETARG_TEXT_PP(1);
	int			ins_c = PG_GETARG_INT32(2);
	int			del_c = PG_GETARG_INT32(3);
	int			sub_c = PG_GETARG_INT32(4);
	const char *s_data;
	const char *t_data;
	int			s_bytes,
				t_bytes;

	/* Extract a pointer to the actual character data */
	s_data = VARDATA_ANY(src);
	t_data = VARDATA_ANY(dst);
	/* Determine length of each string in bytes and characters */
	s_bytes = VARSIZE_ANY_EXHDR(src);
	t_bytes = VARSIZE_ANY_EXHDR(dst);

	PG_RETURN_INT32(varstr_levenshtein(s_data, s_bytes, t_data, t_bytes, ins_c,
									   del_c, sub_c));
}
Beispiel #11
0
Datum
pg_decrypt_iv(PG_FUNCTION_ARGS)
{
	int			err;
	bytea	   *data,
			   *key,
			   *iv,
			   *res;
	text	   *type;
	PX_Combo   *c;
	unsigned	dlen,
				klen,
				rlen,
				ivlen;

	type = PG_GETARG_TEXT_PP(3);
	c = find_provider(type, (PFN) px_find_combo, "Cipher", 0);

	data = PG_GETARG_BYTEA_PP(0);
	key = PG_GETARG_BYTEA_PP(1);
	iv = PG_GETARG_BYTEA_PP(2);
	dlen = VARSIZE_ANY_EXHDR(data);
	klen = VARSIZE_ANY_EXHDR(key);
	ivlen = VARSIZE_ANY_EXHDR(iv);

	rlen = px_combo_decrypt_len(c, dlen);
	res = palloc(VARHDRSZ + rlen);

	err = px_combo_init(c, (uint8 *) VARDATA_ANY(key), klen,
						(uint8 *) VARDATA_ANY(iv), ivlen);
	if (!err)
		err = px_combo_decrypt(c, (uint8 *) VARDATA_ANY(data), dlen,
							   (uint8 *) VARDATA(res), &rlen);

	px_combo_free(c);

	if (err)
		ereport(ERROR,
				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
				 errmsg("decrypt_iv error: %s", px_strerror(err))));

	SET_VARSIZE(res, VARHDRSZ + rlen);

	PG_FREE_IF_COPY(data, 0);
	PG_FREE_IF_COPY(key, 1);
	PG_FREE_IF_COPY(iv, 2);
	PG_FREE_IF_COPY(type, 3);

	PG_RETURN_BYTEA_P(res);
}
Beispiel #12
0
Datum
gin_cmp_prefix(PG_FUNCTION_ARGS)
{
	text	   *a = PG_GETARG_TEXT_PP(0);
	text	   *b = PG_GETARG_TEXT_PP(1);

#ifdef NOT_USED
	StrategyNumber strategy = PG_GETARG_UINT16(2);
	Pointer		extra_data = PG_GETARG_POINTER(3);
#endif
	int			cmp;

	cmp = tsCompareString(VARDATA_ANY(a), VARSIZE_ANY_EXHDR(a),
						  VARDATA_ANY(b), VARSIZE_ANY_EXHDR(b),
						  true);

	if (cmp < 0)
		cmp = 1;				/* prevent continue scan */

	PG_FREE_IF_COPY(a, 0);
	PG_FREE_IF_COPY(b, 1);
	PG_RETURN_INT32(cmp);
}
Beispiel #13
0
Datum
ts_parse_byname(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcctx;
	Datum		result;

	if (SRF_IS_FIRSTCALL())
	{
		text	   *prsname = PG_GETARG_TEXT_PP(0);
		text	   *txt = PG_GETARG_TEXT_PP(1);
		Oid			prsId;

		funcctx = SRF_FIRSTCALL_INIT();
		prsId = get_ts_parser_oid(textToQualifiedNameList(prsname), false);
		prs_setup_firstcall(funcctx, prsId, txt);
	}

	funcctx = SRF_PERCALL_SETUP();

	if ((result = prs_process_call(funcctx)) != (Datum) 0)
		SRF_RETURN_NEXT(funcctx, result);
	SRF_RETURN_DONE(funcctx);
}
Beispiel #14
0
Datum
ora_date_round(PG_FUNCTION_ARGS)
{
	DateADT day = PG_GETARG_DATEADT(0);
	text *fmt = PG_GETARG_TEXT_PP(1);

	DateADT result;

	int f = ora_seq_search(VARDATA_ANY(fmt), date_fmt, VARSIZE_ANY_EXHDR(fmt));
	CHECK_SEQ_SEARCH(f, "round/trunc format string");

	result = _ora_date_round(day, f);
	PG_RETURN_DATEADT(result);
}
Beispiel #15
0
/*
 * jsonb_delete:
 * Return copy of jsonb with the specified item removed.
 * Item is a one key or element from jsonb, specified by name.
 * If there are many keys or elements with than name,
 * the first one will be removed.
 */
Datum
jsonb_delete(PG_FUNCTION_ARGS)
{
	Jsonb 				*in = PG_GETARG_JSONB(0);
	text 				*key = PG_GETARG_TEXT_PP(1);
	char 				*keyptr = VARDATA_ANY(key);
	int					keylen = VARSIZE_ANY_EXHDR(key);
	JsonbParseState 	*state = NULL;
	JsonbIterator 		*it;
	uint32 				r;
	JsonbValue 			v, *res = NULL;
	bool 				skipped = false;

	if (JB_ROOT_IS_SCALAR(in))
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("cannot delete from scalar")));

	if (JB_ROOT_COUNT(in) == 0)
	{
		PG_RETURN_JSONB(in);
	}

	it = JsonbIteratorInit(&in->root);

	while((r = JsonbIteratorNext(&it, &v, false)) != 0)
	{
		if (!skipped && (r == WJB_ELEM || r == WJB_KEY) &&
			(v.type == jbvString && keylen == v.val.string.len &&
			 memcmp(keyptr, v.val.string.val, keylen) == 0))
		{
			/* we should delete only one key/element */
			skipped = true;

			if (r == WJB_KEY)
			{
				/* skip corresponding value */
				JsonbIteratorNext(&it, &v, true);
			}

			continue;
		}

		res = pushJsonbValue(&state, r, r < WJB_BEGIN_ARRAY ? &v : NULL);
	}

	Assert(res != NULL);
	PG_RETURN_JSONB(JsonbValueToJsonb(res));
}
Beispiel #16
0
Datum
text2ltree(PG_FUNCTION_ARGS)
{
    text	   *in = PG_GETARG_TEXT_PP(0);
    char	   *s;
    ltree	   *out;

    s = text_to_cstring(in);

    out = (ltree *) DatumGetPointer(DirectFunctionCall1(ltree_in,
                                    PointerGetDatum(s)));
    pfree(s);
    PG_FREE_IF_COPY(in, 0);
    PG_RETURN_POINTER(out);
}
Beispiel #17
0
Datum
upper(PG_FUNCTION_ARGS)
{
	text	   *in_string = PG_GETARG_TEXT_PP(0);
	char	   *out_string;
	text	   *result;

	out_string = str_toupper(VARDATA_ANY(in_string),
							 VARSIZE_ANY_EXHDR(in_string),
							 PG_GET_COLLATION());
	result = cstring_to_text(out_string);
	pfree(out_string);

	PG_RETURN_TEXT_P(result);
}
Beispiel #18
0
Datum
pg_cancel_backend_msg(PG_FUNCTION_ARGS)
{
	pid_t		pid = PG_GETARG_INT32(0);
	char 	   *msg = text_to_cstring(PG_GETARG_TEXT_PP(1));

	int			r = pg_signal_backend(pid, SIGINT, msg);

	if (r == SIGNAL_BACKEND_NOPERMISSION)
		ereport(ERROR,
				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
				 (errmsg("must be superuser or have the same role to cancel queries running in other server processes"))));

	PG_RETURN_BOOL(r == SIGNAL_BACKEND_SUCCESS);
}
Beispiel #19
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));
}
Beispiel #20
0
Datum
show_trgm(PG_FUNCTION_ARGS)
{
	text	   *in = PG_GETARG_TEXT_PP(0);
	TRGM	   *trg;
	Datum	   *d;
	ArrayType  *a;
	trgm	   *ptr;
	int			i;

	trg = generate_trgm(VARDATA_ANY(in), VARSIZE_ANY_EXHDR(in));
	d = (Datum *) palloc(sizeof(Datum) * (1 + ARRNELEM(trg)));

	for (i = 0, ptr = GETARR(trg); i < ARRNELEM(trg); i++, ptr++)
	{
		text	   *item = (text *) palloc(VARHDRSZ + Max(12, pg_database_encoding_max_length() * 3));

		if (pg_database_encoding_max_length() > 1 && !ISPRINTABLETRGM(ptr))
		{
			snprintf(VARDATA(item), 12, "0x%06x", trgm2int(ptr));
			SET_VARSIZE(item, VARHDRSZ + strlen(VARDATA(item)));
		}
		else
		{
			SET_VARSIZE(item, VARHDRSZ + 3);
			CPTRGM(VARDATA(item), ptr);
		}
		d[i] = PointerGetDatum(item);
	}

	a = construct_array(
						d,
						ARRNELEM(trg),
						TEXTOID,
						-1,
						false,
						'i'
		);

	for (i = 0; i < ARRNELEM(trg); i++)
		pfree(DatumGetPointer(d[i]));

	pfree(d);
	pfree(trg);
	PG_FREE_IF_COPY(in, 0);

	PG_RETURN_POINTER(a);
}
Beispiel #21
0
Datum
quote_variant_name(PG_FUNCTION_ARGS)
{
    StringInfo			out;
    char						*variant_name;

    Assert(fcinfo->flinfo->fn_strict); /* Must be strict */

    variant_name = text_to_cstring(PG_GETARG_TEXT_PP(0));

    out = quote_variant_name_cstring(variant_name);

    /* out is wrapped in () which is not what we want, so we don't return it directly */

    PG_RETURN_TEXT_P( cstring_to_text_with_len(out->data + 1, out->len-2) );
}
Beispiel #22
0
Datum
ssl_issuer_field(PG_FUNCTION_ARGS)
{
	text	   *fieldname = PG_GETARG_TEXT_PP(0);
	Datum		result;

	if (!(MyProcPort->peer))
		PG_RETURN_NULL();

	result = X509_NAME_field_to_text(X509_get_issuer_name(MyProcPort->peer), fieldname);

	if (!result)
		PG_RETURN_NULL();
	else
		return result;
}
Beispiel #23
0
/*
 * pgmpc_update
 * Update remote database.
 */
Datum
pgmpc_update(PG_FUNCTION_ARGS)
{
	char *path = NULL;

	/* Get optional path if defined */
	if (PG_NARGS() == 1 && !PG_ARGISNULL(0))
		path = text_to_cstring(PG_GETARG_TEXT_PP(0));

	/* Run the command */
	pgmpc_init();
	if (!mpd_run_update(mpd_conn, path))
		pgmpc_print_error();
	pgmpc_reset();
	PG_RETURN_VOID();
}
Beispiel #24
0
Datum
citext_hash(PG_FUNCTION_ARGS)
{
	text	   *txt = PG_GETARG_TEXT_PP(0);
	char	   *str;
	Datum		result;

	str = str_tolower(VARDATA_ANY(txt), VARSIZE_ANY_EXHDR(txt));
	result = hash_any((unsigned char *) str, strlen(str));
	pfree(str);

	/* Avoid leaking memory for toasted inputs */
	PG_FREE_IF_COPY(txt, 0);

	PG_RETURN_DATUM(result);
}
Beispiel #25
0
/* ------------------------------------------------------
 * pgstatindex()
 *
 * Usage: SELECT * FROM pgstatindex('t1_pkey');
 *
 * The superuser() check here must be kept as the library might be upgraded
 * without the extension being upgraded, meaning that in pre-1.5 installations
 * these functions could be called by any user.
 * ------------------------------------------------------
 */
Datum
pgstatindex(PG_FUNCTION_ARGS)
{
	text	   *relname = PG_GETARG_TEXT_PP(0);
	Relation	rel;
	RangeVar   *relrv;

	if (!superuser())
		ereport(ERROR,
				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
				 (errmsg("must be superuser to use pgstattuple functions"))));

	relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
	rel = relation_openrv(relrv, AccessShareLock);

	PG_RETURN_DATUM(pgstatindex_impl(rel, fcinfo));
}
Datum
chkpass_ne(PG_FUNCTION_ARGS)
{
	chkpass    *a1 = (chkpass *) PG_GETARG_POINTER(0);
	text	   *a2 = PG_GETARG_TEXT_PP(1);
	char		str[9];
	char	   *crypt_output;

	text_to_cstring_buffer(a2, str, sizeof(str));
	crypt_output = crypt(str, a1->password);
	if (crypt_output == NULL)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("crypt() failed")));

	PG_RETURN_BOOL(strcmp(a1->password, crypt_output) != 0);
}
Beispiel #27
0
Datum
plvchr_char_name(PG_FUNCTION_ARGS)
{
	text *str = PG_GETARG_TEXT_PP(0);
	text *result;
	unsigned char c;

	NON_EMPTY_CHECK(str);
	c = (unsigned char)*(VARDATA_ANY(str));

	if (c >= lengthof(char_names))
		result = ora_substr_text(str, 1, 1);
	else
		result = cstring_to_text(char_names[c]);

	PG_RETURN_TEXT_P(result);
}
Beispiel #28
0
/*
 * Returns Oids of tables in a publication.
 */
Datum
pg_get_publication_tables(PG_FUNCTION_ARGS)
{
	FuncCallContext *funcctx;
	char	   *pubname = text_to_cstring(PG_GETARG_TEXT_PP(0));
	Publication *publication;
	List	   *tables;
	ListCell  **lcp;

	/* stuff done only on the first call of the function */
	if (SRF_IS_FIRSTCALL())
	{
		MemoryContext oldcontext;

		/* create a function context for cross-call persistence */
		funcctx = SRF_FIRSTCALL_INIT();

		/* switch to memory context appropriate for multiple function calls */
		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);

		publication = GetPublicationByName(pubname, false);
		if (publication->alltables)
			tables = GetAllTablesPublicationRelations();
		else
			tables = GetPublicationRelations(publication->oid);
		lcp = (ListCell **) palloc(sizeof(ListCell *));
		*lcp = list_head(tables);
		funcctx->user_fctx = (void *) lcp;

		MemoryContextSwitchTo(oldcontext);
	}

	/* stuff done on every call of the function */
	funcctx = SRF_PERCALL_SETUP();
	lcp = (ListCell **) funcctx->user_fctx;

	while (*lcp != NULL)
	{
		Oid			relid = lfirst_oid(*lcp);

		*lcp = lnext(*lcp);
		SRF_RETURN_NEXT(funcctx, ObjectIdGetDatum(relid));
	}

	SRF_RETURN_DONE(funcctx);
}
Beispiel #29
0
Datum
plvchr_is_kind_a (PG_FUNCTION_ARGS)
{
	text *str = PG_GETARG_TEXT_PP(0);
	int32 k = PG_GETARG_INT32(1);
	char c;

	NON_EMPTY_CHECK(str);
	if (pg_database_encoding_max_length() > 1)
	{
		if (_pg_mblen(VARDATA_ANY(str)) > 1)
			PG_RETURN_INT32( (k == 5) );
	}

	c = *VARDATA_ANY(str);
	PG_RETURN_INT32(is_kind(c,k));
}
Beispiel #30
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);
}