* parseInput subroutine to read a 'T' (row descriptions) message. * We'll build a new PGresult structure (unless called for a Describe * command for a prepared statement) containing the attribute data. * Returns: 0 if processed message successfully, EOF to suspend parsing * (the latter case is not actually used currently). */
| 652 | * (the latter case is not actually used currently). |
| 653 | */ |
| 654 | static int |
| 655 | getRowDescriptions(PGconn *conn, int msgLength) |
| 656 | { |
| 657 | PGresult *result; |
| 658 | int nfields; |
| 659 | const char *errmsg; |
| 660 | int i; |
| 661 | |
| 662 | /* |
| 663 | * When doing Describe for a prepared statement, there'll already be a |
| 664 | * PGresult created by getParamDescriptions, and we should fill data into |
| 665 | * that. Otherwise, create a new, empty PGresult. |
| 666 | */ |
| 667 | if (!conn->cmd_queue_head || |
| 668 | (conn->cmd_queue_head && |
| 669 | conn->cmd_queue_head->queryclass == PGQUERY_DESCRIBE)) |
| 670 | { |
| 671 | if (conn->result) |
| 672 | result = conn->result; |
| 673 | else |
| 674 | result = PQmakeEmptyPGresult(conn, PGRES_COMMAND_OK); |
| 675 | } |
| 676 | else |
| 677 | result = PQmakeEmptyPGresult(conn, PGRES_TUPLES_OK); |
| 678 | if (!result) |
| 679 | { |
| 680 | errmsg = NULL; /* means "out of memory", see below */ |
| 681 | goto advance_and_error; |
| 682 | } |
| 683 | |
| 684 | /* parseInput already read the 'T' label and message length. */ |
| 685 | /* the next two bytes are the number of fields */ |
| 686 | if (pqGetInt(&(result->numAttributes), 2, conn)) |
| 687 | { |
| 688 | /* We should not run out of data here, so complain */ |
| 689 | errmsg = libpq_gettext("insufficient data in \"T\" message"); |
| 690 | goto advance_and_error; |
| 691 | } |
| 692 | nfields = result->numAttributes; |
| 693 | |
| 694 | /* allocate space for the attribute descriptors */ |
| 695 | if (nfields > 0) |
| 696 | { |
| 697 | result->attDescs = (PGresAttDesc *) |
| 698 | pqResultAlloc(result, nfields * sizeof(PGresAttDesc), true); |
| 699 | if (!result->attDescs) |
| 700 | { |
| 701 | errmsg = NULL; /* means "out of memory", see below */ |
| 702 | goto advance_and_error; |
| 703 | } |
| 704 | MemSet(result->attDescs, 0, nfields * sizeof(PGresAttDesc)); |
| 705 | } |
| 706 | |
| 707 | /* result->binary is true only if ALL columns are binary */ |
| 708 | result->binary = (nfields > 0) ? 1 : 0; |
| 709 | |
| 710 | /* get type info */ |
| 711 | for (i = 0; i < nfields; i++) |
no test coverage detected