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

Commit5e3bc5e

Browse files
committed
Avoid memory leakage during regular COPY when outputting toasted values.
COPY BINARY is still broken for toasted data, however.
1 parent77698e1 commit5e3bc5e

File tree

1 file changed

+75
-110
lines changed

1 file changed

+75
-110
lines changed

‎src/backend/commands/copy.c

Lines changed: 75 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,18 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.124 2000/11/16 22:30:19 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.125 2000/12/02 20:49:24 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
14+
#include"postgres.h"
1415

1516
#include<unistd.h>
1617
#include<sys/stat.h>
1718

18-
#include"postgres.h"
19-
2019
#include"access/genam.h"
2120
#include"access/heapam.h"
21+
#include"access/printtup.h"
2222
#include"catalog/catname.h"
2323
#include"catalog/index.h"
2424
#include"catalog/pg_index.h"
@@ -47,21 +47,19 @@
4747
/* non-export function prototypes */
4848
staticvoidCopyTo(Relationrel,boolbinary,booloids,FILE*fp,char*delim,char*null_print);
4949
staticvoidCopyFrom(Relationrel,boolbinary,booloids,FILE*fp,char*delim,char*null_print);
50-
staticOidGetOutputFunction(Oidtype);
5150
staticOidGetInputFunction(Oidtype);
5251
staticOidGetTypeElement(Oidtype);
5352
staticboolIsTypeByVal(Oidtype);
5453
staticvoidCopyReadNewline(FILE*fp,int*newline);
5554
staticchar*CopyReadAttribute(FILE*fp,bool*isnull,char*delim,int*newline,char*null_print);
56-
5755
staticvoidCopyAttributeOut(FILE*fp,char*string,char*delim);
5856
staticintCountTuples(Relationrelation);
5957

6058
/*
6159
* Static communication variables ... pretty grotty, but COPY has
6260
* never been reentrant...
6361
*/
64-
intlineno=0;/*used by elog() -- dz */
62+
intlineno=0;/*exported for use by elog() -- dz */
6563
staticboolfe_eof;
6664

6765
/*
@@ -344,7 +342,11 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
344342
{
345343
mode_toumask;/* Pre-existing umask value */
346344

347-
if (*filename!='/')
345+
/*
346+
* Prevent write to relative path ... too easy to shoot oneself
347+
* in the foot by overwriting a database file ...
348+
*/
349+
if (filename[0]!='/')
348350
elog(ERROR,"Relative path not allowed for server side"
349351
" COPY command.");
350352

@@ -382,27 +384,22 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
382384
}
383385

384386

385-
387+
/*
388+
* Copy from relation TO file.
389+
*/
386390
staticvoid
387391
CopyTo(Relationrel,boolbinary,booloids,FILE*fp,char*delim,char*null_print)
388392
{
389393
HeapTupletuple;
394+
TupleDesctupDesc;
390395
HeapScanDescscandesc;
391-
392-
int32attr_count,
396+
intattr_count,
393397
i;
394-
395-
#ifdef_DROP_COLUMN_HACK__
396-
bool*valid;
397-
398-
#endif/* _DROP_COLUMN_HACK__ */
399398
Form_pg_attribute*attr;
400399
FmgrInfo*out_functions;
401-
Oidout_func_oid;
402400
Oid*elements;
401+
bool*isvarlena;
403402
int32*typmod;
404-
Datumvalue;
405-
boolisnull;/* The attribute we are copying is null */
406403
char*nulls;
407404

408405
/*
@@ -413,47 +410,39 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
413410
* <nulls> is meaningful only if we are doing a binary copy.
414411
*/
415412
char*string;
416-
int32ntuples;
417-
TupleDesctupDesc;
418413

419414
scandesc=heap_beginscan(rel,0,QuerySnapshot,0,NULL);
420415

416+
tupDesc=rel->rd_att;
421417
attr_count=rel->rd_att->natts;
422418
attr=rel->rd_att->attrs;
423-
tupDesc=rel->rd_att;
419+
420+
/* For binary copy we really only need isvarlena, but compute it all... */
421+
out_functions= (FmgrInfo*)palloc(attr_count*sizeof(FmgrInfo));
422+
elements= (Oid*)palloc(attr_count*sizeof(Oid));
423+
isvarlena= (bool*)palloc(attr_count*sizeof(bool));
424+
typmod= (int32*)palloc(attr_count*sizeof(int32));
425+
for (i=0;i<attr_count;i++)
426+
{
427+
Oidout_func_oid;
428+
429+
if (!getTypeOutputInfo(attr[i]->atttypid,
430+
&out_func_oid,&elements[i],&isvarlena[i]))
431+
elog(ERROR,"COPY: couldn't lookup info for type %u",
432+
attr[i]->atttypid);
433+
fmgr_info(out_func_oid,&out_functions[i]);
434+
typmod[i]=attr[i]->atttypmod;
435+
}
424436

425437
if (!binary)
426438
{
427-
out_functions= (FmgrInfo*)palloc(attr_count*sizeof(FmgrInfo));
428-
elements= (Oid*)palloc(attr_count*sizeof(Oid));
429-
typmod= (int32*)palloc(attr_count*sizeof(int32));
430-
#ifdef_DROP_COLUMN_HACK__
431-
valid= (bool*)palloc(attr_count*sizeof(bool));
432-
#endif/* _DROP_COLUMN_HACK__ */
433-
for (i=0;i<attr_count;i++)
434-
{
435-
#ifdef_DROP_COLUMN_HACK__
436-
if (COLUMN_IS_DROPPED(attr[i]))
437-
{
438-
valid[i]= false;
439-
continue;
440-
}
441-
else
442-
valid[i]= true;
443-
#endif/* _DROP_COLUMN_HACK__ */
444-
out_func_oid= (Oid)GetOutputFunction(attr[i]->atttypid);
445-
fmgr_info(out_func_oid,&out_functions[i]);
446-
elements[i]=GetTypeElement(attr[i]->atttypid);
447-
typmod[i]=attr[i]->atttypmod;
448-
}
449439
nulls=NULL;/* meaningless, but compiler doesn't know
450440
* that */
451441
}
452442
else
453443
{
454-
elements=NULL;
455-
typmod=NULL;
456-
out_functions=NULL;
444+
int32ntuples;
445+
457446
nulls= (char*)palloc(attr_count);
458447
for (i=0;i<attr_count;i++)
459448
nulls[i]=' ';
@@ -480,18 +469,31 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
480469

481470
for (i=0;i<attr_count;i++)
482471
{
483-
value=heap_getattr(tuple,i+1,tupDesc,&isnull);
484-
if (!binary)
472+
Datumorigvalue,
473+
value;
474+
boolisnull;
475+
476+
origvalue=heap_getattr(tuple,i+1,tupDesc,&isnull);
477+
478+
if (isnull)
485479
{
486-
#ifdef_DROP_COLUMN_HACK__
487-
if (!valid[i])
488-
{
489-
if (i==attr_count-1)
490-
CopySendChar('\n',fp);
491-
continue;
492-
}
493-
#endif/* _DROP_COLUMN_HACK__ */
494-
if (!isnull)
480+
if (!binary)
481+
CopySendString(null_print,fp);/* null indicator */
482+
else
483+
nulls[i]='n';
484+
}
485+
else
486+
{
487+
/*
488+
* If we have a toasted datum, forcibly detoast it to avoid
489+
* memory leakage inside the type's output routine.
490+
*/
491+
if (isvarlena[i])
492+
value=PointerGetDatum(PG_DETOAST_DATUM(origvalue));
493+
else
494+
value=origvalue;
495+
496+
if (!binary)
495497
{
496498
string=DatumGetCString(FunctionCall3(&out_functions[i],
497499
value,
@@ -500,9 +502,14 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
500502
CopyAttributeOut(fp,string,delim);
501503
pfree(string);
502504
}
503-
else
504-
CopySendString(null_print,fp);/* null indicator */
505505

506+
/* Clean up detoasted copy, if any */
507+
if (value!=origvalue)
508+
pfree(DatumGetPointer(value));
509+
}
510+
511+
if (!binary)
512+
{
506513
if (i==attr_count-1)
507514
CopySendChar('\n',fp);
508515
else
@@ -515,16 +522,6 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
515522
CopySendChar(delim[0],fp);
516523
}
517524
}
518-
else
519-
{
520-
521-
/*
522-
* only interesting thing heap_getattr tells us in this
523-
* case is if we have a null attribute or not.
524-
*/
525-
if (isnull)
526-
nulls[i]='n';
527-
}
528525
}
529526

530527
if (binary)
@@ -561,16 +558,19 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
561558
}
562559

563560
heap_endscan(scandesc);
561+
562+
pfree(out_functions);
563+
pfree(elements);
564+
pfree(isvarlena);
565+
pfree(typmod);
564566
if (binary)
565567
pfree(nulls);
566-
else
567-
{
568-
pfree(out_functions);
569-
pfree(elements);
570-
pfree(typmod);
571-
}
572568
}
573569

570+
571+
/*
572+
* Copy FROM file to relation.
573+
*/
574574
staticvoid
575575
CopyFrom(Relationrel,boolbinary,booloids,FILE*fp,
576576
char*delim,char*null_print)
@@ -635,10 +635,6 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp,
635635
typmod= (int32*)palloc(attr_count*sizeof(int32));
636636
for (i=0;i<attr_count;i++)
637637
{
638-
#ifdef_DROP_COLUMN_HACK__
639-
if (COLUMN_IS_DROPPED(attr[i]))
640-
continue;
641-
#endif/* _DROP_COLUMN_HACK__ */
642638
in_func_oid= (Oid)GetInputFunction(attr[i]->atttypid);
643639
fmgr_info(in_func_oid,&in_functions[i]);
644640
elements[i]=GetTypeElement(attr[i]->atttypid);
@@ -662,13 +658,6 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp,
662658
for (i=0;i<attr_count;i++)
663659
{
664660
nulls[i]=' ';
665-
#ifdef_DROP_COLUMN_HACK__
666-
if (COLUMN_IS_DROPPED(attr[i]))
667-
{
668-
byval[i]='n';
669-
continue;
670-
}
671-
#endif/* _DROP_COLUMN_HACK__ */
672661
byval[i]=IsTypeByVal(attr[i]->atttypid);
673662
}
674663

@@ -704,14 +693,6 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp,
704693
}
705694
for (i=0;i<attr_count&& !done;i++)
706695
{
707-
#ifdef_DROP_COLUMN_HACK__
708-
if (COLUMN_IS_DROPPED(attr[i]))
709-
{
710-
values[i]=PointerGetDatum(NULL);
711-
nulls[i]='n';
712-
continue;
713-
}
714-
#endif/* _DROP_COLUMN_HACK__ */
715696
string=CopyReadAttribute(fp,&isnull,delim,&newline,null_print);
716697
if (isnull)
717698
{
@@ -889,22 +870,6 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp,
889870
}
890871

891872

892-
staticOid
893-
GetOutputFunction(Oidtype)
894-
{
895-
HeapTupletypeTuple;
896-
Oidresult;
897-
898-
typeTuple=SearchSysCache(TYPEOID,
899-
ObjectIdGetDatum(type),
900-
0,0,0);
901-
if (!HeapTupleIsValid(typeTuple))
902-
elog(ERROR,"GetOutputFunction: Cache lookup of type %u failed",type);
903-
result= ((Form_pg_type)GETSTRUCT(typeTuple))->typoutput;
904-
ReleaseSysCache(typeTuple);
905-
returnresult;
906-
}
907-
908873
staticOid
909874
GetInputFunction(Oidtype)
910875
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp