Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f739992

Browse files
committed
tablefunc: Reject negative number of tuples passed to normal_rand()
The function converted the first argument i.e. the number of tuples to return into an unsigned integer which turns out to be huge number when a negative value is passed. This causes the function to take much longer time to execute. Instead, reject a negative value. (If someone really wants to generate many more result rows, they should consider adding a bigint or numeric variant.) While at it, improve SQL test to test the number of tuples returned by this function. Author: Ashutosh Bapat <ashutosh.bapat@2ndquadrant.com> Discussion: https://www.postgresql.org/message-id/CAG-ACPW3PUUmSnM6cLa9Rw4BEC5cEMKjX8Gogc8gvQcT3cYA1A@mail.gmail.com
1 parent 2fbd786 commit f739992

File tree

3 files changed

+18
-6
lines changed

3 files changed

+18
-6
lines changed

contrib/tablefunc/expected/tablefunc.out

+7-4
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@ CREATE EXTENSION tablefunc;
33
-- normal_rand()
44
-- no easy way to do this for regression testing
55
--
6-
SELECT avg(normal_rand)::int FROM normal_rand(100, 250, 0.2);
7-
avg
8-
-----
9-
250
6+
SELECT avg(normal_rand)::int, count(*) FROM normal_rand(100, 250, 0.2);
7+
avg | count
8+
-----+-------
9+
250 | 100
1010
(1 row)
1111

12+
-- negative number of tuples
13+
SELECT avg(normal_rand)::int, count(*) FROM normal_rand(-1, 250, 0.2);
14+
ERROR: number of rows cannot be negative
1215
--
1316
-- crosstab()
1417
--

contrib/tablefunc/sql/tablefunc.sql

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ CREATE EXTENSION tablefunc;
44
-- normal_rand()
55
-- no easy way to do this for regression testing
66
--
7-
SELECT avg(normal_rand)::int FROM normal_rand(100, 250, 0.2);
7+
SELECT avg(normal_rand)::int, count(*) FROM normal_rand(100, 250, 0.2);
8+
-- negative number of tuples
9+
SELECT avg(normal_rand)::int, count(*) FROM normal_rand(-1, 250, 0.2);
810

911
--
1012
-- crosstab()

contrib/tablefunc/tablefunc.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ normal_rand(PG_FUNCTION_ARGS)
184184
/* stuff done only on the first call of the function */
185185
if (SRF_IS_FIRSTCALL())
186186
{
187+
int32 num_tuples;
188+
187189
/* create a function context for cross-call persistence */
188190
funcctx = SRF_FIRSTCALL_INIT();
189191

@@ -193,7 +195,12 @@ normal_rand(PG_FUNCTION_ARGS)
193195
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
194196

195197
/* total number of tuples to be returned */
196-
funcctx->max_calls = PG_GETARG_UINT32(0);
198+
num_tuples = PG_GETARG_INT32(0);
199+
if (num_tuples < 0)
200+
ereport(ERROR,
201+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
202+
errmsg("number of rows cannot be negative")));
203+
funcctx->max_calls = num_tuples;
197204

198205
/* allocate memory for user context */
199206
fctx = (normal_rand_fctx *) palloc(sizeof(normal_rand_fctx));

0 commit comments

Comments
 (0)