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

Commit0ac6298

Browse files
committed
Implement new-protocol binary I/O support in DataRow, Bind, and FunctionCall
messages. Binary I/O is now up and working, but only for a small setof datatypes (integers, text, bytea).
1 parentd85a0a6 commit0ac6298

File tree

7 files changed

+435
-345
lines changed

7 files changed

+435
-345
lines changed

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

Lines changed: 124 additions & 151 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.71 2003/05/08 18:16:36 tgl Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.72 2003/05/09 18:08:48 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -42,14 +42,19 @@ static void printtup_destroy(DestReceiver *self);
4242

4343
/* ----------------
4444
*Private state for a printtup destination object
45+
*
46+
* NOTE: finfo is the lookup info for either typoutput or typsend, whichever
47+
* we are using for this column.
4548
* ----------------
4649
*/
4750
typedefstruct
4851
{/* Per-attribute information */
49-
Oidtypoutput;/* Oid for the attribute's type output fn */
52+
Oidtypoutput;/* Oid for the type's text output fn */
53+
Oidtypsend;/* Oid for the type's binary output fn */
5054
Oidtypelem;/* typelem value to pass to the output fn */
5155
booltypisvarlena;/* is it varlena (ie possibly toastable)? */
52-
FmgrInfofinfo;/* Precomputed call info for typoutput */
56+
int16format;/* format code for this column */
57+
FmgrInfofinfo;/* Precomputed call info for output fn */
5358
}PrinttupAttrInfo;
5459

5560
typedefstruct
@@ -219,9 +224,13 @@ SendRowDescriptionMessage(TupleDesc typeinfo, List *targetlist, int16 *formats)
219224
pq_endmessage(&buf);
220225
}
221226

227+
/*
228+
* Get the lookup info that printtup() needs
229+
*/
222230
staticvoid
223231
printtup_prepare_info(DR_printtup*myState,TupleDesctypeinfo,intnumAttrs)
224232
{
233+
int16*formats=myState->portal->formats;
225234
inti;
226235

227236
if (myState->myinfo)
@@ -232,15 +241,31 @@ printtup_prepare_info(DR_printtup *myState, TupleDesc typeinfo, int numAttrs)
232241
if (numAttrs <=0)
233242
return;
234243
myState->myinfo= (PrinttupAttrInfo*)
235-
palloc(numAttrs*sizeof(PrinttupAttrInfo));
244+
palloc0(numAttrs*sizeof(PrinttupAttrInfo));
236245
for (i=0;i<numAttrs;i++)
237246
{
238247
PrinttupAttrInfo*thisState=myState->myinfo+i;
248+
int16format= (formats ?formats[i] :0);
239249

240-
if (getTypeOutputInfo(typeinfo->attrs[i]->atttypid,
241-
&thisState->typoutput,&thisState->typelem,
242-
&thisState->typisvarlena))
250+
thisState->format=format;
251+
if (format==0)
252+
{
253+
getTypeOutputInfo(typeinfo->attrs[i]->atttypid,
254+
&thisState->typoutput,
255+
&thisState->typelem,
256+
&thisState->typisvarlena);
243257
fmgr_info(thisState->typoutput,&thisState->finfo);
258+
}
259+
elseif (format==1)
260+
{
261+
getTypeBinaryOutputInfo(typeinfo->attrs[i]->atttypid,
262+
&thisState->typsend,
263+
&thisState->typelem,
264+
&thisState->typisvarlena);
265+
fmgr_info(thisState->typsend,&thisState->finfo);
266+
}
267+
else
268+
elog(ERROR,"Unsupported format code %d",format);
244269
}
245270
}
246271

@@ -252,7 +277,6 @@ static void
252277
printtup(HeapTupletuple,TupleDesctypeinfo,DestReceiver*self)
253278
{
254279
DR_printtup*myState= (DR_printtup*)self;
255-
int16*formats=myState->portal->formats;
256280
StringInfoDatabuf;
257281
intnatts=tuple->t_data->t_natts;
258282
inti;
@@ -274,58 +298,56 @@ printtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self)
274298
for (i=0;i<natts;++i)
275299
{
276300
PrinttupAttrInfo*thisState=myState->myinfo+i;
277-
int16format= (formats ?formats[i] :0);
278301
Datumorigattr,
279302
attr;
280303
boolisnull;
281-
char*outputstr;
282304

283305
origattr=heap_getattr(tuple,i+1,typeinfo,&isnull);
284306
if (isnull)
285307
{
286308
pq_sendint(&buf,-1,4);
287309
continue;
288310
}
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)));
306311

307-
pq_sendcountedtext(&buf,outputstr,strlen(outputstr), false);
312+
/*
313+
* If we have a toasted datum, forcibly detoast it here to
314+
* avoid memory leakage inside the type's output routine.
315+
*/
316+
if (thisState->typisvarlena)
317+
attr=PointerGetDatum(PG_DETOAST_DATUM(origattr));
318+
else
319+
attr=origattr;
308320

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+
if (thisState->format==0)
321322
{
322-
/* XXX something similar to above */
323-
elog(ERROR,"Binary transmission not implemented yet");
323+
/* Text output */
324+
char*outputstr;
325+
326+
outputstr=DatumGetCString(FunctionCall3(&thisState->finfo,
327+
attr,
328+
ObjectIdGetDatum(thisState->typelem),
329+
Int32GetDatum(typeinfo->attrs[i]->atttypmod)));
330+
pq_sendcountedtext(&buf,outputstr,strlen(outputstr), false);
331+
pfree(outputstr);
324332
}
325333
else
326334
{
327-
elog(ERROR,"Invalid format code %d",format);
335+
/* Binary output */
336+
bytea*outputbytes;
337+
338+
outputbytes=DatumGetByteaP(FunctionCall2(&thisState->finfo,
339+
attr,
340+
ObjectIdGetDatum(thisState->typelem)));
341+
/* We assume the result will not have been toasted */
342+
pq_sendint(&buf,VARSIZE(outputbytes)-VARHDRSZ,4);
343+
pq_sendbytes(&buf,VARDATA(outputbytes),
344+
VARSIZE(outputbytes)-VARHDRSZ);
345+
pfree(outputbytes);
328346
}
347+
348+
/* Clean up detoasted copy, if any */
349+
if (attr!=origattr)
350+
pfree(DatumGetPointer(attr));
329351
}
330352

331353
pq_endmessage(&buf);
@@ -388,34 +410,28 @@ printtup_20(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self)
388410
origattr=heap_getattr(tuple,i+1,typeinfo,&isnull);
389411
if (isnull)
390412
continue;
391-
if (OidIsValid(thisState->typoutput))
392-
{
393-
/*
394-
* If we have a toasted datum, forcibly detoast it here to
395-
* avoid memory leakage inside the type's output routine.
396-
*/
397-
if (thisState->typisvarlena)
398-
attr=PointerGetDatum(PG_DETOAST_DATUM(origattr));
399-
else
400-
attr=origattr;
401413

402-
outputstr=DatumGetCString(FunctionCall3(&thisState->finfo,
403-
attr,
414+
Assert(thisState->format==0);
415+
416+
/*
417+
* If we have a toasted datum, forcibly detoast it here to
418+
* avoid memory leakage inside the type's output routine.
419+
*/
420+
if (thisState->typisvarlena)
421+
attr=PointerGetDatum(PG_DETOAST_DATUM(origattr));
422+
else
423+
attr=origattr;
424+
425+
outputstr=DatumGetCString(FunctionCall3(&thisState->finfo,
426+
attr,
404427
ObjectIdGetDatum(thisState->typelem),
405428
Int32GetDatum(typeinfo->attrs[i]->atttypmod)));
429+
pq_sendcountedtext(&buf,outputstr,strlen(outputstr), true);
430+
pfree(outputstr);
406431

407-
pq_sendcountedtext(&buf,outputstr,strlen(outputstr), true);
408-
409-
/* Clean up detoasted copy, if any */
410-
if (attr!=origattr)
411-
pfree(DatumGetPointer(attr));
412-
pfree(outputstr);
413-
}
414-
else
415-
{
416-
outputstr="<unprintable>";
417-
pq_sendcountedtext(&buf,outputstr,strlen(outputstr), true);
418-
}
432+
/* Clean up detoasted copy, if any */
433+
if (attr!=origattr)
434+
pfree(DatumGetPointer(attr));
419435
}
420436

421437
pq_endmessage(&buf);
@@ -508,30 +524,29 @@ debugtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self)
508524
origattr=heap_getattr(tuple,i+1,typeinfo,&isnull);
509525
if (isnull)
510526
continue;
511-
if (getTypeOutputInfo(typeinfo->attrs[i]->atttypid,
512-
&typoutput,&typelem,&typisvarlena))
513-
{
514-
/*
515-
* If we have a toasted datum, forcibly detoast it here to
516-
* avoid memory leakage inside the type's output routine.
517-
*/
518-
if (typisvarlena)
519-
attr=PointerGetDatum(PG_DETOAST_DATUM(origattr));
520-
else
521-
attr=origattr;
527+
getTypeOutputInfo(typeinfo->attrs[i]->atttypid,
528+
&typoutput,&typelem,&typisvarlena);
529+
/*
530+
* If we have a toasted datum, forcibly detoast it here to
531+
* avoid memory leakage inside the type's output routine.
532+
*/
533+
if (typisvarlena)
534+
attr=PointerGetDatum(PG_DETOAST_DATUM(origattr));
535+
else
536+
attr=origattr;
522537

523-
value=DatumGetCString(OidFunctionCall3(typoutput,
524-
attr,
525-
ObjectIdGetDatum(typelem),
538+
value=DatumGetCString(OidFunctionCall3(typoutput,
539+
attr,
540+
ObjectIdGetDatum(typelem),
526541
Int32GetDatum(typeinfo->attrs[i]->atttypmod)));
527542

528-
printatt((unsigned)i+1,typeinfo->attrs[i],value);
543+
printatt((unsigned)i+1,typeinfo->attrs[i],value);
529544

530-
/* Clean up detoasted copy, if any */
531-
if (attr!=origattr)
532-
pfree(DatumGetPointer(attr));
533-
pfree(value);
534-
}
545+
pfree(value);
546+
547+
/* Clean up detoasted copy, if any */
548+
if (attr!=origattr)
549+
pfree(DatumGetPointer(attr));
535550
}
536551
printf("\t----\n");
537552
}
@@ -542,7 +557,7 @@ debugtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self)
542557
* We use a different message type, i.e. 'B' instead of 'D' to
543558
* indicate a tuple in internal (binary) form.
544559
*
545-
* This is largely same as printtup_20, except wedon'tusethe typout func.
560+
* This is largely same as printtup_20, except we usebinary formatting.
546561
* ----------------
547562
*/
548563
staticvoid
@@ -587,83 +602,41 @@ printtup_internal_20(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self)
587602
/*
588603
* send the attributes of this tuple
589604
*/
590-
#ifdefIPORTAL_DEBUG
591-
fprintf(stderr,"sending tuple with %d atts\n",natts);
592-
#endif
593-
594605
for (i=0;i<natts;++i)
595606
{
596607
PrinttupAttrInfo*thisState=myState->myinfo+i;
597608
Datumorigattr,
598609
attr;
599610
boolisnull;
600-
int32len;
611+
bytea*outputbytes;
601612

602613
origattr=heap_getattr(tuple,i+1,typeinfo,&isnull);
603614
if (isnull)
604615
continue;
605-
/* send # of bytes, and opaque data */
606-
if (thisState->typisvarlena)
607-
{
608-
/*
609-
* If we have a toasted datum, must detoast before sending.
610-
*/
611-
attr=PointerGetDatum(PG_DETOAST_DATUM(origattr));
612-
613-
len=VARSIZE(attr)-VARHDRSZ;
614616

615-
pq_sendint(&buf,len,VARHDRSZ);
616-
pq_sendbytes(&buf,VARDATA(attr),len);
617+
Assert(thisState->format==1);
617618

618-
#ifdefIPORTAL_DEBUG
619-
{
620-
char*d=VARDATA(attr);
621-
622-
fprintf(stderr,"length %d data %x %x %x %x\n",
623-
len,*d,*(d+1),*(d+2),*(d+3));
624-
}
625-
#endif
626-
627-
/* Clean up detoasted copy, if any */
628-
if (attr!=origattr)
629-
pfree(DatumGetPointer(attr));
630-
}
619+
/*
620+
* If we have a toasted datum, forcibly detoast it here to
621+
* avoid memory leakage inside the type's output routine.
622+
*/
623+
if (thisState->typisvarlena)
624+
attr=PointerGetDatum(PG_DETOAST_DATUM(origattr));
631625
else
632-
{
633-
/* fixed size or cstring */
634626
attr=origattr;
635-
len=typeinfo->attrs[i]->attlen;
636-
if (len <=0)
637-
{
638-
/* it's a cstring */
639-
Assert(len==-2&& !typeinfo->attrs[i]->attbyval);
640-
len=strlen(DatumGetCString(attr))+1;
641-
}
642-
pq_sendint(&buf,len,sizeof(int32));
643-
if (typeinfo->attrs[i]->attbyval)
644-
{
645-
DatumdatumBuf;
646-
647-
/*
648-
* We need this horsing around because we don't know how
649-
* shorter data values are aligned within a Datum.
650-
*/
651-
store_att_byval(&datumBuf,attr,len);
652-
pq_sendbytes(&buf, (char*)&datumBuf,len);
653-
#ifdefIPORTAL_DEBUG
654-
fprintf(stderr,"byval length %d data %ld\n",len,
655-
(long)attr);
656-
#endif
657-
}
658-
else
659-
{
660-
pq_sendbytes(&buf,DatumGetPointer(attr),len);
661-
#ifdefIPORTAL_DEBUG
662-
fprintf(stderr,"byref length %d data %p\n",len,
663-
DatumGetPointer(attr));
664-
#endif
665-
}
666-
}
627+
628+
outputbytes=DatumGetByteaP(FunctionCall2(&thisState->finfo,
629+
attr,
630+
ObjectIdGetDatum(thisState->typelem)));
631+
/* We assume the result will not have been toasted */
632+
pq_sendint(&buf,VARSIZE(outputbytes)-VARHDRSZ,4);
633+
pq_sendbytes(&buf,VARDATA(outputbytes),
634+
VARSIZE(outputbytes)-VARHDRSZ);
635+
pfree(outputbytes);
636+
637+
/* Clean up detoasted copy, if any */
638+
if (attr!=origattr)
639+
pfree(DatumGetPointer(attr));
667640
}
668641

669642
pq_endmessage(&buf);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp