Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Gpdb
提交
2c773296
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,发现更多精彩内容 >>
提交
2c773296
编写于
7月 16, 2008
作者:
B
Bruce Momjian
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add array_fill() to create arrays initialized with a value.
Pavel Stehule
上级
2fa42cc9
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
371 addition
and
8 deletion
+371
-8
doc/src/sgml/func.sgml
doc/src/sgml/func.sgml
+14
-1
src/backend/utils/adt/arrayfuncs.c
src/backend/utils/adt/arrayfuncs.c
+275
-1
src/include/catalog/catversion.h
src/include/catalog/catversion.h
+2
-2
src/include/catalog/pg_proc.h
src/include/catalog/pg_proc.h
+5
-3
src/include/utils/array.h
src/include/utils/array.h
+3
-1
src/test/regress/expected/arrays.out
src/test/regress/expected/arrays.out
+58
-0
src/test/regress/sql/arrays.sql
src/test/regress/sql/arrays.sql
+14
-0
未找到文件。
doc/src/sgml/func.sgml
浏览文件 @
2c773296
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.44
0 2008/07/15 18:24:59
momjian Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.44
1 2008/07/16 00:48:53
momjian Exp $ -->
<chapter
id=
"functions"
>
<title>
Functions and Operators
</title>
...
...
@@ -9371,6 +9371,19 @@ SELECT NULLIF(value, '(none)') ...
<entry><literal>
array_dims(ARRAY[[1,2,3], [4,5,6]])
</literal></entry>
<entry><literal>
[1:2][1:3]
</literal></entry>
</row>
<row>
<entry>
<literal>
<function>
array_fill
</function>
(
<type>
anyelement
</type>
,
<type>
anyarray
</type>
,
<optional>
,
<type>
anyarray
</type></optional>
)
</literal>
</entry>
<entry><type>
anyarray
</type></entry>
<entry>
returns an array initialized with supplied value,
dimensions, and lower bounds
</entry>
<entry><literal>
array_fill(7, ARRAY[3], ARRAY[2])
</literal></entry>
<entry><literal>
[2:4]={7,7,7}
</literal></entry>
</row>
<row>
<entry>
<literal>
...
...
src/backend/utils/adt/arrayfuncs.c
浏览文件 @
2c773296
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.14
5 2008/05/12 00:00:51 alvherre
Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.14
6 2008/07/16 00:48:53 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -95,6 +95,11 @@ static void array_insert_slice(ArrayType *destArray, ArrayType *origArray,
int
*
st
,
int
*
endp
,
int
typlen
,
bool
typbyval
,
char
typalign
);
static
int
array_cmp
(
FunctionCallInfo
fcinfo
);
static
ArrayType
*
create_array_envelope
(
int
ndims
,
int
*
dimv
,
int
*
lbv
,
int
nbytes
,
Oid
elmtype
,
int
dataoffset
);
static
ArrayType
*
array_fill_internal
(
ArrayType
*
dims
,
ArrayType
*
lbs
,
Datum
value
,
Oid
elmtype
,
bool
isnull
,
FunctionCallInfo
fcinfo
);
/*
...
...
@@ -4314,3 +4319,272 @@ generate_subscripts_nodir(PG_FUNCTION_ARGS)
/* just call the other one -- it can handle both cases */
return
generate_subscripts
(
fcinfo
);
}
/*
* array_fill_with_lower_bounds
* Create and fill array with defined lower bounds.
*/
Datum
array_fill_with_lower_bounds
(
PG_FUNCTION_ARGS
)
{
ArrayType
*
dims
;
ArrayType
*
lbs
;
ArrayType
*
result
;
Oid
elmtype
;
Datum
value
;
bool
isnull
;
if
(
PG_ARGISNULL
(
1
)
||
PG_ARGISNULL
(
2
))
ereport
(
ERROR
,
(
errcode
(
ERRCODE_NULL_VALUE_NOT_ALLOWED
),
errmsg
(
"dimension array or low bound array cannot be NULL"
)));
dims
=
PG_GETARG_ARRAYTYPE_P
(
1
);
lbs
=
PG_GETARG_ARRAYTYPE_P
(
2
);
if
(
!
PG_ARGISNULL
(
0
))
{
value
=
PG_GETARG_DATUM
(
0
);
isnull
=
false
;
}
else
{
value
=
0
;
isnull
=
true
;
}
elmtype
=
get_fn_expr_argtype
(
fcinfo
->
flinfo
,
0
);
if
(
!
OidIsValid
(
elmtype
))
elog
(
ERROR
,
"could not determine data type of input"
);
result
=
array_fill_internal
(
dims
,
lbs
,
value
,
elmtype
,
isnull
,
fcinfo
);
PG_RETURN_ARRAYTYPE_P
(
result
);
}
/*
* array_fill
* Create and fill array with default lower bounds.
*/
Datum
array_fill
(
PG_FUNCTION_ARGS
)
{
ArrayType
*
dims
;
ArrayType
*
result
;
Oid
elmtype
;
Datum
value
;
bool
isnull
;
if
(
PG_ARGISNULL
(
1
))
ereport
(
ERROR
,
(
errcode
(
ERRCODE_NULL_VALUE_NOT_ALLOWED
),
errmsg
(
"dimension array or low bound array cannot be NULL"
)));
dims
=
PG_GETARG_ARRAYTYPE_P
(
1
);
if
(
!
PG_ARGISNULL
(
0
))
{
value
=
PG_GETARG_DATUM
(
0
);
isnull
=
false
;
}
else
{
value
=
0
;
isnull
=
true
;
}
elmtype
=
get_fn_expr_argtype
(
fcinfo
->
flinfo
,
0
);
if
(
!
OidIsValid
(
elmtype
))
elog
(
ERROR
,
"could not determine data type of input"
);
result
=
array_fill_internal
(
dims
,
NULL
,
value
,
elmtype
,
isnull
,
fcinfo
);
PG_RETURN_ARRAYTYPE_P
(
result
);
}
static
ArrayType
*
create_array_envelope
(
int
ndims
,
int
*
dimv
,
int
*
lbsv
,
int
nbytes
,
Oid
elmtype
,
int
dataoffset
)
{
ArrayType
*
result
;
result
=
(
ArrayType
*
)
palloc0
(
nbytes
);
SET_VARSIZE
(
result
,
nbytes
);
result
->
ndim
=
ndims
;
result
->
dataoffset
=
dataoffset
;
result
->
elemtype
=
elmtype
;
memcpy
(
ARR_DIMS
(
result
),
dimv
,
ndims
*
sizeof
(
int
));
memcpy
(
ARR_LBOUND
(
result
),
lbsv
,
ndims
*
sizeof
(
int
));
return
result
;
}
static
ArrayType
*
array_fill_internal
(
ArrayType
*
dims
,
ArrayType
*
lbs
,
Datum
value
,
Oid
elmtype
,
bool
isnull
,
FunctionCallInfo
fcinfo
)
{
ArrayType
*
result
;
int
*
dimv
;
int
*
lbsv
;
int
ndims
;
int
nitems
;
int
deflbs
[
MAXDIM
];
int16
elmlen
;
bool
elmbyval
;
char
elmalign
;
ArrayMetaState
*
my_extra
;
/*
* Params checks
*/
if
(
ARR_NDIM
(
dims
)
!=
1
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_ARRAY_SUBSCRIPT_ERROR
),
errmsg
(
"wrong number of array subscripts"
),
errhint
(
"Dimension array must be one dimensional."
)));
if
(
ARR_LBOUND
(
dims
)[
0
]
!=
1
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_ARRAY_SUBSCRIPT_ERROR
),
errmsg
(
"wrong range of array_subscripts"
),
errhint
(
"Lower bound of dimension array must be one."
)));
if
(
ARR_HASNULL
(
dims
))
ereport
(
ERROR
,
(
errcode
(
ERRCODE_NULL_VALUE_NOT_ALLOWED
),
errmsg
(
"dimension values cannot be null"
)));
dimv
=
(
int
*
)
ARR_DATA_PTR
(
dims
);
ndims
=
ARR_DIMS
(
dims
)[
0
];
if
(
ndims
<
0
)
/* we do allow zero-dimension arrays */
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"invalid number of dimensions: %d"
,
ndims
)));
if
(
ndims
>
MAXDIM
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_PROGRAM_LIMIT_EXCEEDED
),
errmsg
(
"number of array dimensions (%d) exceeds the maximum allowed (%d)"
,
ndims
,
MAXDIM
)));
if
(
lbs
!=
NULL
)
{
if
(
ARR_NDIM
(
lbs
)
!=
1
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_ARRAY_SUBSCRIPT_ERROR
),
errmsg
(
"wrong number of array subscripts"
),
errhint
(
"Dimension array must be one dimensional."
)));
if
(
ARR_LBOUND
(
lbs
)[
0
]
!=
1
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_ARRAY_SUBSCRIPT_ERROR
),
errmsg
(
"wrong range of array_subscripts"
),
errhint
(
"Lower bound of dimension array must be one."
)));
if
(
ARR_HASNULL
(
lbs
))
ereport
(
ERROR
,
(
errcode
(
ERRCODE_NULL_VALUE_NOT_ALLOWED
),
errmsg
(
"dimension values cannot be null"
)));
if
(
ARR_DIMS
(
lbs
)[
0
]
!=
ndims
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_ARRAY_SUBSCRIPT_ERROR
),
errmsg
(
"wrong number of array_subscripts"
),
errhint
(
"Low bound array has different size than dimensions array."
)));
lbsv
=
(
int
*
)
ARR_DATA_PTR
(
lbs
);
}
else
{
int
i
;
for
(
i
=
0
;
i
<
MAXDIM
;
i
++
)
deflbs
[
i
]
=
1
;
lbsv
=
deflbs
;
}
/* fast track for empty array */
if
(
ndims
==
0
)
return
construct_empty_array
(
elmtype
);
nitems
=
ArrayGetNItems
(
ndims
,
dimv
);
/*
* We arrange to look up info about element type only once per series of
* calls, assuming the element type doesn't change underneath us.
*/
my_extra
=
(
ArrayMetaState
*
)
fcinfo
->
flinfo
->
fn_extra
;
if
(
my_extra
==
NULL
)
{
fcinfo
->
flinfo
->
fn_extra
=
MemoryContextAlloc
(
fcinfo
->
flinfo
->
fn_mcxt
,
sizeof
(
ArrayMetaState
));
my_extra
=
(
ArrayMetaState
*
)
fcinfo
->
flinfo
->
fn_extra
;
my_extra
->
element_type
=
InvalidOid
;
}
if
(
my_extra
->
element_type
!=
elmtype
)
{
/* Get info about element type */
get_typlenbyvalalign
(
elmtype
,
&
my_extra
->
typlen
,
&
my_extra
->
typbyval
,
&
my_extra
->
typalign
);
my_extra
->
element_type
=
elmtype
;
}
elmlen
=
my_extra
->
typlen
;
elmbyval
=
my_extra
->
typbyval
;
elmalign
=
my_extra
->
typalign
;
/* compute required space */
if
(
!
isnull
)
{
int
i
;
char
*
p
;
int
nbytes
;
Datum
aux_value
=
value
;
/* make sure data is not toasted */
if
(
elmlen
==
-
1
)
value
=
PointerGetDatum
(
PG_DETOAST_DATUM
(
value
));
nbytes
=
att_addlength_datum
(
0
,
elmlen
,
value
);
nbytes
=
att_align_nominal
(
nbytes
,
elmalign
);
nbytes
*=
nitems
;
/* check for overflow of total request */
if
(
!
AllocSizeIsValid
(
nbytes
))
ereport
(
ERROR
,
(
errcode
(
ERRCODE_PROGRAM_LIMIT_EXCEEDED
),
errmsg
(
"array size exceeds the maximum allowed (%d)"
,
(
int
)
MaxAllocSize
)));
nbytes
+=
ARR_OVERHEAD_NONULLS
(
ndims
);
result
=
create_array_envelope
(
ndims
,
dimv
,
lbsv
,
nbytes
,
elmtype
,
0
);
p
=
ARR_DATA_PTR
(
result
);
for
(
i
=
0
;
i
<
nitems
;
i
++
)
p
+=
ArrayCastAndSet
(
value
,
elmlen
,
elmbyval
,
elmalign
,
p
);
/* cleaning up detoasted copies of datum */
if
(
aux_value
!=
value
)
pfree
((
Pointer
)
value
);
}
else
{
int
nbytes
;
int
dataoffset
;
bits8
*
bitmap
;
dataoffset
=
ARR_OVERHEAD_WITHNULLS
(
ndims
,
nitems
);
nbytes
=
dataoffset
;
result
=
create_array_envelope
(
ndims
,
dimv
,
lbsv
,
nbytes
,
elmtype
,
dataoffset
);
bitmap
=
ARR_NULLBITMAP
(
result
);
MemSet
(
bitmap
,
0
,
(
nitems
+
7
)
/
8
);
}
return
result
;
}
src/include/catalog/catversion.h
浏览文件 @
2c773296
...
...
@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.46
7 2008/07/14 00:51:45 tgl
Exp $
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.46
8 2008/07/16 00:48:53 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 2008071
3
1
#define CATALOG_VERSION_NO 2008071
5
1
#endif
src/include/catalog/pg_proc.h
浏览文件 @
2c773296
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.50
5 2008/07/14 00:51:45 tgl
Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.50
6 2008/07/16 00:48:53 momjian
Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
...
...
@@ -1010,8 +1010,10 @@ DATA(insert OID = 1191 ( generate_subscripts PGNSP PGUID 12 1 1000 f f t t i 3
DESCR
(
"array subscripts generator"
);
DATA
(
insert
OID
=
1192
(
generate_subscripts
PGNSP
PGUID
12
1
1000
f
f
t
t
i
2
23
"2277 23"
_null_
_null_
_null_
generate_subscripts_nodir
-
_null_
_null_
));
DESCR
(
"array subscripts generator"
);
DATA
(
insert
OID
=
1193
(
array_fill
PGNSP
PGUID
12
1
0
f
f
f
f
i
2
2277
"2283 1007"
_null_
_null_
_null_
array_fill
-
_null_
_null_
));
DESCR
(
"array constructor with value"
);
DATA
(
insert
OID
=
1286
(
array_fill
PGNSP
PGUID
12
1
0
f
f
f
f
i
3
2277
"2283 1007 1007"
_null_
_null_
_null_
array_fill_with_lower_bounds
-
_null_
_null_
));
DESCR
(
"array constructor with value"
);
DATA
(
insert
OID
=
760
(
smgrin
PGNSP
PGUID
12
1
0
f
f
t
f
s
1
210
"2275"
_null_
_null_
_null_
smgrin
-
_null_
_null_
));
DESCR
(
"I/O"
);
DATA
(
insert
OID
=
761
(
smgrout
PGNSP
PGUID
12
1
0
f
f
t
f
s
1
2275
"210"
_null_
_null_
_null_
smgrout
-
_null_
_null_
));
...
...
src/include/utils/array.h
浏览文件 @
2c773296
...
...
@@ -49,7 +49,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/array.h,v 1.6
7 2008/04/28 14:48:57 alvherre
Exp $
* $PostgreSQL: pgsql/src/include/utils/array.h,v 1.6
8 2008/07/16 00:48:54 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -202,6 +202,8 @@ extern Datum array_larger(PG_FUNCTION_ARGS);
extern
Datum
array_smaller
(
PG_FUNCTION_ARGS
);
extern
Datum
generate_subscripts
(
PG_FUNCTION_ARGS
);
extern
Datum
generate_subscripts_nodir
(
PG_FUNCTION_ARGS
);
extern
Datum
array_fill
(
PG_FUNCTION_ARGS
);
extern
Datum
array_fill_with_lower_bounds
(
PG_FUNCTION_ARGS
);
extern
Datum
array_ref
(
ArrayType
*
array
,
int
nSubscripts
,
int
*
indx
,
int
arraytyplen
,
int
elmlen
,
bool
elmbyval
,
char
elmalign
,
...
...
src/test/regress/expected/arrays.out
浏览文件 @
2c773296
...
...
@@ -933,3 +933,61 @@ select * from unnest2(array[[1,2,3],[4,5,6]]);
drop function unnest1(anyarray);
drop function unnest2(anyarray);
select array_fill(null::integer, array[3,3],array[2,2]);
array_fill
-----------------------------------------------------------------
[2:4][2:4]={{NULL,NULL,NULL},{NULL,NULL,NULL},{NULL,NULL,NULL}}
(1 row)
select array_fill(null::integer, array[3,3]);
array_fill
------------------------------------------------------
{{NULL,NULL,NULL},{NULL,NULL,NULL},{NULL,NULL,NULL}}
(1 row)
select array_fill(null::text, array[3,3],array[2,2]);
array_fill
-----------------------------------------------------------------
[2:4][2:4]={{NULL,NULL,NULL},{NULL,NULL,NULL},{NULL,NULL,NULL}}
(1 row)
select array_fill(null::text, array[3,3]);
array_fill
------------------------------------------------------
{{NULL,NULL,NULL},{NULL,NULL,NULL},{NULL,NULL,NULL}}
(1 row)
select array_fill(7, array[3,3],array[2,2]);
array_fill
--------------------------------------
[2:4][2:4]={{7,7,7},{7,7,7},{7,7,7}}
(1 row)
select array_fill(7, array[3,3]);
array_fill
---------------------------
{{7,7,7},{7,7,7},{7,7,7}}
(1 row)
select array_fill('juhu'::text, array[3,3],array[2,2]);
array_fill
-----------------------------------------------------------------
[2:4][2:4]={{juhu,juhu,juhu},{juhu,juhu,juhu},{juhu,juhu,juhu}}
(1 row)
select array_fill('juhu'::text, array[3,3]);
array_fill
------------------------------------------------------
{{juhu,juhu,juhu},{juhu,juhu,juhu},{juhu,juhu,juhu}}
(1 row)
-- raise exception
select array_fill(1, null, array[2,2]);
ERROR: dimension array or low bound array cannot be NULL
select array_fill(1, array[2,2], null);
ERROR: dimension array or low bound array cannot be NULL
select array_fill(1, array[3,3], array[1,1,1]);
ERROR: wrong number of array_subscripts
HINT: Low bound array has different size than dimensions array.
select array_fill(1, array[1,2,null]);
ERROR: dimension values cannot be null
src/test/regress/sql/arrays.sql
浏览文件 @
2c773296
...
...
@@ -357,3 +357,17 @@ select * from unnest2(array[[1,2,3],[4,5,6]]);
drop
function
unnest1
(
anyarray
);
drop
function
unnest2
(
anyarray
);
select
array_fill
(
null
::
integer
,
array
[
3
,
3
],
array
[
2
,
2
]);
select
array_fill
(
null
::
integer
,
array
[
3
,
3
]);
select
array_fill
(
null
::
text
,
array
[
3
,
3
],
array
[
2
,
2
]);
select
array_fill
(
null
::
text
,
array
[
3
,
3
]);
select
array_fill
(
7
,
array
[
3
,
3
],
array
[
2
,
2
]);
select
array_fill
(
7
,
array
[
3
,
3
]);
select
array_fill
(
'juhu'
::
text
,
array
[
3
,
3
],
array
[
2
,
2
]);
select
array_fill
(
'juhu'
::
text
,
array
[
3
,
3
]);
-- raise exception
select
array_fill
(
1
,
null
,
array
[
2
,
2
]);
select
array_fill
(
1
,
array
[
2
,
2
],
null
);
select
array_fill
(
1
,
array
[
3
,
3
],
array
[
1
,
1
,
1
]);
select
array_fill
(
1
,
array
[
1
,
2
,
null
]);
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录