Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Gpdb
提交
5e3bc5eb
G
Gpdb
项目概览
Greenplum
/
Gpdb
通知
7
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
Gpdb
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
5e3bc5eb
编写于
12月 02, 2000
作者:
T
Tom Lane
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Avoid memory leakage during regular COPY when outputting toasted values.
COPY BINARY is still broken for toasted data, however.
上级
77698e11
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
75 addition
and
110 deletion
+75
-110
src/backend/commands/copy.c
src/backend/commands/copy.c
+75
-110
未找到文件。
src/backend/commands/copy.c
浏览文件 @
5e3bc5eb
...
@@ -7,18 +7,18 @@
...
@@ -7,18 +7,18 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.12
4 2000/11/16 22:30:19
tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.12
5 2000/12/02 20:49:24
tgl Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
#include "postgres.h"
#include <unistd.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/stat.h>
#include "postgres.h"
#include "access/genam.h"
#include "access/genam.h"
#include "access/heapam.h"
#include "access/heapam.h"
#include "access/printtup.h"
#include "catalog/catname.h"
#include "catalog/catname.h"
#include "catalog/index.h"
#include "catalog/index.h"
#include "catalog/pg_index.h"
#include "catalog/pg_index.h"
...
@@ -47,13 +47,11 @@
...
@@ -47,13 +47,11 @@
/* non-export function prototypes */
/* non-export function prototypes */
static
void
CopyTo
(
Relation
rel
,
bool
binary
,
bool
oids
,
FILE
*
fp
,
char
*
delim
,
char
*
null_print
);
static
void
CopyTo
(
Relation
rel
,
bool
binary
,
bool
oids
,
FILE
*
fp
,
char
*
delim
,
char
*
null_print
);
static
void
CopyFrom
(
Relation
rel
,
bool
binary
,
bool
oids
,
FILE
*
fp
,
char
*
delim
,
char
*
null_print
);
static
void
CopyFrom
(
Relation
rel
,
bool
binary
,
bool
oids
,
FILE
*
fp
,
char
*
delim
,
char
*
null_print
);
static
Oid
GetOutputFunction
(
Oid
type
);
static
Oid
GetInputFunction
(
Oid
type
);
static
Oid
GetInputFunction
(
Oid
type
);
static
Oid
GetTypeElement
(
Oid
type
);
static
Oid
GetTypeElement
(
Oid
type
);
static
bool
IsTypeByVal
(
Oid
type
);
static
bool
IsTypeByVal
(
Oid
type
);
static
void
CopyReadNewline
(
FILE
*
fp
,
int
*
newline
);
static
void
CopyReadNewline
(
FILE
*
fp
,
int
*
newline
);
static
char
*
CopyReadAttribute
(
FILE
*
fp
,
bool
*
isnull
,
char
*
delim
,
int
*
newline
,
char
*
null_print
);
static
char
*
CopyReadAttribute
(
FILE
*
fp
,
bool
*
isnull
,
char
*
delim
,
int
*
newline
,
char
*
null_print
);
static
void
CopyAttributeOut
(
FILE
*
fp
,
char
*
string
,
char
*
delim
);
static
void
CopyAttributeOut
(
FILE
*
fp
,
char
*
string
,
char
*
delim
);
static
int
CountTuples
(
Relation
relation
);
static
int
CountTuples
(
Relation
relation
);
...
@@ -61,7 +59,7 @@ static int CountTuples(Relation relation);
...
@@ -61,7 +59,7 @@ static int CountTuples(Relation relation);
* Static communication variables ... pretty grotty, but COPY has
* Static communication variables ... pretty grotty, but COPY has
* never been reentrant...
* never been reentrant...
*/
*/
int
lineno
=
0
;
/*
used
by elog() -- dz */
int
lineno
=
0
;
/*
exported for use
by elog() -- dz */
static
bool
fe_eof
;
static
bool
fe_eof
;
/*
/*
...
@@ -344,7 +342,11 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
...
@@ -344,7 +342,11 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
{
{
mode_t
oumask
;
/* Pre-existing umask value */
mode_t
oumask
;
/* Pre-existing umask value */
if
(
*
filename
!=
'/'
)
/*
* Prevent write to relative path ... too easy to shoot oneself
* in the foot by overwriting a database file ...
*/
if
(
filename
[
0
]
!=
'/'
)
elog
(
ERROR
,
"Relative path not allowed for server side"
elog
(
ERROR
,
"Relative path not allowed for server side"
" COPY command."
);
" COPY command."
);
...
@@ -382,27 +384,22 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
...
@@ -382,27 +384,22 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
}
}
/*
* Copy from relation TO file.
*/
static
void
static
void
CopyTo
(
Relation
rel
,
bool
binary
,
bool
oids
,
FILE
*
fp
,
char
*
delim
,
char
*
null_print
)
CopyTo
(
Relation
rel
,
bool
binary
,
bool
oids
,
FILE
*
fp
,
char
*
delim
,
char
*
null_print
)
{
{
HeapTuple
tuple
;
HeapTuple
tuple
;
TupleDesc
tupDesc
;
HeapScanDesc
scandesc
;
HeapScanDesc
scandesc
;
int
attr_count
,
int32
attr_count
,
i
;
i
;
#ifdef _DROP_COLUMN_HACK__
bool
*
valid
;
#endif
/* _DROP_COLUMN_HACK__ */
Form_pg_attribute
*
attr
;
Form_pg_attribute
*
attr
;
FmgrInfo
*
out_functions
;
FmgrInfo
*
out_functions
;
Oid
out_func_oid
;
Oid
*
elements
;
Oid
*
elements
;
bool
*
isvarlena
;
int32
*
typmod
;
int32
*
typmod
;
Datum
value
;
bool
isnull
;
/* The attribute we are copying is null */
char
*
nulls
;
char
*
nulls
;
/*
/*
...
@@ -413,47 +410,39 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
...
@@ -413,47 +410,39 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
* <nulls> is meaningful only if we are doing a binary copy.
* <nulls> is meaningful only if we are doing a binary copy.
*/
*/
char
*
string
;
char
*
string
;
int32
ntuples
;
TupleDesc
tupDesc
;
scandesc
=
heap_beginscan
(
rel
,
0
,
QuerySnapshot
,
0
,
NULL
);
scandesc
=
heap_beginscan
(
rel
,
0
,
QuerySnapshot
,
0
,
NULL
);
tupDesc
=
rel
->
rd_att
;
attr_count
=
rel
->
rd_att
->
natts
;
attr_count
=
rel
->
rd_att
->
natts
;
attr
=
rel
->
rd_att
->
attrs
;
attr
=
rel
->
rd_att
->
attrs
;
tupDesc
=
rel
->
rd_att
;
/* For binary copy we really only need isvarlena, but compute it all... */
out_functions
=
(
FmgrInfo
*
)
palloc
(
attr_count
*
sizeof
(
FmgrInfo
));
elements
=
(
Oid
*
)
palloc
(
attr_count
*
sizeof
(
Oid
));
isvarlena
=
(
bool
*
)
palloc
(
attr_count
*
sizeof
(
bool
));
typmod
=
(
int32
*
)
palloc
(
attr_count
*
sizeof
(
int32
));
for
(
i
=
0
;
i
<
attr_count
;
i
++
)
{
Oid
out_func_oid
;
if
(
!
getTypeOutputInfo
(
attr
[
i
]
->
atttypid
,
&
out_func_oid
,
&
elements
[
i
],
&
isvarlena
[
i
]))
elog
(
ERROR
,
"COPY: couldn't lookup info for type %u"
,
attr
[
i
]
->
atttypid
);
fmgr_info
(
out_func_oid
,
&
out_functions
[
i
]);
typmod
[
i
]
=
attr
[
i
]
->
atttypmod
;
}
if
(
!
binary
)
if
(
!
binary
)
{
{
out_functions
=
(
FmgrInfo
*
)
palloc
(
attr_count
*
sizeof
(
FmgrInfo
));
elements
=
(
Oid
*
)
palloc
(
attr_count
*
sizeof
(
Oid
));
typmod
=
(
int32
*
)
palloc
(
attr_count
*
sizeof
(
int32
));
#ifdef _DROP_COLUMN_HACK__
valid
=
(
bool
*
)
palloc
(
attr_count
*
sizeof
(
bool
));
#endif
/* _DROP_COLUMN_HACK__ */
for
(
i
=
0
;
i
<
attr_count
;
i
++
)
{
#ifdef _DROP_COLUMN_HACK__
if
(
COLUMN_IS_DROPPED
(
attr
[
i
]))
{
valid
[
i
]
=
false
;
continue
;
}
else
valid
[
i
]
=
true
;
#endif
/* _DROP_COLUMN_HACK__ */
out_func_oid
=
(
Oid
)
GetOutputFunction
(
attr
[
i
]
->
atttypid
);
fmgr_info
(
out_func_oid
,
&
out_functions
[
i
]);
elements
[
i
]
=
GetTypeElement
(
attr
[
i
]
->
atttypid
);
typmod
[
i
]
=
attr
[
i
]
->
atttypmod
;
}
nulls
=
NULL
;
/* meaningless, but compiler doesn't know
nulls
=
NULL
;
/* meaningless, but compiler doesn't know
* that */
* that */
}
}
else
else
{
{
elements
=
NULL
;
int32
ntuples
;
typmod
=
NULL
;
out_functions
=
NULL
;
nulls
=
(
char
*
)
palloc
(
attr_count
);
nulls
=
(
char
*
)
palloc
(
attr_count
);
for
(
i
=
0
;
i
<
attr_count
;
i
++
)
for
(
i
=
0
;
i
<
attr_count
;
i
++
)
nulls
[
i
]
=
' '
;
nulls
[
i
]
=
' '
;
...
@@ -480,18 +469,31 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
...
@@ -480,18 +469,31 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
for
(
i
=
0
;
i
<
attr_count
;
i
++
)
for
(
i
=
0
;
i
<
attr_count
;
i
++
)
{
{
value
=
heap_getattr
(
tuple
,
i
+
1
,
tupDesc
,
&
isnull
);
Datum
origvalue
,
if
(
!
binary
)
value
;
bool
isnull
;
origvalue
=
heap_getattr
(
tuple
,
i
+
1
,
tupDesc
,
&
isnull
);
if
(
isnull
)
{
{
#ifdef _DROP_COLUMN_HACK__
if
(
!
binary
)
if
(
!
valid
[
i
])
CopySendString
(
null_print
,
fp
);
/* null indicator */
{
else
if
(
i
==
attr_count
-
1
)
nulls
[
i
]
=
'n'
;
CopySendChar
(
'\n'
,
fp
);
}
continue
;
else
}
{
#endif
/* _DROP_COLUMN_HACK__ */
/*
if
(
!
isnull
)
* If we have a toasted datum, forcibly detoast it to avoid
* memory leakage inside the type's output routine.
*/
if
(
isvarlena
[
i
])
value
=
PointerGetDatum
(
PG_DETOAST_DATUM
(
origvalue
));
else
value
=
origvalue
;
if
(
!
binary
)
{
{
string
=
DatumGetCString
(
FunctionCall3
(
&
out_functions
[
i
],
string
=
DatumGetCString
(
FunctionCall3
(
&
out_functions
[
i
],
value
,
value
,
...
@@ -500,9 +502,14 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
...
@@ -500,9 +502,14 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
CopyAttributeOut
(
fp
,
string
,
delim
);
CopyAttributeOut
(
fp
,
string
,
delim
);
pfree
(
string
);
pfree
(
string
);
}
}
else
CopySendString
(
null_print
,
fp
);
/* null indicator */
/* Clean up detoasted copy, if any */
if
(
value
!=
origvalue
)
pfree
(
DatumGetPointer
(
value
));
}
if
(
!
binary
)
{
if
(
i
==
attr_count
-
1
)
if
(
i
==
attr_count
-
1
)
CopySendChar
(
'\n'
,
fp
);
CopySendChar
(
'\n'
,
fp
);
else
else
...
@@ -515,16 +522,6 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
...
@@ -515,16 +522,6 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
CopySendChar
(
delim
[
0
],
fp
);
CopySendChar
(
delim
[
0
],
fp
);
}
}
}
}
else
{
/*
* only interesting thing heap_getattr tells us in this
* case is if we have a null attribute or not.
*/
if
(
isnull
)
nulls
[
i
]
=
'n'
;
}
}
}
if
(
binary
)
if
(
binary
)
...
@@ -561,16 +558,19 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
...
@@ -561,16 +558,19 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim, char *null_p
}
}
heap_endscan
(
scandesc
);
heap_endscan
(
scandesc
);
pfree
(
out_functions
);
pfree
(
elements
);
pfree
(
isvarlena
);
pfree
(
typmod
);
if
(
binary
)
if
(
binary
)
pfree
(
nulls
);
pfree
(
nulls
);
else
{
pfree
(
out_functions
);
pfree
(
elements
);
pfree
(
typmod
);
}
}
}
/*
* Copy FROM file to relation.
*/
static
void
static
void
CopyFrom
(
Relation
rel
,
bool
binary
,
bool
oids
,
FILE
*
fp
,
CopyFrom
(
Relation
rel
,
bool
binary
,
bool
oids
,
FILE
*
fp
,
char
*
delim
,
char
*
null_print
)
char
*
delim
,
char
*
null_print
)
...
@@ -635,10 +635,6 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp,
...
@@ -635,10 +635,6 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp,
typmod
=
(
int32
*
)
palloc
(
attr_count
*
sizeof
(
int32
));
typmod
=
(
int32
*
)
palloc
(
attr_count
*
sizeof
(
int32
));
for
(
i
=
0
;
i
<
attr_count
;
i
++
)
for
(
i
=
0
;
i
<
attr_count
;
i
++
)
{
{
#ifdef _DROP_COLUMN_HACK__
if
(
COLUMN_IS_DROPPED
(
attr
[
i
]))
continue
;
#endif
/* _DROP_COLUMN_HACK__ */
in_func_oid
=
(
Oid
)
GetInputFunction
(
attr
[
i
]
->
atttypid
);
in_func_oid
=
(
Oid
)
GetInputFunction
(
attr
[
i
]
->
atttypid
);
fmgr_info
(
in_func_oid
,
&
in_functions
[
i
]);
fmgr_info
(
in_func_oid
,
&
in_functions
[
i
]);
elements
[
i
]
=
GetTypeElement
(
attr
[
i
]
->
atttypid
);
elements
[
i
]
=
GetTypeElement
(
attr
[
i
]
->
atttypid
);
...
@@ -662,13 +658,6 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp,
...
@@ -662,13 +658,6 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp,
for
(
i
=
0
;
i
<
attr_count
;
i
++
)
for
(
i
=
0
;
i
<
attr_count
;
i
++
)
{
{
nulls
[
i
]
=
' '
;
nulls
[
i
]
=
' '
;
#ifdef _DROP_COLUMN_HACK__
if
(
COLUMN_IS_DROPPED
(
attr
[
i
]))
{
byval
[
i
]
=
'n'
;
continue
;
}
#endif
/* _DROP_COLUMN_HACK__ */
byval
[
i
]
=
IsTypeByVal
(
attr
[
i
]
->
atttypid
);
byval
[
i
]
=
IsTypeByVal
(
attr
[
i
]
->
atttypid
);
}
}
...
@@ -704,14 +693,6 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp,
...
@@ -704,14 +693,6 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp,
}
}
for
(
i
=
0
;
i
<
attr_count
&&
!
done
;
i
++
)
for
(
i
=
0
;
i
<
attr_count
&&
!
done
;
i
++
)
{
{
#ifdef _DROP_COLUMN_HACK__
if
(
COLUMN_IS_DROPPED
(
attr
[
i
]))
{
values
[
i
]
=
PointerGetDatum
(
NULL
);
nulls
[
i
]
=
'n'
;
continue
;
}
#endif
/* _DROP_COLUMN_HACK__ */
string
=
CopyReadAttribute
(
fp
,
&
isnull
,
delim
,
&
newline
,
null_print
);
string
=
CopyReadAttribute
(
fp
,
&
isnull
,
delim
,
&
newline
,
null_print
);
if
(
isnull
)
if
(
isnull
)
{
{
...
@@ -889,22 +870,6 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp,
...
@@ -889,22 +870,6 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp,
}
}
static
Oid
GetOutputFunction
(
Oid
type
)
{
HeapTuple
typeTuple
;
Oid
result
;
typeTuple
=
SearchSysCache
(
TYPEOID
,
ObjectIdGetDatum
(
type
),
0
,
0
,
0
);
if
(
!
HeapTupleIsValid
(
typeTuple
))
elog
(
ERROR
,
"GetOutputFunction: Cache lookup of type %u failed"
,
type
);
result
=
((
Form_pg_type
)
GETSTRUCT
(
typeTuple
))
->
typoutput
;
ReleaseSysCache
(
typeTuple
);
return
result
;
}
static
Oid
static
Oid
GetInputFunction
(
Oid
type
)
GetInputFunction
(
Oid
type
)
{
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录