LCOV - differential code coverage report
Current view: top level - src/interfaces/libpq - fe-trace.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 55.3 % 365 202 163 202
Current Date: 2023-04-08 17:13:01 Functions: 59.4 % 32 19 13 19
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (240..) days: 55.3 % 365 202 163 202
Legend: Lines: hit not hit Function coverage date bins:
(240..) days: 59.4 % 32 19 13 19

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  *  fe-trace.c
                                  4                 :  *    functions for libpq protocol tracing
                                  5                 :  *
                                  6                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                  7                 :  * Portions Copyright (c) 1994, Regents of the University of California
                                  8                 :  *
                                  9                 :  * IDENTIFICATION
                                 10                 :  *    src/interfaces/libpq/fe-trace.c
                                 11                 :  *
                                 12                 :  *-------------------------------------------------------------------------
                                 13                 :  */
                                 14                 : 
                                 15                 : #include "postgres_fe.h"
                                 16                 : 
                                 17                 : #include <ctype.h>
                                 18                 : #include <limits.h>
                                 19                 : #include <sys/time.h>
                                 20                 : #include <time.h>
                                 21                 : 
                                 22                 : #ifdef WIN32
                                 23                 : #include "win32.h"
                                 24                 : #else
                                 25                 : #include <unistd.h>
                                 26                 : #endif
                                 27                 : 
                                 28                 : #include "libpq-fe.h"
                                 29                 : #include "libpq-int.h"
                                 30                 : #include "port/pg_bswap.h"
                                 31                 : 
                                 32                 : 
                                 33                 : /* Enable tracing */
                                 34                 : void
  740 alvherre                   35 CBC           9 : PQtrace(PGconn *conn, FILE *debug_port)
                                 36                 : {
                                 37               9 :     if (conn == NULL)
  740 alvherre                   38 UBC           0 :         return;
  740 alvherre                   39 CBC           9 :     PQuntrace(conn);
                                 40               9 :     if (debug_port == NULL)
  740 alvherre                   41 UBC           0 :         return;
                                 42                 : 
  740 alvherre                   43 CBC           9 :     conn->Pfdebug = debug_port;
                                 44               9 :     conn->traceFlags = 0;
                                 45                 : }
                                 46                 : 
                                 47                 : /* Disable tracing */
                                 48                 : void
                                 49               9 : PQuntrace(PGconn *conn)
                                 50                 : {
                                 51               9 :     if (conn == NULL)
  740 alvherre                   52 UBC           0 :         return;
  740 alvherre                   53 CBC           9 :     if (conn->Pfdebug)
                                 54                 :     {
  740 alvherre                   55 UBC           0 :         fflush(conn->Pfdebug);
                                 56               0 :         conn->Pfdebug = NULL;
                                 57                 :     }
                                 58                 : 
  740 alvherre                   59 CBC           9 :     conn->traceFlags = 0;
                                 60                 : }
                                 61                 : 
                                 62                 : /* Set flags for current tracing session */
                                 63                 : void
  668 noah                       64               9 : PQsetTraceFlags(PGconn *conn, int flags)
                                 65                 : {
  740 alvherre                   66               9 :     if (conn == NULL)
  740 alvherre                   67 UBC           0 :         return;
                                 68                 :     /* If PQtrace() failed, do nothing. */
  740 alvherre                   69 CBC           9 :     if (conn->Pfdebug == NULL)
  740 alvherre                   70 UBC           0 :         return;
  740 alvherre                   71 CBC           9 :     conn->traceFlags = flags;
                                 72                 : }
                                 73                 : 
                                 74                 : /*
                                 75                 :  * Print the current time, with microseconds, into a caller-supplied
                                 76                 :  * buffer.
                                 77                 :  * Cribbed from setup_formatted_log_time, but much simpler.
                                 78                 :  */
                                 79                 : static void
  740 alvherre                   80 UBC           0 : pqTraceFormatTimestamp(char *timestr, size_t ts_len)
                                 81                 : {
                                 82                 :     struct timeval tval;
                                 83                 :     time_t      now;
                                 84                 : 
                                 85               0 :     gettimeofday(&tval, NULL);
                                 86                 : 
                                 87                 :     /*
                                 88                 :      * MSVC's implementation of timeval uses a long for tv_sec, however,
                                 89                 :      * localtime() expects a time_t pointer.  Here we'll assign tv_sec to a
                                 90                 :      * local time_t variable so that we pass localtime() the correct pointer
                                 91                 :      * type.
                                 92                 :      */
  733 drowley                    93               0 :     now = tval.tv_sec;
  740 alvherre                   94               0 :     strftime(timestr, ts_len,
                                 95                 :              "%Y-%m-%d %H:%M:%S",
  733 drowley                    96               0 :              localtime(&now));
                                 97                 :     /* append microseconds */
  739 tgl                        98               0 :     snprintf(timestr + strlen(timestr), ts_len - strlen(timestr),
                                 99               0 :              ".%06u", (unsigned int) (tval.tv_usec));
  740 alvherre                  100               0 : }
                                101                 : 
                                102                 : /*
                                103                 :  *   pqTraceOutputByte1: output a 1-char message to the log
                                104                 :  */
                                105                 : static void
  740 alvherre                  106 CBC         124 : pqTraceOutputByte1(FILE *pfdebug, const char *data, int *cursor)
                                107                 : {
                                108             124 :     const char *v = data + *cursor;
                                109                 : 
                                110                 :     /*
                                111                 :      * Show non-printable data in hex format, including the terminating \0
                                112                 :      * that completes ErrorResponse and NoticeResponse messages.
                                113                 :      */
  739 tgl                       114             124 :     if (!isprint((unsigned char) *v))
  740 alvherre                  115               8 :         fprintf(pfdebug, " \\x%02x", *v);
                                116                 :     else
                                117             116 :         fprintf(pfdebug, " %c", *v);
                                118             124 :     *cursor += 1;
                                119             124 : }
                                120                 : 
                                121                 : /*
                                122                 :  *   pqTraceOutputInt16: output a 2-byte integer message to the log
                                123                 :  */
                                124                 : static int
                                125             324 : pqTraceOutputInt16(FILE *pfdebug, const char *data, int *cursor)
                                126                 : {
                                127                 :     uint16      tmp;
                                128                 :     int         result;
                                129                 : 
                                130             324 :     memcpy(&tmp, data + *cursor, 2);
                                131             324 :     *cursor += 2;
                                132             324 :     result = (int) pg_ntoh16(tmp);
                                133             324 :     fprintf(pfdebug, " %d", result);
                                134                 : 
                                135             324 :     return result;
                                136                 : }
                                137                 : 
                                138                 : /*
                                139                 :  *   pqTraceOutputInt32: output a 4-byte integer message to the log
                                140                 :  *
                                141                 :  * If 'suppress' is true, print a literal NNNN instead of the actual number.
                                142                 :  */
                                143                 : static int
                                144             179 : pqTraceOutputInt32(FILE *pfdebug, const char *data, int *cursor, bool suppress)
                                145                 : {
                                146                 :     int         result;
                                147                 : 
                                148             179 :     memcpy(&result, data + *cursor, 4);
                                149             179 :     *cursor += 4;
                                150             179 :     result = (int) pg_ntoh32(result);
                                151             179 :     if (suppress)
                                152              69 :         fprintf(pfdebug, " NNNN");
                                153                 :     else
                                154             110 :         fprintf(pfdebug, " %d", result);
                                155                 : 
                                156             179 :     return result;
                                157                 : }
                                158                 : 
                                159                 : /*
                                160                 :  *   pqTraceOutputString: output a string message to the log
                                161                 :  */
                                162                 : static void
                                163             337 : pqTraceOutputString(FILE *pfdebug, const char *data, int *cursor, bool suppress)
                                164                 : {
                                165                 :     int         len;
                                166                 : 
                                167             337 :     if (suppress)
                                168                 :     {
                                169              24 :         fprintf(pfdebug, " \"SSSS\"");
                                170              24 :         *cursor += strlen(data + *cursor) + 1;
                                171                 :     }
                                172                 :     else
                                173                 :     {
                                174             313 :         len = fprintf(pfdebug, " \"%s\"", data + *cursor);
                                175                 : 
                                176                 :         /*
                                177                 :          * This is a null-terminated string. So add 1 after subtracting 3
                                178                 :          * which is the double quotes and space length from len.
                                179                 :          */
                                180             313 :         *cursor += (len - 3 + 1);
                                181                 :     }
                                182             337 : }
                                183                 : 
                                184                 : /*
                                185                 :  * pqTraceOutputNchar: output a string of exactly len bytes message to the log
                                186                 :  */
                                187                 : static void
                                188              46 : pqTraceOutputNchar(FILE *pfdebug, int len, const char *data, int *cursor)
                                189                 : {
                                190                 :     int         i,
                                191                 :                 next;           /* first char not yet printed */
                                192              46 :     const char *v = data + *cursor;
                                193                 : 
                                194              46 :     fprintf(pfdebug, " \'");
                                195                 : 
                                196             760 :     for (next = i = 0; i < len; ++i)
                                197                 :     {
  739 tgl                       198             714 :         if (isprint((unsigned char) v[i]))
  740 alvherre                  199             714 :             continue;
                                200                 :         else
                                201                 :         {
  740 alvherre                  202 UBC           0 :             fwrite(v + next, 1, i - next, pfdebug);
                                203               0 :             fprintf(pfdebug, "\\x%02x", v[i]);
                                204               0 :             next = i + 1;
                                205                 :         }
                                206                 :     }
  740 alvherre                  207 CBC          46 :     if (next < len)
                                208              46 :         fwrite(v + next, 1, len - next, pfdebug);
                                209                 : 
                                210              46 :     fprintf(pfdebug, "\'");
                                211              46 :     *cursor += len;
                                212              46 : }
                                213                 : 
                                214                 : /*
                                215                 :  * Output functions by protocol message type
                                216                 :  */
                                217                 : 
                                218                 : /* NotificationResponse */
                                219                 : static void
  740 alvherre                  220 UBC           0 : pqTraceOutputA(FILE *f, const char *message, int *cursor, bool regress)
                                221                 : {
                                222               0 :     fprintf(f, "NotificationResponse\t");
                                223               0 :     pqTraceOutputInt32(f, message, cursor, regress);
                                224               0 :     pqTraceOutputString(f, message, cursor, false);
                                225               0 :     pqTraceOutputString(f, message, cursor, false);
                                226               0 : }
                                227                 : 
                                228                 : /* Bind */
                                229                 : static void
  740 alvherre                  230 CBC          34 : pqTraceOutputB(FILE *f, const char *message, int *cursor)
                                231                 : {
                                232                 :     int         nparams;
                                233                 : 
                                234              34 :     fprintf(f, "Bind\t");
                                235              34 :     pqTraceOutputString(f, message, cursor, false);
                                236              34 :     pqTraceOutputString(f, message, cursor, false);
                                237              34 :     nparams = pqTraceOutputInt16(f, message, cursor);
                                238                 : 
                                239              34 :     for (int i = 0; i < nparams; i++)
  740 alvherre                  240 UBC           0 :         pqTraceOutputInt16(f, message, cursor);
                                241                 : 
  740 alvherre                  242 CBC          34 :     nparams = pqTraceOutputInt16(f, message, cursor);
                                243                 : 
                                244              44 :     for (int i = 0; i < nparams; i++)
                                245                 :     {
                                246                 :         int         nbytes;
                                247                 : 
                                248              10 :         nbytes = pqTraceOutputInt32(f, message, cursor, false);
                                249              10 :         if (nbytes == -1)
  740 alvherre                  250 UBC           0 :             continue;
  740 alvherre                  251 CBC          10 :         pqTraceOutputNchar(f, nbytes, message, cursor);
                                252                 :     }
                                253                 : 
                                254              34 :     nparams = pqTraceOutputInt16(f, message, cursor);
                                255              68 :     for (int i = 0; i < nparams; i++)
                                256              34 :         pqTraceOutputInt16(f, message, cursor);
                                257              34 : }
                                258                 : 
                                259                 : /* Close(F) or CommandComplete(B) */
                                260                 : static void
                                261              35 : pqTraceOutputC(FILE *f, bool toServer, const char *message, int *cursor)
                                262                 : {
                                263              35 :     if (toServer)
                                264                 :     {
  740 alvherre                  265 UBC           0 :         fprintf(f, "Close\t");
                                266               0 :         pqTraceOutputByte1(f, message, cursor);
                                267               0 :         pqTraceOutputString(f, message, cursor, false);
                                268                 :     }
                                269                 :     else
                                270                 :     {
  740 alvherre                  271 CBC          35 :         fprintf(f, "CommandComplete\t");
                                272              35 :         pqTraceOutputString(f, message, cursor, false);
                                273                 :     }
                                274              35 : }
                                275                 : 
                                276                 : /* Describe(F) or DataRow(B) */
                                277                 : static void
                                278              72 : pqTraceOutputD(FILE *f, bool toServer, const char *message, int *cursor)
                                279                 : {
                                280              72 :     if (toServer)
                                281                 :     {
                                282              36 :         fprintf(f, "Describe\t");
                                283              36 :         pqTraceOutputByte1(f, message, cursor);
                                284              36 :         pqTraceOutputString(f, message, cursor, false);
                                285                 :     }
                                286                 :     else
                                287                 :     {
                                288                 :         int         nfields;
                                289                 :         int         len;
                                290                 :         int         i;
                                291                 : 
                                292              36 :         fprintf(f, "DataRow\t");
                                293              36 :         nfields = pqTraceOutputInt16(f, message, cursor);
                                294              72 :         for (i = 0; i < nfields; i++)
                                295                 :         {
                                296              36 :             len = pqTraceOutputInt32(f, message, cursor, false);
                                297              36 :             if (len == -1)
  740 alvherre                  298 UBC           0 :                 continue;
  740 alvherre                  299 CBC          36 :             pqTraceOutputNchar(f, len, message, cursor);
                                300                 :         }
                                301                 :     }
                                302              72 : }
                                303                 : 
                                304                 : /* NoticeResponse / ErrorResponse */
                                305                 : static void
                                306               8 : pqTraceOutputNR(FILE *f, const char *type, const char *message, int *cursor,
                                307                 :                 bool regress)
                                308                 : {
                                309               8 :     fprintf(f, "%s\t", type);
                                310                 :     for (;;)
                                311              58 :     {
                                312                 :         char        field;
                                313                 :         bool        suppress;
                                314                 : 
                                315              66 :         pqTraceOutputByte1(f, message, cursor);
                                316              66 :         field = message[*cursor - 1];
                                317              66 :         if (field == '\0')
                                318               8 :             break;
                                319                 : 
                                320              58 :         suppress = regress && (field == 'L' || field == 'F' || field == 'R');
                                321              58 :         pqTraceOutputString(f, message, cursor, suppress);
                                322                 :     }
                                323               8 : }
                                324                 : 
                                325                 : /* Execute(F) or ErrorResponse(B) */
                                326                 : static void
  699 peter                     327              39 : pqTraceOutputE(FILE *f, bool toServer, const char *message, int *cursor, bool regress)
                                328                 : {
  740 alvherre                  329              39 :     if (toServer)
                                330                 :     {
                                331              34 :         fprintf(f, "Execute\t");
                                332              34 :         pqTraceOutputString(f, message, cursor, false);
                                333              34 :         pqTraceOutputInt32(f, message, cursor, false);
                                334                 :     }
                                335                 :     else
  699 peter                     336               5 :         pqTraceOutputNR(f, "ErrorResponse", message, cursor, regress);
  740 alvherre                  337              39 : }
                                338                 : 
                                339                 : /* CopyFail */
                                340                 : static void
  740 alvherre                  341 UBC           0 : pqTraceOutputf(FILE *f, const char *message, int *cursor)
                                342                 : {
                                343               0 :     fprintf(f, "CopyFail\t");
                                344               0 :     pqTraceOutputString(f, message, cursor, false);
                                345               0 : }
                                346                 : 
                                347                 : /* FunctionCall */
                                348                 : static void
                                349               0 : pqTraceOutputF(FILE *f, const char *message, int *cursor, bool regress)
                                350                 : {
                                351                 :     int         nfields;
                                352                 :     int         nbytes;
                                353                 : 
                                354               0 :     fprintf(f, "FunctionCall\t");
                                355               0 :     pqTraceOutputInt32(f, message, cursor, regress);
                                356               0 :     nfields = pqTraceOutputInt16(f, message, cursor);
                                357                 : 
                                358               0 :     for (int i = 0; i < nfields; i++)
                                359               0 :         pqTraceOutputInt16(f, message, cursor);
                                360                 : 
                                361               0 :     nfields = pqTraceOutputInt16(f, message, cursor);
                                362                 : 
                                363               0 :     for (int i = 0; i < nfields; i++)
                                364                 :     {
                                365               0 :         nbytes = pqTraceOutputInt32(f, message, cursor, false);
                                366               0 :         if (nbytes == -1)
                                367               0 :             continue;
                                368               0 :         pqTraceOutputNchar(f, nbytes, message, cursor);
                                369                 :     }
                                370                 : 
                                371               0 :     pqTraceOutputInt16(f, message, cursor);
                                372               0 : }
                                373                 : 
                                374                 : /* CopyInResponse */
                                375                 : static void
                                376               0 : pqTraceOutputG(FILE *f, const char *message, int *cursor)
                                377                 : {
                                378                 :     int         nfields;
                                379                 : 
                                380               0 :     fprintf(f, "CopyInResponse\t");
                                381               0 :     pqTraceOutputByte1(f, message, cursor);
                                382               0 :     nfields = pqTraceOutputInt16(f, message, cursor);
                                383                 : 
                                384               0 :     for (int i = 0; i < nfields; i++)
                                385               0 :         pqTraceOutputInt16(f, message, cursor);
                                386               0 : }
                                387                 : 
                                388                 : /* CopyOutResponse */
                                389                 : static void
                                390               0 : pqTraceOutputH(FILE *f, const char *message, int *cursor)
                                391                 : {
                                392                 :     int         nfields;
                                393                 : 
                                394               0 :     fprintf(f, "CopyOutResponse\t");
                                395               0 :     pqTraceOutputByte1(f, message, cursor);
                                396               0 :     nfields = pqTraceOutputInt16(f, message, cursor);
                                397                 : 
                                398               0 :     for (int i = 0; i < nfields; i++)
                                399               0 :         pqTraceOutputInt16(f, message, cursor);
                                400               0 : }
                                401                 : 
                                402                 : /* BackendKeyData */
                                403                 : static void
                                404               0 : pqTraceOutputK(FILE *f, const char *message, int *cursor, bool regress)
                                405                 : {
                                406               0 :     fprintf(f, "BackendKeyData\t");
                                407               0 :     pqTraceOutputInt32(f, message, cursor, regress);
                                408               0 :     pqTraceOutputInt32(f, message, cursor, regress);
                                409               0 : }
                                410                 : 
                                411                 : /* Parse */
                                412                 : static void
  740 alvherre                  413 CBC          34 : pqTraceOutputP(FILE *f, const char *message, int *cursor, bool regress)
                                414                 : {
                                415                 :     int         nparams;
                                416                 : 
                                417              34 :     fprintf(f, "Parse\t");
                                418              34 :     pqTraceOutputString(f, message, cursor, false);
                                419              34 :     pqTraceOutputString(f, message, cursor, false);
                                420              34 :     nparams = pqTraceOutputInt16(f, message, cursor);
                                421                 : 
                                422              42 :     for (int i = 0; i < nparams; i++)
                                423               8 :         pqTraceOutputInt32(f, message, cursor, regress);
                                424              34 : }
                                425                 : 
                                426                 : /* Query */
                                427                 : static void
                                428               8 : pqTraceOutputQ(FILE *f, const char *message, int *cursor)
                                429                 : {
                                430               8 :     fprintf(f, "Query\t");
                                431               8 :     pqTraceOutputString(f, message, cursor, false);
                                432               8 : }
                                433                 : 
                                434                 : /* Authentication */
                                435                 : static void
  740 alvherre                  436 UBC           0 : pqTraceOutputR(FILE *f, const char *message, int *cursor)
                                437                 : {
                                438               0 :     fprintf(f, "Authentication\t");
                                439               0 :     pqTraceOutputInt32(f, message, cursor, false);
                                440               0 : }
                                441                 : 
                                442                 : /* ParameterStatus */
                                443                 : static void
                                444               0 : pqTraceOutputS(FILE *f, const char *message, int *cursor)
                                445                 : {
                                446               0 :     fprintf(f, "ParameterStatus\t");
                                447               0 :     pqTraceOutputString(f, message, cursor, false);
                                448               0 :     pqTraceOutputString(f, message, cursor, false);
                                449               0 : }
                                450                 : 
                                451                 : /* ParameterDescription */
                                452                 : static void
  740 alvherre                  453 CBC           1 : pqTraceOutputt(FILE *f, const char *message, int *cursor, bool regress)
                                454                 : {
                                455                 :     int         nfields;
                                456                 : 
                                457               1 :     fprintf(f, "ParameterDescription\t");
                                458               1 :     nfields = pqTraceOutputInt16(f, message, cursor);
                                459                 : 
                                460               2 :     for (int i = 0; i < nfields; i++)
                                461               1 :         pqTraceOutputInt32(f, message, cursor, regress);
                                462               1 : }
                                463                 : 
                                464                 : /* RowDescription */
                                465                 : static void
                                466              27 : pqTraceOutputT(FILE *f, const char *message, int *cursor, bool regress)
                                467                 : {
                                468                 :     int         nfields;
                                469                 : 
                                470              27 :     fprintf(f, "RowDescription\t");
                                471              27 :     nfields = pqTraceOutputInt16(f, message, cursor);
                                472                 : 
                                473              57 :     for (int i = 0; i < nfields; i++)
                                474                 :     {
                                475              30 :         pqTraceOutputString(f, message, cursor, false);
                                476              30 :         pqTraceOutputInt32(f, message, cursor, regress);
                                477              30 :         pqTraceOutputInt16(f, message, cursor);
                                478              30 :         pqTraceOutputInt32(f, message, cursor, regress);
                                479              30 :         pqTraceOutputInt16(f, message, cursor);
                                480              30 :         pqTraceOutputInt32(f, message, cursor, false);
                                481              30 :         pqTraceOutputInt16(f, message, cursor);
                                482                 :     }
                                483              27 : }
                                484                 : 
                                485                 : /* NegotiateProtocolVersion */
                                486                 : static void
  740 alvherre                  487 UBC           0 : pqTraceOutputv(FILE *f, const char *message, int *cursor)
                                488                 : {
                                489               0 :     fprintf(f, "NegotiateProtocolVersion\t");
                                490               0 :     pqTraceOutputInt32(f, message, cursor, false);
                                491               0 :     pqTraceOutputInt32(f, message, cursor, false);
                                492               0 : }
                                493                 : 
                                494                 : /* FunctionCallResponse */
                                495                 : static void
                                496               0 : pqTraceOutputV(FILE *f, const char *message, int *cursor)
                                497                 : {
                                498                 :     int         len;
                                499                 : 
                                500               0 :     fprintf(f, "FunctionCallResponse\t");
                                501               0 :     len = pqTraceOutputInt32(f, message, cursor, false);
                                502               0 :     if (len != -1)
                                503               0 :         pqTraceOutputNchar(f, len, message, cursor);
                                504               0 : }
                                505                 : 
                                506                 : /* CopyBothResponse */
                                507                 : static void
                                508               0 : pqTraceOutputW(FILE *f, const char *message, int *cursor, int length)
                                509                 : {
                                510               0 :     fprintf(f, "CopyBothResponse\t");
                                511               0 :     pqTraceOutputByte1(f, message, cursor);
                                512                 : 
                                513               0 :     while (length > *cursor)
                                514               0 :         pqTraceOutputInt16(f, message, cursor);
                                515               0 : }
                                516                 : 
                                517                 : /* ReadyForQuery */
                                518                 : static void
  740 alvherre                  519 CBC          22 : pqTraceOutputZ(FILE *f, const char *message, int *cursor)
                                520                 : {
                                521              22 :     fprintf(f, "ReadyForQuery\t");
                                522              22 :     pqTraceOutputByte1(f, message, cursor);
                                523              22 : }
                                524                 : 
                                525                 : /*
                                526                 :  * Print the given message to the trace output stream.
                                527                 :  */
                                528                 : void
                                529             365 : pqTraceOutputMessage(PGconn *conn, const char *message, bool toServer)
                                530                 : {
                                531                 :     char        id;
                                532                 :     int         length;
                                533             365 :     char       *prefix = toServer ? "F" : "B";
                                534             365 :     int         logCursor = 0;
                                535                 :     bool        regress;
                                536                 : 
                                537             365 :     if ((conn->traceFlags & PQTRACE_SUPPRESS_TIMESTAMPS) == 0)
                                538                 :     {
                                539                 :         char        timestr[128];
                                540                 : 
  740 alvherre                  541 UBC           0 :         pqTraceFormatTimestamp(timestr, sizeof(timestr));
                                542               0 :         fprintf(conn->Pfdebug, "%s\t", timestr);
                                543                 :     }
  740 alvherre                  544 CBC         365 :     regress = (conn->traceFlags & PQTRACE_REGRESS_MODE) != 0;
                                545                 : 
                                546             365 :     id = message[logCursor++];
                                547                 : 
                                548             365 :     memcpy(&length, message + logCursor, 4);
                                549             365 :     length = (int) pg_ntoh32(length);
                                550             365 :     logCursor += 4;
                                551                 : 
                                552                 :     /*
                                553                 :      * In regress mode, suppress the length of ErrorResponse and
                                554                 :      * NoticeResponse.  The F (file name), L (line number) and R (routine
                                555                 :      * name) fields can change as server code is modified, and if their
                                556                 :      * lengths differ from the originals, that would break tests.
                                557                 :      */
  730                           558             365 :     if (regress && !toServer && (id == 'E' || id == 'N'))
                                559               8 :         fprintf(conn->Pfdebug, "%s\tNN\t", prefix);
                                560                 :     else
                                561             357 :         fprintf(conn->Pfdebug, "%s\t%d\t", prefix, length);
                                562                 : 
  740                           563             365 :     switch (id)
                                564                 :     {
                                565              29 :         case '1':
                                566              29 :             fprintf(conn->Pfdebug, "ParseComplete");
                                567                 :             /* No message content */
                                568              29 :             break;
                                569              27 :         case '2':
                                570              27 :             fprintf(conn->Pfdebug, "BindComplete");
                                571                 :             /* No message content */
                                572              27 :             break;
  740 alvherre                  573 UBC           0 :         case '3':
                                574               0 :             fprintf(conn->Pfdebug, "CloseComplete");
                                575                 :             /* No message content */
                                576               0 :             break;
                                577               0 :         case 'A':               /* Notification Response */
                                578               0 :             pqTraceOutputA(conn->Pfdebug, message, &logCursor, regress);
                                579               0 :             break;
  740 alvherre                  580 CBC          34 :         case 'B':               /* Bind */
                                581              34 :             pqTraceOutputB(conn->Pfdebug, message, &logCursor);
                                582              34 :             break;
  740 alvherre                  583 UBC           0 :         case 'c':
                                584               0 :             fprintf(conn->Pfdebug, "CopyDone");
                                585                 :             /* No message content */
                                586               0 :             break;
  740 alvherre                  587 CBC          35 :         case 'C':               /* Close(F) or Command Complete(B) */
                                588              35 :             pqTraceOutputC(conn->Pfdebug, toServer, message, &logCursor);
                                589              35 :             break;
  740 alvherre                  590 UBC           0 :         case 'd':               /* Copy Data */
                                591                 :             /* Drop COPY data to reduce the overhead of logging. */
                                592               0 :             break;
  740 alvherre                  593 CBC          72 :         case 'D':               /* Describe(F) or Data Row(B) */
                                594              72 :             pqTraceOutputD(conn->Pfdebug, toServer, message, &logCursor);
                                595              72 :             break;
                                596              39 :         case 'E':               /* Execute(F) or Error Response(B) */
                                597              39 :             pqTraceOutputE(conn->Pfdebug, toServer, message, &logCursor,
                                598                 :                            regress);
                                599              39 :             break;
  740 alvherre                  600 UBC           0 :         case 'f':               /* Copy Fail */
                                601               0 :             pqTraceOutputf(conn->Pfdebug, message, &logCursor);
                                602               0 :             break;
                                603               0 :         case 'F':               /* Function Call */
                                604               0 :             pqTraceOutputF(conn->Pfdebug, message, &logCursor, regress);
                                605               0 :             break;
                                606               0 :         case 'G':               /* Start Copy In */
                                607               0 :             pqTraceOutputG(conn->Pfdebug, message, &logCursor);
                                608               0 :             break;
  740 alvherre                  609 CBC           6 :         case 'H':               /* Flush(F) or Start Copy Out(B) */
                                610               6 :             if (!toServer)
  740 alvherre                  611 UBC           0 :                 pqTraceOutputH(conn->Pfdebug, message, &logCursor);
                                612                 :             else
  740 alvherre                  613 CBC           6 :                 fprintf(conn->Pfdebug, "Flush");   /* no message content */
                                614               6 :             break;
  740 alvherre                  615 UBC           0 :         case 'I':
                                616               0 :             fprintf(conn->Pfdebug, "EmptyQueryResponse");
                                617                 :             /* No message content */
                                618               0 :             break;
                                619               0 :         case 'K':               /* secret key data from the backend */
                                620               0 :             pqTraceOutputK(conn->Pfdebug, message, &logCursor, regress);
                                621               0 :             break;
  740 alvherre                  622 CBC           5 :         case 'n':
                                623               5 :             fprintf(conn->Pfdebug, "NoData");
                                624                 :             /* No message content */
                                625               5 :             break;
                                626               3 :         case 'N':
                                627               3 :             pqTraceOutputNR(conn->Pfdebug, "NoticeResponse", message,
                                628                 :                             &logCursor, regress);
                                629               3 :             break;
                                630              34 :         case 'P':               /* Parse */
                                631              34 :             pqTraceOutputP(conn->Pfdebug, message, &logCursor, regress);
                                632              34 :             break;
                                633               8 :         case 'Q':               /* Query */
                                634               8 :             pqTraceOutputQ(conn->Pfdebug, message, &logCursor);
                                635               8 :             break;
  740 alvherre                  636 UBC           0 :         case 'R':               /* Authentication */
                                637               0 :             pqTraceOutputR(conn->Pfdebug, message, &logCursor);
                                638               0 :             break;
                                639               0 :         case 's':
                                640               0 :             fprintf(conn->Pfdebug, "PortalSuspended");
                                641                 :             /* No message content */
                                642               0 :             break;
  740 alvherre                  643 CBC          14 :         case 'S':               /* Parameter Status(B) or Sync(F) */
                                644              14 :             if (!toServer)
  740 alvherre                  645 UBC           0 :                 pqTraceOutputS(conn->Pfdebug, message, &logCursor);
                                646                 :             else
  697 tgl                       647 CBC          14 :                 fprintf(conn->Pfdebug, "Sync"); /* no message content */
  740 alvherre                  648              14 :             break;
                                649               1 :         case 't':               /* Parameter Description */
                                650               1 :             pqTraceOutputt(conn->Pfdebug, message, &logCursor, regress);
                                651               1 :             break;
                                652              27 :         case 'T':               /* Row Description */
                                653              27 :             pqTraceOutputT(conn->Pfdebug, message, &logCursor, regress);
                                654              27 :             break;
  740 alvherre                  655 UBC           0 :         case 'v':               /* Negotiate Protocol Version */
                                656               0 :             pqTraceOutputv(conn->Pfdebug, message, &logCursor);
                                657               0 :             break;
                                658               0 :         case 'V':               /* Function Call response */
                                659               0 :             pqTraceOutputV(conn->Pfdebug, message, &logCursor);
                                660               0 :             break;
                                661               0 :         case 'W':               /* Start Copy Both */
                                662               0 :             pqTraceOutputW(conn->Pfdebug, message, &logCursor, length);
                                663               0 :             break;
  740 alvherre                  664 CBC           9 :         case 'X':
                                665               9 :             fprintf(conn->Pfdebug, "Terminate");
                                666                 :             /* No message content */
                                667               9 :             break;
                                668              22 :         case 'Z':               /* Ready For Query */
                                669              22 :             pqTraceOutputZ(conn->Pfdebug, message, &logCursor);
                                670              22 :             break;
  740 alvherre                  671 UBC           0 :         default:
                                672               0 :             fprintf(conn->Pfdebug, "Unknown message: %02x", id);
                                673               0 :             break;
                                674                 :     }
                                675                 : 
  740 alvherre                  676 CBC         365 :     fputc('\n', conn->Pfdebug);
                                677                 : 
                                678                 :     /*
                                679                 :      * Verify the printing routine did it right.  Note that the one-byte
                                680                 :      * message identifier is not included in the length, but our cursor does
                                681                 :      * include it.
                                682                 :      */
                                683             365 :     if (logCursor - 1 != length)
  740 alvherre                  684 UBC           0 :         fprintf(conn->Pfdebug,
                                685                 :                 "mismatched message length: consumed %d, expected %d\n",
                                686                 :                 logCursor - 1, length);
  740 alvherre                  687 CBC         365 : }
                                688                 : 
                                689                 : /*
                                690                 :  * Print special messages (those containing no type byte) to the trace output
                                691                 :  * stream.
                                692                 :  */
                                693                 : void
  740 alvherre                  694 UBC           0 : pqTraceOutputNoTypeByteMessage(PGconn *conn, const char *message)
                                695                 : {
                                696                 :     int         length;
                                697               0 :     int         logCursor = 0;
                                698                 : 
                                699               0 :     if ((conn->traceFlags & PQTRACE_SUPPRESS_TIMESTAMPS) == 0)
                                700                 :     {
                                701                 :         char        timestr[128];
                                702                 : 
                                703               0 :         pqTraceFormatTimestamp(timestr, sizeof(timestr));
                                704               0 :         fprintf(conn->Pfdebug, "%s\t", timestr);
                                705                 :     }
                                706                 : 
                                707               0 :     memcpy(&length, message + logCursor, 4);
                                708               0 :     length = (int) pg_ntoh32(length);
                                709               0 :     logCursor += 4;
                                710                 : 
                                711               0 :     fprintf(conn->Pfdebug, "F\t%d\t", length);
                                712                 : 
                                713               0 :     switch (length)
                                714                 :     {
                                715               0 :         case 16:                /* CancelRequest */
                                716               0 :             fprintf(conn->Pfdebug, "CancelRequest\t");
                                717               0 :             pqTraceOutputInt32(conn->Pfdebug, message, &logCursor, false);
                                718               0 :             pqTraceOutputInt32(conn->Pfdebug, message, &logCursor, false);
                                719               0 :             pqTraceOutputInt32(conn->Pfdebug, message, &logCursor, false);
                                720               0 :             break;
                                721               0 :         case 8:                 /* GSSENCRequest or SSLRequest */
                                722                 :             /* These messages do not reach here. */
                                723                 :         default:
                                724               0 :             fprintf(conn->Pfdebug, "Unknown message: length is %d", length);
                                725               0 :             break;
                                726                 :     }
                                727                 : 
                                728               0 :     fputc('\n', conn->Pfdebug);
                                729               0 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a