Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a84069d

Browse files
committed
Add a new DestReceiver for printing tuples without catalog access.
If you create a DestReciver of type DestRemote and try to use it from a replication connection that is not bound to a specific daabase, or any other hypothetical type of backend that is not bound to a specific database, it will fail because it doesn't have a pg_proc catalog to look up properties of the types being printed. In general, that's an unavoidable problem, but we can hardwire the properties of a few builtin types in order to support utility commands. This new DestReceiver of type DestRemoteSimple does just that. Patch by me, reviewed by Michael Paquier. Discussion: http://postgr.es/m/CA+TgmobNo4qz06wHEmy9DszAre3dYx-WNhHSCbU9SAwf+9Ft6g@mail.gmail.com
1 parent 7b4ac19 commit a84069d

File tree

5 files changed

+148
-2
lines changed

5 files changed

+148
-2
lines changed

src/backend/access/common/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ subdir = src/backend/access/common
1212
top_builddir = ../../../..
1313
include $(top_builddir)/src/Makefile.global
1414

15-
OBJS = heaptuple.o indextuple.o printtup.o reloptions.o scankey.o \
16-
tupconvert.o tupdesc.o
15+
OBJS = heaptuple.o indextuple.o printsimple.o printtup.o reloptions.o \
16+
scankey.o tupconvert.o tupdesc.o
1717

1818
include $(top_srcdir)/src/backend/common.mk
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* printsimple.c
4+
* Routines to print out tuples containing only a limited range of
5+
* builtin types without catalog access. This is intended for
6+
* backends that don't have catalog access because they are not bound
7+
* to a specific database, such as some walsender processes. It
8+
* doesn't handle standalone backends or protocol versions other than
9+
* 3.0, because we don't need such handling for current applications.
10+
*
11+
* Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
12+
* Portions Copyright (c) 1994, Regents of the University of California
13+
*
14+
* IDENTIFICATION
15+
* src/backend/access/common/printsimple.c
16+
*
17+
*-------------------------------------------------------------------------
18+
*/
19+
#include "postgres.h"
20+
21+
#include "access/printsimple.h"
22+
#include "catalog/pg_type.h"
23+
#include "fmgr.h"
24+
#include "libpq/pqformat.h"
25+
26+
/*
27+
* At startup time, send a RowDescription message.
28+
*/
29+
void
30+
printsimple_startup(DestReceiver *self, int operation, TupleDesc tupdesc)
31+
{
32+
StringInfoData buf;
33+
int i;
34+
35+
pq_beginmessage(&buf, 'T'); /* RowDescription */
36+
pq_sendint(&buf, tupdesc->natts, 2);
37+
38+
for (i = 0; i < tupdesc->natts; ++i)
39+
{
40+
Form_pg_attribute attr = tupdesc->attrs[i];
41+
42+
pq_sendstring(&buf, NameStr(attr->attname));
43+
pq_sendint(&buf, 0, 4); /* table oid */
44+
pq_sendint(&buf, 0, 2); /* attnum */
45+
pq_sendint(&buf, (int) attr->atttypid, 4);
46+
pq_sendint(&buf, attr->attlen, 2);
47+
pq_sendint(&buf, attr->atttypmod, 4);
48+
pq_sendint(&buf, 0, 2); /* format code */
49+
}
50+
51+
pq_endmessage(&buf);
52+
}
53+
54+
/*
55+
* For each tuple, send a DataRow message.
56+
*/
57+
bool
58+
printsimple(TupleTableSlot *slot, DestReceiver *self)
59+
{
60+
TupleDesc tupdesc = slot->tts_tupleDescriptor;
61+
StringInfoData buf;
62+
int i;
63+
64+
/* Make sure the tuple is fully deconstructed */
65+
slot_getallattrs(slot);
66+
67+
/* Prepare and send message */
68+
pq_beginmessage(&buf, 'D');
69+
pq_sendint(&buf, tupdesc->natts, 2);
70+
71+
for (i = 0; i < tupdesc->natts; ++i)
72+
{
73+
Form_pg_attribute attr = tupdesc->attrs[i];
74+
Datum value;
75+
76+
if (slot->tts_isnull[i])
77+
{
78+
pq_sendint(&buf, -1, 4);
79+
continue;
80+
}
81+
82+
value = slot->tts_values[i];
83+
84+
/*
85+
* We can't call the regular type output functions here because we
86+
* might not have catalog access. Instead, we must hard-wire
87+
* knowledge of the required types.
88+
*/
89+
switch (attr->atttypid)
90+
{
91+
case TEXTOID:
92+
{
93+
text *t = DatumGetTextPP(value);
94+
95+
pq_sendcountedtext(&buf,
96+
VARDATA_ANY(t),
97+
VARSIZE_ANY_EXHDR(t),
98+
false);
99+
}
100+
break;
101+
102+
default:
103+
elog(ERROR, "unsupported type OID: %u", attr->atttypid);
104+
}
105+
}
106+
107+
pq_endmessage(&buf);
108+
109+
return true;
110+
}

src/backend/tcop/dest.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
#include "postgres.h"
3030

31+
#include "access/printsimple.h"
3132
#include "access/printtup.h"
3233
#include "access/xact.h"
3334
#include "commands/copy.h"
@@ -76,6 +77,11 @@ static DestReceiver debugtupDR = {
7677
DestDebug
7778
};
7879

80+
static DestReceiver printsimpleDR = {
81+
printsimple, printsimple_startup, donothingCleanup, donothingCleanup,
82+
DestRemoteSimple
83+
};
84+
7985
static DestReceiver spi_printtupDR = {
8086
spi_printtup, spi_dest_startup, donothingCleanup, donothingCleanup,
8187
DestSPI
@@ -108,6 +114,9 @@ CreateDestReceiver(CommandDest dest)
108114
case DestRemoteExecute:
109115
return printtup_create_DR(dest);
110116

117+
case DestRemoteSimple:
118+
return &printsimpleDR;
119+
111120
case DestNone:
112121
return &donothingDR;
113122

@@ -151,6 +160,7 @@ EndCommand(const char *commandTag, CommandDest dest)
151160
{
152161
case DestRemote:
153162
case DestRemoteExecute:
163+
case DestRemoteSimple:
154164

155165
/*
156166
* We assume the commandTag is plain ASCII and therefore requires
@@ -191,6 +201,7 @@ NullCommand(CommandDest dest)
191201
{
192202
case DestRemote:
193203
case DestRemoteExecute:
204+
case DestRemoteSimple:
194205

195206
/*
196207
* tell the fe that we saw an empty query string. In protocols
@@ -233,6 +244,7 @@ ReadyForQuery(CommandDest dest)
233244
{
234245
case DestRemote:
235246
case DestRemoteExecute:
247+
case DestRemoteSimple:
236248
if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
237249
{
238250
StringInfoData buf;

src/include/access/printsimple.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* printsimple.h
4+
* print simple tuples without catalog access
5+
*
6+
* Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7+
* Portions Copyright (c) 1994, Regents of the University of California
8+
*
9+
* src/include/access/printsimple.h
10+
*
11+
*-------------------------------------------------------------------------
12+
*/
13+
14+
#ifndef PRINTSIMPLE_H
15+
#define PRINTSIMPLE_H
16+
17+
#include "tcop/dest.h"
18+
19+
extern bool printsimple(TupleTableSlot *slot, DestReceiver *self);
20+
extern void printsimple_startup(DestReceiver *self, int operation,
21+
TupleDesc tupdesc);
22+
23+
#endif /* PRINTSIMPLE_H */

src/include/tcop/dest.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ typedef enum
8989
DestDebug, /* results go to debugging output */
9090
DestRemote, /* results sent to frontend process */
9191
DestRemoteExecute, /* sent to frontend, in Execute command */
92+
DestRemoteSimple, /* sent to frontend, w/no catalog access */
9293
DestSPI, /* results sent to SPI manager */
9394
DestTuplestore, /* results sent to Tuplestore */
9495
DestIntoRel, /* results sent to relation (SELECT INTO) */

0 commit comments

Comments
 (0)