Hi,

I am newbie in postgresql development, so i took easy item in Todo list "
Add generate_series(numeric, numeric)". First, i changed  function with
analogue funcionality (generate_series_timestamp) and added new object in
pg_proc (object id is 6000). My changes successfully was compiled.

I have found some problems when code was tested. (remark step=1.0)

1) STATEMENT:  SELECT generate_series(1.0,6.1);
 1: generate_series (typeid = 1700, len = -1, typmod = -1, byval = f)
----
 1: generate_series = "1.0" (typeid = 1700, len = -1, typmod = -1, byval =
f)
----
 1: generate_series = "2.0" (typeid = 1700, len = -1, typmod = -1, byval =
f)
----
 1: generate_series = "3.0" (typeid = 1700, len = -1, typmod = -1, byval =
f)
----
 1: generate_series = "4.0" (typeid = 1700, len = -1, typmod = -1, byval =
f)
----
 1: generate_series = "5.0" (typeid = 1700, len = -1, typmod = -1, byval =
f)
----
 1: generate_series = "6.0" (typeid = 1700, len = -1, typmod = -1, byval =
f)
----

Function work.

2)  STATEMENT:  SELECT * FROM generate_series(1.0, 6.1)
 1: generate_series (typeid = 1700, len = -1, typmod = -1, byval = f)
----
make_result(): NUMERIC w=0 d=0 POS 0001
CURRENT:: NUMERIC w=0 d=1 POS 0001
FINISH:: NUMERIC w=0 d=1 POS 0006 1000
STEP:: NUMERIC w=0 d=0 POS 0001
make_result(): NUMERIC w=0 d=1 POS 0002
CURRENT:: NUMERIC w=32639 d=16255 NEG 0000 .... (more 0000)

And postgres was crashed.

Could you help to find mistakes?


Some questions:
1) Is correct using Numeric in generate_series_numeric_fctx instead of
NumericVar?
2) How do you determine object id for new function? Maybe you're looking
for last object id in catalog directory (src/include/catalog/pg_*.h) and
increase by one last object id.

P.S. Sorry, I have made mistakes in message, because english isn't  native
language.
From 916bfe117e464fe9185f294cbf4c9979758e7651 Mon Sep 17 00:00:00 2001
From: Malyugin Platon <malugi...@gmail.com>
Date: Mon, 29 Sep 2014 09:40:56 +0700
Subject: [PATCH] Add function generate_series(numeric, numeric)

---
 src/backend/utils/adt/numeric.c | 73 ++++++++++++++++++++++++++++++++++++++---
 src/include/catalog/pg_proc.h   |  2 ++
 src/include/utils/builtins.h    |  1 +
 3 files changed, 72 insertions(+), 4 deletions(-)

diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
index 19d0bdc..73cd169 100644
--- a/src/backend/utils/adt/numeric.c
+++ b/src/backend/utils/adt/numeric.c
@@ -14,7 +14,7 @@
  * Copyright (c) 1998-2014, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *	  src/backend/utils/adt/numeric.c
+ *	  src/backend/utils/adt/numeric.cn
  *
  *-------------------------------------------------------------------------
  */
@@ -35,13 +35,13 @@
 #include "utils/builtins.h"
 #include "utils/int8.h"
 #include "utils/numeric.h"
-
+#include "funcapi.h"
 /* ----------
  * Uncomment the following to enable compilation of dump_numeric()
  * and dump_var() and to get a dump of any result produced by make_result().
- * ----------
+ * ---------- */
 #define NUMERIC_DEBUG
- */
+
 
 
 /* ----------
@@ -260,6 +260,14 @@ typedef struct NumericVar
 } NumericVar;
 
 
+typedef struct
+{
+	Numeric current;
+	Numeric finish;
+	Numeric step;
+	int step_sign;
+} generate_series_numeric_fctx;
+
 /* ----------
  * Some preinitialized constants
  * ----------
@@ -1221,6 +1229,63 @@ numeric_floor(PG_FUNCTION_ARGS)
 	PG_RETURN_NUMERIC(res);
 }
 
+Datum
+generate_series_numeric(PG_FUNCTION_ARGS)
+{
+	generate_series_numeric_fctx *fctx;
+	FuncCallContext *funcctx;
+	Numeric res;
+
+	if (SRF_IS_FIRSTCALL())
+	{
+		Numeric start  = PG_GETARG_NUMERIC(0);
+		Numeric finish = PG_GETARG_NUMERIC(1);
+		MemoryContext oldcontext;
+
+		funcctx = SRF_FIRSTCALL_INIT();
+		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
+		fctx = (generate_series_numeric_fctx *)palloc(sizeof(generate_series_numeric_fctx));
+
+		fctx->current = start;
+		fctx->finish = finish;
+		fctx->step = make_result(&const_one);
+		fctx->step_sign = 1;
+
+		funcctx->user_fctx = fctx;
+		MemoryContextSwitchTo(oldcontext);
+	}
+
+	funcctx = SRF_PERCALL_SETUP();
+
+	fctx = funcctx->user_fctx;
+	dump_numeric("CURRENT:", fctx->current);
+	dump_numeric("FINISH:", fctx->finish);
+	dump_numeric("STEP:", fctx->step);
+
+	res = fctx->current;
+
+	if (fctx->step_sign > 0 ?
+			cmp_numerics(fctx->current, fctx->finish) <= 0 :
+			cmp_numerics(fctx->current, fctx->finish) >= 0)
+	{
+		NumericVar current;
+		NumericVar step;
+		NumericVar new;
+
+		init_var_from_num(fctx->current, &current);
+		init_var_from_num(fctx->step, &step);
+		add_var(&current, &step, &new);
+
+		fctx->current = make_result(&new);
+
+		SRF_RETURN_NEXT(funcctx, NumericGetDatum(res));
+	}
+	else
+	{
+		SRF_RETURN_DONE(funcctx);
+	}
+}
+
 /*
  * Implements the numeric version of the width_bucket() function
  * defined by SQL2003. See also width_bucket_float8().
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 0af1248..7530b64 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -3909,6 +3909,8 @@ 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 = 6000 (  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_ ));
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index bbb5d39..341606e 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -1036,6 +1036,7 @@ 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);
 
 /* ri_triggers.c */
 extern Datum RI_FKey_check_ins(PG_FUNCTION_ARGS);
-- 
1.9.1

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to