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)); }
/* 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)); }
/* * 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); }
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)); }
/* * 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)); }
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)); }
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); }
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)); }
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); }
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); }
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); }
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); }
/* * 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)); }
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); }
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); }
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); }
/* * 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)); }
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); }
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) ); }
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; }
/* * 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(); }
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); }
/* ------------------------------------------------------ * 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); }
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); }
/* * 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); }
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)); }
/* * 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); }