fix issue of lob

This commit is contained in:
gentle_hu 2022-03-17 14:26:01 +08:00
parent f3e27c51bc
commit 97baa93140
11 changed files with 156 additions and 114 deletions

View File

@ -227,6 +227,9 @@ Datum to_tsvector(PG_FUNCTION_ARGS)
{
ts_check_feature_disable();
text* in = PG_GETARG_TEXT_P(0);
FUNC_CHECK_HUGE_POINTER(false, in, "to_txvector()");
Oid cfgId;
cfgId = getTSCurrentConfig(true);

View File

@ -39,11 +39,8 @@ static text* dotrim(const char* string, int stringlen, const char* set, int setl
Datum lower(PG_FUNCTION_ARGS)
{
text* in_string = PG_GETARG_TEXT_PP(0);
if (unlikely(VARATT_IS_HUGE_TOAST_POINTER(in_string))) {
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("lower() arguments cannot exceed 1GB")));
}
FUNC_CHECK_HUGE_POINTER(false, in_string, "lower()");
char* out_string = NULL;
text* result = NULL;
@ -71,11 +68,8 @@ Datum lower(PG_FUNCTION_ARGS)
Datum upper(PG_FUNCTION_ARGS)
{
text* in_string = PG_GETARG_TEXT_PP(0);
if (unlikely(VARATT_IS_HUGE_TOAST_POINTER(in_string))) {
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("upper() arguments cannot exceed 1GB")));
}
FUNC_CHECK_HUGE_POINTER(false, in_string, "upper()");
char* out_string = NULL;
text* result = NULL;
@ -108,6 +102,7 @@ Datum initcap(PG_FUNCTION_ARGS)
text* in_string = PG_GETARG_TEXT_PP(0);
char* out_string = NULL;
text* result = NULL;
FUNC_CHECK_HUGE_POINTER(false, in_string, "initcap()");
out_string = str_initcap(VARDATA_ANY(in_string), VARSIZE_ANY_EXHDR(in_string), PG_GET_COLLATION());
result = cstring_to_text(out_string);
@ -144,6 +139,8 @@ Datum lpad(PG_FUNCTION_ARGS)
int bytelen;
errno_t ss_rc;
FUNC_CHECK_HUGE_POINTER(false, string1, "lpad()");
/* Negative len is silently taken as zero */
if (len < 0)
len = 0;
@ -236,6 +233,7 @@ Datum rpad(PG_FUNCTION_ARGS)
text* ret = NULL;
char *ptr1 = NULL, *ptr2 = NULL, *ptr2start = NULL, *ptr2end = NULL, *ptr_ret = NULL;
int m, s1len, s2len;
FUNC_CHECK_HUGE_POINTER(false, string1, "rpad()");
int bytelen;
errno_t ss_rc;
@ -328,6 +326,8 @@ Datum btrim(PG_FUNCTION_ARGS)
text* set = PG_GETARG_TEXT_PP(1);
text* ret = NULL;
FUNC_CHECK_HUGE_POINTER(false, string, "btrim()");
ret = dotrim(VARDATA_ANY(string), VARSIZE_ANY_EXHDR(string), VARDATA_ANY(set), VARSIZE_ANY_EXHDR(set), true, true);
if ((ret == NULL || 0 == VARSIZE_ANY_EXHDR(ret)) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT)
@ -347,6 +347,8 @@ Datum btrim1(PG_FUNCTION_ARGS)
text* string = PG_GETARG_TEXT_PP(0);
text* ret = NULL;
FUNC_CHECK_HUGE_POINTER(false, string, "btrim1()");
ret = dotrim(VARDATA_ANY(string), VARSIZE_ANY_EXHDR(string), " ", 1, true, true);
if ((ret == NULL || 0 == VARSIZE_ANY_EXHDR(ret)) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT)
@ -512,6 +514,8 @@ Datum byteatrim(PG_FUNCTION_ARGS)
char *ptr = NULL, *end = NULL, *ptr2 = NULL, *ptr2start = NULL, *end2 = NULL;
int m, stringlen, setlen;
FUNC_CHECK_HUGE_POINTER(false, string, "byteatrim()");
stringlen = VARSIZE_ANY_EXHDR(string);
setlen = VARSIZE_ANY_EXHDR(set);
@ -580,6 +584,8 @@ Datum ltrim(PG_FUNCTION_ARGS)
text* set = PG_GETARG_TEXT_PP(1);
text* ret = NULL;
FUNC_CHECK_HUGE_POINTER(false, string, "ltrim()");
ret = dotrim(VARDATA_ANY(string), VARSIZE_ANY_EXHDR(string), VARDATA_ANY(set), VARSIZE_ANY_EXHDR(set), true, false);
if ((ret == NULL || 0 == VARSIZE_ANY_EXHDR(ret)) && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT)
@ -598,6 +604,7 @@ Datum ltrim1(PG_FUNCTION_ARGS)
{
text* string = PG_GETARG_TEXT_PP(0);
text* ret = NULL;
FUNC_CHECK_HUGE_POINTER(false, string, "ltrim1()");
ret = dotrim(VARDATA_ANY(string), VARSIZE_ANY_EXHDR(string), " ", 1, true, false);
@ -627,6 +634,7 @@ Datum rtrim(PG_FUNCTION_ARGS)
text* string = PG_GETARG_TEXT_PP(0);
text* set = PG_GETARG_TEXT_PP(1);
text* ret = NULL;
FUNC_CHECK_HUGE_POINTER(false, string, "rtrim()");
ret = dotrim(VARDATA_ANY(string), VARSIZE_ANY_EXHDR(string), VARDATA_ANY(set), VARSIZE_ANY_EXHDR(set), false, true);
@ -646,6 +654,7 @@ Datum rtrim1(PG_FUNCTION_ARGS)
{
text* string = PG_GETARG_TEXT_PP(0);
text* ret = NULL;
FUNC_CHECK_HUGE_POINTER(false, string, "rtrim1");
if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && CHAR_COERCE_COMPAT) {
/*
@ -695,6 +704,8 @@ Datum translate(PG_FUNCTION_ARGS)
int from_index;
errno_t ss_rc;
FUNC_CHECK_HUGE_POINTER(false, string, "translate()");
m = VARSIZE_ANY_EXHDR(string);
if (m <= 0)
PG_RETURN_TEXT_P(string);
@ -805,6 +816,8 @@ Datum ascii(PG_FUNCTION_ARGS)
int encoding = GetDatabaseEncoding();
unsigned char* data = NULL;
FUNC_CHECK_HUGE_POINTER(false, string, "ascii()");
if (VARSIZE_ANY_EXHDR(string) <= 0)
PG_RETURN_INT32(0);
@ -956,6 +969,9 @@ Datum repeat(PG_FUNCTION_ARGS)
{
text* string = PG_GETARG_TEXT_PP(0);
int32 count = PG_GETARG_INT32(1);
FUNC_CHECK_HUGE_POINTER(false, string, "repeat()");
text* result = NULL;
int slen, tlen;
int i;

View File

@ -252,11 +252,8 @@ Datum textlike(PG_FUNCTION_ARGS)
{
text* str = PG_GETARG_TEXT_PP(0);
text* pat = PG_GETARG_TEXT_PP(1);
if (unlikely(VARATT_IS_HUGE_TOAST_POINTER(str))) {
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("like 'partten' cannot exceed 1GB")));
}
FUNC_CHECK_HUGE_POINTER(false, str, "textlike()");
bool result = false;
char *s, *p;
int slen, plen;
@ -275,6 +272,8 @@ Datum textnlike(PG_FUNCTION_ARGS)
{
text* str = PG_GETARG_TEXT_PP(0);
text* pat = PG_GETARG_TEXT_PP(1);
FUNC_CHECK_HUGE_POINTER(false, str, "textnlike()");
bool result = false;
char *s, *p;
int slen, plen;
@ -293,6 +292,8 @@ Datum bytealike(PG_FUNCTION_ARGS)
{
bytea* str = PG_GETARG_BYTEA_PP(0);
bytea* pat = PG_GETARG_BYTEA_PP(1);
FUNC_CHECK_HUGE_POINTER(false, str, "bytealike()");
bool result = false;
char *s, *p;
int slen, plen;
@ -311,6 +312,8 @@ Datum byteanlike(PG_FUNCTION_ARGS)
{
bytea* str = PG_GETARG_BYTEA_PP(0);
bytea* pat = PG_GETARG_BYTEA_PP(1);
FUNC_CHECK_HUGE_POINTER(false, str, "byteanlike()");
bool result = false;
char *s, *p;
int slen, plen;
@ -330,6 +333,8 @@ byteawithoutorderwithequalcollike(PG_FUNCTION_ARGS)
{
bytea *str = PG_GETARG_BYTEA_PP(0);
bytea *pat = PG_GETARG_BYTEA_PP(1);
FUNC_CHECK_HUGE_POINTER(false, str, "byteanlike()");
bool result = false;
char *s, *p;
int slen, plen;
@ -349,6 +354,8 @@ byteawithoutorderwithequalcolnlike(PG_FUNCTION_ARGS)
{
bytea *str = PG_GETARG_BYTEA_PP(0);
bytea *pat = PG_GETARG_BYTEA_PP(1);
FUNC_CHECK_HUGE_POINTER(false, str, "byteanlike()");
bool result = false;
char *s, *p;
int slen, plen;
@ -367,6 +374,8 @@ Datum rawlike(PG_FUNCTION_ARGS)
{
bytea* str = PG_GETARG_BYTEA_PP(0);
bytea* pat = PG_GETARG_BYTEA_PP(1);
FUNC_CHECK_HUGE_POINTER(false, str, "rawlike()");
bool result = false;
char *s, *p;
int slen, plen;
@ -384,6 +393,8 @@ Datum rawnlike(PG_FUNCTION_ARGS)
{
bytea* str = PG_GETARG_BYTEA_PP(0);
bytea* pat = PG_GETARG_BYTEA_PP(1);
FUNC_CHECK_HUGE_POINTER(false, str, "rawnlike()");
bool result = false;
char *s, *p;
int slen, plen;
@ -431,6 +442,8 @@ Datum texticlike(PG_FUNCTION_ARGS)
{
text* str = PG_GETARG_TEXT_PP(0);
text* pat = PG_GETARG_TEXT_PP(1);
FUNC_CHECK_HUGE_POINTER(false, str, "textclike()");
bool result = false;
result = (Generic_Text_IC_like(str, pat, PG_GET_COLLATION()) == LIKE_TRUE);
@ -442,6 +455,8 @@ Datum texticnlike(PG_FUNCTION_ARGS)
{
text* str = PG_GETARG_TEXT_PP(0);
text* pat = PG_GETARG_TEXT_PP(1);
FUNC_CHECK_HUGE_POINTER(false, str, "texticnlike()");
bool result = false;
result = (Generic_Text_IC_like(str, pat, PG_GET_COLLATION()) != LIKE_TRUE);
@ -457,6 +472,8 @@ Datum like_escape(PG_FUNCTION_ARGS)
{
text* pat = PG_GETARG_TEXT_PP(0);
text* esc = PG_GETARG_TEXT_PP(1);
FUNC_CHECK_HUGE_POINTER(false, pat, "like_escape()");
text* result = NULL;
if (pg_database_encoding_max_length() == 1)
@ -475,6 +492,8 @@ Datum like_escape_bytea(PG_FUNCTION_ARGS)
{
bytea* pat = PG_GETARG_BYTEA_PP(0);
bytea* esc = PG_GETARG_BYTEA_PP(1);
FUNC_CHECK_HUGE_POINTER(false, pat, "like_escape_bytea()");
bytea* result = SB_do_like_escape((text*)pat, (text*)esc);
PG_RETURN_BYTEA_P((bytea*)result);

View File

@ -62,6 +62,8 @@ Datum nlssort(PG_FUNCTION_ARGS)
PG_RETURN_NULL();
}
FUNC_CHECK_HUGE_POINTER(PG_ARGISNULL(0), PG_GETARG_TEXT_P(0), "nlssort()");
nlssort_arg = text_to_cstring(PG_GETARG_TEXT_P(1));
if (check_nlssort_args(nlssort_arg, &sort_method)) {
/* the first argument is null or "" */

View File

@ -598,6 +598,8 @@ Datum regexp_replace(PG_FUNCTION_ARGS)
if (pattern == NULL)
PG_RETURN_TEXT_P(src);
FUNC_CHECK_HUGE_POINTER(false, src, "to_txvector()");
re = RE_compile_and_cache(pattern, re_flags.cflags, PG_GET_COLLATION());
result = replace_text_regexp(src, (void*)re, r, position, occurrence);
@ -880,6 +882,8 @@ Datum regexp_count(PG_FUNCTION_ARGS)
PG_RETURN_NULL();
}
FUNC_CHECK_HUGE_POINTER(false, src, "regexp_count()");
re_flags.glob = true;
regexp_matches_ctx* matchctx = setup_regexp_matches(src, pattern, &re_flags,
PG_GET_COLLATION(), false, false, position - 1);
@ -1040,6 +1044,8 @@ Datum regexp_matches(PG_FUNCTION_ARGS)
FuncCallContext* funcctx = NULL;
regexp_matches_ctx* matchctx = NULL;
FUNC_CHECK_HUGE_POINTER(PG_ARGISNULL(0), PG_GETARG_TEXT_PP(0), "regexp_matches()");
if (SRF_IS_FIRSTCALL()) {
text* pattern = PG_GETARG_TEXT_PP(1);
text* flags = PG_GETARG_TEXT_PP_IF_EXISTS(2);
@ -1278,6 +1284,8 @@ Datum regexp_split_to_table(PG_FUNCTION_ARGS)
FuncCallContext* funcctx = NULL;
regexp_matches_ctx* splitctx = NULL;
FUNC_CHECK_HUGE_POINTER(PG_ARGISNULL(0), PG_GETARG_TEXT_PP(0), "regexp_split_to_table()");
if (SRF_IS_FIRSTCALL()) {
text* pattern = PG_GETARG_TEXT_PP(1);
text* flags = PG_GETARG_TEXT_PP_IF_EXISTS(2);
@ -1341,6 +1349,8 @@ Datum regexp_split_to_array(PG_FUNCTION_ARGS)
text* flags = PG_GETARG_TEXT_PP_IF_EXISTS(2);
pg_re_flags re_flags;
FUNC_CHECK_HUGE_POINTER(PG_ARGISNULL(0), PG_GETARG_TEXT_PP(0), "regexp_split_to_array()");
/* Determine options */
parse_re_flags(&re_flags, flags);
/* User mustn't specify 'g' */

View File

@ -705,6 +705,8 @@ Datum bpcharoctetlen(PG_FUNCTION_ARGS)
{
Datum arg = PG_GETARG_DATUM(0);
FUNC_CHECK_HUGE_POINTER(PG_ARGISNULL(0), DatumGetPointer(arg), "bpcharoctetlen()");
/* We need not detoast the input at all */
PG_RETURN_INT32(toast_raw_datum_size(arg) - VARHDRSZ);
}

View File

@ -213,6 +213,7 @@ char* text_to_cstring(const text* t)
ereport(ERROR,
(errcode(ERRCODE_UNEXPECTED_NULL_VALUE), errmsg("invalid null pointer input for text_to_cstring()")));
}
FUNC_CHECK_HUGE_POINTER(false, t, "text_to_cstring()");
/* must cast away the const, unfortunately */
text* tunpacked = pg_detoast_datum_packed((struct varlena*)t);
@ -245,6 +246,9 @@ char* text_to_cstring(const text* t)
void text_to_cstring_buffer(const text* src, char* dst, size_t dst_len)
{
/* must cast away the const, unfortunately */
FUNC_CHECK_HUGE_POINTER((src == NULL), src, "text_to_cstring_buffer()");
text* srcunpacked = pg_detoast_datum_packed((struct varlena*)src);
size_t src_len = VARSIZE_ANY_EXHDR(srcunpacked);
@ -499,6 +503,8 @@ Datum rawout(PG_FUNCTION_ARGS)
Datum rawtotext(PG_FUNCTION_ARGS)
{
Datum arg1 = PG_GETARG_DATUM(0);
FUNC_CHECK_HUGE_POINTER(PG_ARGISNULL(0), DatumGetPointer(arg1), "rawtotext()");
Datum cstring_result;
Datum result;
@ -513,10 +519,8 @@ Datum rawtotext(PG_FUNCTION_ARGS)
Datum texttoraw(PG_FUNCTION_ARGS)
{
Datum arg1 = PG_GETARG_DATUM(0);
if (VARATT_IS_HUGE_TOAST_POINTER(DatumGetPointer(arg1))) {
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("texttoraw could not support more than 1GB clob/blob data")));
}
FUNC_CHECK_HUGE_POINTER(PG_ARGISNULL(0), DatumGetPointer(arg1), "rawtotext()");
Datum result;
Datum cstring_arg1;
@ -621,7 +625,6 @@ Datum bytea_string_agg_finalfn(PG_FUNCTION_ARGS)
Datum textin(PG_FUNCTION_ARGS)
{
char* inputText = PG_GETARG_CSTRING(0);
PG_RETURN_TEXT_P(cstring_to_text(inputText));
}
@ -791,6 +794,8 @@ Datum textoctetlen(PG_FUNCTION_ARGS)
{
Datum str = PG_GETARG_DATUM(0);
FUNC_CHECK_HUGE_POINTER(PG_ARGISNULL(0), DatumGetPointer(str), "textoctetlen()");
/* We need not detoast the input at all */
PG_RETURN_INT32(toast_raw_datum_size(str) - VARHDRSZ);
}
@ -1270,11 +1275,7 @@ Datum text_substr_orclcompat(PG_FUNCTION_ARGS)
mblen_converter fun_mblen;
fun_mblen = *pg_wchar_table[GetDatabaseEncoding()].mblen;
if (VARATT_IS_HUGE_TOAST_POINTER((varlena *)DatumGetPointer(str))) {
struct varlena* dest_ptr = (struct varlena*)DatumGetPointer(str);
struct varlena* res_ptr = heap_tuple_untoast_attr_slice(dest_ptr, start, length);
return PointerGetDatum(res_ptr);
}
FUNC_CHECK_HUGE_POINTER(PG_ARGISNULL(0), DatumGetPointer(str), "text_substr()");
is_compress = (VARATT_IS_COMPRESSED(DatumGetPointer(str)) || VARATT_IS_EXTERNAL(DatumGetPointer(str)));
// orclcompat is true, withlen is true
@ -1303,10 +1304,7 @@ Datum text_substr_no_len_orclcompat(PG_FUNCTION_ARGS)
mblen_converter fun_mblen;
fun_mblen = *pg_wchar_table[GetDatabaseEncoding()].mblen;
if (VARATT_IS_HUGE_TOAST_POINTER((varlena *)DatumGetPointer(str))) {
ereport(ERROR, (errcode(ERRCODE_UNRECOGNIZED_NODE_TYPE),
errmsg("The data is lob that larger than 1GB, you must use a substr with len(substr(str, start, len))")));
}
FUNC_CHECK_HUGE_POINTER(PG_ARGISNULL(0), DatumGetPointer(str), "text_substr()");
is_compress = (VARATT_IS_COMPRESSED(DatumGetPointer(str)) || VARATT_IS_EXTERNAL(DatumGetPointer(str)));
// orclcompat is true, withlen is false
@ -1331,6 +1329,8 @@ Datum textoverlay(PG_FUNCTION_ARGS)
{
text* t1 = PG_GETARG_TEXT_PP(0);
text* t2 = PG_GETARG_TEXT_PP(1);
FUNC_CHECK_HUGE_POINTER(false, t1, "textoverlay()");
int sp = PG_GETARG_INT32(2); /* substring start position */
int sl = PG_GETARG_INT32(3); /* substring length */
@ -1341,6 +1341,7 @@ Datum textoverlay_no_len(PG_FUNCTION_ARGS)
{
text* t1 = PG_GETARG_TEXT_PP(0);
text* t2 = PG_GETARG_TEXT_PP(1);
FUNC_CHECK_HUGE_POINTER(false, t1, "textoverlay()");
int sp = PG_GETARG_INT32(2); /* substring start position */
int sl;
@ -1384,6 +1385,7 @@ Datum textpos(PG_FUNCTION_ARGS)
{
text* str = PG_GETARG_TEXT_PP(0);
text* search_str = PG_GETARG_TEXT_PP(1);
FUNC_CHECK_HUGE_POINTER(PG_ARGISNULL(0), str, "textpos()");
PG_RETURN_INT32((int32)text_position(str, search_str));
}
@ -1864,7 +1866,8 @@ Datum texteq(PG_FUNCTION_ARGS)
{
Datum arg1 = PG_GETARG_DATUM(0);
Datum arg2 = PG_GETARG_DATUM(1);
if (VARATT_IS_HUGE_TOAST_POINTER(DatumGetPointer(arg1)) && VARATT_IS_HUGE_TOAST_POINTER(DatumGetPointer(arg2))) {
if (VARATT_IS_HUGE_TOAST_POINTER(DatumGetPointer(arg1)) || VARATT_IS_HUGE_TOAST_POINTER(DatumGetPointer(arg2))) {
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("texteq could not support more than 1GB clob/blob data")));
}
@ -1899,7 +1902,7 @@ Datum textne(PG_FUNCTION_ARGS)
{
Datum arg1 = PG_GETARG_DATUM(0);
Datum arg2 = PG_GETARG_DATUM(1);
if (VARATT_IS_HUGE_TOAST_POINTER(DatumGetPointer(arg1)) && VARATT_IS_HUGE_TOAST_POINTER(DatumGetPointer(arg2))) {
if (VARATT_IS_HUGE_TOAST_POINTER(DatumGetPointer(arg1)) || VARATT_IS_HUGE_TOAST_POINTER(DatumGetPointer(arg2))) {
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("textne could not support more than 1GB clob/blob data")));
}
@ -2009,10 +2012,7 @@ Datum text_lt(PG_FUNCTION_ARGS)
{
text* arg1 = PG_GETARG_TEXT_PP(0);
text* arg2 = PG_GETARG_TEXT_PP(1);
if (VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg1) || VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg2)) {
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("text_lt could not support more than 1GB clob/blob data")));
}
FUNC_CHECK_HUGE_POINTER(false, arg1, "text_lt()");
bool result = false;
result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) < 0);
@ -2027,10 +2027,8 @@ Datum text_le(PG_FUNCTION_ARGS)
{
text* arg1 = PG_GETARG_TEXT_PP(0);
text* arg2 = PG_GETARG_TEXT_PP(1);
if (VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg1) || VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg2)) {
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("text_le could not support more than 1GB clob/blob data")));
}
FUNC_CHECK_HUGE_POINTER(false, arg1, "text_le()");
bool result = false;
result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) <= 0);
@ -2045,10 +2043,8 @@ Datum text_gt(PG_FUNCTION_ARGS)
{
text* arg1 = PG_GETARG_TEXT_PP(0);
text* arg2 = PG_GETARG_TEXT_PP(1);
if (VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg1) || VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg2)) {
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("text_gt could not support more than 1GB clob/blob data")));
}
FUNC_CHECK_HUGE_POINTER(false, arg1, "text_gt()");
bool result = false;
result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) > 0);
@ -2063,10 +2059,8 @@ Datum text_ge(PG_FUNCTION_ARGS)
{
text* arg1 = PG_GETARG_TEXT_PP(0);
text* arg2 = PG_GETARG_TEXT_PP(1);
if (VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg1) && VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg2)) {
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("text_ge could not support more than 1GB clob/blob data")));
}
FUNC_CHECK_HUGE_POINTER(false, arg1, "text_ge()");
bool result = false;
result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) >= 0);
@ -2081,10 +2075,8 @@ Datum bttextcmp(PG_FUNCTION_ARGS)
{
text* arg1 = PG_GETARG_TEXT_PP(0);
text* arg2 = PG_GETARG_TEXT_PP(1);
if (VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg1) || VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg2)) {
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("bttextcmp could not support more than 1GB clob/blob data")));
}
FUNC_CHECK_HUGE_POINTER(false, arg1, "bttextcmp()");
int32 result;
result = text_cmp(arg1, arg2, PG_GET_COLLATION());
@ -2789,10 +2781,7 @@ Datum text_larger(PG_FUNCTION_ARGS)
{
text* arg1 = PG_GETARG_TEXT_PP(0);
text* arg2 = PG_GETARG_TEXT_PP(1);
if (VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg1) || VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg2)) {
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("text_larger could not support more than 1GB clob/blob data")));
}
FUNC_CHECK_HUGE_POINTER(false, arg1, "text_larger()");
text* result = NULL;
result = ((text_cmp(arg1, arg2, PG_GET_COLLATION()) > 0) ? arg1 : arg2);
@ -2804,10 +2793,7 @@ Datum text_smaller(PG_FUNCTION_ARGS)
{
text* arg1 = PG_GETARG_TEXT_PP(0);
text* arg2 = PG_GETARG_TEXT_PP(1);
if (VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg1) || VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg2)) {
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("text_smaller could not support more than 1GB clob/blob data")));
}
FUNC_CHECK_HUGE_POINTER(false, arg1, "text_smaller()");
text* result = NULL;
result = ((text_cmp(arg1, arg2, PG_GET_COLLATION()) < 0) ? arg1 : arg2);
@ -2845,10 +2831,8 @@ Datum text_pattern_lt(PG_FUNCTION_ARGS)
{
text* arg1 = PG_GETARG_TEXT_PP(0);
text* arg2 = PG_GETARG_TEXT_PP(1);
if (VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg1) || VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg2)) {
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("text_pattern_lt could not support more than 1GB clob/blob data")));
}
FUNC_CHECK_HUGE_POINTER(false, arg1, "text_pattern()");
int result;
result = internal_text_pattern_compare(arg1, arg2);
@ -2863,10 +2847,8 @@ Datum text_pattern_le(PG_FUNCTION_ARGS)
{
text* arg1 = PG_GETARG_TEXT_PP(0);
text* arg2 = PG_GETARG_TEXT_PP(1);
if (VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg1) || VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg2)) {
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("text_pattern_le could not support more than 1GB clob/blob data")));
}
FUNC_CHECK_HUGE_POINTER(false, arg1, "text_pattern()");
int result;
result = internal_text_pattern_compare(arg1, arg2);
@ -2881,10 +2863,8 @@ Datum text_pattern_ge(PG_FUNCTION_ARGS)
{
text* arg1 = PG_GETARG_TEXT_PP(0);
text* arg2 = PG_GETARG_TEXT_PP(1);
if (VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg1) || VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg2)) {
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("text_pattern_ge could not support more than 1GB clob/blob data")));
}
FUNC_CHECK_HUGE_POINTER(false, arg1, "text_pattern()");
int result;
result = internal_text_pattern_compare(arg1, arg2);
@ -2899,10 +2879,8 @@ Datum text_pattern_gt(PG_FUNCTION_ARGS)
{
text* arg1 = PG_GETARG_TEXT_PP(0);
text* arg2 = PG_GETARG_TEXT_PP(1);
if (VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg1) || VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg2)) {
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("text_pattern_gt could not support more than 1GB clob/blob data")));
}
FUNC_CHECK_HUGE_POINTER(false, arg1, "text_pattern()");
int result;
result = internal_text_pattern_compare(arg1, arg2);
@ -2917,10 +2895,8 @@ Datum bttext_pattern_cmp(PG_FUNCTION_ARGS)
{
text* arg1 = PG_GETARG_TEXT_PP(0);
text* arg2 = PG_GETARG_TEXT_PP(1);
if (VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg1) || VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg2)) {
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("bttext_pattern_cmp could not support more than 1GB clob/blob data")));
}
FUNC_CHECK_HUGE_POINTER(false, arg1, "btext_pattern()");
int result;
result = internal_text_pattern_compare(arg1, arg2);
@ -2941,6 +2917,8 @@ Datum byteaoctetlen(PG_FUNCTION_ARGS)
{
Datum str = PG_GETARG_DATUM(0);
FUNC_CHECK_HUGE_POINTER(PG_ARGISNULL(0), PG_GETARG_TEXT_PP(0), "byteaoctetlen()");
/* We need not detoast the input at all */
PG_RETURN_INT32(toast_raw_datum_size(str) - VARHDRSZ);
}
@ -3747,7 +3725,6 @@ Datum byteaeq(PG_FUNCTION_ARGS)
Datum arg2 = PG_GETARG_DATUM(1);
bool result = false;
Size len1, len2;
/*
* We can use a fast path for unequal lengths, which might save us from
* having to detoast one or both values.
@ -3776,6 +3753,8 @@ Datum byteane(PG_FUNCTION_ARGS)
bool result = false;
Size len1, len2;
FUNC_CHECK_HUGE_POINTER(PG_ARGISNULL(0), DatumGetPointer(arg1), "byteane()");
/*
* We can use a fast path for unequal lengths, which might save us from
* having to detoast one or both values.
@ -3801,6 +3780,8 @@ Datum bytealt(PG_FUNCTION_ARGS)
{
bytea* arg1 = PG_GETARG_BYTEA_PP(0);
bytea* arg2 = PG_GETARG_BYTEA_PP(1);
FUNC_CHECK_HUGE_POINTER(false, arg1, "bytealt()");
int len1, len2;
int cmp;
@ -3822,6 +3803,8 @@ Datum byteale(PG_FUNCTION_ARGS)
int len1, len2;
int cmp;
FUNC_CHECK_HUGE_POINTER(false, arg1, "bytealt()");
len1 = VARSIZE_ANY_EXHDR(arg1);
len2 = VARSIZE_ANY_EXHDR(arg2);
@ -3839,6 +3822,7 @@ Datum byteagt(PG_FUNCTION_ARGS)
bytea* arg2 = PG_GETARG_BYTEA_PP(1);
int len1, len2;
int cmp;
FUNC_CHECK_HUGE_POINTER(false, arg1, "byteagt()");
len1 = VARSIZE_ANY_EXHDR(arg1);
len2 = VARSIZE_ANY_EXHDR(arg2);
@ -3857,6 +3841,7 @@ Datum byteage(PG_FUNCTION_ARGS)
bytea* arg2 = PG_GETARG_BYTEA_PP(1);
int len1, len2;
int cmp;
FUNC_CHECK_HUGE_POINTER(false, arg1, "bytealt()");
len1 = VARSIZE_ANY_EXHDR(arg1);
len2 = VARSIZE_ANY_EXHDR(arg2);
@ -3873,6 +3858,7 @@ Datum byteacmp(PG_FUNCTION_ARGS)
{
bytea* arg1 = PG_GETARG_BYTEA_PP(0);
bytea* arg2 = PG_GETARG_BYTEA_PP(1);
FUNC_CHECK_HUGE_POINTER(false, arg1, "byteacmp()");
int len1, len2;
int cmp;
@ -3911,6 +3897,8 @@ Datum raweq(PG_FUNCTION_ARGS)
int len1, len2;
bool result = false;
FUNC_CHECK_HUGE_POINTER(PG_ARGISNULL(0), arg1, "raweq()");
len1 = VARSIZE_ANY_EXHDR(arg1);
len2 = VARSIZE_ANY_EXHDR(arg2);
@ -3932,6 +3920,7 @@ Datum rawne(PG_FUNCTION_ARGS)
bytea* arg2 = PG_GETARG_BYTEA_PP(1);
int len1, len2;
bool result = false;
FUNC_CHECK_HUGE_POINTER(false, arg1, "rawne()");
len1 = VARSIZE_ANY_EXHDR(arg1);
len2 = VARSIZE_ANY_EXHDR(arg2);
@ -3954,6 +3943,7 @@ Datum rawlt(PG_FUNCTION_ARGS)
bytea* arg2 = PG_GETARG_BYTEA_PP(1);
int len1, len2;
int cmp;
FUNC_CHECK_HUGE_POINTER(false, arg1, "rawlt()");
len1 = VARSIZE_ANY_EXHDR(arg1);
len2 = VARSIZE_ANY_EXHDR(arg2);
@ -3972,6 +3962,7 @@ Datum rawle(PG_FUNCTION_ARGS)
bytea* arg2 = PG_GETARG_BYTEA_PP(1);
int len1, len2;
int cmp;
FUNC_CHECK_HUGE_POINTER(false, arg1, "rawle()");
len1 = VARSIZE_ANY_EXHDR(arg1);
len2 = VARSIZE_ANY_EXHDR(arg2);
@ -3990,6 +3981,7 @@ Datum rawgt(PG_FUNCTION_ARGS)
bytea* arg2 = PG_GETARG_BYTEA_PP(1);
int len1, len2;
int cmp;
FUNC_CHECK_HUGE_POINTER(false, arg1, "rawgt()");
len1 = VARSIZE_ANY_EXHDR(arg1);
len2 = VARSIZE_ANY_EXHDR(arg2);
@ -4008,6 +4000,7 @@ Datum rawge(PG_FUNCTION_ARGS)
bytea* arg2 = PG_GETARG_BYTEA_PP(1);
int len1, len2;
int cmp;
FUNC_CHECK_HUGE_POINTER(false, arg1, "rawge()");
len1 = VARSIZE_ANY_EXHDR(arg1);
len2 = VARSIZE_ANY_EXHDR(arg2);
@ -4026,6 +4019,7 @@ Datum rawcmp(PG_FUNCTION_ARGS)
bytea* arg2 = PG_GETARG_BYTEA_PP(1);
int len1, len2;
int cmp;
FUNC_CHECK_HUGE_POINTER(false, arg1, "rawcmp()");
len1 = VARSIZE_ANY_EXHDR(arg1);
len2 = VARSIZE_ANY_EXHDR(arg2);

View File

@ -349,6 +349,7 @@ Datum pg_convert_to_nocase(PG_FUNCTION_ARGS)
Datum dest_encoding_name = PG_GETARG_DATUM(1);
Datum src_encoding_name = DirectFunctionCall1(namein, CStringGetDatum(u_sess->mb_cxt.DatabaseEncoding->name));
Datum result;
FUNC_CHECK_HUGE_POINTER(PG_ARGISNULL(0), DatumGetPointer(string), "pg_convert()");
/*
* pg_convert expects a bytea as its first argument. We're passing it a

View File

@ -6086,10 +6086,6 @@ static int exec_stmt_dynexecute(PLpgSQL_execstate* estate, PLpgSQL_stmt_dynexecu
}
plpgsql_estate = estate;
#ifndef ENABLE_MULTIPLE_NODES
t_thrd.xact_cxt.isSelectInto = stmt->into;
#endif
/*
* Execute the query without preparing a saved plan.
@ -6142,7 +6138,6 @@ static int exec_stmt_dynexecute(PLpgSQL_execstate* estate, PLpgSQL_stmt_dynexecu
estate->cursor_return_data = saved_cursor_data;
estate->cursor_return_numbers = saved_cursor_numbers;
t_thrd.xact_cxt.isSelectInto = false;
return PLPGSQL_RC_OK;
}

View File

@ -6157,17 +6157,19 @@ static bool ExecTargetList(List* targetlist, ExprContext* econtext, Datum* value
isClobAndNotNull = (IsA(tle->expr, Param)) && (!isnull[resind]) && (((Param*)tle->expr)->paramtype == CLOBOID
|| ((Param*)tle->expr)->paramtype == BLOBOID);
if (isClobAndNotNull) {
/* if type is lob pointer, we should fetch real value from tuple. */
if (VARATT_IS_EXTERNAL_LOB(values[resind])) {
struct varatt_lob_pointer* lob_pointer = (varatt_lob_pointer*)(VARDATA_EXTERNAL(values[resind]));
bool is_null = false;
/* if is big lob, fetch and copy from toast */
if (VARATT_IS_HUGE_TOAST_POINTER(values[resind])) {
Datum new_attr = (Datum)0;
Oid update_oid = econtext->ecxt_scantuple != NULL ?
((HeapTuple)(econtext->ecxt_scantuple->tts_tuple))->t_tableOid : InvalidOid;
values[resind] = fetch_lob_value_from_tuple(lob_pointer, update_oid, &is_null);
isnull[resind] = is_null;
Relation update_rel = heap_open(update_oid, RowExclusiveLock);
struct varlena *old_value = (struct varlena *)DatumGetPointer(values[resind]);
struct varlena *new_value = heap_tuple_fetch_and_copy(update_rel, old_value,true);
new_attr = PointerGetDatum(new_value);
heap_close(update_rel, NoLock);
values[resind] = new_attr;
}
}
ELOG_FIELD_NAME_END;
if (itemIsDone[resind] != ExprSingleResult) {
@ -6314,9 +6316,6 @@ TupleTableSlot* ExecProject(ProjectionInfo* projInfo, ExprDoneCond* isDone)
if (numSimpleVars > 0) {
Datum* values = slot->tts_values;
bool* isnull = slot->tts_isnull;
#ifndef ENABLE_MULTIPLE_NODES
Datum* lobPointers = slot->tts_lobPointers;
#endif
int* varSlotOffsets = projInfo->pi_varSlotOffsets;
int* varNumbers = projInfo->pi_varNumbers;
int i;
@ -6330,26 +6329,7 @@ TupleTableSlot* ExecProject(ProjectionInfo* projInfo, ExprDoneCond* isDone)
Assert (varNumber < varSlot->tts_tupleDescriptor->natts);
Assert (i < slot->tts_tupleDescriptor->natts);
#ifndef ENABLE_MULTIPLE_NODES
Form_pg_attribute attr = varSlot->tts_tupleDescriptor->attrs[varNumber];
if (t_thrd.xact_cxt.isSelectInto && (attr->atttypid == CLOBOID || attr->atttypid == BLOBOID)) {
struct varlena *toast_pointer_lob = NULL;
toast_pointer_lob = toast_pointer_fetch_data(varSlot, attr, varNumber);
Assert(toast_pointer_lob != NULL);
if (!projInfo->pi_topPlan) {
values[i] = varSlot->tts_values[varNumber];
lobPointers[i] = PointerGetDatum(toast_pointer_lob);
} else {
values[i] = PointerGetDatum(toast_pointer_lob);
lobPointers[i] = (Datum)0;
}
} else {
values[i] = varSlot->tts_values[varNumber];
lobPointers[i] = (Datum)0;
}
#else
values[i] = varSlot->tts_values[varNumber];
#endif
isnull[i] = varSlot->tts_isnull[varNumber];
}
} else {

View File

@ -323,6 +323,16 @@ typedef enum {
#define VARATT_IS_1B_E(PTR) ((((varattrib_1b*)(PTR))->va_header) == 0x80)
#define VARATT_IS_HUGE_TOAST_POINTER(PTR) ((((varattrib_1b*)(PTR))->va_header) == 0x80 && \
((((varattrib_1b_e*)(PTR))->va_tag) & 0x01) == 0x01)
#define FUNC_CHECK_HUGE_POINTER(is_null, ptr, funcName) \
do { \
if (!is_null && unlikely(VARATT_IS_HUGE_TOAST_POINTER((varlena *)ptr))) { \
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), \
errmsg("%s could not support larger than 1GB clob/blob data", funcName), \
errcause("parameter larger than 1GB"), erraction("parameter must less than 1GB"))); \
} \
} while (0)
#define VARATT_NOT_PAD_BYTE(PTR) (*((uint8*)(PTR)) != 0)
/* VARSIZE_4B() should only be used on known-aligned data */
@ -345,6 +355,16 @@ typedef enum {
#define VARATT_IS_1B_E(PTR) ((((varattrib_1b*)(PTR))->va_header) == 0x01)
#define VARATT_IS_HUGE_TOAST_POINTER(PTR) ((((varattrib_1b*)(PTR))->va_header) == 0x01 && \
((((varattrib_1b_e*)(PTR))->va_tag) >> 7) == 0x01)
#define FUNC_CHECK_HUGE_POINTER(is_null, ptr, funcName) \
do { \
if (!is_null && VARATT_IS_HUGE_TOAST_POINTER((varlena *)ptr)) { \
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), \
errmsg("%s could not support larger than 1GB clob/blob data", funcName), \
errcause("parameter larger than 1GB"), erraction("parameter must less than 1GB"))); \
} \
} while (0)
#define VARATT_NOT_PAD_BYTE(PTR) (*((uint8*)(PTR)) != 0)
/* VARSIZE_4B() should only be used on known-aligned data */