575{
576 HeapTupleHeader td;
577 Oid tupType;
579 TupleDesc tupdesc;
580 HeapTupleData tmptup,
581 *tuple;
582 int i;
583 bool needsep = false;
584 const char *sep;
585
586 sep = use_line_feeds ? ",\n " : ",";
587
588 td = DatumGetHeapTupleHeader(composite);
589
590
591 tupType = HeapTupleHeaderGetTypeId(td);
592 tupTypmod = HeapTupleHeaderGetTypMod(td);
593 tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
594
595
596 tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
597 tmptup.t_data = td;
598 tuple = &tmptup;
599
600 appendStringInfoChar(
result,
'{');
601
602 for (i = 0; i < tupdesc->natts; i++)
603 {
604 Datum val;
605 bool isnull;
606 char *attname;
608 Oid outfuncoid;
609 Form_pg_attribute att = TupleDescAttr(tupdesc, i);
610
611 if (att->attisdropped)
612 continue;
613
614 if (needsep)
615 appendStringInfoString(
result, sep);
616 needsep = true;
617
618 attname = NameStr(att->attname);
619 escape_json(
result, attname);
620 appendStringInfoChar(
result,
':');
621
622 val = heap_getattr(tuple, i + 1, tupdesc, &isnull);
623
624 if (isnull)
625 {
627 outfuncoid = InvalidOid;
628 }
629 else
631
633 }
634
635 appendStringInfoChar(
result,
'}');
636 ReleaseTupleDesc(tupdesc);
637}
char result[OUT_DOUBLE_BUFFER_SIZE]
static void json_categorize_type(Oid typoid, JsonTypeCategory *tcategory, Oid *outfuncoid)
static void datum_to_json(Datum val, bool is_null, StringInfo result, JsonTypeCategory tcategory, Oid outfuncoid, bool key_scalar)