@ -481,14 +481,7 @@ Datum record_out(PG_FUNCTION_ARGS)
|
||||
column_info->column_type = column_type;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have a toasted datum, forcibly detoast it here to avoid
|
||||
* memory leakage inside the type's output routine.
|
||||
*/
|
||||
if (column_info->typisvarlena)
|
||||
attr = PointerGetDatum(PG_DETOAST_DATUM(values[i]));
|
||||
else
|
||||
attr = values[i];
|
||||
attr = values[i];
|
||||
|
||||
value = OutputFunctionCall(&column_info->proc, attr);
|
||||
|
||||
@ -523,12 +516,9 @@ Datum record_out(PG_FUNCTION_ARGS)
|
||||
}
|
||||
if (nq)
|
||||
appendStringInfoCharMacro(&buf, '"');
|
||||
|
||||
pfree_ext(value);
|
||||
|
||||
/* Clean up detoasted copy, if any */
|
||||
if (DatumGetPointer(attr) != DatumGetPointer(values[i]))
|
||||
pfree(DatumGetPointer(attr));
|
||||
if (value != NULL) {
|
||||
pfree_ext(value);
|
||||
}
|
||||
}
|
||||
|
||||
appendStringInfoChar(&buf, ')');
|
||||
@ -784,26 +774,14 @@ Datum record_send(PG_FUNCTION_ARGS)
|
||||
column_info->column_type = column_type;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have a toasted datum, forcibly detoast it here to avoid
|
||||
* memory leakage inside the type's output routine.
|
||||
*/
|
||||
if (column_info->typisvarlena)
|
||||
attr = PointerGetDatum(PG_DETOAST_DATUM(values[i]));
|
||||
else
|
||||
attr = values[i];
|
||||
attr = values[i];
|
||||
|
||||
outputbytes = SendFunctionCall(&column_info->proc, attr);
|
||||
|
||||
/* We assume the result will not have been toasted */
|
||||
pq_sendint32(&buf, VARSIZE(outputbytes) - VARHDRSZ);
|
||||
pq_sendbytes(&buf, VARDATA(outputbytes), VARSIZE(outputbytes) - VARHDRSZ);
|
||||
|
||||
pfree_ext(outputbytes);
|
||||
|
||||
/* Clean up detoasted copy, if any */
|
||||
if (DatumGetPointer(attr) != DatumGetPointer(values[i]))
|
||||
pfree(DatumGetPointer(attr));
|
||||
}
|
||||
|
||||
pfree_ext(values);
|
||||
|
||||
@ -771,7 +771,6 @@ void InsertOneValue(char* value, int i)
|
||||
Oid typioparam;
|
||||
Oid typinput;
|
||||
Oid typoutput;
|
||||
char* prt = NULL;
|
||||
|
||||
AssertArg(i >= 0 && i < MAXATTR);
|
||||
|
||||
@ -782,9 +781,7 @@ void InsertOneValue(char* value, int i)
|
||||
boot_get_type_io_data(typoid, &typlen, &typbyval, &typalign, &typdelim, &typioparam, &typinput, &typoutput);
|
||||
|
||||
values[i] = OidInputFunctionCall(typinput, value, typioparam, -1);
|
||||
prt = OidOutputFunctionCall(typoutput, values[i]);
|
||||
ereport(DEBUG4, (errmsg("inserted -> %s", prt)));
|
||||
pfree(prt);
|
||||
ereport(DEBUG4, (errmsg("inserted -> %s", OidOutputFunctionCall(typoutput, values[i]))));
|
||||
}
|
||||
|
||||
/* ----------------
|
||||
|
||||
@ -1324,8 +1324,7 @@ char *SPI_fname(TupleDesc tupdesc, int fnumber)
|
||||
|
||||
char *SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
|
||||
{
|
||||
char *result = NULL;
|
||||
Datum orig_val, val;
|
||||
Datum val;
|
||||
bool is_null = false;
|
||||
Oid typoid, foutoid;
|
||||
bool typo_is_varlen = false;
|
||||
@ -1337,7 +1336,7 @@ char *SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
orig_val = tableam_tops_tuple_getattr(tuple, (unsigned int)fnumber, tupdesc, &is_null);
|
||||
val = tableam_tops_tuple_getattr(tuple, (unsigned int)fnumber, tupdesc, &is_null);
|
||||
|
||||
if (is_null) {
|
||||
return NULL;
|
||||
@ -1351,24 +1350,7 @@ char *SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
|
||||
|
||||
getTypeOutputInfo(typoid, &foutoid, &typo_is_varlen);
|
||||
|
||||
/*
|
||||
* If we have a toasted datum, forcibly detoast it here to avoid memory
|
||||
* leakage inside the type's output routine.
|
||||
*/
|
||||
if (typo_is_varlen) {
|
||||
val = PointerGetDatum(PG_DETOAST_DATUM(orig_val));
|
||||
} else {
|
||||
val = orig_val;
|
||||
}
|
||||
|
||||
result = OidOutputFunctionCall(foutoid, val);
|
||||
|
||||
/* Clean up detoasted copy, if any */
|
||||
if (val != orig_val) {
|
||||
pfree(DatumGetPointer(val));
|
||||
}
|
||||
|
||||
return result;
|
||||
return OidOutputFunctionCall(foutoid, val);
|
||||
}
|
||||
|
||||
Datum SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull)
|
||||
|
||||
@ -1075,8 +1075,7 @@ void printtup(TupleTableSlot *slot, DestReceiver *self)
|
||||
*/
|
||||
for (i = 0; i < natts; ++i) {
|
||||
PrinttupAttrInfo *thisState = myState->myinfo + i;
|
||||
Datum origattr = slot->tts_values[i];
|
||||
Datum attr = static_cast<uintptr_t>(0);
|
||||
Datum attr = slot->tts_values[i];
|
||||
|
||||
/*
|
||||
* skip null value attribute,
|
||||
@ -1090,20 +1089,11 @@ void printtup(TupleTableSlot *slot, DestReceiver *self)
|
||||
if (typeinfo->attrs[i].atttypid == ANYARRAYOID && slot->tts_dataRow != NULL) {
|
||||
/*
|
||||
* For ANYARRAY type, the not null DataRow-based tuple indicates the value in
|
||||
* origattr had been converted to CSTRING type previously by using anyarray_out.
|
||||
* attr had been converted to CSTRING type previously by using anyarray_out.
|
||||
* just send over the DataRow message as we received it.
|
||||
*/
|
||||
pq_sendcountedtext(buf, (char *)origattr, strlen((char *)origattr), false);
|
||||
pq_sendcountedtext(buf, (char *)attr, strlen((char *)attr), false);
|
||||
} else {
|
||||
/*
|
||||
* If we have a toasted datum, forcibly detoast it here to avoid
|
||||
* memory leakage inside the type's output routine.
|
||||
*/
|
||||
if (thisState->typisvarlena)
|
||||
attr = PointerGetDatum(PG_DETOAST_DATUM(origattr));
|
||||
else
|
||||
attr = origattr;
|
||||
|
||||
if (thisState->format == 0) {
|
||||
/* Text output */
|
||||
char *outputstr = NULL;
|
||||
@ -1111,6 +1101,7 @@ void printtup(TupleTableSlot *slot, DestReceiver *self)
|
||||
t_thrd.xact_cxt.callPrint = true;
|
||||
#endif
|
||||
outputstr = OutputFunctionCall(&thisState->finfo, attr);
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
if (thisState->typisvarlena && self->forAnalyzeSampleTuple &&
|
||||
(typeinfo->attrs[i].atttypid == BYTEAOID || typeinfo->attrs[i].atttypid == CHAROID ||
|
||||
typeinfo->attrs[i].atttypid == TEXTOID || typeinfo->attrs[i].atttypid == BLOBOID ||
|
||||
@ -1141,11 +1132,14 @@ void printtup(TupleTableSlot *slot, DestReceiver *self)
|
||||
outputstr = TextDatumGetCString(str);
|
||||
pfree(result);
|
||||
}
|
||||
#endif
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
t_thrd.xact_cxt.callPrint = false;
|
||||
#endif
|
||||
pq_sendcountedtext(buf, outputstr, strlen(outputstr), false);
|
||||
pfree(outputstr);
|
||||
if (outputstr != NULL) {
|
||||
pfree(outputstr);
|
||||
}
|
||||
} else {
|
||||
/* Binary output */
|
||||
bytea *outputbytes = NULL;
|
||||
@ -1155,10 +1149,6 @@ void printtup(TupleTableSlot *slot, DestReceiver *self)
|
||||
pq_sendbytes(buf, VARDATA(outputbytes), VARSIZE(outputbytes) - VARHDRSZ);
|
||||
pfree(outputbytes);
|
||||
}
|
||||
|
||||
/* Clean up detoasted copy, if any */
|
||||
if (DatumGetPointer(attr) != DatumGetPointer(origattr))
|
||||
pfree(DatumGetPointer(attr));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1313,38 +1303,24 @@ void debugtup(TupleTableSlot *slot, DestReceiver *self)
|
||||
TupleDesc typeinfo = slot->tts_tupleDescriptor;
|
||||
int natts = typeinfo->natts;
|
||||
int i;
|
||||
Datum origattr, attr;
|
||||
Datum attr = 0;
|
||||
char *value = NULL;
|
||||
bool isnull = false;
|
||||
Oid typoutput;
|
||||
bool typisvarlena = false;
|
||||
|
||||
for (i = 0; i < natts; ++i) {
|
||||
origattr = tableam_tslot_getattr(slot, i + 1, &isnull);
|
||||
attr = tableam_tslot_getattr(slot, i + 1, &isnull);
|
||||
if (isnull) {
|
||||
continue;
|
||||
}
|
||||
getTypeOutputInfo(typeinfo->attrs[i].atttypid, &typoutput, &typisvarlena);
|
||||
|
||||
/*
|
||||
* If we have a toasted datum, forcibly detoast it here to avoid
|
||||
* memory leakage inside the type's output routine.
|
||||
*/
|
||||
if (typisvarlena) {
|
||||
attr = PointerGetDatum(PG_DETOAST_DATUM(origattr));
|
||||
} else {
|
||||
attr = origattr;
|
||||
}
|
||||
|
||||
value = OidOutputFunctionCall(typoutput, attr);
|
||||
|
||||
printatt((unsigned)i + 1, &typeinfo->attrs[i], value);
|
||||
|
||||
pfree(value);
|
||||
|
||||
/* Clean up detoasted copy, if any */
|
||||
if (DatumGetPointer(attr) != DatumGetPointer(origattr)) {
|
||||
pfree(DatumGetPointer(attr));
|
||||
if (value != NULL) {
|
||||
pfree(value);
|
||||
}
|
||||
}
|
||||
printf("\t----\n");
|
||||
@ -1403,8 +1379,7 @@ static void printtup_internal_20(TupleTableSlot *slot, DestReceiver *self)
|
||||
*/
|
||||
for (i = 0; i < natts; ++i) {
|
||||
PrinttupAttrInfo *thisState = myState->myinfo + i;
|
||||
Datum origattr = slot->tts_values[i];
|
||||
Datum attr = static_cast<uintptr_t>(0);
|
||||
Datum attr = slot->tts_values[i];
|
||||
bytea *outputbytes = NULL;
|
||||
|
||||
if (slot->tts_isnull[i])
|
||||
@ -1412,24 +1387,10 @@ static void printtup_internal_20(TupleTableSlot *slot, DestReceiver *self)
|
||||
|
||||
Assert(thisState->format == 1);
|
||||
|
||||
/*
|
||||
* If we have a toasted datum, forcibly detoast it here to avoid
|
||||
* memory leakage inside the type's output routine.
|
||||
*/
|
||||
if (thisState->typisvarlena)
|
||||
attr = PointerGetDatum(PG_DETOAST_DATUM(origattr));
|
||||
else
|
||||
attr = origattr;
|
||||
|
||||
outputbytes = SendFunctionCall(&thisState->finfo, attr);
|
||||
/* We assume the result will not have been toasted */
|
||||
pq_sendint32(buf, VARSIZE(outputbytes) - VARHDRSZ);
|
||||
pq_sendbytes(buf, VARDATA(outputbytes), VARSIZE(outputbytes) - VARHDRSZ);
|
||||
pfree(outputbytes);
|
||||
|
||||
/* Clean up detoasted copy, if any */
|
||||
if (DatumGetPointer(attr) != DatumGetPointer(origattr))
|
||||
pfree(DatumGetPointer(attr));
|
||||
}
|
||||
|
||||
pq_endmessage_reuse(buf);
|
||||
|
||||
Reference in New Issue
Block a user