Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Gpdb
提交
1871c892
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,发现更多精彩内容 >>
提交
1871c892
编写于
11月 11, 2014
作者:
F
Fujii Masao
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add generate_series(numeric, numeric).
Платон Малюгин Reviewed by Michael Paquier, Ali Akbar and Marti Raudsepp
上级
a1b395b6
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
212 addition
and
5 deletion
+212
-5
doc/src/sgml/func.sgml
doc/src/sgml/func.sgml
+12
-4
src/backend/utils/adt/numeric.c
src/backend/utils/adt/numeric.c
+124
-0
src/include/catalog/catversion.h
src/include/catalog/catversion.h
+1
-1
src/include/catalog/pg_proc.h
src/include/catalog/pg_proc.h
+4
-0
src/include/utils/builtins.h
src/include/utils/builtins.h
+2
-0
src/test/regress/expected/numeric.out
src/test/regress/expected/numeric.out
+52
-0
src/test/regress/sql/numeric.sql
src/test/regress/sql/numeric.sql
+17
-0
未找到文件。
doc/src/sgml/func.sgml
浏览文件 @
1871c892
...
...
@@ -14076,8 +14076,8 @@ AND
<tbody>
<row>
<entry><literal><function>generate_series(<parameter>start</parameter>, <parameter>stop</parameter>)</function></literal></entry>
<entry><type>int</type>
or <type>bigint
</type></entry>
<entry><type>setof int</type>
or <type>setof bigint
</type> (same as argument type)</entry>
<entry><type>int</type>
, <type>bigint</type> or <type>numeric
</type></entry>
<entry><type>setof int</type>
, <type>setof bigint</type>, or <type>setof numeric
</type> (same as argument type)</entry>
<entry>
Generate a series of values, from <parameter>start</parameter> to <parameter>stop</parameter>
with a step size of one
...
...
@@ -14086,8 +14086,8 @@ AND
<row>
<entry><literal><function>generate_series(<parameter>start</parameter>, <parameter>stop</parameter>, <parameter>step</parameter>)</function></literal></entry>
<entry><type>int</type>
or <type>bigint
</type></entry>
<entry><type>setof int</type>
or <type>setof bigint
</type> (same as argument type)</entry>
<entry><type>int</type>
, <type>bigint</type> or <type>numeric
</type></entry>
<entry><type>setof int</type>
, <type>setof bigint</type> or <type>setof numeric
</type> (same as argument type)</entry>
<entry>
Generate a series of values, from <parameter>start</parameter> to <parameter>stop</parameter>
with a step size of <parameter>step</parameter>
...
...
@@ -14137,6 +14137,14 @@ SELECT * FROM generate_series(4,3);
-----------------
(0 rows)
SELECT generate_series(1.1, 4, 1.3);
generate_series
-----------------
1.1
2.4
3.7
(3 rows)
-- this example relies on the date-plus-integer operator
SELECT current_date + s.a AS dates FROM generate_series(0,14,7) AS s(a);
dates
...
...
src/backend/utils/adt/numeric.c
浏览文件 @
1871c892
...
...
@@ -28,6 +28,7 @@
#include "access/hash.h"
#include "catalog/pg_type.h"
#include "funcapi.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
#include "nodes/nodeFuncs.h"
...
...
@@ -260,6 +261,18 @@ typedef struct NumericVar
}
NumericVar
;
/* ----------
* Data for generate_series
* ----------
*/
typedef
struct
{
NumericVar
current
;
NumericVar
stop
;
NumericVar
step
;
}
generate_series_numeric_fctx
;
/* ----------
* Some preinitialized constants
* ----------
...
...
@@ -1229,6 +1242,117 @@ numeric_floor(PG_FUNCTION_ARGS)
PG_RETURN_NUMERIC
(
res
);
}
/*
* generate_series_numeric() -
*
* Generate series of numeric.
*/
Datum
generate_series_numeric
(
PG_FUNCTION_ARGS
)
{
return
generate_series_step_numeric
(
fcinfo
);
}
Datum
generate_series_step_numeric
(
PG_FUNCTION_ARGS
)
{
generate_series_numeric_fctx
*
fctx
;
FuncCallContext
*
funcctx
;
MemoryContext
oldcontext
;
if
(
SRF_IS_FIRSTCALL
())
{
Numeric
start_num
=
PG_GETARG_NUMERIC
(
0
);
Numeric
stop_num
=
PG_GETARG_NUMERIC
(
1
);
NumericVar
steploc
=
const_one
;
/* handle NaN in start and stop values */
if
(
NUMERIC_IS_NAN
(
start_num
))
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"start value cannot be NaN"
)));
if
(
NUMERIC_IS_NAN
(
stop_num
))
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"stop value cannot be NaN"
)));
/* see if we were given an explicit step size */
if
(
PG_NARGS
()
==
3
)
{
Numeric
step_num
=
PG_GETARG_NUMERIC
(
2
);
if
(
NUMERIC_IS_NAN
(
step_num
))
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"step size cannot be NaN"
)));
init_var_from_num
(
step_num
,
&
steploc
);
if
(
cmp_var
(
&
steploc
,
&
const_zero
)
==
0
)
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"step size cannot equal zero"
)));
}
/* create a function context for cross-call persistence */
funcctx
=
SRF_FIRSTCALL_INIT
();
/*
* Switch to memory context appropriate for multiple function calls.
*/
oldcontext
=
MemoryContextSwitchTo
(
funcctx
->
multi_call_memory_ctx
);
/* allocate memory for user context */
fctx
=
(
generate_series_numeric_fctx
*
)
palloc
(
sizeof
(
generate_series_numeric_fctx
));
/*
* Use fctx to keep state from call to call. Seed current with the
* original start value.
*/
init_var_from_num
(
start_num
,
&
fctx
->
current
);
init_var_from_num
(
stop_num
,
&
fctx
->
stop
);
init_var
(
&
fctx
->
step
);
set_var_from_var
(
&
steploc
,
&
fctx
->
step
);
funcctx
->
user_fctx
=
fctx
;
MemoryContextSwitchTo
(
oldcontext
);
}
/* stuff done on every call of the function */
funcctx
=
SRF_PERCALL_SETUP
();
/*
* Get the saved state and use current state as the result of this
* iteration.
*/
fctx
=
funcctx
->
user_fctx
;
if
((
fctx
->
step
.
sign
==
NUMERIC_POS
&&
cmp_var
(
&
fctx
->
current
,
&
fctx
->
stop
)
<=
0
)
||
(
fctx
->
step
.
sign
==
NUMERIC_NEG
&&
cmp_var
(
&
fctx
->
current
,
&
fctx
->
stop
)
>=
0
))
{
Numeric
result
=
make_result
(
&
fctx
->
current
);
/* switch to memory context appropriate for iteration calculation */
oldcontext
=
MemoryContextSwitchTo
(
funcctx
->
multi_call_memory_ctx
);
/* increment current in preparation for next iteration */
add_var
(
&
fctx
->
current
,
&
fctx
->
step
,
&
fctx
->
current
);
MemoryContextSwitchTo
(
oldcontext
);
/* do when there is more left to send */
SRF_RETURN_NEXT
(
funcctx
,
NumericGetDatum
(
result
));
}
else
/* do when there is no more left */
SRF_RETURN_DONE
(
funcctx
);
}
/*
* Implements the numeric version of the width_bucket() function
* defined by SQL2003. See also width_bucket_float8().
...
...
src/include/catalog/catversion.h
浏览文件 @
1871c892
...
...
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 201411
07
1
#define CATALOG_VERSION_NO 201411
11
1
#endif
src/include/catalog/pg_proc.h
浏览文件 @
1871c892
...
...
@@ -3952,6 +3952,10 @@ DATA(insert OID = 1068 ( generate_series PGNSP PGUID 12 1 1000 0 0 f f f f t t
DESCR
(
"non-persistent series generator"
);
DATA
(
insert
OID
=
1069
(
generate_series
PGNSP
PGUID
12
1
1000
0
0
f
f
f
f
t
t
i
2
0
20
"20 20"
_null_
_null_
_null_
_null_
generate_series_int8
_null_
_null_
_null_
));
DESCR
(
"non-persistent series generator"
);
DATA
(
insert
OID
=
3259
(
generate_series
PGNSP
PGUID
12
1
1000
0
0
f
f
f
f
t
t
i
3
0
1700
"1700 1700 1700"
_null_
_null_
_null_
_null_
generate_series_step_numeric
_null_
_null_
_null_
));
DESCR
(
"non-persistent series generator"
);
DATA
(
insert
OID
=
3260
(
generate_series
PGNSP
PGUID
12
1
1000
0
0
f
f
f
f
t
t
i
2
0
1700
"1700 1700"
_null_
_null_
_null_
_null_
generate_series_numeric
_null_
_null_
_null_
));
DESCR
(
"non-persistent series generator"
);
DATA
(
insert
OID
=
938
(
generate_series
PGNSP
PGUID
12
1
1000
0
0
f
f
f
f
t
t
i
3
0
1114
"1114 1114 1186"
_null_
_null_
_null_
_null_
generate_series_timestamp
_null_
_null_
_null_
));
DESCR
(
"non-persistent series generator"
);
DATA
(
insert
OID
=
939
(
generate_series
PGNSP
PGUID
12
1
1000
0
0
f
f
f
f
t
t
s
3
0
1184
"1184 1184 1186"
_null_
_null_
_null_
_null_
generate_series_timestamptz
_null_
_null_
_null_
));
...
...
src/include/utils/builtins.h
浏览文件 @
1871c892
...
...
@@ -1029,6 +1029,8 @@ extern Datum int8_avg(PG_FUNCTION_ARGS);
extern
Datum
int2int4_sum
(
PG_FUNCTION_ARGS
);
extern
Datum
width_bucket_numeric
(
PG_FUNCTION_ARGS
);
extern
Datum
hash_numeric
(
PG_FUNCTION_ARGS
);
extern
Datum
generate_series_numeric
(
PG_FUNCTION_ARGS
);
extern
Datum
generate_series_step_numeric
(
PG_FUNCTION_ARGS
);
/* ri_triggers.c */
extern
Datum
RI_FKey_check_ins
(
PG_FUNCTION_ARGS
);
...
...
src/test/regress/expected/numeric.out
浏览文件 @
1871c892
...
...
@@ -1409,3 +1409,55 @@ select 10.0 ^ 2147483647 as overflows;
ERROR: value overflows numeric format
select 117743296169.0 ^ 1000000000 as overflows;
ERROR: value overflows numeric format
--
-- Tests for generate_series
--
select * from generate_series(0.0::numeric, 4.0::numeric);
generate_series
-----------------
0.0
1.0
2.0
3.0
4.0
(5 rows)
select * from generate_series(0.1::numeric, 4.0::numeric, 1.3::numeric);
generate_series
-----------------
0.1
1.4
2.7
4.0
(4 rows)
select * from generate_series(4.0::numeric, -1.5::numeric, -2.2::numeric);
generate_series
-----------------
4.0
1.8
-0.4
(3 rows)
-- Trigger errors
select * from generate_series(-100::numeric, 100::numeric, 0::numeric);
ERROR: step size cannot equal zero
select * from generate_series(-100::numeric, 100::numeric, 'nan'::numeric);
ERROR: step size cannot be NaN
select * from generate_series('nan'::numeric, 100::numeric, 10::numeric);
ERROR: start value cannot be NaN
select * from generate_series(0::numeric, 'nan'::numeric, 10::numeric);
ERROR: stop value cannot be NaN
-- Checks maximum, output is truncated
select (i / (10::numeric ^ 131071))::numeric(1,0)
from generate_series(6 * (10::numeric ^ 131071),
9 * (10::numeric ^ 131071),
10::numeric ^ 131071) as a(i);
numeric
---------
6
7
8
9
(4 rows)
src/test/regress/sql/numeric.sql
浏览文件 @
1871c892
...
...
@@ -837,3 +837,20 @@ select 10.0 ^ -2147483648 as rounds_to_zero;
select
10
.
0
^
-
2147483647
as
rounds_to_zero
;
select
10
.
0
^
2147483647
as
overflows
;
select
117743296169
.
0
^
1000000000
as
overflows
;
--
-- Tests for generate_series
--
select
*
from
generate_series
(
0
.
0
::
numeric
,
4
.
0
::
numeric
);
select
*
from
generate_series
(
0
.
1
::
numeric
,
4
.
0
::
numeric
,
1
.
3
::
numeric
);
select
*
from
generate_series
(
4
.
0
::
numeric
,
-
1
.
5
::
numeric
,
-
2
.
2
::
numeric
);
-- Trigger errors
select
*
from
generate_series
(
-
100
::
numeric
,
100
::
numeric
,
0
::
numeric
);
select
*
from
generate_series
(
-
100
::
numeric
,
100
::
numeric
,
'nan'
::
numeric
);
select
*
from
generate_series
(
'nan'
::
numeric
,
100
::
numeric
,
10
::
numeric
);
select
*
from
generate_series
(
0
::
numeric
,
'nan'
::
numeric
,
10
::
numeric
);
-- Checks maximum, output is truncated
select
(
i
/
(
10
::
numeric
^
131071
))::
numeric
(
1
,
0
)
from
generate_series
(
6
*
(
10
::
numeric
^
131071
),
9
*
(
10
::
numeric
^
131071
),
10
::
numeric
^
131071
)
as
a
(
i
);
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录