#include "nodes/pg_list.h"
#include "pgstat.h"
#include "pgtime.h"
+#include "port/pg_bitutils.h"
#include "postmaster/fork_process.h"
#include "postmaster/interrupt.h"
#include "postmaster/postmaster.h"
{
PipeProtoHeader p;
int chunklen;
+ bits8 dest_flags;
/* Do we have a valid header? */
memcpy(&p, cursor, offsetof(PipeProtoHeader, data));
+ dest_flags = p.flags & (PIPE_PROTO_DEST_STDERR | PIPE_PROTO_DEST_CSVLOG);
if (p.nuls[0] == '\0' && p.nuls[1] == '\0' &&
p.len > 0 && p.len <= PIPE_MAX_PAYLOAD &&
p.pid != 0 &&
- (p.is_last == 't' || p.is_last == 'f' ||
- p.is_last == 'T' || p.is_last == 'F'))
+ pg_popcount((char *) &dest_flags, 1) == 1)
{
List *buffer_list;
ListCell *cell;
if (count < chunklen)
break;
- dest = (p.is_last == 'T' || p.is_last == 'F') ?
- LOG_DESTINATION_CSVLOG : LOG_DESTINATION_STDERR;
+ if ((p.flags & PIPE_PROTO_DEST_STDERR) != 0)
+ dest = LOG_DESTINATION_STDERR;
+ else if ((p.flags & PIPE_PROTO_DEST_CSVLOG) != 0)
+ dest = LOG_DESTINATION_CSVLOG;
+ else
+ {
+ /* this should never happen as of the header validation */
+ Assert(false);
+ }
/* Locate any existing buffer for this source pid */
buffer_list = buffer_lists[p.pid % NBUFFER_LISTS];
free_slot = buf;
}
- if (p.is_last == 'f' || p.is_last == 'F')
+ if ((p.flags & PIPE_PROTO_IS_LAST) == 0)
{
/*
* Save a complete non-final chunk in a per-pid buffer
p.proto.nuls[0] = p.proto.nuls[1] = '\0';
p.proto.pid = MyProcPid;
+ p.proto.flags = 0;
+ if (dest == LOG_DESTINATION_STDERR)
+ p.proto.flags |= PIPE_PROTO_DEST_STDERR;
+ else if (dest == LOG_DESTINATION_CSVLOG)
+ p.proto.flags |= PIPE_PROTO_DEST_CSVLOG;
/* write all but the last chunk */
while (len > PIPE_MAX_PAYLOAD)
{
- p.proto.is_last = (dest == LOG_DESTINATION_CSVLOG ? 'F' : 'f');
+ /* no need to set PIPE_PROTO_IS_LAST yet */
p.proto.len = PIPE_MAX_PAYLOAD;
memcpy(p.proto.data, data, PIPE_MAX_PAYLOAD);
rc = write(fd, &p, PIPE_HEADER_SIZE + PIPE_MAX_PAYLOAD);
}
/* write the last chunk */
- p.proto.is_last = (dest == LOG_DESTINATION_CSVLOG ? 'T' : 't');
+ p.proto.flags |= PIPE_PROTO_IS_LAST;
p.proto.len = len;
memcpy(p.proto.data, data, len);
rc = write(fd, &p, PIPE_HEADER_SIZE + len);
char nuls[2]; /* always \0\0 */
uint16 len; /* size of this chunk (counts data only) */
int32 pid; /* writer's pid */
- char is_last; /* last chunk of message? 't' or 'f' ('T' or
- * 'F' for CSV case) */
+ bits8 flags; /* bitmask of PIPE_PROTO_* */
char data[FLEXIBLE_ARRAY_MEMBER]; /* data payload starts here */
} PipeProtoHeader;
#define PIPE_HEADER_SIZE offsetof(PipeProtoHeader, data)
#define PIPE_MAX_PAYLOAD ((int) (PIPE_CHUNK_SIZE - PIPE_HEADER_SIZE))
+/* flag bits for PipeProtoHeader->flags */
+#define PIPE_PROTO_IS_LAST 0x01 /* last chunk of message? */
+/* log destinations */
+#define PIPE_PROTO_DEST_STDERR 0x10
+#define PIPE_PROTO_DEST_CSVLOG 0x20
/* GUC options */
extern bool Logging_collector;