nabstime.c
来自「PostgreSQL7.4.6 for Linux」· C语言 代码 · 共 1,745 行 · 第 1/3 页
C
1,745 行
}Datumabstimege(PG_FUNCTION_ARGS){ AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0); AbsoluteTime t2 = PG_GETARG_ABSOLUTETIME(1); PG_RETURN_BOOL(abstime_cmp_internal(t1, t2) >= 0);}Datumbtabstimecmp(PG_FUNCTION_ARGS){ AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0); AbsoluteTime t2 = PG_GETARG_ABSOLUTETIME(1); PG_RETURN_INT32(abstime_cmp_internal(t1, t2));}/* timestamp_abstime() * Convert timestamp to abstime. */Datumtimestamp_abstime(PG_FUNCTION_ARGS){ Timestamp timestamp = PG_GETARG_TIMESTAMP(0); AbsoluteTime result; fsec_t fsec; int tz; struct tm tt, *tm = &tt; if (TIMESTAMP_IS_NOBEGIN(timestamp)) result = NOSTART_ABSTIME; else if (TIMESTAMP_IS_NOEND(timestamp)) result = NOEND_ABSTIME; else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) == 0) { tz = DetermineLocalTimeZone(tm); result = tm2abstime(tm, tz); } else { ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range"))); result = INVALID_ABSTIME; } PG_RETURN_ABSOLUTETIME(result);}/* abstime_timestamp() * Convert abstime to timestamp. */Datumabstime_timestamp(PG_FUNCTION_ARGS){ AbsoluteTime abstime = PG_GETARG_ABSOLUTETIME(0); Timestamp result; struct tm tt, *tm = &tt; int tz; char zone[MAXDATELEN + 1], *tzn = zone; switch (abstime) { case INVALID_ABSTIME: ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot convert abstime \"invalid\" to timestamp"))); TIMESTAMP_NOBEGIN(result); break; case NOSTART_ABSTIME: TIMESTAMP_NOBEGIN(result); break; case NOEND_ABSTIME: TIMESTAMP_NOEND(result); break; default: abstime2tm(abstime, &tz, tm, &tzn); if (tm2timestamp(tm, 0, NULL, &result) != 0) ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range"))); break; }; PG_RETURN_TIMESTAMP(result);}/* timestamptz_abstime() * Convert timestamp with time zone to abstime. */Datumtimestamptz_abstime(PG_FUNCTION_ARGS){ TimestampTz timestamp = PG_GETARG_TIMESTAMP(0); AbsoluteTime result; fsec_t fsec; struct tm tt, *tm = &tt; if (TIMESTAMP_IS_NOBEGIN(timestamp)) result = NOSTART_ABSTIME; else if (TIMESTAMP_IS_NOEND(timestamp)) result = NOEND_ABSTIME; else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) == 0) result = tm2abstime(tm, 0); else { ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range"))); result = INVALID_ABSTIME; } PG_RETURN_ABSOLUTETIME(result);}/* abstime_timestamptz() * Convert abstime to timestamp with time zone. */Datumabstime_timestamptz(PG_FUNCTION_ARGS){ AbsoluteTime abstime = PG_GETARG_ABSOLUTETIME(0); TimestampTz result; struct tm tt, *tm = &tt; int tz; char zone[MAXDATELEN + 1], *tzn = zone; switch (abstime) { case INVALID_ABSTIME: ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot convert abstime \"invalid\" to timestamp"))); TIMESTAMP_NOBEGIN(result); break; case NOSTART_ABSTIME: TIMESTAMP_NOBEGIN(result); break; case NOEND_ABSTIME: TIMESTAMP_NOEND(result); break; default: abstime2tm(abstime, &tz, tm, &tzn); if (tm2timestamp(tm, 0, &tz, &result) != 0) ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range"))); break; }; PG_RETURN_TIMESTAMP(result);}/***************************************************************************** * USER I/O ROUTINES * *****************************************************************************//* * reltimein - converts a reltime string in an internal format */Datumreltimein(PG_FUNCTION_ARGS){ char *str = PG_GETARG_CSTRING(0); RelativeTime result; struct tm tt, *tm = &tt; fsec_t fsec; int dtype; int dterr; char *field[MAXDATEFIELDS]; int nf, ftype[MAXDATEFIELDS]; char lowstr[MAXDATELEN + 1]; if (strlen(str) >= sizeof(lowstr)) dterr = DTERR_BAD_FORMAT; else dterr = ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf); if (dterr == 0) dterr = DecodeInterval(field, ftype, nf, &dtype, tm, &fsec); if (dterr != 0) { if (dterr == DTERR_FIELD_OVERFLOW) dterr = DTERR_INTERVAL_OVERFLOW; DateTimeParseError(dterr, str, "reltime"); } switch (dtype) { case DTK_DELTA: result = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec); result += ((tm->tm_year * 36525 * 864) + (((tm->tm_mon * 30) + tm->tm_mday) * 86400)); break; default: elog(ERROR, "unexpected dtype %d while parsing reltime \"%s\"", dtype, str); result = INVALID_RELTIME; break; } PG_RETURN_RELATIVETIME(result);}/* * reltimeout - converts the internal format to a reltime string */Datumreltimeout(PG_FUNCTION_ARGS){ RelativeTime time = PG_GETARG_RELATIVETIME(0); char *result; struct tm tt, *tm = &tt; char buf[MAXDATELEN + 1]; reltime2tm(time, tm); EncodeInterval(tm, 0, DateStyle, buf); result = pstrdup(buf); PG_RETURN_CSTRING(result);}/* * reltimerecv - converts external binary format to reltime */Datumreltimerecv(PG_FUNCTION_ARGS){ StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); PG_RETURN_RELATIVETIME((RelativeTime) pq_getmsgint(buf, sizeof(RelativeTime)));}/* * reltimesend - converts reltime to binary format */Datumreltimesend(PG_FUNCTION_ARGS){ RelativeTime time = PG_GETARG_RELATIVETIME(0); StringInfoData buf; pq_begintypsend(&buf); pq_sendint(&buf, time, sizeof(time)); PG_RETURN_BYTEA_P(pq_endtypsend(&buf));}static voidreltime2tm(RelativeTime time, struct tm * tm){ double dtime = time; FMODULO(dtime, tm->tm_year, 31557600); FMODULO(dtime, tm->tm_mon, 2592000); FMODULO(dtime, tm->tm_mday, 86400); FMODULO(dtime, tm->tm_hour, 3600); FMODULO(dtime, tm->tm_min, 60); FMODULO(dtime, tm->tm_sec, 1);}/* * tintervalin - converts an interval string to internal format */Datumtintervalin(PG_FUNCTION_ARGS){ char *intervalstr = PG_GETARG_CSTRING(0); TimeInterval interval; AbsoluteTime i_start, i_end, t1, t2; interval = (TimeInterval) palloc(sizeof(TimeIntervalData)); if (istinterval(intervalstr, &t1, &t2) == 0) ereport(ERROR, (errcode(ERRCODE_INVALID_DATETIME_FORMAT), errmsg("invalid input syntax for type tinterval: \"%s\"", intervalstr))); if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME) interval->status = T_INTERVAL_INVAL; /* undefined */ else interval->status = T_INTERVAL_VALID; i_start = ABSTIMEMIN(t1, t2); i_end = ABSTIMEMAX(t1, t2); interval->data[0] = i_start; interval->data[1] = i_end; PG_RETURN_TIMEINTERVAL(interval);}/* * tintervalout - converts an internal interval format to a string */Datumtintervalout(PG_FUNCTION_ARGS){ TimeInterval interval = PG_GETARG_TIMEINTERVAL(0); char *i_str, *p; i_str = (char *) palloc(T_INTERVAL_LEN); /* ["..." "..."] */ strcpy(i_str, "[\""); if (interval->status == T_INTERVAL_INVAL) strcat(i_str, INVALID_INTERVAL_STR); else { p = DatumGetCString(DirectFunctionCall1(abstimeout, AbsoluteTimeGetDatum(interval->data[0]))); strcat(i_str, p); pfree(p); strcat(i_str, "\" \""); p = DatumGetCString(DirectFunctionCall1(abstimeout, AbsoluteTimeGetDatum(interval->data[1]))); strcat(i_str, p); pfree(p); } strcat(i_str, "\"]"); PG_RETURN_CSTRING(i_str);}/* * tintervalrecv - converts external binary format to tinterval */Datumtintervalrecv(PG_FUNCTION_ARGS){ StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); TimeInterval interval; interval = (TimeInterval) palloc(sizeof(TimeIntervalData)); interval->status = pq_getmsgint(buf, sizeof(interval->status)); if (!(interval->status == T_INTERVAL_INVAL || interval->status == T_INTERVAL_VALID)) ereport(ERROR, (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), errmsg("invalid status in external \"tinterval\" value"))); interval->data[0] = pq_getmsgint(buf, sizeof(interval->data[0])); interval->data[1] = pq_getmsgint(buf, sizeof(interval->data[1])); PG_RETURN_TIMEINTERVAL(interval);}/* * tintervalsend - converts tinterval to binary format */Datumtintervalsend(PG_FUNCTION_ARGS){ TimeInterval interval = PG_GETARG_TIMEINTERVAL(0); StringInfoData buf; pq_begintypsend(&buf); pq_sendint(&buf, interval->status, sizeof(interval->status)); pq_sendint(&buf, interval->data[0], sizeof(interval->data[0])); pq_sendint(&buf, interval->data[1], sizeof(interval->data[1])); PG_RETURN_BYTEA_P(pq_endtypsend(&buf));}/***************************************************************************** * PUBLIC ROUTINES * *****************************************************************************/Datuminterval_reltime(PG_FUNCTION_ARGS){ Interval *interval = PG_GETARG_INTERVAL_P(0); RelativeTime time; int year, month;#ifdef HAVE_INT64_TIMESTAMP int64 span;#else double span;#endif if (interval->month == 0) { year = 0; month = 0; } else if (abs(interval->month) >= 12) { year = (interval->month / 12); month = (interval->month % 12); } else { year = 0; month = interval->month; }#ifdef HAVE_INT64_TIMESTAMP span = ((((INT64CONST(365250000) * year) + (INT64CONST(30000000) * month)) * INT64CONST(86400)) + interval->time); span /= INT64CONST(1000000);#else span = (((((double) 365.25 * year) + ((double) 30 * month)) * 86400) + interval->time);#endif if ((span < INT_MIN) || (span > INT_MAX)) time = INVALID_RELTIME; else time = span; PG_RETURN_RELATIVETIME(time);}Datumreltime_interval(PG_FUNCTION_ARGS){ RelativeTime reltime = PG_GETARG_RELATIVETIME(0); Interval *result; int year, month; result = (Interval *) palloc(sizeof(Interval)); switch (reltime) { case INVALID_RELTIME: ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot convert reltime \"invalid\" to interval"))); result->time = 0; result->month = 0; break; default:#ifdef HAVE_INT64_TIMESTAMP year = (reltime / (36525 * 864)); reltime -= (year * (36525 * 864)); month = (reltime / (30 * 86400)); reltime -= (month * (30 * 86400)); result->time = (reltime * INT64CONST(1000000));#else TMODULO(reltime, year, (36525 * 864)); TMODULO(reltime, month, (30 * 86400)); result->time = reltime;#endif result->month = ((12 * year) + month); break; } PG_RETURN_INTERVAL_P(result);}/* * mktinterval - creates a time interval with endpoints t1 and t2 */Datummktinterval(PG_FUNCTION_ARGS){ AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0); AbsoluteTime t2 = PG_GETARG_ABSOLUTETIME(1); AbsoluteTime tstart = ABSTIMEMIN(t1, t2); AbsoluteTime tend = ABSTIMEMAX(t1, t2); TimeInterval interval; interval = (TimeInterval) palloc(sizeof(TimeIntervalData)); if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME) interval->status = T_INTERVAL_INVAL; else { interval->status = T_INTERVAL_VALID; interval->data[0] = tstart; interval->data[1] = tend; } PG_RETURN_TIMEINTERVAL(interval);}/* * timepl, timemi and abstimemi use the formula * abstime + reltime = abstime * so abstime - reltime = abstime * and abstime - abstime = reltime *//* * timepl - returns the value of (abstime t1 + reltime t2) */Datumtimepl(PG_FUNCTION_ARGS){ AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0); RelativeTime t2 = PG_GETARG_RELATIVETIME(1); if (AbsoluteTimeIsReal(t1) && RelativeTimeIsValid(t2) && ((t2 > 0) ? (t1 < NOEND_ABSTIME - t2) : (t1 > NOSTART_ABSTIME - t2))) /* prevent overflow */ PG_RETURN_ABSOLUTETIME(t1 + t2); PG_RETURN_ABSOLUTETIME(INVALID_ABSTIME);}/* * timemi - returns the value of (abstime t1 - reltime t2) */Datumtimemi(PG_FUNCTION_ARGS){ AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0); RelativeTime t2 = PG_GETARG_RELATIVETIME(1); if (AbsoluteTimeIsReal(t1) && RelativeTimeIsValid(t2) && ((t2 > 0) ? (t1 > NOSTART_ABSTIME + t2) : (t1 < NOEND_ABSTIME + t2))) /* prevent overflow */ PG_RETURN_ABSOLUTETIME(t1 - t2); PG_RETURN_ABSOLUTETIME(INVALID_ABSTIME);}/* * intinterval - returns true iff absolute date is in the interval */Datumintinterval(PG_FUNCTION_ARGS){ AbsoluteTime t = PG_GETARG_ABSOLUTETIME(0); TimeInterval interval = PG_GETARG_TIMEINTERVAL(1); if (interval->status == T_INTERVAL_VALID && t != INVALID_ABSTIME) { if (DatumGetBool(DirectFunctionCall2(abstimege, AbsoluteTimeGetDatum(t), AbsoluteTimeGetDatum(interval->data[0]))) && DatumGetBool(DirectFunctionCall2(abstimele, AbsoluteTimeGetDatum(t), AbsoluteTimeGetDatum(interval->data[1])))) PG_RETURN_BOOL(true); } PG_RETURN_BOOL(false);}/* * tintervalrel - returns relative time corresponding to interval */Datumtintervalrel(PG_FUNCTION_ARGS){ TimeInterval interval = PG_GETARG_TIMEINTERVAL(0); AbsoluteTime t1 = interval->data[0];
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?