* Handle TIMELINE_HISTORY command. */
| 486 | * Handle TIMELINE_HISTORY command. |
| 487 | */ |
| 488 | static void |
| 489 | SendTimeLineHistory(TimeLineHistoryCmd *cmd) |
| 490 | { |
| 491 | StringInfoData buf; |
| 492 | char histfname[MAXFNAMELEN]; |
| 493 | char path[MAXPGPATH]; |
| 494 | int fd; |
| 495 | off_t histfilelen; |
| 496 | off_t bytesleft; |
| 497 | Size len; |
| 498 | |
| 499 | /* |
| 500 | * Reply with a result set with one row, and two columns. The first col is |
| 501 | * the name of the history file, 2nd is the contents. |
| 502 | */ |
| 503 | |
| 504 | TLHistoryFileName(histfname, cmd->timeline); |
| 505 | TLHistoryFilePath(path, cmd->timeline); |
| 506 | |
| 507 | /* Send a RowDescription message */ |
| 508 | pq_beginmessage(&buf, 'T'); |
| 509 | pq_sendint16(&buf, 2); /* 2 fields */ |
| 510 | |
| 511 | /* first field */ |
| 512 | pq_sendstring(&buf, "filename"); /* col name */ |
| 513 | pq_sendint32(&buf, 0); /* table oid */ |
| 514 | pq_sendint16(&buf, 0); /* attnum */ |
| 515 | pq_sendint32(&buf, TEXTOID); /* type oid */ |
| 516 | pq_sendint16(&buf, -1); /* typlen */ |
| 517 | pq_sendint32(&buf, 0); /* typmod */ |
| 518 | pq_sendint16(&buf, 0); /* format code */ |
| 519 | |
| 520 | /* second field */ |
| 521 | pq_sendstring(&buf, "content"); /* col name */ |
| 522 | pq_sendint32(&buf, 0); /* table oid */ |
| 523 | pq_sendint16(&buf, 0); /* attnum */ |
| 524 | pq_sendint32(&buf, TEXTOID); /* type oid */ |
| 525 | pq_sendint16(&buf, -1); /* typlen */ |
| 526 | pq_sendint32(&buf, 0); /* typmod */ |
| 527 | pq_sendint16(&buf, 0); /* format code */ |
| 528 | pq_endmessage(&buf); |
| 529 | |
| 530 | /* Send a DataRow message */ |
| 531 | pq_beginmessage(&buf, 'D'); |
| 532 | pq_sendint16(&buf, 2); /* # of columns */ |
| 533 | len = strlen(histfname); |
| 534 | pq_sendint32(&buf, len); /* col1 len */ |
| 535 | pq_sendbytes(&buf, histfname, len); |
| 536 | |
| 537 | fd = OpenTransientFile(path, O_RDONLY | PG_BINARY); |
| 538 | if (fd < 0) |
| 539 | ereport(ERROR, |
| 540 | (errcode_for_file_access(), |
| 541 | errmsg("could not open file \"%s\": %m", path))); |
| 542 | |
| 543 | /* Determine file length and send it to client */ |
| 544 | histfilelen = lseek(fd, 0, SEEK_END); |
| 545 | if (histfilelen < 0) |
no test coverage detected