Datum hstore_each(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; HStore *hs; int i; if (SRF_IS_FIRSTCALL()) { hs = PG_GETARG_HS(0); funcctx = SRF_FIRSTCALL_INIT(); setup_firstcall(funcctx, hs, fcinfo); } funcctx = SRF_PERCALL_SETUP(); hs = (HStore *) funcctx->user_fctx; i = funcctx->call_cntr; if (i < HS_COUNT(hs)) { HEntry *entries = ARRPTR(hs); char *ptr = STRPTR(hs); Datum res, dvalues[2]; bool nulls[2] = {false, false}; text *item; HeapTuple tuple; item = cstring_to_text_with_len(HS_KEY(entries, ptr, i), HS_KEYLEN(entries, i)); dvalues[0] = PointerGetDatum(item); if (HS_VALISNULL(entries, i)) { dvalues[1] = (Datum) 0; nulls[1] = true; } else { item = cstring_to_text_with_len(HS_VAL(entries, ptr, i), HS_VALLEN(entries, i)); dvalues[1] = PointerGetDatum(item); } tuple = heap_form_tuple(funcctx->tuple_desc, dvalues, nulls); res = HeapTupleGetDatum(tuple); SRF_RETURN_NEXT(funcctx, PointerGetDatum(res)); } SRF_RETURN_DONE(funcctx); }
static ArrayType * hstore_to_array_internal(HStore *hs, int ndims) { HEntry *entries = ARRPTR(hs); char *base = STRPTR(hs); int count = HS_COUNT(hs); int out_size[2] = {0, 2}; int lb[2] = {1, 1}; Datum *out_datums; bool *out_nulls; int i; Assert(ndims < 3); if (count == 0 || ndims == 0) return construct_empty_array(TEXTOID); out_size[0] = count * 2 / ndims; out_datums = palloc(sizeof(Datum) * count * 2); out_nulls = palloc(sizeof(bool) * count * 2); for (i = 0; i < count; ++i) { text *key = cstring_to_text_with_len(HS_KEY(entries, base, i), HS_KEYLEN(entries, i)); out_datums[i * 2] = PointerGetDatum(key); out_nulls[i * 2] = false; if (HS_VALISNULL(entries, i)) { out_datums[i * 2 + 1] = (Datum) 0; out_nulls[i * 2 + 1] = true; } else { text *item = cstring_to_text_with_len(HS_VAL(entries, base, i), HS_VALLEN(entries, i)); out_datums[i * 2 + 1] = PointerGetDatum(item); out_nulls[i * 2 + 1] = false; } } return construct_md_array(out_datums, out_nulls, ndims, out_size, lb, TEXTOID, -1, false, 'i'); }
Datum hstore_skeys(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; HStore *hs; int i; if (SRF_IS_FIRSTCALL()) { hs = PG_GETARG_HS(0); funcctx = SRF_FIRSTCALL_INIT(); setup_firstcall(funcctx, hs, NULL); } funcctx = SRF_PERCALL_SETUP(); hs = (HStore *) funcctx->user_fctx; i = funcctx->call_cntr; if (i < HS_COUNT(hs)) { HEntry *entries = ARRPTR(hs); text *item; item = cstring_to_text_with_len(HS_KEY(entries, STRPTR(hs), i), HS_KEYLEN(entries, i)); SRF_RETURN_NEXT(funcctx, PointerGetDatum(item)); } SRF_RETURN_DONE(funcctx); }
/* * Perform output plugin write into tuplestore. */ static void LogicalOutputWrite(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xid, bool last_write) { Datum values[3]; bool nulls[3]; DecodingOutputState *p; /* SQL Datums can only be of a limited length... */ if (ctx->out->len > MaxAllocSize - VARHDRSZ) elog(ERROR, "too much output for sql interface"); p = (DecodingOutputState *) ctx->output_writer_private; memset(nulls, 0, sizeof(nulls)); values[0] = LSNGetDatum(lsn); values[1] = TransactionIdGetDatum(xid); /* * Assert ctx->out is in database encoding when we're writing textual * output. */ if (!p->binary_output) Assert(pg_verify_mbstr(GetDatabaseEncoding(), ctx->out->data, ctx->out->len, false)); /* ick, but cstring_to_text_with_len works for bytea perfectly fine */ values[2] = PointerGetDatum( cstring_to_text_with_len(ctx->out->data, ctx->out->len)); tuplestore_putvalues(p->tupstore, p->tupdesc, values, nulls); p->returned_rows++; }
static void elements_array_element_end(void *state, bool isnull) { ElementsState _state = (ElementsState) state; MemoryContext old_cxt; int len; text *val; HeapTuple tuple; Datum values[1]; static bool nulls[1] = {false}; /* skip over nested objects */ if (_state->lex->lex_level != 1) return; /* use the tmp context so we can clean up after each tuple is done */ old_cxt = MemoryContextSwitchTo(_state->tmp_cxt); len = _state->lex->prev_token_terminator - _state->result_start; val = cstring_to_text_with_len(_state->result_start, len); values[0] = PointerGetDatum(val); tuple = heap_form_tuple(_state->ret_tdesc, values, nulls); tuplestore_puttuple(_state->tuple_store, tuple); /* clean up and switch back */ MemoryContextSwitchTo(old_cxt); MemoryContextReset(_state->tmp_cxt); }
/* * Converts a VARCHAR2 type to the specified size. * * maxlen is the typmod, ie, declared length plus VARHDRSZ bytes. * isExplicit is true if this is for an explicit cast to varchar2(N). * * Truncation rules: for an explicit cast, silently truncate to the given * length; for an implicit cast, raise error if length limit is exceeded */ PGDLLEXPORT Datum varchar2(PG_FUNCTION_ARGS) { VarChar *source = PG_GETARG_VARCHAR_PP(0); int32 typmod = PG_GETARG_INT32(1); bool isExplicit = PG_GETARG_BOOL(2); int32 len, maxlen; char *s_data; len = VARSIZE_ANY_EXHDR(source); s_data = VARDATA_ANY(source); maxlen = typmod - VARHDRSZ; /* No work if typmod is invalid or supplied data fits it already */ if (maxlen < 0 || len <= maxlen) PG_RETURN_VARCHAR_P(source); /* error out if value too long unless it's an explicit cast */ if (!isExplicit) { if (len > maxlen) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("input value length is %d; too long for type varchar2(%d)",len ,maxlen))); } PG_RETURN_VARCHAR_P((VarChar *) cstring_to_text_with_len(s_data,maxlen)); }
static VarChar * nvarchar2_input(const char *s, size_t len, int32 atttypmod) { VarChar *result; /* input data */ size_t maxlen; maxlen = atttypmod - VARHDRSZ; /* * Perform the typmod check; error out if value too long for NVARCHAR2 */ if (atttypmod >= (int32) VARHDRSZ && len > maxlen) { /* Verify that input length is within typmod limit. * * NOTE: blankspace is not truncated */ size_t mbmaxlen = pg_mbstrlen(s); if (mbmaxlen > maxlen) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("input value length is %zd; too long for type nvarchar2(%zd)", mbmaxlen , maxlen))); } result = (VarChar *) cstring_to_text_with_len(s, len); return result; }
Datum gin_extract_tsvector(PG_FUNCTION_ARGS) { TSVector vector = PG_GETARG_TSVECTOR(0); int32 *nentries = (int32 *) PG_GETARG_POINTER(1); Datum *entries = NULL; *nentries = vector->size; if (vector->size > 0) { int i; WordEntry *we = ARRPTR(vector); entries = (Datum *) palloc(sizeof(Datum) * vector->size); for (i = 0; i < vector->size; i++) { text *txt; txt = cstring_to_text_with_len(STRPTR(vector) + we->pos, we->len); entries[i] = PointerGetDatum(txt); we++; } } PG_FREE_IF_COPY(vector, 0); PG_RETURN_POINTER(entries); }
Datum fsm_page_contents(PG_FUNCTION_ARGS) { bytea *raw_page = PG_GETARG_BYTEA_P(0); StringInfoData sinfo; FSMPage fsmpage; int i; if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("must be superuser to use raw page functions")))); fsmpage = (FSMPage) PageGetContents(VARDATA(raw_page)); initStringInfo(&sinfo); for (i = 0; i < NodesPerPage; i++) { if (fsmpage->fp_nodes[i] != 0) appendStringInfo(&sinfo, "%d: %d\n", i, fsmpage->fp_nodes[i]); } appendStringInfo(&sinfo, "fp_next_slot: %d\n", fsmpage->fp_next_slot); PG_RETURN_TEXT_P(cstring_to_text_with_len(sinfo.data, sinfo.len)); }
Datum dbms_pipe_unique_session_name (PG_FUNCTION_ARGS) { StringInfoData strbuf; text *result; float8 endtime; int cycle = 0; int timeout = 10; WATCH_PRE(timeout, endtime, cycle); if (ora_lock_shmem(SHMEMMSGSZ, MAX_PIPES,MAX_EVENTS,MAX_LOCKS,false)) { initStringInfo(&strbuf); appendStringInfo(&strbuf,"PG$PIPE$%d$%d",sid, MyProcPid); result = cstring_to_text_with_len(strbuf.data, strbuf.len); pfree(strbuf.data); LWLockRelease(shmem_lockid); PG_RETURN_TEXT_P(result); } WATCH_POST(timeout, endtime, cycle); LOCK_ERROR(); PG_RETURN_NULL(); }
Datum hstore_slice_to_array(PG_FUNCTION_ARGS) { HStore *hs = PG_GETARG_HS(0); HEntry *entries = ARRPTR(hs); char *ptr = STRPTR(hs); ArrayType *key_array = PG_GETARG_ARRAYTYPE_P(1); ArrayType *aout; Datum *key_datums; bool *key_nulls; Datum *out_datums; bool *out_nulls; int key_count; int i; deconstruct_array(key_array, TEXTOID, -1, false, 'i', &key_datums, &key_nulls, &key_count); if (key_count == 0) { aout = construct_empty_array(TEXTOID); PG_RETURN_POINTER(aout); } out_datums = palloc(sizeof(Datum) * key_count); out_nulls = palloc(sizeof(bool) * key_count); for (i = 0; i < key_count; ++i) { text *key = (text *) DatumGetPointer(key_datums[i]); int idx; if (key_nulls[i]) idx = -1; else idx = hstoreFindKey(hs, NULL, VARDATA(key), VARSIZE(key) - VARHDRSZ); if (idx < 0 || HS_VALISNULL(entries, idx)) { out_nulls[i] = true; out_datums[i] = (Datum) 0; } else { out_datums[i] = PointerGetDatum( cstring_to_text_with_len(HS_VAL(entries, ptr, idx), HS_VALLEN(entries, idx))); out_nulls[i] = false; } } aout = construct_md_array(out_datums, out_nulls, ARR_NDIM(key_array), ARR_DIMS(key_array), ARR_LBOUND(key_array), TEXTOID, -1, false, 'i'); PG_RETURN_POINTER(aout); }
Datum hstore_akeys(PG_FUNCTION_ARGS) { HStore *hs = PG_GETARG_HS(0); Datum *d; ArrayType *a; HEntry *entries = ARRPTR(hs); char *base = STRPTR(hs); int count = HS_COUNT(hs); int i; if (count == 0) { a = construct_empty_array(TEXTOID); PG_RETURN_POINTER(a); } d = (Datum *) palloc(sizeof(Datum) * count); for (i = 0; i < count; ++i) { text *item = cstring_to_text_with_len(HS_KEY(entries, base, i), HS_KEYLEN(entries, i)); d[i] = PointerGetDatum(item); } a = construct_array(d, count, TEXTOID, -1, false, 'i'); PG_RETURN_POINTER(a); }
/* * jsonb_pretty: * Pretty-printed text for the jsonb */ Datum jsonb_pretty(PG_FUNCTION_ARGS) { Jsonb *jb = PG_GETARG_JSONB(0); StringInfo str = makeStringInfo(); JsonbToCStringWorker(str, &jb->root, VARSIZE(jb), true); PG_RETURN_TEXT_P(cstring_to_text_with_len(str->data, str->len)); }
static HeapTuple uri_new(FunctionCallInfo fcinfo, const char *str, size_t len) { TupleDesc td; struct uri_info u; Datum d[URI_LEN]; bool n[URI_LEN]; if (!uri_parse(str, len, &u)) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid uri: \"%.*s\"", (int)len, str))); if (!(n[URI_SCHEME] = !u.scheme)) d[URI_SCHEME] = PointerGetDatum(cstring_to_text_with_len(u.scheme, u.scheme_len)); if (!(n[URI_HOST] = !u.host)) d[URI_HOST] = PointerGetDatum(domainname_new(u.host, u.host_len)); if (!(n[URI_PORT] = u.port < 0)) d[URI_PORT] = Int16GetDatum(u.port); if (!(n[URI_PATH] = !u.path)) d[URI_PATH] = PointerGetDatum(cstring_to_text_with_len(u.path, u.path_len)); get_call_result_type(fcinfo, NULL, &td); return heap_form_tuple(BlessTupleDesc(td), d, n); }
/* * 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'); }
Datum comment_recv(PG_FUNCTION_ARGS) { StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); Comment *result; char *str; int nbytes; str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes); result = cstring_to_text_with_len(str, nbytes); pfree(str); PG_RETURN_COMMENT_P(result); }
static void get_object_field_end(void *state, char *fname, bool isnull) { GetState _state = (GetState) state; bool get_last = false; int lex_level = _state->lex->lex_level; /* same tests as in get_object_field_start, mutatis mutandis */ if (lex_level == 1 && _state->search_type == JSON_SEARCH_OBJECT && strcmp(fname, _state->search_term) == 0) { get_last = true; } else if (_state->search_type == JSON_SEARCH_PATH && lex_level <= _state->npath && _state->pathok[lex_level - 1] && strcmp(fname, _state->path[lex_level - 1]) == 0) { /* done with this field so reset pathok */ if (lex_level < _state->npath) _state->pathok[lex_level] = false; if (lex_level == _state->npath) get_last = true; } /* for as_test variants our work is already done */ if (get_last && _state->result_start != NULL) { /* * make a text object from the string from the prevously noted json * start up to the end of the previous token (the lexer is by now * ahead of us on whatevere came after what we're interested in). */ int len = _state->lex->prev_token_terminator - _state->result_start; if (isnull && _state->normalize_results) _state->tresult = (text *) NULL; else _state->tresult = cstring_to_text_with_len(_state->result_start, len); } /* * don't need to reset _state->result_start b/c we're only returning one * datum, the conditions should not occur more than once, and this lets us * check cheaply that they don't (see object_field_start() ) */ }
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) ); }
static void each_object_field_end(void *state, char *fname, bool isnull) { EachState _state = (EachState) state; MemoryContext old_cxt; int len; text *val; HeapTuple tuple; Datum values[2]; bool nulls[2] = {false, false}; /* skip over nested objects */ if (_state->lex->lex_level != 1) return; /* use the tmp context so we can clean up after each tuple is done */ old_cxt = MemoryContextSwitchTo(_state->tmp_cxt); values[0] = CStringGetTextDatum(fname); if (isnull && _state->normalize_results) { nulls[1] = true; values[1] = (Datum) NULL; } else if (_state->next_scalar) { values[1] = CStringGetTextDatum(_state->normalized_scalar); _state->next_scalar = false; } else { len = _state->lex->prev_token_terminator - _state->result_start; val = cstring_to_text_with_len(_state->result_start, len); values[1] = PointerGetDatum(val); } tuple = heap_form_tuple(_state->ret_tdesc, values, nulls); tuplestore_puttuple(_state->tuple_store, tuple); /* clean up and switch back */ MemoryContextSwitchTo(old_cxt); MemoryContextReset(_state->tmp_cxt); }
Datum hstore_svals(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; HStore *hs; int i; if (SRF_IS_FIRSTCALL()) { hs = PG_GETARG_HS(0); funcctx = SRF_FIRSTCALL_INIT(); setup_firstcall(funcctx, hs, NULL); } funcctx = SRF_PERCALL_SETUP(); hs = (HStore *) funcctx->user_fctx; i = funcctx->call_cntr; if (i < HS_COUNT(hs)) { HEntry *entries = ARRPTR(hs); if (HS_VALISNULL(entries, i)) { ReturnSetInfo *rsi; /* ugly ugly ugly. why no macro for this? */ (funcctx)->call_cntr++; rsi = (ReturnSetInfo *) fcinfo->resultinfo; rsi->isDone = ExprMultipleResult; PG_RETURN_NULL(); } else { text *item; item = cstring_to_text_with_len(HS_VAL(entries, STRPTR(hs), i), HS_VALLEN(entries, i)); SRF_RETURN_NEXT(funcctx, PointerGetDatum(item)); } } SRF_RETURN_DONE(funcctx); }
Datum pg_gen_salt(PG_FUNCTION_ARGS) { text *arg0 = PG_GETARG_TEXT_PP(0); int len; char buf[PX_MAX_SALT_LEN + 1]; text_to_cstring_buffer(arg0, buf, sizeof(buf)); len = px_gen_salt(buf, buf, 0); if (len < 0) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("gen_salt: %s", px_strerror(len)))); PG_FREE_IF_COPY(arg0, 0); PG_RETURN_TEXT_P(cstring_to_text_with_len(buf, len)); }
Datum hstore_fetchval(PG_FUNCTION_ARGS) { HStore *hs = PG_GETARG_HS(0); text *key = PG_GETARG_TEXT_PP(1); HEntry *entries = ARRPTR(hs); text *out; int idx = hstoreFindKey(hs, NULL, VARDATA_ANY(key), VARSIZE_ANY_EXHDR(key)); if (idx < 0 || HS_VALISNULL(entries, idx)) PG_RETURN_NULL(); out = cstring_to_text_with_len(HS_VAL(entries, STRPTR(hs), idx), HS_VALLEN(entries, idx)); PG_RETURN_TEXT_P(out); }
Datum hstore_avals(PG_FUNCTION_ARGS) { HStore *hs = PG_GETARG_HS(0); Datum *d; bool *nulls; ArrayType *a; HEntry *entries = ARRPTR(hs); char *base = STRPTR(hs); int count = HS_COUNT(hs); int lb = 1; int i; if (count == 0) { a = construct_empty_array(TEXTOID); PG_RETURN_POINTER(a); } d = (Datum *) palloc(sizeof(Datum) * count); nulls = (bool *) palloc(sizeof(bool) * count); for (i = 0; i < count; ++i) { if (HS_VALISNULL(entries, i)) { d[i] = (Datum) 0; nulls[i] = true; } else { text *item = cstring_to_text_with_len(HS_VAL(entries, base, i), HS_VALLEN(entries, i)); d[i] = PointerGetDatum(item); nulls[i] = false; } } a = construct_md_array(d, nulls, 1, &count, &lb, TEXTOID, -1, false, 'i'); PG_RETURN_POINTER(a); }
static VarChar * varchar2_input(const char *s, size_t len, int32 atttypmod) { VarChar *result; /* input data */ size_t maxlen; maxlen = atttypmod - VARHDRSZ; /* * Perform the typmod check; error out if value too long for VARCHAR2 */ if (atttypmod >= (int32) VARHDRSZ && len > maxlen) if (len > maxlen) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("input value length is %zd; too long for type varchar2(%zd)", len , maxlen))); result = (VarChar *) cstring_to_text_with_len(s, len); return result; }
Datum hstore_to_json(PG_FUNCTION_ARGS) { HStore *in = PG_GETARG_HS(0); int i; int count = HS_COUNT(in); char *base = STRPTR(in); HEntry *entries = ARRPTR(in); StringInfoData tmp, dst; if (count == 0) PG_RETURN_TEXT_P(cstring_to_text_with_len("{}",2)); initStringInfo(&tmp); initStringInfo(&dst); appendStringInfoChar(&dst, '{'); for (i = 0; i < count; i++) { resetStringInfo(&tmp); appendBinaryStringInfo(&tmp, HS_KEY(entries, base, i), HS_KEYLEN(entries, i)); escape_json(&dst, tmp.data); appendStringInfoString(&dst, ": "); if (HS_VALISNULL(entries, i)) appendStringInfoString(&dst, "null"); else { resetStringInfo(&tmp); appendBinaryStringInfo(&tmp, HS_VAL(entries, base, i), HS_VALLEN(entries, i)); escape_json(&dst, tmp.data); } if (i + 1 != count) appendStringInfoString(&dst, ", "); } appendStringInfoChar(&dst, '}'); PG_RETURN_TEXT_P(cstring_to_text(dst.data)); }
Datum domainname_parents(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; text *in = PG_GETARG_TEXT_P(0); const char *s = VARDATA(in); const char *p = s, *e = s + VARSIZE_ANY_EXHDR(in); unsigned i; if (SRF_IS_FIRSTCALL()) funcctx = SRF_FIRSTCALL_INIT(); funcctx = SRF_PERCALL_SETUP(); for (i = 0; i < funcctx->call_cntr && ++p < e; i ++) STRSEARCH(p, e-p, *p == '.'); if (i == funcctx->call_cntr) SRF_RETURN_NEXT(funcctx, PointerGetDatum(cstring_to_text_with_len(s, p-s))); else SRF_RETURN_DONE(funcctx); }
Datum plvstr_rstrip (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) + len_s - 1; while (count < num) { pat_p = VARDATA_ANY(pat) + len_p - 1; 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(VARDATA_ANY(str),len_s)); }
/* * Converts a NVARCHAR2 type to the specified size. * * maxlen is the typmod, ie, declared length plus VARHDRSZ bytes. * isExplicit is true if this is for an explicit cast to nvarchar2(N). * * Truncation rules: for an explicit cast, silently truncate to the given * length; for an implicit cast, raise error if length limit is exceeded */ Datum nvarchar2(PG_FUNCTION_ARGS) { VarChar *source = PG_GETARG_VARCHAR_PP(0); int32 typmod = PG_GETARG_INT32(1); bool isExplicit = PG_GETARG_BOOL(2); int32 len, maxlen; size_t maxmblen; char *s_data; len = VARSIZE_ANY_EXHDR(source); s_data = VARDATA_ANY(source); maxlen = typmod - VARHDRSZ; /* No work if typmod is invalid or supplied data fits it already */ if (maxlen < 0 || len <= maxlen) PG_RETURN_VARCHAR_P(source); /* only reach here if string is too long... */ /* truncate multibyte string preserving multibyte boundary */ maxmblen = pg_mbcharcliplen(s_data, len, maxlen); /* error out if value too long unless it's an explicit cast */ if (!isExplicit) { /* if there is still data beyond maxmblen, error out * * Remember - no blankspace truncation on implicit cast */ if (len > maxmblen) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("input value too long for type nvarchar2(%d)", maxlen))); } PG_RETURN_VARCHAR_P((VarChar *) cstring_to_text_with_len(s_data, maxmblen)); }
/* * 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) { char *buf = splitctx->conv_buf; 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 (buf) { int bufsiz PG_USED_FOR_ASSERTS_ONLY = splitctx->conv_bufsiz; int len; endpos = splitctx->match_locs[splitctx->next_match * 2]; if (endpos < startpos) elog(ERROR, "invalid match starting position"); len = pg_wchar2mb_with_len(splitctx->wide_str + startpos, buf, endpos-startpos); Assert(len < bufsiz); return PointerGetDatum(cstring_to_text_with_len(buf, len)); } else { 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)); } }
static void get_array_element_end(void *state, bool isnull) { GetState _state = (GetState) state; bool get_last = false; int lex_level = _state->lex->lex_level; /* same logic as in get_object_end, modified for arrays */ if (lex_level == 1 && _state->search_type == JSON_SEARCH_ARRAY && _state->array_index == _state->search_index) { get_last = true; } else if (_state->search_type == JSON_SEARCH_PATH && lex_level <= _state->npath && _state->pathok[lex_level - 1] && _state->array_level_index[lex_level - 1] == _state->path_level_index[lex_level - 1]) { /* done with this element so reset pathok */ if (lex_level < _state->npath) _state->pathok[lex_level] = false; if (lex_level == _state->npath) get_last = true; } if (get_last && _state->result_start != NULL) { int len = _state->lex->prev_token_terminator - _state->result_start; if (isnull && _state->normalize_results) _state->tresult = (text *) NULL; else _state->tresult = cstring_to_text_with_len(_state->result_start, len); } }