📄 timestamp.c
字号:
PG_RETURN_BOOL(!TIMESTAMP_NOT_FINITE(timestamp));}Datuminterval_finite(PG_FUNCTION_ARGS){ PG_RETURN_BOOL(true);}/*---------------------------------------------------------- * Relational operators for timestamp. *---------------------------------------------------------*/voidGetEpochTime(struct pg_tm * tm){ struct pg_tm *t0; pg_time_t epoch = 0; t0 = pg_gmtime(&epoch); tm->tm_year = t0->tm_year; tm->tm_mon = t0->tm_mon; tm->tm_mday = t0->tm_mday; tm->tm_hour = t0->tm_hour; tm->tm_min = t0->tm_min; tm->tm_sec = t0->tm_sec; tm->tm_year += 1900; tm->tm_mon++;}TimestampSetEpochTimestamp(void){ Timestamp dt; struct pg_tm tt, *tm = &tt; GetEpochTime(tm); /* we don't bother to test for failure ... */ tm2timestamp(tm, 0, NULL, &dt); return dt;} /* SetEpochTimestamp() *//* * We are currently sharing some code between timestamp and timestamptz. * The comparison functions are among them. - thomas 2001-09-25 * * timestamp_relop - is timestamp1 relop timestamp2 * * collate invalid timestamp at the end */inttimestamp_cmp_internal(Timestamp dt1, Timestamp dt2){#ifdef HAVE_INT64_TIMESTAMP return (dt1 < dt2) ? -1 : ((dt1 > dt2) ? 1 : 0);#else /* * When using float representation, we have to be wary of NaNs. * * We consider all NANs to be equal and larger than any non-NAN. This is * somewhat arbitrary; the important thing is to have a consistent sort * order. */ if (isnan(dt1)) { if (isnan(dt2)) return 0; /* NAN = NAN */ else return 1; /* NAN > non-NAN */ } else if (isnan(dt2)) { return -1; /* non-NAN < NAN */ } else { if (dt1 > dt2) return 1; else if (dt1 < dt2) return -1; else return 0; }#endif}Datumtimestamp_eq(PG_FUNCTION_ARGS){ Timestamp dt1 = PG_GETARG_TIMESTAMP(0); Timestamp dt2 = PG_GETARG_TIMESTAMP(1); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) == 0);}Datumtimestamp_ne(PG_FUNCTION_ARGS){ Timestamp dt1 = PG_GETARG_TIMESTAMP(0); Timestamp dt2 = PG_GETARG_TIMESTAMP(1); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) != 0);}Datumtimestamp_lt(PG_FUNCTION_ARGS){ Timestamp dt1 = PG_GETARG_TIMESTAMP(0); Timestamp dt2 = PG_GETARG_TIMESTAMP(1); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) < 0);}Datumtimestamp_gt(PG_FUNCTION_ARGS){ Timestamp dt1 = PG_GETARG_TIMESTAMP(0); Timestamp dt2 = PG_GETARG_TIMESTAMP(1); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) > 0);}Datumtimestamp_le(PG_FUNCTION_ARGS){ Timestamp dt1 = PG_GETARG_TIMESTAMP(0); Timestamp dt2 = PG_GETARG_TIMESTAMP(1); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) <= 0);}Datumtimestamp_ge(PG_FUNCTION_ARGS){ Timestamp dt1 = PG_GETARG_TIMESTAMP(0); Timestamp dt2 = PG_GETARG_TIMESTAMP(1); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) >= 0);}Datumtimestamp_cmp(PG_FUNCTION_ARGS){ Timestamp dt1 = PG_GETARG_TIMESTAMP(0); Timestamp dt2 = PG_GETARG_TIMESTAMP(1); PG_RETURN_INT32(timestamp_cmp_internal(dt1, dt2));}Datumtimestamp_hash(PG_FUNCTION_ARGS){ /* We can use either hashint8 or hashfloat8 directly */#ifdef HAVE_INT64_TIMESTAMP return hashint8(fcinfo);#else return hashfloat8(fcinfo);#endif}/* * Crosstype comparison functions for timestamp vs timestamptz */Datumtimestamp_eq_timestamptz(PG_FUNCTION_ARGS){ Timestamp timestampVal = PG_GETARG_TIMESTAMP(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); TimestampTz dt1; dt1 = timestamp2timestamptz(timestampVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) == 0);}Datumtimestamp_ne_timestamptz(PG_FUNCTION_ARGS){ Timestamp timestampVal = PG_GETARG_TIMESTAMP(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); TimestampTz dt1; dt1 = timestamp2timestamptz(timestampVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) != 0);}Datumtimestamp_lt_timestamptz(PG_FUNCTION_ARGS){ Timestamp timestampVal = PG_GETARG_TIMESTAMP(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); TimestampTz dt1; dt1 = timestamp2timestamptz(timestampVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) < 0);}Datumtimestamp_gt_timestamptz(PG_FUNCTION_ARGS){ Timestamp timestampVal = PG_GETARG_TIMESTAMP(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); TimestampTz dt1; dt1 = timestamp2timestamptz(timestampVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) > 0);}Datumtimestamp_le_timestamptz(PG_FUNCTION_ARGS){ Timestamp timestampVal = PG_GETARG_TIMESTAMP(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); TimestampTz dt1; dt1 = timestamp2timestamptz(timestampVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) <= 0);}Datumtimestamp_ge_timestamptz(PG_FUNCTION_ARGS){ Timestamp timestampVal = PG_GETARG_TIMESTAMP(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); TimestampTz dt1; dt1 = timestamp2timestamptz(timestampVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) >= 0);}Datumtimestamp_cmp_timestamptz(PG_FUNCTION_ARGS){ Timestamp timestampVal = PG_GETARG_TIMESTAMP(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); TimestampTz dt1; dt1 = timestamp2timestamptz(timestampVal); PG_RETURN_INT32(timestamp_cmp_internal(dt1, dt2));}Datumtimestamptz_eq_timestamp(PG_FUNCTION_ARGS){ TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); Timestamp timestampVal = PG_GETARG_TIMESTAMP(1); TimestampTz dt2; dt2 = timestamp2timestamptz(timestampVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) == 0);}Datumtimestamptz_ne_timestamp(PG_FUNCTION_ARGS){ TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); Timestamp timestampVal = PG_GETARG_TIMESTAMP(1); TimestampTz dt2; dt2 = timestamp2timestamptz(timestampVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) != 0);}Datumtimestamptz_lt_timestamp(PG_FUNCTION_ARGS){ TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); Timestamp timestampVal = PG_GETARG_TIMESTAMP(1); TimestampTz dt2; dt2 = timestamp2timestamptz(timestampVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) < 0);}Datumtimestamptz_gt_timestamp(PG_FUNCTION_ARGS){ TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); Timestamp timestampVal = PG_GETARG_TIMESTAMP(1); TimestampTz dt2; dt2 = timestamp2timestamptz(timestampVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) > 0);}Datumtimestamptz_le_timestamp(PG_FUNCTION_ARGS){ TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); Timestamp timestampVal = PG_GETARG_TIMESTAMP(1); TimestampTz dt2; dt2 = timestamp2timestamptz(timestampVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) <= 0);}Datumtimestamptz_ge_timestamp(PG_FUNCTION_ARGS){ TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); Timestamp timestampVal = PG_GETARG_TIMESTAMP(1); TimestampTz dt2; dt2 = timestamp2timestamptz(timestampVal); PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) >= 0);}Datumtimestamptz_cmp_timestamp(PG_FUNCTION_ARGS){ TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); Timestamp timestampVal = PG_GETARG_TIMESTAMP(1); TimestampTz dt2; dt2 = timestamp2timestamptz(timestampVal); PG_RETURN_INT32(timestamp_cmp_internal(dt1, dt2));}/* * interval_relop - is interval1 relop interval2 * * collate invalid interval at the end */static intinterval_cmp_internal(Interval *interval1, Interval *interval2){#ifdef HAVE_INT64_TIMESTAMP int64 span1, span2;#else double span1, span2;#endif span1 = interval1->time; span2 = interval2->time;#ifdef HAVE_INT64_TIMESTAMP span1 += interval1->month * INT64CONST(30) * USECS_PER_DAY; span1 += interval1->day * INT64CONST(24) * USECS_PER_HOUR; span2 += interval2->month * INT64CONST(30) * USECS_PER_DAY; span2 += interval2->day * INT64CONST(24) * USECS_PER_HOUR;#else span1 += interval1->month * ((double) DAYS_PER_MONTH * SECS_PER_DAY); span1 += interval1->day * ((double) HOURS_PER_DAY * SECS_PER_HOUR); span2 += interval2->month * ((double) DAYS_PER_MONTH * SECS_PER_DAY); span2 += interval2->day * ((double) HOURS_PER_DAY * SECS_PER_HOUR);#endif return ((span1 < span2) ? -1 : (span1 > span2) ? 1 : 0);}Datuminterval_eq(PG_FUNCTION_ARGS){ Interval *interval1 = PG_GETARG_INTERVAL_P(0); Interval *interval2 = PG_GETARG_INTERVAL_P(1); PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) == 0);}Datuminterval_ne(PG_FUNCTION_ARGS){ Interval *interval1 = PG_GETARG_INTERVAL_P(0); Interval *interval2 = PG_GETARG_INTERVAL_P(1); PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) != 0);}Datuminterval_lt(PG_FUNCTION_ARGS){ Interval *interval1 = PG_GETARG_INTERVAL_P(0); Interval *interval2 = PG_GETARG_INTERVAL_P(1); PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) < 0);}Datuminterval_gt(PG_FUNCTION_ARGS){ Interval *interval1 = PG_GETARG_INTERVAL_P(0); Interval *interval2 = PG_GETARG_INTERVAL_P(1); PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) > 0);}Datuminterval_le(PG_FUNCTION_ARGS){ Interval *interval1 = PG_GETARG_INTERVAL_P(0); Interval *interval2 = PG_GETARG_INTERVAL_P(1); PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) <= 0);}Datuminterval_ge(PG_FUNCTION_ARGS){ Interval *interval1 = PG_GETARG_INTERVAL_P(0); Interval *interval2 = PG_GETARG_INTERVAL_P(1); PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) >= 0);}Datuminterval_cmp(PG_FUNCTION_ARGS){ Interval *interval1 = PG_GETARG_INTERVAL_P(0); Interval *interval2 = PG_GETARG_INTERVAL_P(1); PG_RETURN_INT32(interval_cmp_internal(interval1, interval2));}Datuminterval_hash(PG_FUNCTION_ARGS){ Interval *key = PG_GETARG_INTERVAL_P(0); uint32 thash; uint32 mhash; /* * To avoid any problems with padding bytes in the struct, we figure the * field hashes separately and XOR them. This also provides a convenient * framework for dealing with the fact that the time field might be either * double or int64. */#ifdef HAVE_INT64_TIMESTAMP thash = DatumGetUInt32(DirectFunctionCall1(hashint8, Int64GetDatumFast(key->time)));#else thash = DatumGetUInt32(DirectFunctionCall1(hashfloat8, Float8GetDatumFast(key->time)));#endif thash ^= DatumGetUInt32(hash_uint32(key->day)); /* Shift so "k days" and "k months" don't hash to the same thing */ mhash = DatumGetUInt32(hash_uint32(key->month)); thash ^= mhash << 24; thash ^= mhash >> 8; PG_RETURN_UINT32(thash);}/* overlaps_timestamp() --- implements the SQL92 OVERLAPS operator. * * Algorithm is per SQL92 spec. This is much harder than you'd think * because the spec requires us to deliver a non-null answer in some cases * where some of the inputs are null. */Datumoverlaps_timestamp(PG_FUNCTION_ARGS){ /* * The arguments are Timestamps, but we leave them as generic Datums to * avoid unnecessary conversions between value and reference forms --- not * to mention possible dereferences of null pointers. */ Datum ts1 = PG_GETARG_DATUM(0); Datum te1 = PG_GETARG_DATUM(1); Datum ts2 = PG_GETARG_DATUM(2); Datum te2 = PG_GETARG_DATUM(3); bool ts1IsNull = PG_ARGISNULL(0); bool te1IsNull = PG_ARGISNULL(1); bool ts2IsNull = PG_ARGISNULL(2); bool te2IsNull = PG_ARGISNULL(3);#define TIMESTAMP_GT(t1,t2) \ DatumGetBool(DirectFunctionCall2(timestamp_gt,t1,t2))#define TIMESTAMP_LT(t1,t2) \ DatumGetBool(DirectFunctionCall2(timestamp_lt,t1,t2)) /* * If both endpoints of interval 1 are null, the result is null (unknown). * If just one endpoint is null, take ts1 as the non-null one. Otherwise, * take ts1 as the lesser endpoint. */ if (ts1IsNull) { if (te1IsNull) PG_RETURN_NULL(); /* swap null for non-null */ ts1 = te1; te1IsNull = true; } else if (!te1IsNull) { if (TIMESTAMP_GT(ts1, te1)) { Datum tt = ts1; ts1 = te1; te1 = tt; } } /* Likewise for interval 2. */ if (ts2IsNull) { if (te2IsNull) PG_RETURN_NULL(); /* swap null for non-null */ ts2 = te2; te2IsNull = true; } else if (!te2IsNull) { if (TIMESTAMP_GT(ts2, te2)) { Datum tt = ts2; ts2 = te2; te2 = tt; } } /* * At this point neither ts1 nor ts2 is null, so we can consider three * cases: ts1 > ts2, ts1 < ts2, ts1 = ts2 */ if (TIMESTAMP_GT(ts1, ts2)) { /* * This case is ts1 < te2 OR te1 < te2, which may look redundant but * in the presence of nulls it's not quite completely so. */ if (te2IsNull) PG_RETURN_NULL(); if (TIMESTAMP_LT(ts1, te2)) PG_RETURN_BOOL(true); if (te1IsNull) PG_RETURN_NULL(); /* * If te1 is not null then we had ts1 <= te1 above, and we just found * ts1 >= te2, hence te1 >= te2. */ PG_RETURN_BOOL(false); } else if (TIMESTAMP_LT(ts1, ts2)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -