Code

postrr.sql: Removed unnecessary aliases.
[postrr.git] / src / rrtimeslice.c
index d34da914a53713f40e9c5589ed424209868791a7..25e9cb38c1ce2caf73eb3b7e5d5e476e4d4eda3b 100644 (file)
 #include <fmgr.h>
 
 /* Postgres utilities */
+#include <access/hash.h>
 #include <executor/spi.h>
 #include <utils/array.h>
 #include <utils/datetime.h>
 #include <utils/timestamp.h>
-#include <miscadmin.h> /* DateStyle, IntervalStyle */
+#include <miscadmin.h> /* DateStyle */
 
 #ifdef HAVE_INT64_TIMESTAMP
 #      define TSTAMP_TO_INT64(t) (t)
@@ -58,7 +59,7 @@
  */
 
 struct rrtimeslice {
-       Timestamp tstamp;
+       TimestampTz tstamp;
        int32  tsid;
        uint32 seq;
 };
@@ -206,14 +207,16 @@ PG_FUNCTION_INFO_V1(rrtimeslice_typmodin);
 PG_FUNCTION_INFO_V1(rrtimeslice_typmodout);
 
 PG_FUNCTION_INFO_V1(rrtimeslice_to_rrtimeslice);
+PG_FUNCTION_INFO_V1(rrtimeslice_to_timestamptz);
 
-PG_FUNCTION_INFO_V1(rrtimeslice_eq);
-PG_FUNCTION_INFO_V1(rrtimeslice_ne);
-PG_FUNCTION_INFO_V1(rrtimeslice_lt);
-PG_FUNCTION_INFO_V1(rrtimeslice_gt);
-PG_FUNCTION_INFO_V1(rrtimeslice_le);
-PG_FUNCTION_INFO_V1(rrtimeslice_ge);
-PG_FUNCTION_INFO_V1(rrtimeslice_cmp);
+PG_FUNCTION_INFO_V1(rrtimeslice_seq_eq);
+PG_FUNCTION_INFO_V1(rrtimeslice_seq_ne);
+PG_FUNCTION_INFO_V1(rrtimeslice_seq_lt);
+PG_FUNCTION_INFO_V1(rrtimeslice_seq_gt);
+PG_FUNCTION_INFO_V1(rrtimeslice_seq_le);
+PG_FUNCTION_INFO_V1(rrtimeslice_seq_ge);
+PG_FUNCTION_INFO_V1(rrtimeslice_seq_cmp);
+PG_FUNCTION_INFO_V1(rrtimeslice_seq_hash);
 
 /*
  * public API
@@ -256,7 +259,7 @@ rrtimeslice_in(PG_FUNCTION_ARGS)
 {
        rrtimeslice_t *tslice;
 
-       Timestamp tstamp = 0;
+       TimestampTz tstamp = 0;
        int32 typmod;
 
        struct pg_tm tm;
@@ -292,7 +295,7 @@ rrtimeslice_in(PG_FUNCTION_ARGS)
 
        switch (dtype) {
                case DTK_DATE:
-                       if (tm2timestamp(&tm, fsec, NULL, &tstamp))
+                       if (tm2timestamp(&tm, fsec, &tz, &tstamp))
                                ereport(ERROR, (
                                                        errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
                                                        errmsg("timestamp out of range: %s", time_str)
@@ -327,15 +330,15 @@ rrtimeslice_out(PG_FUNCTION_ARGS)
 {
        rrtimeslice_t *tslice;
 
-       Interval interval;
-
        struct pg_tm tm;
        fsec_t fsec = 0;
-       char *tz = NULL;
+       int tz = 0;
+
+       char *tz_str = NULL;
 
        char  ts_str[MAXDATELEN + 1];
-       char  buf_ts[MAXDATELEN + 1];
        char  buf_l[MAXDATELEN + 1];
+       char  buf_u[MAXDATELEN + 1];
        char *result;
 
        int32 len = 0;
@@ -350,33 +353,32 @@ rrtimeslice_out(PG_FUNCTION_ARGS)
        tslice = PG_GETARG_RRTIMESLICE_P(0);
 
        if (TIMESTAMP_NOT_FINITE(tslice->tstamp)
-                       || (timestamp2tm(tslice->tstamp, NULL, &tm, &fsec, NULL, NULL) != 0))
+                       || timestamp2tm(tslice->tstamp, &tz, &tm, &fsec, &tz_str, NULL))
                ereport(ERROR, (
                                        errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
                                        errmsg("invalid (non-finite) timestamp")
                                ));
-       else
-               EncodeDateTime(&tm, fsec, NULL, &tz, DateStyle, buf_ts);
+
+       EncodeDateTime(&tm, fsec, &tz, &tz_str, DateStyle, buf_u);
 
        if (! rrtimeslice_get_spec(tslice->tsid, &len, &num)) {
-               memset(&interval, 0, sizeof(interval));
-               interval.time = len * USECS_PER_SEC;
-               fsec = 0;
+               TimestampTz lower = tslice->tstamp - (len * USECS_PER_SEC);
 
-               if (interval2tm(interval, &tm, &fsec))
+               if (timestamp2tm(lower, &tz, &tm, &fsec, &tz_str, NULL))
                        ereport(ERROR, (
-                                               errmsg("could not convert interval to tm")
+                                               errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
+                                               errmsg("invalid (non-finite) lower timestamp")
                                        ));
+
+               EncodeDateTime(&tm, fsec, &tz, &tz_str, DateStyle, buf_l);
        }
        else {
                strncpy(buf_l, "ERR", sizeof(buf_l));
                buf_l[sizeof(buf_l) - 1] = '\0';
        }
 
-       EncodeInterval(&tm, fsec, IntervalStyle, buf_l);
-
-       snprintf(ts_str, sizeof(ts_str), "%s -%s (#%i)",
-                       buf_ts, buf_l, tslice->seq);
+       snprintf(ts_str, sizeof(ts_str), "(\"%s\", \"%s\"] #%i/%i",
+                       buf_l, buf_u, tslice->seq, num);
 
        result = pstrdup(ts_str);
        PG_RETURN_CSTRING(result);
@@ -470,8 +472,25 @@ rrtimeslice_to_rrtimeslice(PG_FUNCTION_ARGS)
        PG_RETURN_RRTIMESLICE_P(tslice);
 } /* rrtimeslice_to_rrtimeslice */
 
+Datum
+rrtimeslice_to_timestamptz(PG_FUNCTION_ARGS)
+{
+       rrtimeslice_t *tslice;
+
+       if (PG_NARGS() != 1)
+               ereport(ERROR, (
+                                       errmsg("rrtimeslice_to_timestamptz() "
+                                               "expects one argument"),
+                                       errhint("Usage: rrtimeslice_to_timestamptz"
+                                               "(rrtimeslice)")
+                               ));
+
+       tslice = PG_GETARG_RRTIMESLICE_P(0);
+       PG_RETURN_TIMESTAMPTZ(tslice->tstamp);
+} /* rrtimeslice_to_timestamptz */
+
 int
-rrtimeslice_cmp_internal(rrtimeslice_t *ts1, rrtimeslice_t *ts2)
+rrtimeslice_seq_cmp_internal(rrtimeslice_t *ts1, rrtimeslice_t *ts2)
 {
        if ((! ts1) && (! ts2))
                return 0;
@@ -492,74 +511,83 @@ rrtimeslice_cmp_internal(rrtimeslice_t *ts1, rrtimeslice_t *ts2)
                                                "rrtimeslices with different typmods (yet)")
                                ));
 
-       if (ts1->seq == ts2->seq)
+       if (ts1->seq < ts2->seq)
+               return -1;
+       else if (ts1->seq == ts2->seq)
                return 0;
-
-       return timestamp_cmp_internal(ts1->tstamp, ts2->tstamp);
-} /* rrtimeslice_cmp_internal */
+       else
+               return 1;
+} /* rrtimeslice_seq_cmp_internal */
 
 Datum
-rrtimeslice_eq(PG_FUNCTION_ARGS)
+rrtimeslice_seq_eq(PG_FUNCTION_ARGS)
 {
        rrtimeslice_t *ts1 = PG_GETARG_RRTIMESLICE_P(0);
        rrtimeslice_t *ts2 = PG_GETARG_RRTIMESLICE_P(1);
 
-       PG_RETURN_BOOL(rrtimeslice_cmp_internal(ts1, ts2) == 0);
-} /* rrtimeslice_eq */
+       PG_RETURN_BOOL(rrtimeslice_seq_cmp_internal(ts1, ts2) == 0);
+} /* rrtimeslice_seq_eq */
 
 Datum
-rrtimeslice_ne(PG_FUNCTION_ARGS)
+rrtimeslice_seq_ne(PG_FUNCTION_ARGS)
 {
        rrtimeslice_t *ts1 = PG_GETARG_RRTIMESLICE_P(0);
        rrtimeslice_t *ts2 = PG_GETARG_RRTIMESLICE_P(1);
 
-       PG_RETURN_BOOL(rrtimeslice_cmp_internal(ts1, ts2) != 0);
-} /* rrtimeslice_ne */
+       PG_RETURN_BOOL(rrtimeslice_seq_cmp_internal(ts1, ts2) != 0);
+} /* rrtimeslice_seq_ne */
 
 Datum
-rrtimeslice_lt(PG_FUNCTION_ARGS)
+rrtimeslice_seq_lt(PG_FUNCTION_ARGS)
 {
        rrtimeslice_t *ts1 = PG_GETARG_RRTIMESLICE_P(0);
        rrtimeslice_t *ts2 = PG_GETARG_RRTIMESLICE_P(1);
 
-       PG_RETURN_BOOL(rrtimeslice_cmp_internal(ts1, ts2) < 0);
-} /* rrtimeslice_lt */
+       PG_RETURN_BOOL(rrtimeslice_seq_cmp_internal(ts1, ts2) < 0);
+} /* rrtimeslice_seq_lt */
 
 Datum
-rrtimeslice_le(PG_FUNCTION_ARGS)
+rrtimeslice_seq_le(PG_FUNCTION_ARGS)
 {
        rrtimeslice_t *ts1 = PG_GETARG_RRTIMESLICE_P(0);
        rrtimeslice_t *ts2 = PG_GETARG_RRTIMESLICE_P(1);
 
-       PG_RETURN_BOOL(rrtimeslice_cmp_internal(ts1, ts2) <= 0);
-} /* rrtimeslice_le */
+       PG_RETURN_BOOL(rrtimeslice_seq_cmp_internal(ts1, ts2) <= 0);
+} /* rrtimeslice_seq_le */
 
 Datum
-rrtimeslice_gt(PG_FUNCTION_ARGS)
+rrtimeslice_seq_gt(PG_FUNCTION_ARGS)
 {
        rrtimeslice_t *ts1 = PG_GETARG_RRTIMESLICE_P(0);
        rrtimeslice_t *ts2 = PG_GETARG_RRTIMESLICE_P(1);
 
-       PG_RETURN_BOOL(rrtimeslice_cmp_internal(ts1, ts2) > 0);
-} /* rrtimeslice_gt */
+       PG_RETURN_BOOL(rrtimeslice_seq_cmp_internal(ts1, ts2) > 0);
+} /* rrtimeslice_seq_gt */
 
 Datum
-rrtimeslice_ge(PG_FUNCTION_ARGS)
+rrtimeslice_seq_ge(PG_FUNCTION_ARGS)
 {
        rrtimeslice_t *ts1 = PG_GETARG_RRTIMESLICE_P(0);
        rrtimeslice_t *ts2 = PG_GETARG_RRTIMESLICE_P(1);
 
-       PG_RETURN_BOOL(rrtimeslice_cmp_internal(ts1, ts2) >= 0);
-} /* rrtimeslice_ge */
+       PG_RETURN_BOOL(rrtimeslice_seq_cmp_internal(ts1, ts2) >= 0);
+} /* rrtimeslice_seq_ge */
 
 Datum
-rrtimeslice_cmp(PG_FUNCTION_ARGS)
+rrtimeslice_seq_cmp(PG_FUNCTION_ARGS)
 {
        rrtimeslice_t *ts1 = PG_GETARG_RRTIMESLICE_P(0);
        rrtimeslice_t *ts2 = PG_GETARG_RRTIMESLICE_P(1);
 
-       PG_RETURN_INT32(rrtimeslice_cmp_internal(ts1, ts2));
-} /* rrtimeslice_ge */
+       PG_RETURN_INT32(rrtimeslice_seq_cmp_internal(ts1, ts2));
+} /* rrtimeslice_seq_ge */
+
+Datum
+rrtimeslice_seq_hash(PG_FUNCTION_ARGS)
+{
+       rrtimeslice_t *ts = PG_GETARG_RRTIMESLICE_P(0);
+       return hash_uint32(ts->seq);
+} /* rrtimeslice_seq_hash */
 
 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */