Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc0a8c3a

Browse files
committed
Update 3.0 protocol support to match recent agreements about how to
handle multiple 'formats' for data I/O. Restructure CommandDest andDestReceiver stuff one more time (it's finally starting to look a bitclean though). Code now matches latest 3.0 protocol document as faras message formats go --- but there is no support for binary I/O yet.
1 parent5e7a5c9 commitc0a8c3a

File tree

24 files changed

+999
-680
lines changed

24 files changed

+999
-680
lines changed

‎src/backend/access/common/printtup.c

Lines changed: 159 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* Portions Copyright (c) 1994, Regents of the University of California
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.70 2003/05/06 20:26:26 tgl Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.71 2003/05/08 18:16:36 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -20,12 +20,17 @@
2020
#include"libpq/libpq.h"
2121
#include"libpq/pqformat.h"
2222
#include"utils/lsyscache.h"
23+
#include"utils/portal.h"
2324

2425

2526
staticvoidprinttup_startup(DestReceiver*self,intoperation,
26-
constchar*portalName,TupleDesctypeinfo,List*targetlist);
27-
staticvoidprinttup(HeapTupletuple,TupleDesctypeinfo,DestReceiver*self);
28-
staticvoidprinttup_internal(HeapTupletuple,TupleDesctypeinfo,DestReceiver*self);
27+
TupleDesctypeinfo);
28+
staticvoidprinttup(HeapTupletuple,TupleDesctypeinfo,
29+
DestReceiver*self);
30+
staticvoidprinttup_20(HeapTupletuple,TupleDesctypeinfo,
31+
DestReceiver*self);
32+
staticvoidprinttup_internal_20(HeapTupletuple,TupleDesctypeinfo,
33+
DestReceiver*self);
2934
staticvoidprinttup_shutdown(DestReceiver*self);
3035
staticvoidprinttup_destroy(DestReceiver*self);
3136

@@ -50,6 +55,7 @@ typedef struct
5055
typedefstruct
5156
{
5257
DestReceiverpub;/* publicly-known function pointers */
58+
Portalportal;/* the Portal we are printing from */
5359
boolsendDescrip;/* send RowDescription at startup? */
5460
TupleDescattrinfo;/* The attr info we are set up for */
5561
intnattrs;
@@ -61,43 +67,33 @@ typedef struct
6167
* ----------------
6268
*/
6369
DestReceiver*
64-
printtup_create_DR(CommandDestdest)
70+
printtup_create_DR(CommandDestdest,Portalportal)
6571
{
6672
DR_printtup*self= (DR_printtup*)palloc(sizeof(DR_printtup));
67-
boolisBinary;
68-
boolsendDescrip;
6973

70-
switch (dest)
74+
if (PG_PROTOCOL_MAJOR(FrontendProtocol) >=3)
75+
self->pub.receiveTuple=printtup;
76+
else
7177
{
72-
caseRemote:
73-
isBinary= false;
74-
sendDescrip= true;
75-
break;
76-
caseRemoteInternal:
77-
isBinary= true;
78-
sendDescrip= true;
79-
break;
80-
caseRemoteExecute:
81-
isBinary= false;
82-
sendDescrip= false;/* no T message for Execute */
83-
break;
84-
caseRemoteExecuteInternal:
85-
isBinary= true;
86-
sendDescrip= false;/* no T message for Execute */
87-
break;
88-
89-
default:
90-
elog(ERROR,"printtup_create_DR: unsupported dest");
91-
returnNULL;
78+
/*
79+
* In protocol 2.0 the Bind message does not exist, so there is
80+
* no way for the columns to have different print formats; it's
81+
* sufficient to look at the first one.
82+
*/
83+
if (portal->formats&&portal->formats[0]!=0)
84+
self->pub.receiveTuple=printtup_internal_20;
85+
else
86+
self->pub.receiveTuple=printtup_20;
9287
}
93-
94-
self->pub.receiveTuple=isBinary ?printtup_internal :printtup;
9588
self->pub.startup=printtup_startup;
9689
self->pub.shutdown=printtup_shutdown;
9790
self->pub.destroy=printtup_destroy;
9891
self->pub.mydest=dest;
9992

100-
self->sendDescrip=sendDescrip;
93+
self->portal=portal;
94+
95+
/* Send T message automatically if Remote, but not if RemoteExecute */
96+
self->sendDescrip= (dest==Remote);
10197

10298
self->attrinfo=NULL;
10399
self->nattrs=0;
@@ -107,10 +103,10 @@ printtup_create_DR(CommandDest dest)
107103
}
108104

109105
staticvoid
110-
printtup_startup(DestReceiver*self,intoperation,
111-
constchar*portalName,TupleDesctypeinfo,List*targetlist)
106+
printtup_startup(DestReceiver*self,intoperation,TupleDesctypeinfo)
112107
{
113108
DR_printtup*myState= (DR_printtup*)self;
109+
Portalportal=myState->portal;
114110

115111
if (PG_PROTOCOL_MAJOR(FrontendProtocol)<3)
116112
{
@@ -119,7 +115,9 @@ printtup_startup(DestReceiver *self, int operation,
119115
*
120116
* If portal name not specified, use "blank" portal.
121117
*/
122-
if (portalName==NULL)
118+
constchar*portalName=portal->name;
119+
120+
if (portalName==NULL||portalName[0]=='\0')
123121
portalName="blank";
124122

125123
pq_puttextmessage('P',portalName);
@@ -130,7 +128,16 @@ printtup_startup(DestReceiver *self, int operation,
130128
* then we send back the tuple descriptor of the tuples.
131129
*/
132130
if (operation==CMD_SELECT&&myState->sendDescrip)
133-
SendRowDescriptionMessage(typeinfo,targetlist);
131+
{
132+
List*targetlist;
133+
134+
if (portal->strategy==PORTAL_ONE_SELECT)
135+
targetlist= ((Query*)lfirst(portal->parseTrees))->targetList;
136+
else
137+
targetlist=NIL;
138+
139+
SendRowDescriptionMessage(typeinfo,targetlist,portal->formats);
140+
}
134141

135142
/* ----------------
136143
* We could set up the derived attr info at this time, but we postpone it
@@ -150,11 +157,13 @@ printtup_startup(DestReceiver *self, int operation,
150157
* Notes: the TupleDesc has typically been manufactured by ExecTypeFromTL()
151158
* or some similar function; it does not contain a full set of fields.
152159
* The targetlist will be NIL when executing a utility function that does
153-
* not have a plan. If the targetlist isn't NIL then it is a Plan node's
154-
* targetlist; it is up to us to ignore resjunk columns in it.
160+
* not have a plan. If the targetlist isn't NIL then it is a Query node's
161+
* targetlist; it is up to us to ignore resjunk columns in it. The formats[]
162+
* array pointer might be NULL (if we are doing Describe on a prepared stmt);
163+
* send zeroes for the format codes in that case.
155164
*/
156165
void
157-
SendRowDescriptionMessage(TupleDesctypeinfo,List*targetlist)
166+
SendRowDescriptionMessage(TupleDesctypeinfo,List*targetlist,int16*formats)
158167
{
159168
Form_pg_attribute*attrs=typeinfo->attrs;
160169
intnatts=typeinfo->natts;
@@ -198,6 +207,14 @@ SendRowDescriptionMessage(TupleDesc typeinfo, List *targetlist)
198207
if (proto >=2)
199208
pq_sendint(&buf,attrs[i]->atttypmod,
200209
sizeof(attrs[i]->atttypmod));
210+
/* format info appears in protocol 3.0 and up */
211+
if (proto >=3)
212+
{
213+
if (formats)
214+
pq_sendint(&buf,formats[i],2);
215+
else
216+
pq_sendint(&buf,0,2);
217+
}
201218
}
202219
pq_endmessage(&buf);
203220
}
@@ -228,11 +245,98 @@ printtup_prepare_info(DR_printtup *myState, TupleDesc typeinfo, int numAttrs)
228245
}
229246

230247
/* ----------------
231-
*printtup
248+
*printtup --- print a tuple in protocol 3.0
232249
* ----------------
233250
*/
234251
staticvoid
235252
printtup(HeapTupletuple,TupleDesctypeinfo,DestReceiver*self)
253+
{
254+
DR_printtup*myState= (DR_printtup*)self;
255+
int16*formats=myState->portal->formats;
256+
StringInfoDatabuf;
257+
intnatts=tuple->t_data->t_natts;
258+
inti;
259+
260+
/* Set or update my derived attribute info, if needed */
261+
if (myState->attrinfo!=typeinfo||myState->nattrs!=natts)
262+
printtup_prepare_info(myState,typeinfo,natts);
263+
264+
/*
265+
* Prepare a DataRow message
266+
*/
267+
pq_beginmessage(&buf,'D');
268+
269+
pq_sendint(&buf,natts,2);
270+
271+
/*
272+
* send the attributes of this tuple
273+
*/
274+
for (i=0;i<natts;++i)
275+
{
276+
PrinttupAttrInfo*thisState=myState->myinfo+i;
277+
int16format= (formats ?formats[i] :0);
278+
Datumorigattr,
279+
attr;
280+
boolisnull;
281+
char*outputstr;
282+
283+
origattr=heap_getattr(tuple,i+1,typeinfo,&isnull);
284+
if (isnull)
285+
{
286+
pq_sendint(&buf,-1,4);
287+
continue;
288+
}
289+
if (format==0)
290+
{
291+
if (OidIsValid(thisState->typoutput))
292+
{
293+
/*
294+
* If we have a toasted datum, forcibly detoast it here to
295+
* avoid memory leakage inside the type's output routine.
296+
*/
297+
if (thisState->typisvarlena)
298+
attr=PointerGetDatum(PG_DETOAST_DATUM(origattr));
299+
else
300+
attr=origattr;
301+
302+
outputstr=DatumGetCString(FunctionCall3(&thisState->finfo,
303+
attr,
304+
ObjectIdGetDatum(thisState->typelem),
305+
Int32GetDatum(typeinfo->attrs[i]->atttypmod)));
306+
307+
pq_sendcountedtext(&buf,outputstr,strlen(outputstr), false);
308+
309+
/* Clean up detoasted copy, if any */
310+
if (attr!=origattr)
311+
pfree(DatumGetPointer(attr));
312+
pfree(outputstr);
313+
}
314+
else
315+
{
316+
outputstr="<unprintable>";
317+
pq_sendcountedtext(&buf,outputstr,strlen(outputstr), false);
318+
}
319+
}
320+
elseif (format==1)
321+
{
322+
/* XXX something similar to above */
323+
elog(ERROR,"Binary transmission not implemented yet");
324+
}
325+
else
326+
{
327+
elog(ERROR,"Invalid format code %d",format);
328+
}
329+
}
330+
331+
pq_endmessage(&buf);
332+
}
333+
334+
/* ----------------
335+
*printtup_20 --- print a tuple in protocol 2.0
336+
* ----------------
337+
*/
338+
staticvoid
339+
printtup_20(HeapTupletuple,TupleDesctypeinfo,DestReceiver*self)
236340
{
237341
DR_printtup*myState= (DR_printtup*)self;
238342
StringInfoDatabuf;
@@ -300,7 +404,7 @@ printtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self)
300404
ObjectIdGetDatum(thisState->typelem),
301405
Int32GetDatum(typeinfo->attrs[i]->atttypmod)));
302406

303-
pq_sendcountedtext(&buf,outputstr,strlen(outputstr));
407+
pq_sendcountedtext(&buf,outputstr,strlen(outputstr), true);
304408

305409
/* Clean up detoasted copy, if any */
306410
if (attr!=origattr)
@@ -310,7 +414,7 @@ printtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self)
310414
else
311415
{
312416
outputstr="<unprintable>";
313-
pq_sendcountedtext(&buf,outputstr,strlen(outputstr));
417+
pq_sendcountedtext(&buf,outputstr,strlen(outputstr), true);
314418
}
315419
}
316420

@@ -363,38 +467,23 @@ printatt(unsigned attributeId,
363467
attributeP->attbyval ?'t' :'f');
364468
}
365469

366-
/* ----------------
367-
*showatts
368-
* ----------------
369-
*/
370-
staticvoid
371-
showatts(constchar*name,TupleDesctupleDesc)
372-
{
373-
intnatts=tupleDesc->natts;
374-
Form_pg_attribute*attinfo=tupleDesc->attrs;
375-
inti;
376-
377-
puts(name);
378-
for (i=0;i<natts;++i)
379-
printatt((unsigned)i+1,attinfo[i], (char*)NULL);
380-
printf("\t----\n");
381-
}
382-
383470
/* ----------------
384471
*debugStartup - prepare to print tuples for an interactive backend
385472
* ----------------
386473
*/
387474
void
388-
debugStartup(DestReceiver*self,intoperation,
389-
constchar*portalName,TupleDesctypeinfo,List*targetlist)
475+
debugStartup(DestReceiver*self,intoperation,TupleDesctypeinfo)
390476
{
477+
intnatts=typeinfo->natts;
478+
Form_pg_attribute*attinfo=typeinfo->attrs;
479+
inti;
480+
391481
/*
392482
* show the return type of the tuples
393483
*/
394-
if (portalName==NULL)
395-
portalName="blank";
396-
397-
showatts(portalName,typeinfo);
484+
for (i=0;i<natts;++i)
485+
printatt((unsigned)i+1,attinfo[i], (char*)NULL);
486+
printf("\t----\n");
398487
}
399488

400489
/* ----------------
@@ -448,15 +537,16 @@ debugtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self)
448537
}
449538

450539
/* ----------------
451-
*printtup_internal
452-
*We use a different data prefix, e.g. 'B' instead of 'D' to
453-
*indicate a tuple in internal (binary) form.
540+
*printtup_internal_20 --- print a binary tuple in protocol 2.0
541+
*
542+
* We use a different message type, i.e. 'B' instead of 'D' to
543+
* indicate a tuple in internal (binary) form.
454544
*
455-
*This is largely same asprinttup, except we don't use the typout func.
545+
*This is largely same asprinttup_20, except we don't use the typout func.
456546
* ----------------
457547
*/
458548
staticvoid
459-
printtup_internal(HeapTupletuple,TupleDesctypeinfo,DestReceiver*self)
549+
printtup_internal_20(HeapTupletuple,TupleDesctypeinfo,DestReceiver*self)
460550
{
461551
DR_printtup*myState= (DR_printtup*)self;
462552
StringInfoDatabuf;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp