diff --git a/src/rrtimeslice.c b/src/rrtimeslice.c
index d34da914a53713f40e9c5589ed424209868791a7..25e9cb38c1ce2caf73eb3b7e5d5e476e4d4eda3b 100644 (file)
--- a/src/rrtimeslice.c
+++ b/src/rrtimeslice.c
#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)
*/
struct rrtimeslice {
- Timestamp tstamp;
+ TimestampTz tstamp;
int32 tsid;
uint32 seq;
};
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
{
rrtimeslice_t *tslice;
- Timestamp tstamp = 0;
+ TimestampTz tstamp = 0;
int32 typmod;
struct pg_tm tm;
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)
{
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;
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);
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;
"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 : */