Commit 12661642 authored by Joe Conway's avatar Joe Conway

Add function (actually an int4 and an int8 version) that generates

a series of numbers, optionally using an explicit step size other
than the default value (one). Use function in the information_schema
to replace hard-wired knowledge of INDEX_MAX_KEYS. initdb forced due
to pg_proc change. Documentation update still needed -- will be
committed separately.
parent 9dac5264
......@@ -4,7 +4,7 @@
*
* Copyright 2003, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.22 2004/01/24 23:45:13 tgl Exp $
* $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.23 2004/02/03 08:29:56 joe Exp $
*/
/*
......@@ -399,17 +399,9 @@ GRANT SELECT ON columns TO PUBLIC;
CREATE FUNCTION _pg_keypositions() RETURNS SETOF integer
LANGUAGE sql
IMMUTABLE
AS 'select 1 union all select 2 union all select 3 union all
select 4 union all select 5 union all select 6 union all
select 7 union all select 8 union all select 9 union all
select 10 union all select 11 union all select 12 union all
select 13 union all select 14 union all select 15 union all
select 16 union all select 17 union all select 18 union all
select 19 union all select 20 union all select 21 union all
select 22 union all select 23 union all select 24 union all
select 25 union all select 26 union all select 27 union all
select 28 union all select 29 union all select 30 union all
select 31 union all select 32';
AS 'select g.s
from generate_series(1,current_setting(''max_index_keys'')::int,1)
as g(s)';
CREATE VIEW constraint_column_usage AS
SELECT CAST(current_database() AS sql_identifier) AS table_catalog,
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.59 2003/12/01 21:52:37 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.60 2004/02/03 08:29:56 joe Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -34,6 +34,7 @@
#include <ctype.h>
#include <limits.h>
#include "funcapi.h"
#include "libpq/pqformat.h"
#include "utils/builtins.h"
......@@ -44,6 +45,13 @@
#define SHRT_MIN (-0x8000)
#endif
typedef struct
{
int32 current;
int32 finish;
int32 step;
} generate_series_fctx;
/*****************************************************************************
* USER I/O ROUTINES *
*****************************************************************************/
......@@ -1021,3 +1029,84 @@ int2shr(PG_FUNCTION_ARGS)
PG_RETURN_INT16(arg1 >> arg2);
}
/*
* non-persistent numeric series generator
*/
Datum
generate_series_int4(PG_FUNCTION_ARGS)
{
return generate_series_step_int4(fcinfo);
}
Datum
generate_series_step_int4(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
generate_series_fctx *fctx;
int32 result;
MemoryContext oldcontext;
/* stuff done only on the first call of the function */
if (SRF_IS_FIRSTCALL())
{
int32 start = PG_GETARG_INT32(0);
int32 finish = PG_GETARG_INT32(1);
int32 step = 1;
/* see if we were given an explicit step size */
if (PG_NARGS() == 3)
step = PG_GETARG_INT32(2);
if (step == 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("step size may not 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_fctx *) palloc(sizeof(generate_series_fctx));
/*
* Use fctx to keep state from call to call.
* Seed current with the original start value
*/
fctx->current = start;
fctx->finish = finish;
fctx->step = 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 as the result for
* this iteration
*/
fctx = funcctx->user_fctx;
result = fctx->current;
if ((fctx->step > 0 && fctx->current <= fctx->finish) ||
(fctx->step < 0 && fctx->current >= fctx->finish))
{
/* increment current in preparation for next iteration */
fctx->current += fctx->step;
/* do when there is more left to send */
SRF_RETURN_NEXT(funcctx, Int32GetDatum(result));
}
else
/* do when there is no more left */
SRF_RETURN_DONE(funcctx);
}
......@@ -7,21 +7,29 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/int8.c,v 1.50 2003/12/01 21:52:37 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/int8.c,v 1.51 2004/02/03 08:29:56 joe Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <ctype.h>
#include <limits.h>
#include <math.h>
#include "funcapi.h"
#include "libpq/pqformat.h"
#include "utils/int8.h"
#define MAXINT8LEN 25
typedef struct
{
int64 current;
int64 finish;
int64 step;
} generate_series_fctx;
/***********************************************************************
**
......@@ -936,3 +944,84 @@ int8_text(PG_FUNCTION_ARGS)
PG_RETURN_TEXT_P(result);
}
/*
* non-persistent numeric series generator
*/
Datum
generate_series_int8(PG_FUNCTION_ARGS)
{
return generate_series_step_int8(fcinfo);
}
Datum
generate_series_step_int8(PG_FUNCTION_ARGS)
{
FuncCallContext *funcctx;
generate_series_fctx *fctx;
int64 result;
MemoryContext oldcontext;
/* stuff done only on the first call of the function */
if (SRF_IS_FIRSTCALL())
{
int64 start = PG_GETARG_INT64(0);
int64 finish = PG_GETARG_INT64(1);
int64 step = 1;
/* see if we were given an explicit step size */
if (PG_NARGS() == 3)
step = PG_GETARG_INT64(2);
if (step == 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("step size may not 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_fctx *) palloc(sizeof(generate_series_fctx));
/*
* Use fctx to keep state from call to call.
* Seed current with the original start value
*/
fctx->current = start;
fctx->finish = finish;
fctx->step = 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 as the result for
* this iteration
*/
fctx = funcctx->user_fctx;
result = fctx->current;
if ((fctx->step > 0 && fctx->current <= fctx->finish) ||
(fctx->step < 0 && fctx->current >= fctx->finish))
{
/* increment current in preparation for next iteration */
fctx->current += fctx->step;
/* do when there is more left to send */
SRF_RETURN_NEXT(funcctx, Int64GetDatum(result));
}
else
/* do when there is no more left */
SRF_RETURN_DONE(funcctx);
}
......@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.216 2004/01/14 23:01:55 tgl Exp $
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.217 2004/02/03 08:29:56 joe Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200401141
#define CATALOG_VERSION_NO 200402021
#endif
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.318 2004/01/06 23:55:19 tgl Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.319 2004/02/03 08:29:56 joe Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
......@@ -3424,6 +3424,17 @@ DESCR("constraint description with pretty-print option");
DATA(insert OID = 2509 ( pg_get_expr PGNSP PGUID 12 f f t f s 3 25 "25 26 16" _null_ pg_get_expr_ext - _null_ ));
DESCR("deparse an encoded expression with pretty-print option");
/* non-persistent series generator */
DATA(insert OID = 1066 ( generate_series PGNSP PGUID 12 f f t t v 3 23 "23 23 23" _null_ generate_series_step_int4 - _null_ ));
DESCR("non-persistent series generator");
DATA(insert OID = 1067 ( generate_series PGNSP PGUID 12 f f t t v 2 23 "23 23" _null_ generate_series_int4 - _null_ ));
DESCR("non-persistent series generator");
DATA(insert OID = 1068 ( generate_series PGNSP PGUID 12 f f t t v 3 20 "20 20 20" _null_ generate_series_step_int8 - _null_ ));
DESCR("non-persistent series generator");
DATA(insert OID = 1069 ( generate_series PGNSP PGUID 12 f f t t v 2 20 "20 20" _null_ generate_series_int8 - _null_ ));
DESCR("non-persistent series generator");
/*
* Symbolic values for provolatile column: these indicate whether the result
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.233 2004/01/19 19:04:40 tgl Exp $
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.234 2004/02/03 08:29:57 joe Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -175,6 +175,8 @@ extern Datum int2xor(PG_FUNCTION_ARGS);
extern Datum int2not(PG_FUNCTION_ARGS);
extern Datum int2shl(PG_FUNCTION_ARGS);
extern Datum int2shr(PG_FUNCTION_ARGS);
extern Datum generate_series_int4(PG_FUNCTION_ARGS);
extern Datum generate_series_step_int4(PG_FUNCTION_ARGS);
/* name.c */
extern Datum namein(PG_FUNCTION_ARGS);
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/int8.h,v 1.40 2003/12/01 21:52:38 momjian Exp $
* $PostgreSQL: pgsql/src/include/utils/int8.h,v 1.41 2004/02/03 08:29:57 joe Exp $
*
* NOTES
* These data types are supported on all 64-bit architectures, and may
......@@ -112,4 +112,7 @@ extern Datum oidtoi8(PG_FUNCTION_ARGS);
extern Datum int8_text(PG_FUNCTION_ARGS);
extern Datum text_int8(PG_FUNCTION_ARGS);
extern Datum generate_series_int8(PG_FUNCTION_ARGS);
extern Datum generate_series_step_int8(PG_FUNCTION_ARGS);
#endif /* INT8_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment