538{
539 HeapTupleHeader td;
540 Oid tupType;
542 TupleDesc tupdesc;
543 HeapTupleData tmptup,
544 *tuple;
545 int i;
546 bool needsep = false;
547 const char *sep;
548
549 sep = use_line_feeds ? ",\n " : ",";
550
551 td = DatumGetHeapTupleHeader(composite);
552
553
554 tupType = HeapTupleHeaderGetTypeId(td);
555 tupTypmod = HeapTupleHeaderGetTypMod(td);
556 tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
557
558
559 tmptup.t_len = HeapTupleHeaderGetDatumLength(td);
560 tmptup.t_data = td;
561 tuple = &tmptup;
562
563 appendStringInfoChar(
result,
'{');
564
565 for (i = 0; i < tupdesc->natts; i++)
566 {
567 Datum val;
568 bool isnull;
569 char *attname;
571 Oid outfuncoid;
572 Form_pg_attribute att = TupleDescAttr(tupdesc, i);
573
574 if (att->attisdropped)
575 continue;
576
577 if (needsep)
578 appendStringInfoString(
result, sep);
579 needsep = true;
580
581 attname = NameStr(att->attname);
582 escape_json(
result, attname);
583 appendStringInfoChar(
result,
':');
584
585 val = heap_getattr(tuple, i + 1, tupdesc, &isnull);
586
587 if (isnull)
588 {
590 outfuncoid = InvalidOid;
591 }
592 else
594
596 }
597
598 appendStringInfoChar(
result,
'}');
599 ReleaseTupleDesc(tupdesc);
600}
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)