Skip to content

Commit bbd8550

Browse files
committed
Refactor other replication commands to use DestRemoteSimple.
Commit a84069d added a new type of DestReceiver to avoid duplicating the existing code for the SHOW command, but it turns out we can leverage that new DestReceiver type in a few more places, saving some code. Michael Paquier, reviewed by Andres Freund and by me. Discussion: http://postgr.es/m/CAB7nPqSdFOQC0evc0r1nJeQyGBqjBrR41MC4rcMqUUpoJaZbtQ%40mail.gmail.com Discussion: http://postgr.es/m/CAB7nPqT2K4XFT1JgqufFBjsOc-NUKXg5qBDucHPMbk6Xi1kYaA@mail.gmail.com
1 parent c3e3844 commit bbd8550

File tree

3 files changed

+114
-162
lines changed

3 files changed

+114
-162
lines changed

src/backend/access/common/printsimple.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "catalog/pg_type.h"
2323
#include "fmgr.h"
2424
#include "libpq/pqformat.h"
25+
#include "utils/builtins.h"
2526

2627
/*
2728
* At startup time, send a RowDescription message.
@@ -99,6 +100,26 @@ printsimple(TupleTableSlot *slot, DestReceiver *self)
99100
}
100101
break;
101102

103+
case INT4OID:
104+
{
105+
int32 num = DatumGetInt32(value);
106+
char str[12]; /* sign, 10 digits and '\0' */
107+
108+
pg_ltoa(num, str);
109+
pq_sendcountedtext(&buf, str, strlen(str), false);
110+
}
111+
break;
112+
113+
case INT8OID:
114+
{
115+
int64 num = DatumGetInt64(value);
116+
char str[23]; /* sign, 21 digits and '\0' */
117+
118+
pg_lltoa(num, str);
119+
pq_sendcountedtext(&buf, str, strlen(str), false);
120+
}
121+
break;
122+
102123
default:
103124
elog(ERROR, "unsupported type OID: %u", attr->atttypid);
104125
}

src/backend/access/common/tupdesc.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,14 @@ TupleDescInitBuiltinEntry(TupleDesc desc,
629629
att->attstorage = 'p';
630630
att->attcollation = InvalidOid;
631631
break;
632+
633+
case INT8OID:
634+
att->attlen = 8;
635+
att->attbyval = FLOAT8PASSBYVAL;
636+
att->attalign = 'd';
637+
att->attstorage = 'p';
638+
att->attcollation = InvalidOid;
639+
break;
632640
}
633641
}
634642

src/backend/replication/walsender.c

Lines changed: 85 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -302,13 +302,15 @@ WalSndShutdown(void)
302302
static void
303303
IdentifySystem(void)
304304
{
305-
StringInfoData buf;
306305
char sysid[32];
307-
char tli[11];
308306
char xpos[MAXFNAMELEN];
309307
XLogRecPtr logptr;
310308
char *dbname = NULL;
311-
Size len;
309+
DestReceiver *dest;
310+
TupOutputState *tstate;
311+
TupleDesc tupdesc;
312+
Datum values[4];
313+
bool nulls[4];
312314

313315
/*
314316
* Reply with a result set with one row, four columns. First col is system
@@ -328,8 +330,6 @@ IdentifySystem(void)
328330
else
329331
logptr = GetFlushRecPtr();
330332

331-
snprintf(tli, sizeof(tli), "%u", ThisTimeLineID);
332-
333333
snprintf(xpos, sizeof(xpos), "%X/%X", (uint32) (logptr >> 32), (uint32) logptr);
334334

335335
if (MyDatabaseId != InvalidOid)
@@ -346,79 +346,42 @@ IdentifySystem(void)
346346
MemoryContextSwitchTo(cur);
347347
}
348348

349-
/* Send a RowDescription message */
350-
pq_beginmessage(&buf, 'T');
351-
pq_sendint(&buf, 4, 2); /* 4 fields */
352-
353-
/* first field */
354-
pq_sendstring(&buf, "systemid"); /* col name */
355-
pq_sendint(&buf, 0, 4); /* table oid */
356-
pq_sendint(&buf, 0, 2); /* attnum */
357-
pq_sendint(&buf, TEXTOID, 4); /* type oid */
358-
pq_sendint(&buf, -1, 2); /* typlen */
359-
pq_sendint(&buf, 0, 4); /* typmod */
360-
pq_sendint(&buf, 0, 2); /* format code */
361-
362-
/* second field */
363-
pq_sendstring(&buf, "timeline"); /* col name */
364-
pq_sendint(&buf, 0, 4); /* table oid */
365-
pq_sendint(&buf, 0, 2); /* attnum */
366-
pq_sendint(&buf, INT4OID, 4); /* type oid */
367-
pq_sendint(&buf, 4, 2); /* typlen */
368-
pq_sendint(&buf, 0, 4); /* typmod */
369-
pq_sendint(&buf, 0, 2); /* format code */
370-
371-
/* third field */
372-
pq_sendstring(&buf, "xlogpos"); /* col name */
373-
pq_sendint(&buf, 0, 4); /* table oid */
374-
pq_sendint(&buf, 0, 2); /* attnum */
375-
pq_sendint(&buf, TEXTOID, 4); /* type oid */
376-
pq_sendint(&buf, -1, 2); /* typlen */
377-
pq_sendint(&buf, 0, 4); /* typmod */
378-
pq_sendint(&buf, 0, 2); /* format code */
349+
dest = CreateDestReceiver(DestRemoteSimple);
350+
MemSet(nulls, false, sizeof(nulls));
379351

380-
/* fourth field */
381-
pq_sendstring(&buf, "dbname"); /* col name */
382-
pq_sendint(&buf, 0, 4); /* table oid */
383-
pq_sendint(&buf, 0, 2); /* attnum */
384-
pq_sendint(&buf, TEXTOID, 4); /* type oid */
385-
pq_sendint(&buf, -1, 2); /* typlen */
386-
pq_sendint(&buf, 0, 4); /* typmod */
387-
pq_sendint(&buf, 0, 2); /* format code */
388-
pq_endmessage(&buf);
352+
/* need a tuple descriptor representing four columns */
353+
tupdesc = CreateTemplateTupleDesc(4, false);
354+
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "systemid",
355+
TEXTOID, -1, 0);
356+
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "timeline",
357+
INT4OID, -1, 0);
358+
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 3, "xlogpos",
359+
TEXTOID, -1, 0);
360+
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 4, "dbname",
361+
TEXTOID, -1, 0);
389362

390-
/* Send a DataRow message */
391-
pq_beginmessage(&buf, 'D');
392-
pq_sendint(&buf, 4, 2); /* # of columns */
363+
/* prepare for projection of tuples */
364+
tstate = begin_tup_output_tupdesc(dest, tupdesc);
393365

394366
/* column 1: system identifier */
395-
len = strlen(sysid);
396-
pq_sendint(&buf, len, 4);
397-
pq_sendbytes(&buf, (char *) &sysid, len);
367+
values[0] = CStringGetTextDatum(sysid);
398368

399369
/* column 2: timeline */
400-
len = strlen(tli);
401-
pq_sendint(&buf, len, 4);
402-
pq_sendbytes(&buf, (char *) tli, len);
370+
values[1] = Int32GetDatum(ThisTimeLineID);
403371

404372
/* column 3: xlog position */
405-
len = strlen(xpos);
406-
pq_sendint(&buf, len, 4);
407-
pq_sendbytes(&buf, (char *) xpos, len);
373+
values[2] = CStringGetTextDatum(xpos);
408374

409375
/* column 4: database name, or NULL if none */
410376
if (dbname)
411-
{
412-
len = strlen(dbname);
413-
pq_sendint(&buf, len, 4);
414-
pq_sendbytes(&buf, (char *) dbname, len);
415-
}
377+
values[3] = CStringGetTextDatum(dbname);
416378
else
417-
{
418-
pq_sendint(&buf, -1, 4);
419-
}
379+
nulls[3] = true;
420380

421-
pq_endmessage(&buf);
381+
/* send it to dest */
382+
do_tup_output(tstate, values, nulls);
383+
384+
end_tup_output(tstate);
422385
}
423386

424387

@@ -695,54 +658,41 @@ StartReplication(StartReplicationCmd *cmd)
695658
*/
696659
if (sendTimeLineIsHistoric)
697660
{
698-
char tli_str[11];
699661
char startpos_str[8 + 1 + 8 + 1];
700-
Size len;
662+
DestReceiver *dest;
663+
TupOutputState *tstate;
664+
TupleDesc tupdesc;
665+
Datum values[2];
666+
bool nulls[2];
701667

702-
snprintf(tli_str, sizeof(tli_str), "%u", sendTimeLineNextTLI);
703668
snprintf(startpos_str, sizeof(startpos_str), "%X/%X",
704669
(uint32) (sendTimeLineValidUpto >> 32),
705670
(uint32) sendTimeLineValidUpto);
706671

707-
pq_beginmessage(&buf, 'T'); /* RowDescription */
708-
pq_sendint(&buf, 2, 2); /* 2 fields */
709-
710-
/* Field header */
711-
pq_sendstring(&buf, "next_tli");
712-
pq_sendint(&buf, 0, 4); /* table oid */
713-
pq_sendint(&buf, 0, 2); /* attnum */
672+
dest = CreateDestReceiver(DestRemoteSimple);
673+
MemSet(nulls, false, sizeof(nulls));
714674

715675
/*
676+
* Need a tuple descriptor representing two columns.
716677
* int8 may seem like a surprising data type for this, but in theory
717678
* int4 would not be wide enough for this, as TimeLineID is unsigned.
718679
*/
719-
pq_sendint(&buf, INT8OID, 4); /* type oid */
720-
pq_sendint(&buf, -1, 2);
721-
pq_sendint(&buf, 0, 4);
722-
pq_sendint(&buf, 0, 2);
723-
724-
pq_sendstring(&buf, "next_tli_startpos");
725-
pq_sendint(&buf, 0, 4); /* table oid */
726-
pq_sendint(&buf, 0, 2); /* attnum */
727-
pq_sendint(&buf, TEXTOID, 4); /* type oid */
728-
pq_sendint(&buf, -1, 2);
729-
pq_sendint(&buf, 0, 4);
730-
pq_sendint(&buf, 0, 2);
731-
pq_endmessage(&buf);
680+
tupdesc = CreateTemplateTupleDesc(2, false);
681+
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "next_tli",
682+
INT8OID, -1, 0);
683+
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "next_tli_startpos",
684+
TEXTOID, -1, 0);
732685

733-
/* Data row */
734-
pq_beginmessage(&buf, 'D');
735-
pq_sendint(&buf, 2, 2); /* number of columns */
686+
/* prepare for projection of tuple */
687+
tstate = begin_tup_output_tupdesc(dest, tupdesc);
736688

737-
len = strlen(tli_str);
738-
pq_sendint(&buf, len, 4); /* length */
739-
pq_sendbytes(&buf, tli_str, len);
689+
values[0] = Int64GetDatum((int64) sendTimeLineNextTLI);
690+
values[1] = CStringGetTextDatum(startpos_str);
740691

741-
len = strlen(startpos_str);
742-
pq_sendint(&buf, len, 4); /* length */
743-
pq_sendbytes(&buf, startpos_str, len);
692+
/* send it to dest */
693+
do_tup_output(tstate, values, nulls);
744694

745-
pq_endmessage(&buf);
695+
end_tup_output(tstate);
746696
}
747697

748698
/* Send CommandComplete message */
@@ -790,8 +740,12 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd)
790740
{
791741
const char *snapshot_name = NULL;
792742
char xpos[MAXFNAMELEN];
793-
StringInfoData buf;
794-
Size len;
743+
char *slot_name;
744+
DestReceiver *dest;
745+
TupOutputState *tstate;
746+
TupleDesc tupdesc;
747+
Datum values[4];
748+
bool nulls[4];
795749

796750
Assert(!MyReplicationSlot);
797751

@@ -868,82 +822,51 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd)
868822
(uint32) (MyReplicationSlot->data.confirmed_flush >> 32),
869823
(uint32) MyReplicationSlot->data.confirmed_flush);
870824

871-
pq_beginmessage(&buf, 'T');
872-
pq_sendint(&buf, 4, 2); /* 4 fields */
873-
874-
/* first field: slot name */
875-
pq_sendstring(&buf, "slot_name"); /* col name */
876-
pq_sendint(&buf, 0, 4); /* table oid */
877-
pq_sendint(&buf, 0, 2); /* attnum */
878-
pq_sendint(&buf, TEXTOID, 4); /* type oid */
879-
pq_sendint(&buf, -1, 2); /* typlen */
880-
pq_sendint(&buf, 0, 4); /* typmod */
881-
pq_sendint(&buf, 0, 2); /* format code */
882-
883-
/* second field: LSN at which we became consistent */
884-
pq_sendstring(&buf, "consistent_point"); /* col name */
885-
pq_sendint(&buf, 0, 4); /* table oid */
886-
pq_sendint(&buf, 0, 2); /* attnum */
887-
pq_sendint(&buf, TEXTOID, 4); /* type oid */
888-
pq_sendint(&buf, -1, 2); /* typlen */
889-
pq_sendint(&buf, 0, 4); /* typmod */
890-
pq_sendint(&buf, 0, 2); /* format code */
891-
892-
/* third field: exported snapshot's name */
893-
pq_sendstring(&buf, "snapshot_name"); /* col name */
894-
pq_sendint(&buf, 0, 4); /* table oid */
895-
pq_sendint(&buf, 0, 2); /* attnum */
896-
pq_sendint(&buf, TEXTOID, 4); /* type oid */
897-
pq_sendint(&buf, -1, 2); /* typlen */
898-
pq_sendint(&buf, 0, 4); /* typmod */
899-
pq_sendint(&buf, 0, 2); /* format code */
900-
901-
/* fourth field: output plugin */
902-
pq_sendstring(&buf, "output_plugin"); /* col name */
903-
pq_sendint(&buf, 0, 4); /* table oid */
904-
pq_sendint(&buf, 0, 2); /* attnum */
905-
pq_sendint(&buf, TEXTOID, 4); /* type oid */
906-
pq_sendint(&buf, -1, 2); /* typlen */
907-
pq_sendint(&buf, 0, 4); /* typmod */
908-
pq_sendint(&buf, 0, 2); /* format code */
825+
dest = CreateDestReceiver(DestRemoteSimple);
826+
MemSet(nulls, false, sizeof(nulls));
909827

910-
pq_endmessage(&buf);
911-
912-
/* Send a DataRow message */
913-
pq_beginmessage(&buf, 'D');
914-
pq_sendint(&buf, 4, 2); /* # of columns */
828+
/*
829+
* Need a tuple descriptor representing four columns:
830+
* - first field: the slot name
831+
* - second field: LSN at which we became consistent
832+
* - third field: exported snapshot's name
833+
* - fourth field: output plugin
834+
*/
835+
tupdesc = CreateTemplateTupleDesc(4, false);
836+
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "slot_name",
837+
TEXTOID, -1, 0);
838+
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "consistent_point",
839+
TEXTOID, -1, 0);
840+
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 3, "snapshot_name",
841+
TEXTOID, -1, 0);
842+
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 4, "output_plugin",
843+
TEXTOID, -1, 0);
844+
845+
/* prepare for projection of tuples */
846+
tstate = begin_tup_output_tupdesc(dest, tupdesc);
915847

916848
/* slot_name */
917-
len = strlen(NameStr(MyReplicationSlot->data.name));
918-
pq_sendint(&buf, len, 4); /* col1 len */
919-
pq_sendbytes(&buf, NameStr(MyReplicationSlot->data.name), len);
849+
slot_name = NameStr(MyReplicationSlot->data.name);
850+
values[0] = CStringGetTextDatum(slot_name);
920851

921852
/* consistent wal location */
922-
len = strlen(xpos);
923-
pq_sendint(&buf, len, 4);
924-
pq_sendbytes(&buf, xpos, len);
853+
values[1] = CStringGetTextDatum(xpos);
925854

926855
/* snapshot name, or NULL if none */
927856
if (snapshot_name != NULL)
928-
{
929-
len = strlen(snapshot_name);
930-
pq_sendint(&buf, len, 4);
931-
pq_sendbytes(&buf, snapshot_name, len);
932-
}
857+
values[2] = CStringGetTextDatum(snapshot_name);
933858
else
934-
pq_sendint(&buf, -1, 4);
859+
nulls[2] = true;
935860

936861
/* plugin, or NULL if none */
937862
if (cmd->plugin != NULL)
938-
{
939-
len = strlen(cmd->plugin);
940-
pq_sendint(&buf, len, 4);
941-
pq_sendbytes(&buf, cmd->plugin, len);
942-
}
863+
values[3] = CStringGetTextDatum(cmd->plugin);
943864
else
944-
pq_sendint(&buf, -1, 4);
865+
nulls[3] = true;
945866

946-
pq_endmessage(&buf);
867+
/* send it to dest */
868+
do_tup_output(tstate, values, nulls);
869+
end_tup_output(tstate);
947870

948871
ReplicationSlotRelease();
949872
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy