diff --git a/src/backend/catalog/information_schema.sql b/src/backend/catalog/information_schema.sql index d9c484b0243e08dff4a41367d5360a338f23d9a7..1a699acd1b8e79bf2412f15902ee5a202fe27095 100644 --- a/src/backend/catalog/information_schema.sql +++ b/src/backend/catalog/information_schema.sql @@ -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, diff --git a/src/backend/utils/adt/int.c b/src/backend/utils/adt/int.c index e23706582e268a31ed79be5cfff1f9ec55e7120a..82dab407ff40c52afbb16abbb5e3c0b08367c98a 100644 --- a/src/backend/utils/adt/int.c +++ b/src/backend/utils/adt/int.c @@ -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); +} + diff --git a/src/backend/utils/adt/int8.c b/src/backend/utils/adt/int8.c index 016330a053395a716d74914b00508437e0362cfb..200876e7989573a866de2a150bbc25d193f356a8 100644 --- a/src/backend/utils/adt/int8.c +++ b/src/backend/utils/adt/int8.c @@ -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); +} + diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 7dd262c1e464f424a41acbfb4faf420a7dc3fd2b..fa6a7f1e605240796f63be6de3553ece0530a626 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -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 diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 4f197e99753abfefccf362f549950341e43325a2..fb6eb885d8530735c34734f2846d223285306a0b 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -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 diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index dc5e2f267cc7dfd94d0c6f57317d90ed2a7b0222..593f002c68f17f5305464875c2234924f2bd5d33 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -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); diff --git a/src/include/utils/int8.h b/src/include/utils/int8.h index 7fe9800b2359010ee7f166bcd99a1cb27bffea75..eaaf9448a927b4ad68e7e1b47de04d16469e1155 100644 --- a/src/include/utils/int8.h +++ b/src/include/utils/int8.h @@ -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 */