/* ---------- * heap_tuple_untoast_attr_slice - * * Public entry point to get back part of a toasted value * from compression or external storage. * ---------- */ varattrib * heap_tuple_untoast_attr_slice(varattrib *attr, int32 sliceoffset, int32 slicelength) { varattrib *preslice; varattrib *result; int32 attrsize; if (VARATT_IS_COMPRESSED(attr)) { varattrib *tmp; if (VARATT_IS_EXTERNAL(attr)) tmp = toast_fetch_datum(attr); else { tmp = attr; /* compressed in main tuple */ } preslice = (varattrib *) palloc(attr->va_content.va_external.va_rawsize + VARHDRSZ); VARATT_SIZEP(preslice) = attr->va_content.va_external.va_rawsize + VARHDRSZ; pglz_decompress((PGLZ_Header *) tmp, VARATT_DATA(preslice)); if (tmp != attr) pfree(tmp); } else { /* Plain value */ if (VARATT_IS_EXTERNAL(attr)) { /* fast path */ return (toast_fetch_datum_slice(attr, sliceoffset, slicelength)); } else preslice = attr; } /* slicing of datum for compressed cases and plain value */ attrsize = VARSIZE(preslice) - VARHDRSZ; if (sliceoffset >= attrsize) { sliceoffset = 0; slicelength = 0; } if (((sliceoffset + slicelength) > attrsize) || slicelength < 0) slicelength = attrsize - sliceoffset; result = (varattrib *) palloc(slicelength + VARHDRSZ); VARATT_SIZEP(result) = slicelength + VARHDRSZ; memcpy(VARDATA(result), VARDATA(preslice) + sliceoffset, slicelength); if (preslice != attr) pfree(preslice); return result; }
/* ---------- * heap_tuple_untoast_attr - * * Public entry point to get back a toasted value from compression * or external storage. * ---------- */ varattrib * heap_tuple_untoast_attr(varattrib *attr) { varattrib *result; if (VARATT_IS_EXTERNAL(attr)) { if (VARATT_IS_COMPRESSED(attr)) { /* ---------- * This is an external stored compressed value * Fetch it from the toast heap and decompress. * ---------- */ varattrib *tmp; tmp = toast_fetch_datum(attr); result = (varattrib *) palloc(attr->va_content.va_external.va_rawsize + VARHDRSZ); VARATT_SIZEP(result) = attr->va_content.va_external.va_rawsize + VARHDRSZ; pglz_decompress((PGLZ_Header *) tmp, VARATT_DATA(result)); pfree(tmp); } else { /* * This is an external stored plain value */ result = toast_fetch_datum(attr); } } else if (VARATT_IS_COMPRESSED(attr)) { /* * This is a compressed value inside of the main tuple */ result = (varattrib *) palloc(attr->va_content.va_compressed.va_rawsize + VARHDRSZ); VARATT_SIZEP(result) = attr->va_content.va_compressed.va_rawsize + VARHDRSZ; pglz_decompress((PGLZ_Header *) attr, VARATT_DATA(result)); } else /* * This is a plain value inside of the main tuple - why am I * called? */ return attr; return result; }
text* String_createText(jstring javaString) { text* result = 0; if(javaString != 0) { /* Would be nice if a direct conversion from UTF16 was provided. */ char* utf8 = (char*)JNI_getStringUTFChars(javaString, 0); char* denc = (char*)pg_do_encoding_conversion( (unsigned char*)utf8, strlen(utf8), PG_UTF8, GetDatabaseEncoding()); int dencLen = strlen(denc); int varSize = dencLen + VARHDRSZ; /* Allocate and initialize the text structure. */ result = (text*)palloc(varSize); #if (PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER < 3) VARATT_SIZEP(result) = varSize; /* Total size of structure, not just data */ #else SET_VARSIZE(result, varSize); /* Total size of structure, not just data */ #endif memcpy(VARDATA(result), denc, dencLen); /* pg_do_encoding_conversion will return the source argument * when no conversion is required. We don't want to accidentally * free that pointer. */ if(denc != utf8) pfree(denc); JNI_releaseStringUTFChars(javaString, utf8); } return result; }
/* * Converts OpenSSL ASN1_STRING structure into text * * Converts ASN1_STRING into text, converting all the characters into * current database encoding if possible. Any invalid characters are * replaced by question marks. * * Parameter: str - OpenSSL ASN1_STRING structure. Memory managment * of this structure is responsibility of caller. * * Returns Datum, which can be directly returned from a C language SQL * function. */ Datum ASN1_STRING_to_text(ASN1_STRING *str) { BIO *membuf = NULL; size_t size, outlen; char *sp; char *dp; text *result; membuf = BIO_new(BIO_s_mem()); (void) BIO_set_close(membuf, BIO_CLOSE); ASN1_STRING_print_ex(membuf, str, ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB) | ASN1_STRFLGS_UTF8_CONVERT)); outlen = 0; BIO_write(membuf, &outlen, 1); size = BIO_get_mem_data(membuf, &sp); dp = (char *) pg_do_encoding_conversion((unsigned char *) sp, size - 1, PG_UTF8, GetDatabaseEncoding()); outlen = strlen(dp); result = palloc(VARHDRSZ + outlen); memcpy(VARDATA(result), dp, outlen); if (dp != sp) pfree(dp); BIO_free(membuf); VARATT_SIZEP(result) = outlen + VARHDRSZ; PG_RETURN_TEXT_P(result); }
Datum pg_stat_get_backend_activity(PG_FUNCTION_ARGS) { int32 beid = PG_GETARG_INT32(0); text *result; PgBackendStatus *beentry; int len; const char *activity; if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL) activity = "<backend information not available>"; else if (!superuser() && beentry->st_userid != GetUserId()) activity = "<insufficient privilege>"; else if (*(beentry->st_activity) == '\0') activity = "<command string not enabled>"; else activity = beentry->st_activity; len = strlen(activity); result = palloc(VARHDRSZ + len); VARATT_SIZEP(result) = VARHDRSZ + len; memcpy(VARDATA(result), activity, len); PG_RETURN_TEXT_P(result); }
Datum pg_digest(PG_FUNCTION_ARGS) { bytea *arg; text *name; unsigned len, hlen; PX_MD *md; bytea *res; if (PG_ARGISNULL(0) || PG_ARGISNULL(1)) PG_RETURN_NULL(); name = PG_GETARG_TEXT_P(1); /* will give error if fails */ md = find_provider(name, (PFN) px_find_digest, "Digest", 0); hlen = px_md_result_size(md); res = (text *) palloc(hlen + VARHDRSZ); VARATT_SIZEP(res) = hlen + VARHDRSZ; arg = PG_GETARG_BYTEA_P(0); len = VARSIZE(arg) - VARHDRSZ; px_md_update(md, (uint8 *) VARDATA(arg), len); px_md_finish(md, (uint8 *) VARDATA(res)); px_md_free(md); PG_FREE_IF_COPY(arg, 0); PG_FREE_IF_COPY(name, 1); PG_RETURN_BYTEA_P(res); }
Datum ltree2text(PG_FUNCTION_ARGS) { ltree *in = PG_GETARG_LTREE(0); char *ptr; int i; ltree_level *curlevel; text *out; out = (text *) palloc(in->len + VARHDRSZ); ptr = VARDATA(out); curlevel = LTREE_FIRST(in); for (i = 0; i < in->numlevel; i++) { if (i != 0) { *ptr = '.'; ptr++; } memcpy(ptr, curlevel->name, curlevel->len); ptr += curlevel->len; curlevel = LEVEL_NEXT(curlevel); } VARATT_SIZEP(out) = VARHDRSZ + (ptr - VARDATA(out)); PG_FREE_IF_COPY(in, 0); PG_RETURN_POINTER(out); }
Datum pg_gen_salt_rounds(PG_FUNCTION_ARGS) { text *arg0; int rounds; int len; text *res; char buf[PX_MAX_SALT_LEN + 1]; if (PG_ARGISNULL(0) || PG_ARGISNULL(1)) PG_RETURN_NULL(); arg0 = PG_GETARG_TEXT_P(0); rounds = PG_GETARG_INT32(1); len = VARSIZE(arg0) - VARHDRSZ; len = len > PX_MAX_SALT_LEN ? PX_MAX_SALT_LEN : len; memcpy(buf, VARDATA(arg0), len); buf[len] = 0; len = px_gen_salt(buf, buf, rounds); if (len < 0) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("gen_salt: %s", px_strerror(len)))); res = (text *) palloc(len + VARHDRSZ); VARATT_SIZEP(res) = len + VARHDRSZ; memcpy(VARDATA(res), buf, len); PG_FREE_IF_COPY(arg0, 0); PG_RETURN_TEXT_P(res); }
Datum spheretrans_type(PG_FUNCTION_ARGS) { SEuler * se = ( SEuler * ) PG_GETARG_POINTER ( 0 ) ; BpChar *result = ( BpChar * ) MALLOC ( 3 + VARHDRSZ ); char ret[4] ; int i ; unsigned char t = 0; for ( i=0; i<3; i++ ){ switch ( i ){ case 0: t = se->phi_a ; break; case 1: t = se->theta_a; break; case 2: t = se->psi_a ; break; } switch ( t ){ case EULER_AXIS_X : ret[i]='X'; break; case EULER_AXIS_Y : ret[i]='Y'; break; case EULER_AXIS_Z : ret[i]='Z'; break; } } ret[3] = '\0'; #if PG_VERSION_NUM < 80300 VARATT_SIZEP(result) = 3 + VARHDRSZ; #else SET_VARSIZE(result, 3 + VARHDRSZ); #endif memcpy((void*)VARDATA(result), (void*)&ret[0], 3 ); PG_RETURN_BPCHAR_P(result); }
Datum binary_decode(PG_FUNCTION_ARGS) { text *data = PG_GETARG_TEXT_P(0); Datum name = PG_GETARG_DATUM(1); bytea *result; char *namebuf; int datalen, resultlen, res; struct pg_encoding *enc; datalen = VARSIZE(data) - VARHDRSZ; namebuf = DatumGetCString(DirectFunctionCall1(textout, name)); enc = pg_find_encoding(namebuf); if (enc == NULL) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("unrecognized encoding: \"%s\"", namebuf))); resultlen = enc->decode_len(VARDATA(data), datalen); result = palloc(VARHDRSZ + resultlen); res = enc->decode(VARDATA(data), datalen, VARDATA(result)); /* Make this FATAL 'cause we've trodden on memory ... */ if (res > resultlen) elog(FATAL, "overflow - decode estimate too small"); VARATT_SIZEP(result) = VARHDRSZ + res; PG_RETURN_BYTEA_P(result); }
Datum gin_extract_tsvector(PG_FUNCTION_ARGS) { tsvector *vector = (tsvector *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); uint32 *nentries = (uint32 *) PG_GETARG_POINTER(1); Datum *entries = NULL; *nentries = 0; if (vector->size > 0) { int i; WordEntry *we = ARRPTR(vector); *nentries = (uint32) vector->size; entries = (Datum *) palloc(sizeof(Datum) * vector->size); for (i = 0; i < vector->size; i++) { text *txt = (text *) palloc(VARHDRSZ + we->len); VARATT_SIZEP(txt) = VARHDRSZ + we->len; memcpy(VARDATA(txt), STRPTR(vector) + we->pos, we->len); entries[i] = PointerGetDatum(txt); we++; } } PG_FREE_IF_COPY(vector, 0); PG_RETURN_POINTER(entries); }
Datum dmetaphone_alt(PG_FUNCTION_ARGS) { text *arg, *result; int alen, rsize; char *aptr, *codes[2], *code, *rptr; #ifdef DMETAPHONE_NOSTRICT if (PG_ARGISNULL(0)) PG_RETURNNULL(); #endif arg = PG_GETARG_TEXT_P(0); alen = VARSIZE(arg) - VARHDRSZ; aptr = palloc(alen + 1); memcpy(aptr, VARDATA(arg), alen); aptr[alen] = 0; DoubleMetaphone(aptr, codes); code = codes[1]; if (!code) code = ""; rsize = VARHDRSZ + strlen(code); result = (text *) palloc(rsize); memset(result, 0, rsize); rptr = VARDATA(result); memcpy(rptr, code, strlen(code)); VARATT_SIZEP(result) = rsize; PG_RETURN_TEXT_P(result); }
/* * varchar_input -- common guts of varcharin and varcharrecv * * s is the input text of length len (may not be null-terminated) * atttypmod is the typmod value to apply * * Note that atttypmod is measured in characters, which * is not necessarily the same as the number of bytes. * * If the input string is too long, raise an error, unless the extra * characters are spaces, in which case they're truncated. (per SQL) */ static VarChar * varchar_input(const char *s, size_t len, int32 atttypmod) { VarChar *result; size_t maxlen; /* verify encoding */ pg_verifymbstr(s, len, false); maxlen = atttypmod - VARHDRSZ; if (atttypmod >= (int32) VARHDRSZ && len > maxlen) { /* Verify that extra characters are spaces, and clip them off */ size_t mbmaxlen = pg_mbcharcliplen(s, len, maxlen); size_t j; for (j = mbmaxlen; j < len; j++) { if (s[j] != ' ') ereport(ERROR, (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION), errmsg("value too long for type character varying(%d)", (int) maxlen))); } len = mbmaxlen; } result = (VarChar *) palloc(len + VARHDRSZ); VARATT_SIZEP(result) = len + VARHDRSZ; memcpy(VARDATA(result), s, len); return result; }
static Datum _byte_array_coerceObject(Type self, jobject byteArray) { bytea* bytes = 0; if(byteArray == 0) return 0; if(JNI_isInstanceOf(byteArray, s_byteArray_class)) { jsize length = JNI_getArrayLength((jarray)byteArray); int32 byteaSize = length + VARHDRSZ; bytes = (bytea*)palloc(byteaSize); #if (PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER < 3) VARATT_SIZEP(bytes) = byteaSize; #else SET_VARSIZE(bytes, byteaSize); #endif JNI_getByteArrayRegion((jbyteArray)byteArray, 0, length, (jbyte*)VARDATA(bytes)); } else if(JNI_isInstanceOf(byteArray, s_BlobValue_class)) { jobject byteBuffer; int32 byteaSize; jlong length = JNI_callLongMethod(byteArray, s_BlobValue_length); byteaSize = (int32)(length + VARHDRSZ); bytes = (bytea*)palloc(byteaSize); #if (PGSQL_MAJOR_VER == 8 && PGSQL_MINOR_VER < 3) VARATT_SIZEP(bytes) = byteaSize; #else SET_VARSIZE(bytes, byteaSize); #endif byteBuffer = JNI_newDirectByteBuffer((void*)VARDATA(bytes), length); if(byteBuffer != 0) JNI_callVoidMethod(byteArray, s_BlobValue_getContents, byteBuffer); JNI_deleteLocalRef(byteBuffer); } else { Exception_throwIllegalArgument("Not coercable to bytea"); } PG_RETURN_BYTEA_P(bytes); }
Datum pg_crypt(PG_FUNCTION_ARGS) { text *arg0; text *arg1; unsigned len0, len1, clen; char *buf0, *buf1, *cres, *resbuf; text *res; if (PG_ARGISNULL(0) || PG_ARGISNULL(1)) PG_RETURN_NULL(); arg0 = PG_GETARG_TEXT_P(0); arg1 = PG_GETARG_TEXT_P(1); len0 = VARSIZE(arg0) - VARHDRSZ; len1 = VARSIZE(arg1) - VARHDRSZ; buf0 = palloc(len0 + 1); buf1 = palloc(len1 + 1); memcpy(buf0, VARDATA(arg0), len0); memcpy(buf1, VARDATA(arg1), len1); buf0[len0] = '\0'; buf1[len1] = '\0'; resbuf = palloc(PX_MAX_CRYPT); memset(resbuf, 0, PX_MAX_CRYPT); cres = px_crypt(buf0, buf1, resbuf, PX_MAX_CRYPT); pfree(buf0); pfree(buf1); if (cres == NULL) ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), errmsg("crypt(3) returned NULL"))); clen = strlen(cres); res = (text *) palloc(clen + VARHDRSZ); VARATT_SIZEP(res) = clen + VARHDRSZ; memcpy(VARDATA(res), cres, clen); pfree(resbuf); PG_FREE_IF_COPY(arg0, 0); PG_FREE_IF_COPY(arg1, 1); PG_RETURN_TEXT_P(res); }
text * charl2text(char *in, int len) { text *out = (text *) palloc(len + VARHDRSZ); memcpy(VARDATA(out), in, len); VARATT_SIZEP(out) = len + VARHDRSZ; return out; }
/* * debug function, used only for view query * which will be executed in non-leaf pages in index */ Datum tsquerytree(PG_FUNCTION_ARGS) { QUERYTYPE *query = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0))); INFIX nrm; text *res; ITEM *q; int4 len; if (query->size == 0) { res = (text *) palloc(VARHDRSZ); VARATT_SIZEP(res) = VARHDRSZ; PG_RETURN_POINTER(res); } q = clean_NOT_v2(GETQUERY(query), &len); if (!q) { res = (text *) palloc(1 + VARHDRSZ); VARATT_SIZEP(res) = 1 + VARHDRSZ; *((char *) VARDATA(res)) = 'T'; } else { nrm.curpol = q; nrm.buflen = 32; nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen); *(nrm.cur) = '\0'; nrm.op = GETOPERAND(query); infix(&nrm, true); res = (text *) palloc(nrm.cur - nrm.buf + VARHDRSZ); VARATT_SIZEP(res) = nrm.cur - nrm.buf + VARHDRSZ; strncpy(VARDATA(res), nrm.buf, nrm.cur - nrm.buf); pfree(q); } PG_FREE_IF_COPY(query, 0); PG_RETURN_POINTER(res); }
Datum int4_text(PG_FUNCTION_ARGS) { int32 arg1 = PG_GETARG_INT32(0); text *result = (text *) palloc(12 + VARHDRSZ); /* sign,10 digits,'\0' */ pg_ltoa(arg1, VARDATA(result)); VARATT_SIZEP(result) = strlen(VARDATA(result)) + VARHDRSZ; PG_RETURN_TEXT_P(result); }
Datum int2_text(PG_FUNCTION_ARGS) { int16 arg1 = PG_GETARG_INT16(0); text *result = (text *) palloc(7 + VARHDRSZ); /* sign,5 digits, '\0' */ pg_itoa(arg1, VARDATA(result)); VARATT_SIZEP(result) = strlen(VARDATA(result)) + VARHDRSZ; PG_RETURN_TEXT_P(result); }
/* * Equivalent of X509_NAME_oneline that respects encoding * * This function converts X509_NAME structure to the text variable * converting all textual data into current database encoding. * * Parameter: X509_NAME *name X509_NAME structure to be converted * * Returns: text datum which contains string representation of * X509_NAME */ Datum X509_NAME_to_text(X509_NAME *name) { BIO *membuf = BIO_new(BIO_s_mem()); int i, nid, count = X509_NAME_entry_count(name); X509_NAME_ENTRY *e; ASN1_STRING *v; const char *field_name; size_t size, outlen; char *sp; char *dp; text *result; (void) BIO_set_close(membuf, BIO_CLOSE); for (i = 0; i < count; i++) { e = X509_NAME_get_entry(name, i); nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e)); v = X509_NAME_ENTRY_get_data(e); field_name = OBJ_nid2sn(nid); if (!field_name) field_name = OBJ_nid2ln(nid); BIO_printf(membuf, "/%s=", field_name); ASN1_STRING_print_ex(membuf, v, ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB) | ASN1_STRFLGS_UTF8_CONVERT)); } i = 0; BIO_write(membuf, &i, 1); size = BIO_get_mem_data(membuf, &sp); dp = (char *) pg_do_encoding_conversion((unsigned char *) sp, size - 1, PG_UTF8, GetDatabaseEncoding()); BIO_free(membuf); outlen = strlen(dp); result = palloc(VARHDRSZ + outlen); memcpy(VARDATA(result), dp, outlen); /* * pg_do_encoding_conversion has annoying habit of returning source * pointer */ if (dp != sp) pfree(dp); VARATT_SIZEP(result) = outlen + VARHDRSZ; PG_RETURN_TEXT_P(result); }
Datum pgsql_version(PG_FUNCTION_ARGS) { int n = strlen(PG_VERSION_STR); text *ret = (text *) palloc(n + VARHDRSZ); VARATT_SIZEP(ret) = n + VARHDRSZ; memcpy(VARDATA(ret), PG_VERSION_STR, n); PG_RETURN_TEXT_P(ret); }
text * genhl(HLPRSTEXT * prs) { text *out; int len = 128; char *ptr; HLWORD *wrd = prs->words; out = (text *) palloc(len); ptr = ((char *) out) + VARHDRSZ; while (wrd - prs->words < prs->curwords) { while (wrd->len + prs->stopsellen + prs->startsellen + (ptr - ((char *) out)) >= len) { int dist = ptr - ((char *) out); len *= 2; out = (text *) repalloc(out, len); ptr = ((char *) out) + dist; } if (wrd->in && !wrd->repeated) { if (wrd->replace) { *ptr = ' '; ptr++; } else { if (wrd->selected) { memcpy(ptr, prs->startsel, prs->startsellen); ptr += prs->startsellen; } memcpy(ptr, wrd->word, wrd->len); ptr += wrd->len; if (wrd->selected) { memcpy(ptr, prs->stopsel, prs->stopsellen); ptr += prs->stopsellen; } } } else if (!wrd->repeated) pfree(wrd->word); wrd++; } VARATT_SIZEP(out) = ptr - ((char *) out); return out; }
Datum pg_decrypt_iv(PG_FUNCTION_ARGS) { int err; bytea *data, *key, *iv, *res; text *type; PX_Combo *c; unsigned dlen, klen, rlen, ivlen; if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2) || PG_ARGISNULL(3)) PG_RETURN_NULL(); type = PG_GETARG_TEXT_P(3); c = find_provider(type, (PFN) px_find_combo, "Cipher", 0); data = PG_GETARG_BYTEA_P(0); key = PG_GETARG_BYTEA_P(1); iv = PG_GETARG_BYTEA_P(2); dlen = VARSIZE(data) - VARHDRSZ; klen = VARSIZE(key) - VARHDRSZ; ivlen = VARSIZE(iv) - VARHDRSZ; rlen = px_combo_decrypt_len(c, dlen); res = palloc(VARHDRSZ + rlen); err = px_combo_init(c, (uint8 *) VARDATA(key), klen, (uint8 *) VARDATA(iv), ivlen); if (!err) px_combo_decrypt(c, (uint8 *) VARDATA(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)))); VARATT_SIZEP(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 char_text(PG_FUNCTION_ARGS) { char arg1 = PG_GETARG_CHAR(0); text *result = palloc(VARHDRSZ + 1); /* * Convert \0 to an empty string, for consistency with charout (and * because the text stuff doesn't like embedded nulls all that well). */ if (arg1 != '\0') { VARATT_SIZEP(result) = VARHDRSZ + 1; *(VARDATA(result)) = arg1; } else VARATT_SIZEP(result) = VARHDRSZ; PG_RETURN_TEXT_P(result); }
Datum querytree(PG_FUNCTION_ARGS) { QUERYTYPE *query = (QUERYTYPE *) PG_DETOAST_DATUM(PG_GETARG_POINTER(0)); INFIX nrm; text *res; ITEM *q; int4 len; if (query->size == 0) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("empty query"))); q = (ITEM *) palloc(sizeof(ITEM) * query->size); memcpy((void *) q, GETQUERY(query), sizeof(ITEM) * query->size); len = shorterquery(q, query->size); PG_FREE_IF_COPY(query, 0); if (len == 0) { res = (text *) palloc(1 + VARHDRSZ); VARATT_SIZEP(res) = 1 + VARHDRSZ; *((char *) VARDATA(res)) = 'T'; } else { nrm.curpol = q + len - 1; nrm.buflen = 32; nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen); *(nrm.cur) = '\0'; infix(&nrm, true); res = (text *) palloc(nrm.cur - nrm.buf + VARHDRSZ); VARATT_SIZEP(res) = nrm.cur - nrm.buf + VARHDRSZ; strncpy(VARDATA(res), nrm.buf, nrm.cur - nrm.buf); } pfree(q); PG_RETURN_POINTER(res); }
/* * Convert string using encoding_nanme. * * TEXT convert2(TEXT string, NAME src_encoding_name, NAME dest_encoding_name) */ Datum pg_convert2(PG_FUNCTION_ARGS) { text *string = PG_GETARG_TEXT_P(0); char *src_encoding_name = NameStr(*PG_GETARG_NAME(1)); int src_encoding = pg_char_to_encoding(src_encoding_name); char *dest_encoding_name = NameStr(*PG_GETARG_NAME(2)); int dest_encoding = pg_char_to_encoding(dest_encoding_name); unsigned char *result; text *retval; unsigned char *str; int len; if (src_encoding < 0) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("invalid source encoding name \"%s\"", src_encoding_name))); if (dest_encoding < 0) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("invalid destination encoding name \"%s\"", dest_encoding_name))); /* make sure that source string is null terminated */ len = VARSIZE(string) - VARHDRSZ; str = palloc(len + 1); memcpy(str, VARDATA(string), len); *(str + len) = '\0'; result = pg_do_encoding_conversion(str, len, src_encoding, dest_encoding); if (result == NULL) elog(ERROR, "encoding conversion failed"); /* * build text data type structure. we cannot use textin() here, since * textin assumes that input string encoding is same as database * encoding. */ len = strlen(result) + VARHDRSZ; retval = palloc(len); VARATT_SIZEP(retval) = len; memcpy(VARDATA(retval), result, len - VARHDRSZ); if (result != str) pfree(result); pfree(str); /* free memory if allocated by the toaster */ PG_FREE_IF_COPY(string, 0); PG_RETURN_TEXT_P(retval); }
text * concat_text(text *arg1, text *arg2) { int32 new_text_size = VARSIZE(arg1) + VARSIZE(arg2) - VARHDRSZ; text *new_text = (text *) palloc(new_text_size); memset((void *) new_text, 0, new_text_size); VARATT_SIZEP(new_text) = new_text_size; strncpy(VARDATA(new_text), VARDATA(arg1), VARSIZE(arg1) - VARHDRSZ); strncat(VARDATA(new_text), VARDATA(arg2), VARSIZE(arg2) - VARHDRSZ); return new_text; }
/* char_bpchar() * Convert char to bpchar(1). */ Datum char_bpchar(PG_FUNCTION_ARGS) { char c = PG_GETARG_CHAR(0); BpChar *result; result = (BpChar *) palloc(VARHDRSZ + 1); VARATT_SIZEP(result) = VARHDRSZ + 1; *(VARDATA(result)) = c; PG_RETURN_BPCHAR_P(result); }
text * pgxml_result_to_text(xmlXPathObjectPtr res, xmlChar * toptag, xmlChar * septag, xmlChar * plainsep) { xmlChar *xpresstr; int32 ressize; text *xpres; if (res == NULL) { xmlCleanupParser(); return NULL; } switch (res->type) { case XPATH_NODESET: xpresstr = pgxmlNodeSetToText(res->nodesetval, toptag, septag, plainsep); break; case XPATH_STRING: xpresstr = xmlStrdup(res->stringval); break; default: elog(NOTICE, "Unsupported XQuery result: %d", res->type); xpresstr = xmlStrdup("<unsupported/>"); } /* Now convert this result back to text */ ressize = strlen(xpresstr); xpres = (text *) palloc(ressize + VARHDRSZ); memcpy(VARDATA(xpres), xpresstr, ressize); VARATT_SIZEP(xpres) = ressize + VARHDRSZ; /* Free various storage */ xmlCleanupParser(); /* xmlFreeDoc(doctree); -- will die at end of tuple anyway */ xmlFree(xpresstr); elog_error(ERROR, "XPath error", 0); return xpres; }
text *chr_ptr_to_text_ptr(char *arg) { text *retVal; retVal = (text *)malloc(VARHDRSZ + strlen(arg)); #ifdef SET_VARSIZE SET_VARSIZE(retVal, VARHDRSZ + strlen(arg)); #else VARATT_SIZEP(retVal) = strlen(arg) + VARHDRSZ; #endif memcpy(VARDATA(retVal), arg, strlen(arg)); return retVal; }