* parseInput subroutine to read a 'D' (row data) message. * We fill rowbuf with column pointers and then call the row processor. * Returns: 0 if processed message successfully, EOF to suspend parsing * (the latter case is not actually used currently). */
| 911 | * (the latter case is not actually used currently). |
| 912 | */ |
| 913 | static int |
| 914 | getAnotherTuple(PGconn *conn, int msgLength) |
| 915 | { |
| 916 | PGresult *result = conn->result; |
| 917 | int nfields = result->numAttributes; |
| 918 | const char *errmsg; |
| 919 | PGdataValue *rowbuf; |
| 920 | int tupnfields; /* # fields from tuple */ |
| 921 | int vlen; /* length of the current field value */ |
| 922 | int i; |
| 923 | |
| 924 | /* Get the field count and make sure it's what we expect */ |
| 925 | if (pqGetInt(&tupnfields, 2, conn)) |
| 926 | { |
| 927 | /* We should not run out of data here, so complain */ |
| 928 | errmsg = libpq_gettext("insufficient data in \"D\" message"); |
| 929 | goto advance_and_error; |
| 930 | } |
| 931 | |
| 932 | if (tupnfields != nfields) |
| 933 | { |
| 934 | errmsg = libpq_gettext("unexpected field count in \"D\" message"); |
| 935 | goto advance_and_error; |
| 936 | } |
| 937 | |
| 938 | /* Resize row buffer if needed */ |
| 939 | rowbuf = conn->rowBuf; |
| 940 | if (nfields > conn->rowBufLen) |
| 941 | { |
| 942 | rowbuf = (PGdataValue *) realloc(rowbuf, |
| 943 | nfields * sizeof(PGdataValue)); |
| 944 | if (!rowbuf) |
| 945 | { |
| 946 | errmsg = NULL; /* means "out of memory", see below */ |
| 947 | goto advance_and_error; |
| 948 | } |
| 949 | conn->rowBuf = rowbuf; |
| 950 | conn->rowBufLen = nfields; |
| 951 | } |
| 952 | |
| 953 | /* Scan the fields */ |
| 954 | for (i = 0; i < nfields; i++) |
| 955 | { |
| 956 | /* get the value length */ |
| 957 | if (pqGetInt(&vlen, 4, conn)) |
| 958 | { |
| 959 | /* We should not run out of data here, so complain */ |
| 960 | errmsg = libpq_gettext("insufficient data in \"D\" message"); |
| 961 | goto advance_and_error; |
| 962 | } |
| 963 | rowbuf[i].len = vlen; |
| 964 | |
| 965 | /* |
| 966 | * rowbuf[i].value always points to the next address in the data |
| 967 | * buffer even if the value is NULL. This allows row processors to |
| 968 | * estimate data sizes more easily. |
| 969 | */ |
| 970 | rowbuf[i].value = conn->inBuffer + conn->inCursor; |
no test coverage detected