📄 printtup.c
字号:
else attr = origattr; if (thisState->format == 0) { /* Text output */ char *outputstr; outputstr = DatumGetCString(FunctionCall3(&thisState->finfo, attr, ObjectIdGetDatum(thisState->typelem), Int32GetDatum(typeinfo->attrs[i]->atttypmod))); pq_sendcountedtext(&buf, outputstr, strlen(outputstr), false); pfree(outputstr); } else { /* Binary output */ bytea *outputbytes; outputbytes = DatumGetByteaP(FunctionCall2(&thisState->finfo, attr, ObjectIdGetDatum(thisState->typelem))); /* We assume the result will not have been toasted */ pq_sendint(&buf, VARSIZE(outputbytes) - VARHDRSZ, 4); pq_sendbytes(&buf, VARDATA(outputbytes), VARSIZE(outputbytes) - VARHDRSZ); pfree(outputbytes); } /* Clean up detoasted copy, if any */ if (attr != origattr) pfree(DatumGetPointer(attr)); } pq_endmessage(&buf);}/* ---------------- * printtup_20 --- print a tuple in protocol 2.0 * ---------------- */static voidprinttup_20(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self){ DR_printtup *myState = (DR_printtup *) self; StringInfoData buf; int natts = typeinfo->natts; int i, j, k; /* Set or update my derived attribute info, if needed */ if (myState->attrinfo != typeinfo || myState->nattrs != natts) printtup_prepare_info(myState, typeinfo, natts); /* * tell the frontend to expect new tuple data (in ASCII style) */ pq_beginmessage(&buf, 'D'); /* * send a bitmap of which attributes are not null */ j = 0; k = 1 << 7; for (i = 0; i < natts; ++i) { if (!heap_attisnull(tuple, i + 1)) j |= k; /* set bit if not null */ k >>= 1; if (k == 0) /* end of byte? */ { pq_sendint(&buf, j, 1); j = 0; k = 1 << 7; } } if (k != (1 << 7)) /* flush last partial byte */ pq_sendint(&buf, j, 1); /* * send the attributes of this tuple */ for (i = 0; i < natts; ++i) { PrinttupAttrInfo *thisState = myState->myinfo + i; Datum origattr, attr; bool isnull; char *outputstr; origattr = heap_getattr(tuple, i + 1, typeinfo, &isnull); if (isnull) continue; Assert(thisState->format == 0); /* * 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; outputstr = DatumGetCString(FunctionCall3(&thisState->finfo, attr, ObjectIdGetDatum(thisState->typelem), Int32GetDatum(typeinfo->attrs[i]->atttypmod))); pq_sendcountedtext(&buf, outputstr, strlen(outputstr), true); pfree(outputstr); /* Clean up detoasted copy, if any */ if (attr != origattr) pfree(DatumGetPointer(attr)); } pq_endmessage(&buf);}/* ---------------- * printtup_shutdown * ---------------- */static voidprinttup_shutdown(DestReceiver *self){ DR_printtup *myState = (DR_printtup *) self; if (myState->myinfo) pfree(myState->myinfo); myState->myinfo = NULL; myState->attrinfo = NULL;}/* ---------------- * printtup_destroy * ---------------- */static voidprinttup_destroy(DestReceiver *self){ pfree(self);}/* ---------------- * printatt * ---------------- */static voidprintatt(unsigned attributeId, Form_pg_attribute attributeP, char *value){ printf("\t%2d: %s%s%s%s\t(typeid = %u, len = %d, typmod = %d, byval = %c)\n", attributeId, NameStr(attributeP->attname), value != NULL ? " = \"" : "", value != NULL ? value : "", value != NULL ? "\"" : "", (unsigned int) (attributeP->atttypid), attributeP->attlen, attributeP->atttypmod, attributeP->attbyval ? 't' : 'f');}/* ---------------- * debugStartup - prepare to print tuples for an interactive backend * ---------------- */voiddebugStartup(DestReceiver *self, int operation, TupleDesc typeinfo){ int natts = typeinfo->natts; Form_pg_attribute *attinfo = typeinfo->attrs; int i; /* * show the return type of the tuples */ for (i = 0; i < natts; ++i) printatt((unsigned) i + 1, attinfo[i], (char *) NULL); printf("\t----\n");}/* ---------------- * debugtup - print one tuple for an interactive backend * ---------------- */voiddebugtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self){ int natts = typeinfo->natts; int i; Datum origattr, attr; char *value; bool isnull; Oid typoutput, typelem; bool typisvarlena; for (i = 0; i < natts; ++i) { origattr = heap_getattr(tuple, i + 1, typeinfo, &isnull); if (isnull) continue; getTypeOutputInfo(typeinfo->attrs[i]->atttypid, &typoutput, &typelem, &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 = DatumGetCString(OidFunctionCall3(typoutput, attr, ObjectIdGetDatum(typelem), Int32GetDatum(typeinfo->attrs[i]->atttypmod))); printatt((unsigned) i + 1, typeinfo->attrs[i], value); pfree(value); /* Clean up detoasted copy, if any */ if (attr != origattr) pfree(DatumGetPointer(attr)); } printf("\t----\n");}/* ---------------- * printtup_internal_20 --- print a binary tuple in protocol 2.0 * * We use a different message type, i.e. 'B' instead of 'D' to * indicate a tuple in internal (binary) form. * * This is largely same as printtup_20, except we use binary formatting. * ---------------- */static voidprinttup_internal_20(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self){ DR_printtup *myState = (DR_printtup *) self; StringInfoData buf; int natts = typeinfo->natts; int i, j, k; /* Set or update my derived attribute info, if needed */ if (myState->attrinfo != typeinfo || myState->nattrs != natts) printtup_prepare_info(myState, typeinfo, natts); /* * tell the frontend to expect new tuple data (in binary style) */ pq_beginmessage(&buf, 'B'); /* * send a bitmap of which attributes are not null */ j = 0; k = 1 << 7; for (i = 0; i < natts; ++i) { if (!heap_attisnull(tuple, i + 1)) j |= k; /* set bit if not null */ k >>= 1; if (k == 0) /* end of byte? */ { pq_sendint(&buf, j, 1); j = 0; k = 1 << 7; } } if (k != (1 << 7)) /* flush last partial byte */ pq_sendint(&buf, j, 1); /* * send the attributes of this tuple */ for (i = 0; i < natts; ++i) { PrinttupAttrInfo *thisState = myState->myinfo + i; Datum origattr, attr; bool isnull; bytea *outputbytes; origattr = heap_getattr(tuple, i + 1, typeinfo, &isnull); if (isnull) continue; 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 = DatumGetByteaP(FunctionCall2(&thisState->finfo, attr, ObjectIdGetDatum(thisState->typelem))); /* We assume the result will not have been toasted */ pq_sendint(&buf, VARSIZE(outputbytes) - VARHDRSZ, 4); pq_sendbytes(&buf, VARDATA(outputbytes), VARSIZE(outputbytes) - VARHDRSZ); pfree(outputbytes); /* Clean up detoasted copy, if any */ if (attr != origattr) pfree(DatumGetPointer(attr)); } pq_endmessage(&buf);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -