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; }
jstring String_createJavaString(text* t) { jstring result = 0; if(t != 0) { char* utf8; char* src = VARDATA(t); int srcLen = VARSIZE(t) - VARHDRSZ; if(srcLen == 0) return 0; /* Would be nice if a direct conversion to UTF16 was provided. */ utf8 = (char*)pg_do_encoding_conversion((unsigned char*)src, srcLen, GetDatabaseEncoding(), PG_UTF8); result = JNI_newStringUTF(utf8); /* pg_do_encoding_conversion will return the source argument * when no conversion is required. We don't want to accidentally * free that pointer. */ if(utf8 != src) pfree(utf8); } return result; }
/* * Read the next line from a tsearch data file (expected to be in UTF-8), and * convert it to database encoding if needed. The returned string is palloc'd. * NULL return means EOF. * * Note: direct use of this function is now deprecated. Go through * tsearch_readline() to provide better error reporting. */ char * t_readline(FILE *fp) { int len; char *recoded; char buf[4096]; /* lines must not be longer than this */ if (fgets(buf, sizeof(buf), fp) == NULL) return NULL; len = strlen(buf); /* Make sure the input is valid UTF-8 */ (void) pg_verify_mbstr(PG_UTF8, buf, len, false); /* And convert */ recoded = (char *) pg_do_encoding_conversion((unsigned char *) buf, len, PG_UTF8, GetDatabaseEncoding()); if (recoded == buf) { /* * conversion didn't pstrdup, so we must. We can use the length of the * original string, because no conversion was done. */ recoded = pnstrdup(recoded, len); } return recoded; }
/* * 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_t ASN1_STRING_to_text(ASN1_STRING *str) { BIO *membuf; size_t size; char nullterm; 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)); /* ensure null termination of the BIO's content */ nullterm = '\0'; BIO_write(membuf, &nullterm, 1); size = BIO_get_mem_data(membuf, &sp); dp = (char *) pg_do_encoding_conversion((unsigned char *) sp, size - 1, PG_UTF8, get_db_encoding()); result = cstring_to_text(dp); if (dp != sp) pfree(dp); BIO_free(membuf); RET_TEXT_P(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); }
jstring String_createJavaStringFromNTS(const char* cp) { jstring result = 0; if(cp != 0) { jobject bytebuf; jobject charbuf; Size sz = strlen(cp); char const * utf8 = cp; if ( s_two_step_conversion ) { utf8 = (char*)pg_do_encoding_conversion((unsigned char*)cp, (int)sz, s_server_encoding, PG_UTF8); sz = strlen(utf8); } bytebuf = JNI_newDirectByteBuffer((void *)utf8, sz); charbuf = JNI_callObjectMethodLocked(s_CharsetDecoder_instance, s_CharsetDecoder_decode, bytebuf); result = JNI_callObjectMethodLocked(charbuf, s_Object_toString); JNI_deleteLocalRef(bytebuf); JNI_deleteLocalRef(charbuf); /* pg_do_encoding_conversion will return the source argument * when no conversion is required. We don't want to accidentally * free that pointer. */ if(utf8 != cp) pfree((void *)utf8); } return result; }
jstring String_createJavaString(text* t) { jstring result = 0; if(t != 0) { jobject bytebuf; jobject charbuf; char* src = VARDATA(t); char* utf8 = src; Size srcLen = VARSIZE(t) - VARHDRSZ; if(srcLen == 0) return s_the_empty_string; if ( s_two_step_conversion ) { utf8 = (char*)pg_do_encoding_conversion((unsigned char*)src, (int)srcLen, s_server_encoding, PG_UTF8); srcLen = strlen(utf8); } bytebuf = JNI_newDirectByteBuffer(utf8, srcLen); charbuf = JNI_callObjectMethodLocked(s_CharsetDecoder_instance, s_CharsetDecoder_decode, bytebuf); result = JNI_callObjectMethodLocked(charbuf, s_Object_toString); JNI_deleteLocalRef(bytebuf); JNI_deleteLocalRef(charbuf); /* pg_do_encoding_conversion will return the source argument * when no conversion is required. We don't want to accidentally * free that pointer. */ if(utf8 != src) pfree(utf8); } return result; }
/* * On win32, strftime() returns the encoding in CP_ACP, which is likely * different from SERVER_ENCODING. This is especially important in Japanese * versions of Windows which will use SJIS encoding, which we don't support * as a server encoding. * * Replace strftime() with a version that gets the string in UTF16 and then * converts it to the appropriate encoding as necessary. * * Note that this only affects the calls to strftime() in this file, which are * used to get the locale-aware strings. Other parts of the backend use * pg_strftime(), which isn't locale-aware and does not need to be replaced. */ static size_t strftime_win32(char *dst, size_t dstlen, const wchar_t *format, const struct tm *tm) { size_t len; wchar_t wbuf[MAX_L10N_DATA]; int encoding; encoding = GetDatabaseEncoding(); len = wcsftime(wbuf, MAX_L10N_DATA, format, tm); if (len == 0) /* strftime call failed - return 0 with the contents of dst unspecified */ return 0; len = WideCharToMultiByte(CP_UTF8, 0, wbuf, len, dst, dstlen, NULL, NULL); if (len == 0) elog(ERROR, "could not convert string to UTF-8:error %lu", GetLastError()); dst[len] = '\0'; if (encoding != PG_UTF8) { char *convstr = pg_do_encoding_conversion(dst, len, PG_UTF8, encoding); if (dst != convstr) { strlcpy(dst, convstr, dstlen); len = strlen(dst); } } return len; }
char* String_createNTS(jstring javaString) { char* result = 0; if( 0 == javaString ) return result; if ( uninitialized ) { const char* u8buf; s_server_encoding = GetDatabaseEncoding(); u8buf = JNI_getStringUTFChars( javaString, NULL); if ( 0 == u8buf ) return result; result = (char*)pg_do_encoding_conversion( (unsigned char *)u8buf, (int)strlen( u8buf), PG_UTF8, s_server_encoding); if ( result == u8buf ) result = pstrdup( result); JNI_releaseStringUTFChars( javaString, u8buf); return result; } else { jobject charbuf = JNI_callStaticObjectMethodLocked(s_CharBuffer_class, s_CharBuffer_wrap, javaString); StringInfoData sid; initStringInfo(&sid); appendCharBuffer(&sid, charbuf); JNI_deleteLocalRef(charbuf); result = (char*)pg_do_encoding_conversion( (unsigned char *)sid.data, sid.len, PG_UTF8, s_server_encoding); /* pg_do_encoding_conversion will return the source argument * when no conversion is required. Don't free it in that case. */ if(result != sid.data) pfree(sid.data); } return result; }
char * CheckerConversion(Checker *checker, char *src) { int len; if (!checker->check_encoding) return src; len = strlen(src); if (checker->encoding == checker->db_encoding || checker->encoding == PG_SQL_ASCII) { /* * No conversion is needed, but we must still validate the data. */ pg_verify_mbstr(checker->db_encoding, src, len, false); return src; } if (checker->db_encoding == PG_SQL_ASCII) { /* * No conversion is possible, but we must still validate the data, * because the client-side code might have done string escaping using * the selected client_encoding. If the client encoding is ASCII-safe * then we just do a straight validation under that encoding. For an * ASCII-unsafe encoding we have a problem: we dare not pass such data * to the parser but we have no way to convert it. We compromise by * rejecting the data if it contains any non-ASCII characters. */ if (PG_VALID_BE_ENCODING(checker->encoding)) pg_verify_mbstr(checker->encoding, src, len, false); else { int i; for (i = 0; i < len; i++) { if (src[i] == '\0' || IS_HIGHBIT_SET(src[i])) ereport(ERROR, (errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE), errmsg("invalid byte value for encoding \"%s\": 0x%02x", pg_enc2name_tbl[PG_SQL_ASCII].name, (unsigned char) src[i]))); } } return src; } /* Convert the input into the database encoding. */ return (char *) pg_do_encoding_conversion((unsigned char *) src, len, checker->encoding, checker->db_encoding); }
/* * 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); }
/* * 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); }
/* encode(t, encoding) */ static char * encode_text(int encoding, text *t, int *length) { char *src = VARDATA_ANY(t); char *encoded; encoded = (char *) pg_do_encoding_conversion((unsigned char *) src, VARSIZE_ANY_EXHDR(t), GetDatabaseEncoding(), encoding); *length = (src == encoded ? VARSIZE_ANY_EXHDR(t) : strlen(encoded)); return encoded; }
/* * Convert string using encoding_names. * * BYTEA convert(BYTEA string, NAME src_encoding_name, NAME dest_encoding_name) */ Datum pg_convert(PG_FUNCTION_ARGS) { bytea *string = PG_GETARG_BYTEA_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; bytea *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 valid and null terminated */ len = VARSIZE(string) - VARHDRSZ; pg_verify_mbstr(src_encoding, VARDATA(string), len, false); str = palloc(len + 1); memcpy(str, VARDATA(string), len); *(str + len) = '\0'; result = pg_do_encoding_conversion(str, len, src_encoding, dest_encoding); /* * build bytea data type structure. */ len = strlen((char *) result) + VARHDRSZ; retval = palloc(len); SET_VARSIZE(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_BYTEA_P(retval); }
/* * Return a strdup'ed string converted from the specified encoding to the * database encoding. */ static char * db_encoding_strdup(int encoding, const char *str) { char *pstr; char *mstr; /* convert the string to the database encoding */ pstr = (char *) pg_do_encoding_conversion( (unsigned char *) str, strlen(str), encoding, GetDatabaseEncoding()); mstr = strdup(pstr); if (pstr != str) pfree(pstr); return mstr; }
/* * returns src in case of no conversion or error */ static text * convert_charset(text *src, int cset_from, int cset_to) { int src_len = VARSIZE(src) - VARHDRSZ; unsigned char *dst; unsigned char *csrc = (unsigned char *) VARDATA(src); text *res; dst = pg_do_encoding_conversion(csrc, src_len, cset_from, cset_to); if (dst == csrc) return src; res = cstring_to_text((char *) dst); pfree(dst); return res; }
/* * 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_t 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; char nullterm; 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)); } /* ensure null termination of the BIO's content */ nullterm = '\0'; BIO_write(membuf, &nullterm, 1); size = BIO_get_mem_data(membuf, &sp); dp = (char *) pg_do_encoding_conversion((unsigned char *) sp, size - 1, PG_UTF8, get_db_encoding()); result = cstring_to_text(dp); if (dp != sp) pfree(dp); BIO_free(membuf); RET_TEXT_P(result); }
static char * percent_encode(unsigned char *s, int srclen) { unsigned char *end; StringInfoData buf; int len; initStringInfo(&buf); if (srclen < 0) srclen = strlen((char *) s); end = s + srclen; for (; s < end; s += len) { unsigned char *utf; int ulen; len = pg_mblen((const char *) s); if (len == 1) { if (('0' <= s[0] && s[0] <= '9') || ('A' <= s[0] && s[0] <= 'Z') || ('a' <= s[0] && s[0] <= 'z') || (s[0] == '-') || (s[0] == '.') || (s[0] == '_') || (s[0] == '~')) { appendStringInfoChar(&buf, s[0]); continue; } } utf = pg_do_encoding_conversion(s, len, GetDatabaseEncoding(), PG_UTF8); ulen = pg_encoding_mblen(PG_UTF8, (const char *) utf); while(ulen--) { appendStringInfo(&buf, "%%%2X", *utf); utf++; } } return buf.data; }
jstring String_createJavaStringFromNTS(const char* cp) { jstring result = 0; if(cp != 0) { /* Would be nice if a direct conversion to UTF16 was provided. */ char* utf8 = (char*)pg_do_encoding_conversion((unsigned char*)cp, strlen(cp), GetDatabaseEncoding(), PG_UTF8); result = JNI_newStringUTF(utf8); /* pg_do_encoding_conversion will return the source argument * when no conversion is required. We don't want to accidentally * free that pointer. */ if(utf8 != cp) pfree(utf8); } return result; }
char* String_createNTS(jstring javaString) { char* result = 0; if(javaString != 0) { /* Would be nice if a direct conversion from UTF16 was provided. */ char* utf8 = (char*)JNI_getStringUTFChars(javaString, 0); result = (char*)pg_do_encoding_conversion( (unsigned char*)utf8, strlen(utf8), PG_UTF8, GetDatabaseEncoding()); /* pg_do_encoding_conversion will return the source argument * when no conversion is required. We always want a copy here. */ if(result == utf8) result = pstrdup(result); JNI_releaseStringUTFChars(javaString, utf8); } return result; }
void String_appendJavaString(StringInfoData* buf, jstring javaString) { if(javaString != 0) { /* Would be nice if a direct conversion from UTF16 was provided. */ char* utf8 = (char*)JNI_getStringUTFChars(javaString, 0); char* dbEnc = (char*)pg_do_encoding_conversion( (unsigned char*)utf8, strlen(utf8), PG_UTF8, GetDatabaseEncoding()); appendStringInfoString(buf, dbEnc); /* pg_do_encoding_conversion will return the source argument * when no conversion is required. We don't want to accidentally * free that pointer. */ if(dbEnc != utf8) pfree(dbEnc); JNI_releaseStringUTFChars(javaString, utf8); } }
text* String_createText(jstring javaString) { text* result = 0; if(javaString != 0) { char* denc; Size dencLen; Size varSize; jobject charbuf = JNI_callStaticObjectMethodLocked(s_CharBuffer_class, s_CharBuffer_wrap, javaString); StringInfoData sid; initStringInfo(&sid); appendCharBuffer(&sid, charbuf); JNI_deleteLocalRef(charbuf); denc = sid.data; dencLen = sid.len; if ( s_two_step_conversion ) { denc = (char*)pg_do_encoding_conversion( (unsigned char*)denc, (int)dencLen, PG_UTF8, s_server_encoding); dencLen = strlen(denc); } varSize = dencLen + VARHDRSZ; /* Allocate and initialize the text structure. */ result = (text*)palloc(varSize); #if PG_VERSION_NUM < 80300 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); if(denc != sid.data) pfree(denc); pfree(sid.data); } return result; }
/* * Convert a C string in the PostgreSQL server encoding to a Python * unicode object. Reference ownership is passed to the caller. */ PyObject * PyString_FromStringAndSize(const char *s, Py_ssize_t size) { char *utf8string; PyObject *o; utf8string = (char *) pg_do_encoding_conversion((unsigned char *) s, strlen(s), GetDatabaseEncoding(), PG_UTF8); if (size < 0) { o = PyUnicode_FromString(utf8string); } else { o = PyUnicode_FromStringAndSize(utf8string, size); } if (utf8string != s) pfree(utf8string); return o; }
/* * Retrieve statement statistics. */ Datum pg_stat_statements(PG_FUNCTION_ARGS) { ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; TupleDesc tupdesc; Tuplestorestate *tupstore; MemoryContext per_query_ctx; MemoryContext oldcontext; Oid userid = GetUserId(); bool is_superuser = superuser(); HASH_SEQ_STATUS hash_seq; pgssEntry *entry; if (!pgss || !pgss_hash) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("pg_stat_statements must be loaded via shared_preload_libraries"))); /* check to see if caller supports us returning a tuplestore */ if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("set-valued function called in context that cannot accept a set"))); if (!(rsinfo->allowedModes & SFRM_Materialize)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("materialize mode required, but it is not " \ "allowed in this context"))); /* Build a tuple descriptor for our result type */ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) elog(ERROR, "return type must be a row type"); per_query_ctx = rsinfo->econtext->ecxt_per_query_memory; oldcontext = MemoryContextSwitchTo(per_query_ctx); tupstore = tuplestore_begin_heap(true, false, work_mem); rsinfo->returnMode = SFRM_Materialize; rsinfo->setResult = tupstore; rsinfo->setDesc = tupdesc; MemoryContextSwitchTo(oldcontext); LWLockAcquire(pgss->lock, LW_SHARED); hash_seq_init(&hash_seq, pgss_hash); while ((entry = hash_seq_search(&hash_seq)) != NULL) { Datum values[PG_STAT_STATEMENTS_COLS]; bool nulls[PG_STAT_STATEMENTS_COLS]; int i = 0; Counters tmp; memset(values, 0, sizeof(values)); memset(nulls, 0, sizeof(nulls)); values[i++] = ObjectIdGetDatum(entry->key.userid); values[i++] = ObjectIdGetDatum(entry->key.dbid); if (is_superuser || entry->key.userid == userid) { char *qstr; qstr = (char *) pg_do_encoding_conversion((unsigned char *) entry->query, entry->key.query_len, entry->key.encoding, GetDatabaseEncoding()); values[i++] = CStringGetTextDatum(qstr); if (qstr != entry->query) pfree(qstr); } else values[i++] = CStringGetTextDatum("<insufficient privilege>"); /* copy counters to a local variable to keep locking time short */ { volatile pgssEntry *e = (volatile pgssEntry *) entry; SpinLockAcquire(&e->mutex); tmp = e->counters; SpinLockRelease(&e->mutex); } values[i++] = Int64GetDatumFast(tmp.calls); values[i++] = Float8GetDatumFast(tmp.total_time); values[i++] = Int64GetDatumFast(tmp.rows); values[i++] = Int64GetDatumFast(tmp.shared_blks_hit); values[i++] = Int64GetDatumFast(tmp.shared_blks_read); values[i++] = Int64GetDatumFast(tmp.shared_blks_written); values[i++] = Int64GetDatumFast(tmp.local_blks_hit); values[i++] = Int64GetDatumFast(tmp.local_blks_read); values[i++] = Int64GetDatumFast(tmp.local_blks_written); values[i++] = Int64GetDatumFast(tmp.temp_blks_read); values[i++] = Int64GetDatumFast(tmp.temp_blks_written); Assert(i == PG_STAT_STATEMENTS_COLS); tuplestore_putvalues(tupstore, tupdesc, values, nulls); } LWLockRelease(pgss->lock); /* clean up and return the tuplestore */ tuplestore_donestoring(tupstore); return (Datum) 0; }
static text * get_line(FILE *f, int max_linesize, int encoding, bool *iseof) { int c; char *buffer = NULL; char *bpt; int csize = 0; text *result = NULL; bool eof = true; buffer = palloc(max_linesize + 2); bpt = buffer; errno = 0; while (csize < max_linesize && (c = fgetc(f)) != EOF) { eof = false; /* I was able read one char */ if (c == '\r') /* lookin ahead \n */ { c = fgetc(f); if (c == EOF) break; /* last char */ if (c != '\n') ungetc(c, f); /* skip \r\n */ break; } else if (c == '\n') break; ++csize; *bpt++ = c; } if (!eof) { char *decoded; int len; pg_verify_mbstr(encoding, buffer, csize, false); decoded = (char *) pg_do_encoding_conversion((unsigned char *) buffer, csize, encoding, GetDatabaseEncoding()); len = (decoded == buffer ? csize : strlen(decoded)); result = palloc(len + VARHDRSZ); memcpy(VARDATA(result), decoded, len); SET_VARSIZE(result, len + VARHDRSZ); if (decoded != buffer) pfree(decoded); *iseof = false; } else { switch (errno) { case 0: break; case EBADF: CUSTOM_EXCEPTION(INVALID_OPERATION, "file descriptor isn't valid for reading"); break; default: CUSTOM_EXCEPTION(READ_ERROR, strerror(errno)); break; } *iseof = true; } pfree(buffer); return result; }
Datum LWGEOM_to_latlon(PG_FUNCTION_ARGS) { /* Get the parameters */ GSERIALIZED *pg_lwgeom = (GSERIALIZED *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); text *format_text = PG_GETARG_TEXT_P(1); LWGEOM *lwgeom; char *format_str = NULL; char * formatted_str; text * formatted_text; char * tmp; /* Only supports points. */ uint8_t geom_type = gserialized_get_type(pg_lwgeom); if (POINTTYPE != geom_type) { lwerror("Only points are supported, you tried type %s.", lwtype_name(geom_type)); } /* Convert to LWGEOM type */ lwgeom = lwgeom_from_gserialized(pg_lwgeom); if (format_text == NULL) { lwerror("ST_AsLatLonText: invalid format string (null"); PG_RETURN_NULL(); } format_str = text2cstring(format_text); assert(format_str != NULL); /* The input string supposedly will be in the database encoding, so convert to UTF-8. */ tmp = (char *)pg_do_encoding_conversion( (uint8_t *)format_str, strlen(format_str), GetDatabaseEncoding(), PG_UTF8); assert(tmp != NULL); if ( tmp != format_str ) { pfree(format_str); format_str = tmp; } /* Produce the formatted string. */ formatted_str = lwpoint_to_latlon((LWPOINT *)lwgeom, format_str); assert(formatted_str != NULL); pfree(format_str); /* Convert the formatted string from UTF-8 back to database encoding. */ tmp = (char *)pg_do_encoding_conversion( (uint8_t *)formatted_str, strlen(formatted_str), PG_UTF8, GetDatabaseEncoding()); assert(tmp != NULL); if ( tmp != formatted_str) { pfree(formatted_str); formatted_str = tmp; } /* Convert to the postgres output string type. */ formatted_text = cstring2text(formatted_str); pfree(formatted_str); PG_RETURN_POINTER(formatted_text); }
/** * Validation function take first argument as XML type, then check if is * well formated. If so, do the same for RNG document. If both success, check * XML document against RNG schema restrictions. * @return true if pass, false otherwise */ Datum xmlvalidate_rng(PG_FUNCTION_ARGS) { #ifdef USE_LIBXML text *data = NULL; char *rng = NULL; xmlChar *utf8rng = NULL; xmltype *xmldata = NULL; char *xmldataint = NULL; xmlChar *xmldatastr = NULL; bool result = false; int lenxml = -1; // length of xml data int lenrng = -1; // length of xsd data xmlDocPtr doc = NULL; int ret = -1; xmlRelaxNGParserCtxtPtr ctxt = NULL; xmlRelaxNGPtr schema = NULL; xmlRelaxNGValidCtxtPtr validctxt = NULL; // creating xmlChar * from internal xmltype of stored XML xmldata = PG_GETARG_XML_P(0); xmldataint = VARDATA(xmldata); lenxml = VARSIZE(xmldata) - VARHDRSZ; xmldatastr = (xmlChar *) palloc((lenxml + 1) * sizeof(xmlChar)); memcpy(xmldatastr, xmldataint, lenxml); xmldatastr[lenxml] = '\0'; // creating xmlChar* from text representation of XSD data = PG_GETARG_TEXT_P(1); lenrng = VARSIZE(data) - VARHDRSZ; rng = text_to_cstring(data); //encode XML to internal representation with UTF-8, only one used in LibXML utf8rng = pg_do_encoding_conversion((unsigned char*)rng, lenrng, GetDatabaseEncoding(), PG_UTF8); //initialize LibXML structures, if allready done -> do nothing pg_xml_init(); xmlInitParser(); doc = xmlReadMemory((const char *)xmldatastr, lenxml, "include.xml", NULL, 0); if (doc == NULL) { elog(ERROR, "Failed to parse XML document"); PG_RETURN_BOOL (false); } ctxt = xmlRelaxNGNewMemParserCtxt(rng, lenrng); if (ctxt == NULL) { // unable to create parser context elog(ERROR, "Error with creating schema, check if RelaxNG schema is valid"); PG_RETURN_BOOL (false); } schema = xmlRelaxNGParse(ctxt); // parse schema xmlRelaxNGFreeParserCtxt(ctxt); // realease parser context validctxt = xmlRelaxNGNewValidCtxt(schema); if (validctxt == NULL) { // cant create validation context xmlRelaxNGFree(schema); elog(ERROR, "Cant create validation context"); PG_RETURN_BOOL (false); } // set errors to SQL errors xmlRelaxNGSetValidErrors(validctxt, xml_error_handler, NULL, 0); ret = xmlRelaxNGValidateDoc(validctxt, doc); if (ret == 0) { elog(INFO, "Validates"); result = true; } else if (ret > 0) { elog(INFO, "Dont validates"); result = false; } else { elog(INFO, "Validation generated an internal error"); result = false; } xmlRelaxNGFree(schema); xmlRelaxNGFreeValidCtxt(validctxt); xmlFreeDoc(doc); // clean up document in memmory xmlCleanupParser(); // clean up stream parser PG_RETURN_BOOL (result); #else NO_XML_SUPPORT(); PG_RETURN_BOOL (false); #endif }
/* ---------- * conv_proc( * INTEGER, -- source encoding id * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) * INTEGER -- source string length * ) returns VOID; * ---------- */ Datum sjis_eudc_to_utf8(PG_FUNCTION_ARGS) { unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); unsigned char *p; unsigned char *fallback_character = NULL; int len = PG_GETARG_INT32(4); int sjis_len; int clen; CHECK_ENCODING_CONVERSION_ARGS(PG_SJIS, PG_UTF8); if (sjis_to_utf8 == NULL) sjis_to_utf8 = load_external_function( "utf8_and_sjis", "sjis_to_utf8", true, NULL); *dest = '\0'; p = src; sjis_len = 0; for (; len > 0; len -= clen) { const unsigned char *c = p + sjis_len; if (c[0] == '\0') report_invalid_encoding(PG_SJIS, (const char *) p + sjis_len, len); if (c[0] >= 0xf0 && c[0] <= 0xf9 && len >= 2 && ISSJISTAIL(c[1])) { int ucs; int m; int n; clen = 2; /* SJIS to UTF8 */ if (sjis_len > 0) { DirectFunctionCall5(sjis_to_utf8, PG_SJIS, PG_UTF8, CStringGetDatum(p), CStringGetDatum(dest), sjis_len); dest = dest + strlen((char *) dest); p += sjis_len; sjis_len = 0; } p += clen; elog(eudc_log_level, "eudc character found: %02x%02x in SJIS to UTF8 conversion", c[0], c[1]); /* SJIS EUDC to UTF8 */ if (eudc_fallback_character && eudc_fallback_character[0]) { /* map to fallback character */ int i; if (fallback_character == NULL) { fallback_character = pg_do_encoding_conversion( (unsigned char *) eudc_fallback_character, strlen(eudc_fallback_character), GetDatabaseEncoding(), PG_UTF8); } for (i = 0; fallback_character[i]; i++) *dest++ = fallback_character[i]; } else { /* linear mapping */ n = c[0] - 0xf0; m = c[1] - 0x40; if (m >= 0x40) m--; ucs = 0xe000 + n * 188 + m; *dest++ = (ucs >> 12) | 0xe0; *dest++ = (ucs & 0x0fc0) >> 6 | 0x80; *dest++ = (ucs & 0x003f) | 0x80; } *dest = '\0'; } else {