Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Gpdb
提交
1d0d8d3c
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,发现更多精彩内容 >>
提交
1d0d8d3c
编写于
11月 18, 2005
作者:
T
Tom Lane
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Mop-up for nulls-in-arrays patch: fix some places that access array
contents directly.
上级
3201b7f3
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
233 addition
and
278 deletion
+233
-278
contrib/dblink/dblink.c
contrib/dblink/dblink.c
+115
-197
contrib/tsearch2/rank.c
contrib/tsearch2/rank.c
+14
-7
contrib/tsearch2/snowball/header.h
contrib/tsearch2/snowball/header.h
+0
-3
contrib/tsearch2/ts_cfg.c
contrib/tsearch2/ts_cfg.c
+2
-0
src/backend/utils/adt/acl.c
src/backend/utils/adt/acl.c
+37
-10
src/backend/utils/adt/varlena.c
src/backend/utils/adt/varlena.c
+39
-13
src/include/utils/acl.h
src/include/utils/acl.h
+4
-21
src/pl/plpgsql/src/pl_exec.c
src/pl/plpgsql/src/pl_exec.c
+22
-27
未找到文件。
contrib/dblink/dblink.c
浏览文件 @
1d0d8d3c
...
...
@@ -73,6 +73,7 @@ static HTAB *createConnHash(void);
static
void
createNewConnection
(
const
char
*
name
,
remoteConn
*
rconn
);
static
void
deleteConnection
(
const
char
*
name
);
static
char
**
get_pkey_attnames
(
Oid
relid
,
int16
*
numatts
);
static
char
**
get_text_array_contents
(
ArrayType
*
array
,
int
*
numitems
);
static
char
*
get_sql_insert
(
Oid
relid
,
int2vector
*
pkattnums
,
int16
pknumatts
,
char
**
src_pkattvals
,
char
**
tgt_pkattvals
);
static
char
*
get_sql_delete
(
Oid
relid
,
int2vector
*
pkattnums
,
int16
pknumatts
,
char
**
tgt_pkattvals
);
static
char
*
get_sql_update
(
Oid
relid
,
int2vector
*
pkattnums
,
int16
pknumatts
,
char
**
src_pkattvals
,
char
**
tgt_pkattvals
);
...
...
@@ -1120,29 +1121,18 @@ PG_FUNCTION_INFO_V1(dblink_build_sql_insert);
Datum
dblink_build_sql_insert
(
PG_FUNCTION_ARGS
)
{
text
*
relname_text
=
PG_GETARG_TEXT_P
(
0
);
int2vector
*
pkattnums
=
(
int2vector
*
)
PG_GETARG_POINTER
(
1
);
int32
pknumatts_tmp
=
PG_GETARG_INT32
(
2
);
ArrayType
*
src_pkattvals_arry
=
PG_GETARG_ARRAYTYPE_P
(
3
);
ArrayType
*
tgt_pkattvals_arry
=
PG_GETARG_ARRAYTYPE_P
(
4
);
Oid
relid
;
text
*
relname_text
;
int2vector
*
pkattnums
;
int
pknumatts_tmp
;
int16
pknumatts
=
0
;
char
**
src_pkattvals
;
char
**
tgt_pkattvals
;
ArrayType
*
src_pkattvals_arry
;
ArrayType
*
tgt_pkattvals_arry
;
int
src_ndim
;
int
*
src_dim
;
int
src_nitems
;
int
tgt_ndim
;
int
*
tgt_dim
;
int
tgt_nitems
;
int
i
;
char
*
ptr
;
char
*
sql
;
int16
typlen
;
bool
typbyval
;
char
typalign
;
relname_text
=
PG_GETARG_TEXT_P
(
0
);
/*
* Convert relname to rel OID.
...
...
@@ -1154,34 +1144,27 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
errmsg
(
"relation
\"
%s
\"
does not exist"
,
GET_STR
(
relname_text
))));
pkattnums
=
(
int2vector
*
)
PG_GETARG_POINTER
(
1
);
pknumatts_tmp
=
PG_GETARG_INT32
(
2
);
if
(
pknumatts_tmp
<=
SHRT_MAX
)
pknumatts
=
pknumatts_tmp
;
else
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"input for number of primary key "
\
"attributes too large"
)));
/*
* There should be at least one key attribute
*/
if
(
pknumatts
=
=
0
)
if
(
pknumatts
_tmp
<
=
0
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"number of key attributes must be > 0"
)));
src_pkattvals_arry
=
PG_GETARG_ARRAYTYPE_P
(
3
);
tgt_pkattvals_arry
=
PG_GETARG_ARRAYTYPE_P
(
4
);
if
(
pknumatts_tmp
<=
SHRT_MAX
)
pknumatts
=
pknumatts_tmp
;
else
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"input for number of primary key "
\
"attributes too large"
)));
/*
* Source array is made up of key values that will be used to locate the
* tuple of interest from the local system.
*/
src_ndim
=
ARR_NDIM
(
src_pkattvals_arry
);
src_dim
=
ARR_DIMS
(
src_pkattvals_arry
);
src_nitems
=
ArrayGetNItems
(
src_ndim
,
src_dim
);
src_pkattvals
=
get_text_array_contents
(
src_pkattvals_arry
,
&
src_nitems
);
/*
* There should be one source array key value for each key attnum
...
...
@@ -1192,29 +1175,11 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
errmsg
(
"source key array length must match number of key "
\
"attributes"
)));
/*
* get array of pointers to c-strings from the input source array
*/
Assert
(
ARR_ELEMTYPE
(
src_pkattvals_arry
)
==
TEXTOID
);
get_typlenbyvalalign
(
ARR_ELEMTYPE
(
src_pkattvals_arry
),
&
typlen
,
&
typbyval
,
&
typalign
);
src_pkattvals
=
(
char
**
)
palloc
(
src_nitems
*
sizeof
(
char
*
));
ptr
=
ARR_DATA_PTR
(
src_pkattvals_arry
);
for
(
i
=
0
;
i
<
src_nitems
;
i
++
)
{
src_pkattvals
[
i
]
=
DatumGetCString
(
DirectFunctionCall1
(
textout
,
PointerGetDatum
(
ptr
)));
ptr
=
att_addlength
(
ptr
,
typlen
,
PointerGetDatum
(
ptr
));
ptr
=
(
char
*
)
att_align
(
ptr
,
typalign
);
}
/*
* Target array is made up of key values that will be used to build the
* SQL string for use on the remote system.
*/
tgt_ndim
=
ARR_NDIM
(
tgt_pkattvals_arry
);
tgt_dim
=
ARR_DIMS
(
tgt_pkattvals_arry
);
tgt_nitems
=
ArrayGetNItems
(
tgt_ndim
,
tgt_dim
);
tgt_pkattvals
=
get_text_array_contents
(
tgt_pkattvals_arry
,
&
tgt_nitems
);
/*
* There should be one target array key value for each key attnum
...
...
@@ -1225,22 +1190,6 @@ dblink_build_sql_insert(PG_FUNCTION_ARGS)
errmsg
(
"target key array length must match number of key "
\
"attributes"
)));
/*
* get array of pointers to c-strings from the input target array
*/
Assert
(
ARR_ELEMTYPE
(
tgt_pkattvals_arry
)
==
TEXTOID
);
get_typlenbyvalalign
(
ARR_ELEMTYPE
(
tgt_pkattvals_arry
),
&
typlen
,
&
typbyval
,
&
typalign
);
tgt_pkattvals
=
(
char
**
)
palloc
(
tgt_nitems
*
sizeof
(
char
*
));
ptr
=
ARR_DATA_PTR
(
tgt_pkattvals_arry
);
for
(
i
=
0
;
i
<
tgt_nitems
;
i
++
)
{
tgt_pkattvals
[
i
]
=
DatumGetCString
(
DirectFunctionCall1
(
textout
,
PointerGetDatum
(
ptr
)));
ptr
=
att_addlength
(
ptr
,
typlen
,
PointerGetDatum
(
ptr
));
ptr
=
(
char
*
)
att_align
(
ptr
,
typalign
);
}
/*
* Prep work is finally done. Go get the SQL string.
*/
...
...
@@ -1272,24 +1221,15 @@ PG_FUNCTION_INFO_V1(dblink_build_sql_delete);
Datum
dblink_build_sql_delete
(
PG_FUNCTION_ARGS
)
{
text
*
relname_text
=
PG_GETARG_TEXT_P
(
0
);
int2vector
*
pkattnums
=
(
int2vector
*
)
PG_GETARG_POINTER
(
1
);
int32
pknumatts_tmp
=
PG_GETARG_INT32
(
2
);
ArrayType
*
tgt_pkattvals_arry
=
PG_GETARG_ARRAYTYPE_P
(
3
);
Oid
relid
;
text
*
relname_text
;
int2vector
*
pkattnums
;
int
pknumatts_tmp
;
int16
pknumatts
=
0
;
char
**
tgt_pkattvals
;
ArrayType
*
tgt_pkattvals_arry
;
int
tgt_ndim
;
int
*
tgt_dim
;
int
tgt_nitems
;
int
i
;
char
*
ptr
;
char
*
sql
;
int16
typlen
;
bool
typbyval
;
char
typalign
;
relname_text
=
PG_GETARG_TEXT_P
(
0
);
/*
* Convert relname to rel OID.
...
...
@@ -1301,33 +1241,27 @@ dblink_build_sql_delete(PG_FUNCTION_ARGS)
errmsg
(
"relation
\"
%s
\"
does not exist"
,
GET_STR
(
relname_text
))));
pkattnums
=
(
int2vector
*
)
PG_GETARG_POINTER
(
1
);
pknumatts_tmp
=
PG_GETARG_INT32
(
2
);
if
(
pknumatts_tmp
<=
SHRT_MAX
)
pknumatts
=
pknumatts_tmp
;
else
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"input for number of primary key "
\
"attributes too large"
)));
/*
* There should be at least one key attribute
*/
if
(
pknumatts
=
=
0
)
if
(
pknumatts
_tmp
<
=
0
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"number of key attributes must be > 0"
)));
tgt_pkattvals_arry
=
PG_GETARG_ARRAYTYPE_P
(
3
);
if
(
pknumatts_tmp
<=
SHRT_MAX
)
pknumatts
=
pknumatts_tmp
;
else
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"input for number of primary key "
\
"attributes too large"
)));
/*
* Target array is made up of key values that will be used to build the
* SQL string for use on the remote system.
*/
tgt_ndim
=
ARR_NDIM
(
tgt_pkattvals_arry
);
tgt_dim
=
ARR_DIMS
(
tgt_pkattvals_arry
);
tgt_nitems
=
ArrayGetNItems
(
tgt_ndim
,
tgt_dim
);
tgt_pkattvals
=
get_text_array_contents
(
tgt_pkattvals_arry
,
&
tgt_nitems
);
/*
* There should be one target array key value for each key attnum
...
...
@@ -1338,22 +1272,6 @@ dblink_build_sql_delete(PG_FUNCTION_ARGS)
errmsg
(
"target key array length must match number of key "
\
"attributes"
)));
/*
* get array of pointers to c-strings from the input target array
*/
Assert
(
ARR_ELEMTYPE
(
tgt_pkattvals_arry
)
==
TEXTOID
);
get_typlenbyvalalign
(
ARR_ELEMTYPE
(
tgt_pkattvals_arry
),
&
typlen
,
&
typbyval
,
&
typalign
);
tgt_pkattvals
=
(
char
**
)
palloc
(
tgt_nitems
*
sizeof
(
char
*
));
ptr
=
ARR_DATA_PTR
(
tgt_pkattvals_arry
);
for
(
i
=
0
;
i
<
tgt_nitems
;
i
++
)
{
tgt_pkattvals
[
i
]
=
DatumGetCString
(
DirectFunctionCall1
(
textout
,
PointerGetDatum
(
ptr
)));
ptr
=
att_addlength
(
ptr
,
typlen
,
PointerGetDatum
(
ptr
));
ptr
=
(
char
*
)
att_align
(
ptr
,
typalign
);
}
/*
* Prep work is finally done. Go get the SQL string.
*/
...
...
@@ -1389,29 +1307,18 @@ PG_FUNCTION_INFO_V1(dblink_build_sql_update);
Datum
dblink_build_sql_update
(
PG_FUNCTION_ARGS
)
{
text
*
relname_text
=
PG_GETARG_TEXT_P
(
0
);
int2vector
*
pkattnums
=
(
int2vector
*
)
PG_GETARG_POINTER
(
1
);
int32
pknumatts_tmp
=
PG_GETARG_INT32
(
2
);
ArrayType
*
src_pkattvals_arry
=
PG_GETARG_ARRAYTYPE_P
(
3
);
ArrayType
*
tgt_pkattvals_arry
=
PG_GETARG_ARRAYTYPE_P
(
4
);
Oid
relid
;
text
*
relname_text
;
int2vector
*
pkattnums
;
int
pknumatts_tmp
;
int16
pknumatts
=
0
;
char
**
src_pkattvals
;
char
**
tgt_pkattvals
;
ArrayType
*
src_pkattvals_arry
;
ArrayType
*
tgt_pkattvals_arry
;
int
src_ndim
;
int
*
src_dim
;
int
src_nitems
;
int
tgt_ndim
;
int
*
tgt_dim
;
int
tgt_nitems
;
int
i
;
char
*
ptr
;
char
*
sql
;
int16
typlen
;
bool
typbyval
;
char
typalign
;
relname_text
=
PG_GETARG_TEXT_P
(
0
);
/*
* Convert relname to rel OID.
...
...
@@ -1423,34 +1330,27 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
errmsg
(
"relation
\"
%s
\"
does not exist"
,
GET_STR
(
relname_text
))));
pkattnums
=
(
int2vector
*
)
PG_GETARG_POINTER
(
1
);
pknumatts_tmp
=
PG_GETARG_INT32
(
2
);
if
(
pknumatts_tmp
<=
SHRT_MAX
)
pknumatts
=
pknumatts_tmp
;
else
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"input for number of primary key "
\
"attributes too large"
)));
/*
* There should be one source array key values for each key attnum
*/
if
(
pknumatts
=
=
0
)
if
(
pknumatts
_tmp
<
=
0
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"number of key attributes must be > 0"
)));
src_pkattvals_arry
=
PG_GETARG_ARRAYTYPE_P
(
3
);
tgt_pkattvals_arry
=
PG_GETARG_ARRAYTYPE_P
(
4
);
if
(
pknumatts_tmp
<=
SHRT_MAX
)
pknumatts
=
pknumatts_tmp
;
else
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"input for number of primary key "
\
"attributes too large"
)));
/*
* Source array is made up of key values that will be used to locate the
* tuple of interest from the local system.
*/
src_ndim
=
ARR_NDIM
(
src_pkattvals_arry
);
src_dim
=
ARR_DIMS
(
src_pkattvals_arry
);
src_nitems
=
ArrayGetNItems
(
src_ndim
,
src_dim
);
src_pkattvals
=
get_text_array_contents
(
src_pkattvals_arry
,
&
src_nitems
);
/*
* There should be one source array key value for each key attnum
...
...
@@ -1461,29 +1361,11 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
errmsg
(
"source key array length must match number of key "
\
"attributes"
)));
/*
* get array of pointers to c-strings from the input source array
*/
Assert
(
ARR_ELEMTYPE
(
src_pkattvals_arry
)
==
TEXTOID
);
get_typlenbyvalalign
(
ARR_ELEMTYPE
(
src_pkattvals_arry
),
&
typlen
,
&
typbyval
,
&
typalign
);
src_pkattvals
=
(
char
**
)
palloc
(
src_nitems
*
sizeof
(
char
*
));
ptr
=
ARR_DATA_PTR
(
src_pkattvals_arry
);
for
(
i
=
0
;
i
<
src_nitems
;
i
++
)
{
src_pkattvals
[
i
]
=
DatumGetCString
(
DirectFunctionCall1
(
textout
,
PointerGetDatum
(
ptr
)));
ptr
=
att_addlength
(
ptr
,
typlen
,
PointerGetDatum
(
ptr
));
ptr
=
(
char
*
)
att_align
(
ptr
,
typalign
);
}
/*
* Target array is made up of key values that will be used to build the
* SQL string for use on the remote system.
*/
tgt_ndim
=
ARR_NDIM
(
tgt_pkattvals_arry
);
tgt_dim
=
ARR_DIMS
(
tgt_pkattvals_arry
);
tgt_nitems
=
ArrayGetNItems
(
tgt_ndim
,
tgt_dim
);
tgt_pkattvals
=
get_text_array_contents
(
tgt_pkattvals_arry
,
&
tgt_nitems
);
/*
* There should be one target array key value for each key attnum
...
...
@@ -1494,22 +1376,6 @@ dblink_build_sql_update(PG_FUNCTION_ARGS)
errmsg
(
"target key array length must match number of key "
\
"attributes"
)));
/*
* get array of pointers to c-strings from the input target array
*/
Assert
(
ARR_ELEMTYPE
(
tgt_pkattvals_arry
)
==
TEXTOID
);
get_typlenbyvalalign
(
ARR_ELEMTYPE
(
tgt_pkattvals_arry
),
&
typlen
,
&
typbyval
,
&
typalign
);
tgt_pkattvals
=
(
char
**
)
palloc
(
tgt_nitems
*
sizeof
(
char
*
));
ptr
=
ARR_DATA_PTR
(
tgt_pkattvals_arry
);
for
(
i
=
0
;
i
<
tgt_nitems
;
i
++
)
{
tgt_pkattvals
[
i
]
=
DatumGetCString
(
DirectFunctionCall1
(
textout
,
PointerGetDatum
(
ptr
)));
ptr
=
att_addlength
(
ptr
,
typlen
,
PointerGetDatum
(
ptr
));
ptr
=
(
char
*
)
att_align
(
ptr
,
typalign
);
}
/*
* Prep work is finally done. Go get the SQL string.
*/
...
...
@@ -1598,6 +1464,67 @@ get_pkey_attnames(Oid relid, int16 *numatts)
return
result
;
}
/*
* Deconstruct a text[] into C-strings (note any NULL elements will be
* returned as NULL pointers)
*/
static
char
**
get_text_array_contents
(
ArrayType
*
array
,
int
*
numitems
)
{
int
ndim
=
ARR_NDIM
(
array
);
int
*
dims
=
ARR_DIMS
(
array
);
int
nitems
;
int16
typlen
;
bool
typbyval
;
char
typalign
;
char
**
values
;
char
*
ptr
;
bits8
*
bitmap
;
int
bitmask
;
int
i
;
Assert
(
ARR_ELEMTYPE
(
array
)
==
TEXTOID
);
*
numitems
=
nitems
=
ArrayGetNItems
(
ndim
,
dims
);
get_typlenbyvalalign
(
ARR_ELEMTYPE
(
array
),
&
typlen
,
&
typbyval
,
&
typalign
);
values
=
(
char
**
)
palloc
(
nitems
*
sizeof
(
char
*
));
ptr
=
ARR_DATA_PTR
(
array
);
bitmap
=
ARR_NULLBITMAP
(
array
);
bitmask
=
1
;
for
(
i
=
0
;
i
<
nitems
;
i
++
)
{
if
(
bitmap
&&
(
*
bitmap
&
bitmask
)
==
0
)
{
values
[
i
]
=
NULL
;
}
else
{
values
[
i
]
=
DatumGetCString
(
DirectFunctionCall1
(
textout
,
PointerGetDatum
(
ptr
)));
ptr
=
att_addlength
(
ptr
,
typlen
,
PointerGetDatum
(
ptr
));
ptr
=
(
char
*
)
att_align
(
ptr
,
typalign
);
}
/* advance bitmap pointer if any */
if
(
bitmap
)
{
bitmask
<<=
1
;
if
(
bitmask
==
0x100
)
{
bitmap
++
;
bitmask
=
1
;
}
}
}
return
values
;
}
static
char
*
get_sql_insert
(
Oid
relid
,
int2vector
*
pkattnums
,
int16
pknumatts
,
char
**
src_pkattvals
,
char
**
tgt_pkattvals
)
{
...
...
@@ -1665,7 +1592,7 @@ get_sql_insert(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
key
=
-
1
;
if
(
key
>
-
1
)
val
=
pstrdup
(
tgt_pkattvals
[
key
])
;
val
=
tgt_pkattvals
[
key
]
?
pstrdup
(
tgt_pkattvals
[
key
])
:
NULL
;
else
val
=
SPI_getvalue
(
tuple
,
tupdesc
,
i
+
1
);
...
...
@@ -1697,7 +1624,6 @@ get_sql_delete(Oid relid, int2vector *pkattnums, int16 pknumatts, char **tgt_pka
int
natts
;
StringInfo
str
=
makeStringInfo
();
char
*
sql
;
char
*
val
=
NULL
;
int
i
;
/* get relation name including any needed schema prefix and quoting */
...
...
@@ -1721,17 +1647,13 @@ get_sql_delete(Oid relid, int2vector *pkattnums, int16 pknumatts, char **tgt_pka
appendStringInfo
(
str
,
"%s"
,
quote_ident_cstr
(
NameStr
(
tupdesc
->
attrs
[
pkattnum
-
1
]
->
attname
)));
if
(
tgt_pkattvals
!=
NULL
)
val
=
pstrdup
(
tgt_pkattvals
[
i
]);
else
if
(
tgt_pkattvals
==
NULL
)
/* internal error */
elog
(
ERROR
,
"target key array must not be NULL"
);
if
(
val
!=
NULL
)
{
appendStringInfo
(
str
,
" = %s"
,
quote_literal_cstr
(
val
));
pfree
(
val
);
}
if
(
tgt_pkattvals
[
i
]
!=
NULL
)
appendStringInfo
(
str
,
" = %s"
,
quote_literal_cstr
(
tgt_pkattvals
[
i
]));
else
appendStringInfo
(
str
,
" IS NULL"
);
}
...
...
@@ -1795,7 +1717,7 @@ get_sql_update(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
key
=
-
1
;
if
(
key
>
-
1
)
val
=
pstrdup
(
tgt_pkattvals
[
key
])
;
val
=
tgt_pkattvals
[
key
]
?
pstrdup
(
tgt_pkattvals
[
key
])
:
NULL
;
else
val
=
SPI_getvalue
(
tuple
,
tupdesc
,
i
+
1
);
...
...
@@ -1822,7 +1744,7 @@ get_sql_update(Oid relid, int2vector *pkattnums, int16 pknumatts, char **src_pka
quote_ident_cstr
(
NameStr
(
tupdesc
->
attrs
[
pkattnum
-
1
]
->
attname
)));
if
(
tgt_pkattvals
!=
NULL
)
val
=
pstrdup
(
tgt_pkattvals
[
i
])
;
val
=
tgt_pkattvals
[
i
]
?
pstrdup
(
tgt_pkattvals
[
i
])
:
NULL
;
else
val
=
SPI_getvalue
(
tuple
,
tupdesc
,
pkattnum
);
...
...
@@ -1905,7 +1827,6 @@ get_tuple_of_interest(Oid relid, int2vector *pkattnums, int16 pknumatts, char **
int
ret
;
HeapTuple
tuple
;
int
i
;
char
*
val
=
NULL
;
/* get relation name including any needed schema prefix and quoting */
relname
=
generate_relation_name
(
relid
);
...
...
@@ -1940,12 +1861,9 @@ get_tuple_of_interest(Oid relid, int2vector *pkattnums, int16 pknumatts, char **
appendStringInfo
(
str
,
"%s"
,
quote_ident_cstr
(
NameStr
(
tupdesc
->
attrs
[
pkattnum
-
1
]
->
attname
)));
val
=
pstrdup
(
src_pkattvals
[
i
]);
if
(
val
!=
NULL
)
{
appendStringInfo
(
str
,
" = %s"
,
quote_literal_cstr
(
val
));
pfree
(
val
);
}
if
(
src_pkattvals
[
i
]
!=
NULL
)
appendStringInfo
(
str
,
" = %s"
,
quote_literal_cstr
(
src_pkattvals
[
i
]));
else
appendStringInfo
(
str
,
" IS NULL"
);
}
...
...
contrib/tsearch2/rank.c
浏览文件 @
1d0d8d3c
...
...
@@ -3,20 +3,20 @@
* Teodor Sigaev <teodor@sigaev.ru>
*/
#include "postgres.h"
#include <math.h>
#include "access/gist.h"
#include "access/itup.h"
#include "utils/builtins.h"
#include "catalog/namespace.h"
#include "commands/trigger.h"
#include "executor/spi.h"
#include "fmgr.h"
#include "funcapi.h"
#include "storage/bufpage.h"
#include "executor/spi.h"
#include "commands/trigger.h"
#include "nodes/pg_list.h"
#include "catalog/namespace.h"
#include "storage/bufpage.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "tsvector.h"
#include "query.h"
...
...
@@ -354,6 +354,7 @@ rank(PG_FUNCTION_ARGS)
int
method
=
DEF_NORM_METHOD
;
float
res
=
0
.
0
;
float
ws
[
lengthof
(
weights
)];
float4
*
arrdata
;
int
i
;
if
(
ARR_NDIM
(
win
)
!=
1
)
...
...
@@ -366,9 +367,15 @@ rank(PG_FUNCTION_ARGS)
(
errcode
(
ERRCODE_ARRAY_SUBSCRIPT_ERROR
),
errmsg
(
"array of weight is too short"
)));
if
(
ARR_HASNULL
(
win
))
ereport
(
ERROR
,
(
errcode
(
ERRCODE_NULL_VALUE_NOT_ALLOWED
),
errmsg
(
"array of weight must not contain nulls"
)));
arrdata
=
(
float4
*
)
ARR_DATA_PTR
(
win
);
for
(
i
=
0
;
i
<
lengthof
(
weights
);
i
++
)
{
ws
[
i
]
=
(
((
float4
*
)
ARR_DATA_PTR
(
win
))[
i
]
>=
0
)
?
((
float4
*
)
ARR_DATA_PTR
(
win
))
[
i
]
:
weights
[
i
];
ws
[
i
]
=
(
arrdata
[
i
]
>=
0
)
?
arrdata
[
i
]
:
weights
[
i
];
if
(
ws
[
i
]
>
1
.
0
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
...
...
contrib/tsearch2/snowball/header.h
浏览文件 @
1d0d8d3c
...
...
@@ -3,9 +3,6 @@
#include "api.h"
#define MAXINT INT_MAX
#define MININT INT_MIN
#define HEAD 2*sizeof(int)
#define SIZE(p) ((int *)(p))[-1]
...
...
contrib/tsearch2/ts_cfg.c
浏览文件 @
1d0d8d3c
...
...
@@ -113,6 +113,8 @@ init_cfg(Oid id, TSCfgInfo * cfg)
ts_error
(
ERROR
,
"Wrong dimension"
);
if
(
ARRNELEMS
(
a
)
<
1
)
continue
;
if
(
ARR_HASNULL
(
a
))
ts_error
(
ERROR
,
"Array must not contain nulls"
);
cfg
->
map
[
lexid
].
len
=
ARRNELEMS
(
a
);
cfg
->
map
[
lexid
].
dict_id
=
(
Datum
*
)
malloc
(
sizeof
(
Datum
)
*
cfg
->
map
[
lexid
].
len
);
...
...
src/backend/utils/adt/acl.c
浏览文件 @
1d0d8d3c
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.12
8 2005/11/17 22:14:52
tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.12
9 2005/11/18 02:38:23
tgl Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -67,6 +67,7 @@ static List *cached_membership_roles = NIL;
static
const
char
*
getid
(
const
char
*
s
,
char
*
n
);
static
void
putid
(
char
*
p
,
const
char
*
s
);
static
Acl
*
allocacl
(
int
n
);
static
void
check_acl
(
const
Acl
*
acl
);
static
const
char
*
aclparse
(
const
char
*
s
,
AclItem
*
aip
);
static
bool
aclitem_match
(
const
AclItem
*
a1
,
const
AclItem
*
a2
);
static
void
check_circularity
(
const
Acl
*
old_acl
,
const
AclItem
*
mod_aip
,
...
...
@@ -359,6 +360,26 @@ allocacl(int n)
return
new_acl
;
}
/*
* Verify that an ACL array is acceptable (one-dimensional and has no nulls)
*/
static
void
check_acl
(
const
Acl
*
acl
)
{
if
(
ARR_ELEMTYPE
(
acl
)
!=
ACLITEMOID
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"ACL array contains wrong datatype"
)));
if
(
ARR_NDIM
(
acl
)
!=
1
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"ACL arrays must be one-dimensional"
)));
if
(
ARR_HASNULL
(
acl
))
ereport
(
ERROR
,
(
errcode
(
ERRCODE_NULL_VALUE_NOT_ALLOWED
),
errmsg
(
"ACL arrays must not contain nulls"
)));
}
/*
* aclitemin
* Allocates storage for, and fills in, a new AclItem given a string
...
...
@@ -612,15 +633,8 @@ aclupdate(const Acl *old_acl, const AclItem *mod_aip,
int
dst
,
num
;
/* These checks for null input are probably dead code, but... */
if
(
!
old_acl
||
ACL_NUM
(
old_acl
)
<
0
)
old_acl
=
allocacl
(
0
);
if
(
!
mod_aip
)
{
new_acl
=
allocacl
(
ACL_NUM
(
old_acl
));
memcpy
(
new_acl
,
old_acl
,
ACL_SIZE
(
old_acl
));
return
new_acl
;
}
/* Caller probably already checked old_acl, but be safe */
check_acl
(
old_acl
);
/* If granting grant options, check for circularity */
if
(
modechg
!=
ACL_MODECHG_DEL
&&
...
...
@@ -740,6 +754,8 @@ aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
targ
,
num
;
check_acl
(
old_acl
);
/*
* Make a copy of the given ACL, substituting new owner ID for old
* wherever it appears as either grantor or grantee. Also note if the new
...
...
@@ -836,6 +852,8 @@ check_circularity(const Acl *old_acl, const AclItem *mod_aip,
num
;
AclMode
own_privs
;
check_acl
(
old_acl
);
/*
* For now, grant options can only be granted to roles, not PUBLIC.
* Otherwise we'd have to work a bit harder here.
...
...
@@ -916,6 +934,8 @@ recursive_revoke(Acl *acl,
int
i
,
num
;
check_acl
(
acl
);
/* The owner can never truly lose grant options, so short-circuit */
if
(
grantee
==
ownerId
)
return
acl
;
...
...
@@ -1005,6 +1025,8 @@ aclmask(const Acl *acl, Oid roleid, Oid ownerId,
if
(
acl
==
NULL
)
elog
(
ERROR
,
"null ACL"
);
check_acl
(
acl
);
/* Quick exit for mask == 0 */
if
(
mask
==
0
)
return
0
;
...
...
@@ -1091,6 +1113,8 @@ aclmask_direct(const Acl *acl, Oid roleid, Oid ownerId,
if
(
acl
==
NULL
)
elog
(
ERROR
,
"null ACL"
);
check_acl
(
acl
);
/* Quick exit for mask == 0 */
if
(
mask
==
0
)
return
0
;
...
...
@@ -1151,6 +1175,8 @@ aclmembers(const Acl *acl, Oid **roleids)
return
0
;
}
check_acl
(
acl
);
/* Allocate the worst-case space requirement */
list
=
palloc
(
ACL_NUM
(
acl
)
*
2
*
sizeof
(
Oid
));
acldat
=
ACL_DAT
(
acl
);
...
...
@@ -1240,6 +1266,7 @@ aclcontains(PG_FUNCTION_ARGS)
int
i
,
num
;
check_acl
(
acl
);
num
=
ACL_NUM
(
acl
);
aidat
=
ACL_DAT
(
acl
);
for
(
i
=
0
;
i
<
num
;
++
i
)
...
...
src/backend/utils/adt/varlena.c
浏览文件 @
1d0d8d3c
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.1
39 2005/10/29 00:31:51 petere
Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.1
40 2005/11/18 02:38:23 tgl
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -2491,16 +2491,18 @@ array_to_text(PG_FUNCTION_ARGS)
int
nitems
,
*
dims
,
ndims
;
char
*
p
;
Oid
element_type
;
int
typlen
;
bool
typbyval
;
char
typalign
;
StringInfo
result_str
=
makeStringInfo
();
bool
printed
=
false
;
char
*
p
;
bits8
*
bitmap
;
int
bitmask
;
int
i
;
ArrayMetaState
*
my_extra
;
p
=
ARR_DATA_PTR
(
v
);
ndims
=
ARR_NDIM
(
v
);
dims
=
ARR_DIMS
(
v
);
nitems
=
ArrayGetNItems
(
ndims
,
dims
);
...
...
@@ -2522,7 +2524,7 @@ array_to_text(PG_FUNCTION_ARGS)
fcinfo
->
flinfo
->
fn_extra
=
MemoryContextAlloc
(
fcinfo
->
flinfo
->
fn_mcxt
,
sizeof
(
ArrayMetaState
));
my_extra
=
(
ArrayMetaState
*
)
fcinfo
->
flinfo
->
fn_extra
;
my_extra
->
element_type
=
InvalidOid
;
my_extra
->
element_type
=
~
element_type
;
}
if
(
my_extra
->
element_type
!=
element_type
)
...
...
@@ -2542,23 +2544,47 @@ array_to_text(PG_FUNCTION_ARGS)
typbyval
=
my_extra
->
typbyval
;
typalign
=
my_extra
->
typalign
;
p
=
ARR_DATA_PTR
(
v
);
bitmap
=
ARR_NULLBITMAP
(
v
);
bitmask
=
1
;
for
(
i
=
0
;
i
<
nitems
;
i
++
)
{
Datum
itemvalue
;
char
*
value
;
itemvalue
=
fetch_att
(
p
,
typbyval
,
typlen
);
/* Get source element, checking for NULL */
if
(
bitmap
&&
(
*
bitmap
&
bitmask
)
==
0
)
{
/* we ignore nulls */
}
else
{
itemvalue
=
fetch_att
(
p
,
typbyval
,
typlen
);
value
=
DatumGetCString
(
FunctionCall1
(
&
my_extra
->
proc
,
itemvalue
));
value
=
DatumGetCString
(
FunctionCall1
(
&
my_extra
->
proc
,
itemvalue
));
if
(
i
>
0
)
appendStringInfo
(
result_str
,
"%s%s"
,
fldsep
,
value
);
else
appendStringInfoString
(
result_str
,
value
);
if
(
printed
)
appendStringInfo
(
result_str
,
"%s%s"
,
fldsep
,
value
);
else
appendStringInfoString
(
result_str
,
value
);
printed
=
true
;
p
=
att_addlength
(
p
,
typlen
,
PointerGetDatum
(
p
));
p
=
(
char
*
)
att_align
(
p
,
typalign
);
}
p
=
att_addlength
(
p
,
typlen
,
PointerGetDatum
(
p
));
p
=
(
char
*
)
att_align
(
p
,
typalign
);
/* advance bitmap pointer if any */
if
(
bitmap
)
{
bitmask
<<=
1
;
if
(
bitmask
==
0x100
)
{
bitmap
++
;
bitmask
=
1
;
}
}
}
PG_RETURN_TEXT_P
(
PG_STR_GET_TEXT
(
result_str
->
data
));
...
...
src/include/utils/acl.h
浏览文件 @
1d0d8d3c
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.8
7 2005/11/17 22:14:55
tgl Exp $
* $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.8
8 2005/11/18 02:38:24
tgl Exp $
*
* NOTES
* An ACL array is simply an array of AclItems, representing the union
...
...
@@ -78,9 +78,9 @@ typedef struct AclItem
#define ACLITEM_ALL_GOPTION_BITS ((AclMode) 0xFFFF << 16)
/*
* Definitions for convenient access to Acl (array of AclItem)
and IdList
*
(array of Oid). These are standard PostgreSQL arrays, but are restricted
*
to have one dimension
. We also ignore the lower bound when reading,
* Definitions for convenient access to Acl (array of AclItem)
.
*
These are standard PostgreSQL arrays, but are restricted to have one
*
dimension and no nulls
. We also ignore the lower bound when reading,
* and set it to one when writing.
*
* CAUTION: as of PostgreSQL 7.1, these arrays are toastable (just like all
...
...
@@ -100,16 +100,6 @@ typedef ArrayType Acl;
#define ACL_N_SIZE(N) (ARR_OVERHEAD_NONULLS(1) + ((N) * sizeof(AclItem)))
#define ACL_SIZE(ACL) ARR_SIZE(ACL)
/*
* IdList a one-dimensional array of Oid
*/
typedef
ArrayType
IdList
;
#define IDLIST_NUM(IDL) (ARR_DIMS(IDL)[0])
#define IDLIST_DAT(IDL) ((Oid *) ARR_DATA_PTR(IDL))
#define IDLIST_N_SIZE(N) (ARR_OVERHEAD_NONULLS(1) + ((N) * sizeof(Oid)))
#define IDLIST_SIZE(IDL) ARR_SIZE(IDL)
/*
* fmgr macros for these types
*/
...
...
@@ -123,13 +113,6 @@ typedef ArrayType IdList;
#define PG_GETARG_ACL_P_COPY(n) DatumGetAclPCopy(PG_GETARG_DATUM(n))
#define PG_RETURN_ACL_P(x) PG_RETURN_POINTER(x)
#define DatumGetIdListP(X) ((IdList *) PG_DETOAST_DATUM(X))
#define DatumGetIdListPCopy(X) ((IdList *) PG_DETOAST_DATUM_COPY(X))
#define PG_GETARG_IDLIST_P(n) DatumGetIdListP(PG_GETARG_DATUM(n))
#define PG_GETARG_IDLIST_P_COPY(n) DatumGetIdListPCopy(PG_GETARG_DATUM(n))
#define PG_RETURN_IDLIST_P(x) PG_RETURN_POINTER(x)
/*
* ACL modification opcodes for aclupdate
*/
...
...
src/pl/plpgsql/src/pl_exec.c
浏览文件 @
1d0d8d3c
...
...
@@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.15
5 2005/11/17 22:14:55
tgl Exp $
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.15
6 2005/11/18 02:38:24
tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
...
...
@@ -3241,8 +3241,7 @@ exec_assign_value(PLpgSQL_execstate * estate,
int
i
;
PLpgSQL_expr
*
subscripts
[
MAXDIM
];
int
subscriptvals
[
MAXDIM
];
bool
havenullsubscript
,
oldarrayisnull
;
bool
oldarrayisnull
;
Oid
arraytypeid
,
arrayelemtypeid
;
int16
arraytyplen
,
...
...
@@ -3295,9 +3294,9 @@ exec_assign_value(PLpgSQL_execstate * estate,
arraytyplen
=
get_typlen
(
arraytypeid
);
/*
* Evaluate the subscripts, switch into left-to-right order
* Evaluate the subscripts, switch into left-to-right order.
* Like ExecEvalArrayRef(), complain if any subscript is null.
*/
havenullsubscript
=
false
;
for
(
i
=
0
;
i
<
nsubscripts
;
i
++
)
{
bool
subisnull
;
...
...
@@ -3306,43 +3305,39 @@ exec_assign_value(PLpgSQL_execstate * estate,
exec_eval_integer
(
estate
,
subscripts
[
nsubscripts
-
1
-
i
],
&
subisnull
);
havenullsubscript
|=
subisnull
;
if
(
subisnull
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_NULL_VALUE_NOT_ALLOWED
),
errmsg
(
"array subscript in assignment must not be NULL"
)));
}
/*
* Skip the assignment if we have any nulls in the subscripts
* or the righthand side. This is pretty bogus but it
* corresponds to the current behavior of ExecEvalArrayRef().
*/
if
(
havenullsubscript
||
*
isNull
)
return
;
/* Coerce source value to match array element type. */
coerced_value
=
exec_simple_cast_value
(
value
,
valtype
,
arrayelemtypeid
,
-
1
,
*
isNull
);
/*
* If the original array is null, cons up an empty array so
* that the assignment can proceed; we'll end with a
* one-element array containing just the assigned-to
* subscript. This only works for varlena arrays, though; for
* fixed-length array types we skip the assignment. Again,
* this corresponds to the current behavior of
* fixed-length array types we skip the assignment. We can't
* support assignment of a null entry into a fixed-length
* array, either, so that's a no-op too. This is all ugly
* but corresponds to the current behavior of
* ExecEvalArrayRef().
*/
if
(
oldarrayisnull
)
{
if
(
arraytyplen
>
0
)
/* fixed-length array? */
return
;
if
(
arraytyplen
>
0
&&
/* fixed-length array? */
(
oldarrayisnull
||
*
isNull
))
return
;
if
(
oldarrayisnull
)
oldarrayval
=
construct_empty_array
(
arrayelemtypeid
);
}
else
oldarrayval
=
(
ArrayType
*
)
DatumGetPointer
(
oldarraydatum
);
/* Coerce source value to match array element type. */
coerced_value
=
exec_simple_cast_value
(
value
,
valtype
,
arrayelemtypeid
,
-
1
,
*
isNull
);
/*
* Build the modified array value.
*/
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录