PostgreSQL Source Code  git master
timestamp.c File Reference
#include "postgres.h"
#include <ctype.h>
#include <math.h>
#include <limits.h>
#include <sys/time.h>
#include "access/xact.h"
#include "catalog/pg_type.h"
#include "common/int.h"
#include "common/int128.h"
#include "funcapi.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
#include "nodes/nodeFuncs.h"
#include "nodes/supportnodes.h"
#include "parser/scansup.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/date.h"
#include "utils/datetime.h"
#include "utils/float.h"
#include "utils/numeric.h"
#include "utils/sortsupport.h"
Include dependency graph for timestamp.c:

Go to the source code of this file.

Data Structures

struct  generate_series_timestamp_fctx
 
struct  generate_series_timestamptz_fctx
 
struct  IntervalAggState
 

Macros

#define SAMESIGN(a, b)   (((a) < 0) == ((b) < 0))
 
#define IA_TOTAL_COUNT(ia)    ((ia)->N + (ia)->pInfcount + (ia)->nInfcount)
 
#define TIMESTAMP_GT(t1, t2)    DatumGetBool(DirectFunctionCall2(timestamp_gt,t1,t2))
 
#define TIMESTAMP_LT(t1, t2)    DatumGetBool(DirectFunctionCall2(timestamp_lt,t1,t2))
 

Typedefs

typedef struct IntervalAggState IntervalAggState
 

Functions

static TimeOffset time2t (const int hour, const int min, const int sec, const fsec_t fsec)
 
static Timestamp dt2local (Timestamp dt, int timezone)
 
static bool AdjustIntervalForTypmod (Interval *interval, int32 typmod, Node *escontext)
 
static TimestampTz timestamp2timestamptz (Timestamp timestamp)
 
static Timestamp timestamptz2timestamp (TimestampTz timestamp)
 
static void EncodeSpecialInterval (const Interval *interval, char *str)
 
static void interval_um_internal (const Interval *interval, Interval *result)
 
static int32 anytimestamp_typmodin (bool istz, ArrayType *ta)
 
int32 anytimestamp_typmod_check (bool istz, int32 typmod)
 
static char * anytimestamp_typmodout (bool istz, int32 typmod)
 
Datum timestamp_in (PG_FUNCTION_ARGS)
 
Datum timestamp_out (PG_FUNCTION_ARGS)
 
Datum timestamp_recv (PG_FUNCTION_ARGS)
 
Datum timestamp_send (PG_FUNCTION_ARGS)
 
Datum timestamptypmodin (PG_FUNCTION_ARGS)
 
Datum timestamptypmodout (PG_FUNCTION_ARGS)
 
Datum timestamp_support (PG_FUNCTION_ARGS)
 
Datum timestamp_scale (PG_FUNCTION_ARGS)
 
bool AdjustTimestampForTypmod (Timestamp *time, int32 typmod, Node *escontext)
 
Datum timestamptz_in (PG_FUNCTION_ARGS)
 
static int parse_sane_timezone (struct pg_tm *tm, text *zone)
 
static pg_tzlookup_timezone (text *zone)
 
static Timestamp make_timestamp_internal (int year, int month, int day, int hour, int min, double sec)
 
Datum make_timestamp (PG_FUNCTION_ARGS)
 
Datum make_timestamptz (PG_FUNCTION_ARGS)
 
Datum make_timestamptz_at_timezone (PG_FUNCTION_ARGS)
 
Datum float8_timestamptz (PG_FUNCTION_ARGS)
 
Datum timestamptz_out (PG_FUNCTION_ARGS)
 
Datum timestamptz_recv (PG_FUNCTION_ARGS)
 
Datum timestamptz_send (PG_FUNCTION_ARGS)
 
Datum timestamptztypmodin (PG_FUNCTION_ARGS)
 
Datum timestamptztypmodout (PG_FUNCTION_ARGS)
 
Datum timestamptz_scale (PG_FUNCTION_ARGS)
 
Datum interval_in (PG_FUNCTION_ARGS)
 
Datum interval_out (PG_FUNCTION_ARGS)
 
Datum interval_recv (PG_FUNCTION_ARGS)
 
Datum interval_send (PG_FUNCTION_ARGS)
 
Datum intervaltypmodin (PG_FUNCTION_ARGS)
 
Datum intervaltypmodout (PG_FUNCTION_ARGS)
 
static int intervaltypmodleastfield (int32 typmod)
 
Datum interval_support (PG_FUNCTION_ARGS)
 
Datum interval_scale (PG_FUNCTION_ARGS)
 
Datum make_interval (PG_FUNCTION_ARGS)
 
void EncodeSpecialTimestamp (Timestamp dt, char *str)
 
Datum now (PG_FUNCTION_ARGS)
 
Datum statement_timestamp (PG_FUNCTION_ARGS)
 
Datum clock_timestamp (PG_FUNCTION_ARGS)
 
Datum pg_postmaster_start_time (PG_FUNCTION_ARGS)
 
Datum pg_conf_load_time (PG_FUNCTION_ARGS)
 
TimestampTz GetCurrentTimestamp (void)
 
TimestampTz GetSQLCurrentTimestamp (int32 typmod)
 
Timestamp GetSQLLocalTimestamp (int32 typmod)
 
Datum timeofday (PG_FUNCTION_ARGS)
 
void TimestampDifference (TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)
 
long TimestampDifferenceMilliseconds (TimestampTz start_time, TimestampTz stop_time)
 
bool TimestampDifferenceExceeds (TimestampTz start_time, TimestampTz stop_time, int msec)
 
TimestampTz time_t_to_timestamptz (pg_time_t tm)
 
pg_time_t timestamptz_to_time_t (TimestampTz t)
 
const char * timestamptz_to_str (TimestampTz t)
 
void dt2time (Timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec)
 
int timestamp2tm (Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
 
int tm2timestamp (struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result)
 
void interval2itm (Interval span, struct pg_itm *itm)
 
int itm2interval (struct pg_itm *itm, Interval *span)
 
int itmin2interval (struct pg_itm_in *itm_in, Interval *span)
 
Datum timestamp_finite (PG_FUNCTION_ARGS)
 
Datum interval_finite (PG_FUNCTION_ARGS)
 
void GetEpochTime (struct pg_tm *tm)
 
Timestamp SetEpochTimestamp (void)
 
int timestamp_cmp_internal (Timestamp dt1, Timestamp dt2)
 
Datum timestamp_eq (PG_FUNCTION_ARGS)
 
Datum timestamp_ne (PG_FUNCTION_ARGS)
 
Datum timestamp_lt (PG_FUNCTION_ARGS)
 
Datum timestamp_gt (PG_FUNCTION_ARGS)
 
Datum timestamp_le (PG_FUNCTION_ARGS)
 
Datum timestamp_ge (PG_FUNCTION_ARGS)
 
Datum timestamp_cmp (PG_FUNCTION_ARGS)
 
static int timestamp_fastcmp (Datum x, Datum y, SortSupport ssup)
 
Datum timestamp_sortsupport (PG_FUNCTION_ARGS)
 
Datum timestamp_hash (PG_FUNCTION_ARGS)
 
Datum timestamp_hash_extended (PG_FUNCTION_ARGS)
 
int32 timestamp_cmp_timestamptz_internal (Timestamp timestampVal, TimestampTz dt2)
 
Datum timestamp_eq_timestamptz (PG_FUNCTION_ARGS)
 
Datum timestamp_ne_timestamptz (PG_FUNCTION_ARGS)
 
Datum timestamp_lt_timestamptz (PG_FUNCTION_ARGS)
 
Datum timestamp_gt_timestamptz (PG_FUNCTION_ARGS)
 
Datum timestamp_le_timestamptz (PG_FUNCTION_ARGS)
 
Datum timestamp_ge_timestamptz (PG_FUNCTION_ARGS)
 
Datum timestamp_cmp_timestamptz (PG_FUNCTION_ARGS)
 
Datum timestamptz_eq_timestamp (PG_FUNCTION_ARGS)
 
Datum timestamptz_ne_timestamp (PG_FUNCTION_ARGS)
 
Datum timestamptz_lt_timestamp (PG_FUNCTION_ARGS)
 
Datum timestamptz_gt_timestamp (PG_FUNCTION_ARGS)
 
Datum timestamptz_le_timestamp (PG_FUNCTION_ARGS)
 
Datum timestamptz_ge_timestamp (PG_FUNCTION_ARGS)
 
Datum timestamptz_cmp_timestamp (PG_FUNCTION_ARGS)
 
static INT128 interval_cmp_value (const Interval *interval)
 
static int interval_cmp_internal (const Interval *interval1, const Interval *interval2)
 
static int interval_sign (const Interval *interval)
 
Datum interval_eq (PG_FUNCTION_ARGS)
 
Datum interval_ne (PG_FUNCTION_ARGS)
 
Datum interval_lt (PG_FUNCTION_ARGS)
 
Datum interval_gt (PG_FUNCTION_ARGS)
 
Datum interval_le (PG_FUNCTION_ARGS)
 
Datum interval_ge (PG_FUNCTION_ARGS)
 
Datum interval_cmp (PG_FUNCTION_ARGS)
 
Datum interval_hash (PG_FUNCTION_ARGS)
 
Datum interval_hash_extended (PG_FUNCTION_ARGS)
 
Datum overlaps_timestamp (PG_FUNCTION_ARGS)
 
Datum timestamp_smaller (PG_FUNCTION_ARGS)
 
Datum timestamp_larger (PG_FUNCTION_ARGS)
 
Datum timestamp_mi (PG_FUNCTION_ARGS)
 
Datum interval_justify_interval (PG_FUNCTION_ARGS)
 
Datum interval_justify_hours (PG_FUNCTION_ARGS)
 
Datum interval_justify_days (PG_FUNCTION_ARGS)
 
Datum timestamp_pl_interval (PG_FUNCTION_ARGS)
 
Datum timestamp_mi_interval (PG_FUNCTION_ARGS)
 
static TimestampTz timestamptz_pl_interval_internal (TimestampTz timestamp, Interval *span, pg_tz *attimezone)
 
static TimestampTz timestamptz_mi_interval_internal (TimestampTz timestamp, Interval *span, pg_tz *attimezone)
 
Datum timestamptz_pl_interval (PG_FUNCTION_ARGS)
 
Datum timestamptz_mi_interval (PG_FUNCTION_ARGS)
 
Datum timestamptz_pl_interval_at_zone (PG_FUNCTION_ARGS)
 
Datum timestamptz_mi_interval_at_zone (PG_FUNCTION_ARGS)
 
Datum interval_um (PG_FUNCTION_ARGS)
 
Datum interval_smaller (PG_FUNCTION_ARGS)
 
Datum interval_larger (PG_FUNCTION_ARGS)
 
static void finite_interval_pl (const Interval *span1, const Interval *span2, Interval *result)
 
Datum interval_pl (PG_FUNCTION_ARGS)
 
static void finite_interval_mi (const Interval *span1, const Interval *span2, Interval *result)
 
Datum interval_mi (PG_FUNCTION_ARGS)
 
Datum interval_mul (PG_FUNCTION_ARGS)
 
Datum mul_d_interval (PG_FUNCTION_ARGS)
 
Datum interval_div (PG_FUNCTION_ARGS)
 
Datum in_range_timestamptz_interval (PG_FUNCTION_ARGS)
 
Datum in_range_timestamp_interval (PG_FUNCTION_ARGS)
 
Datum in_range_interval_interval (PG_FUNCTION_ARGS)
 
static IntervalAggStatemakeIntervalAggState (FunctionCallInfo fcinfo)
 
static void do_interval_accum (IntervalAggState *state, Interval *newval)
 
static void do_interval_discard (IntervalAggState *state, Interval *newval)
 
Datum interval_avg_accum (PG_FUNCTION_ARGS)
 
Datum interval_avg_combine (PG_FUNCTION_ARGS)
 
Datum interval_avg_serialize (PG_FUNCTION_ARGS)
 
Datum interval_avg_deserialize (PG_FUNCTION_ARGS)
 
Datum interval_avg_accum_inv (PG_FUNCTION_ARGS)
 
Datum interval_avg (PG_FUNCTION_ARGS)
 
Datum interval_sum (PG_FUNCTION_ARGS)
 
Datum timestamp_age (PG_FUNCTION_ARGS)
 
Datum timestamptz_age (PG_FUNCTION_ARGS)
 
Datum timestamp_bin (PG_FUNCTION_ARGS)
 
Datum timestamp_trunc (PG_FUNCTION_ARGS)
 
Datum timestamptz_bin (PG_FUNCTION_ARGS)
 
static TimestampTz timestamptz_trunc_internal (text *units, TimestampTz timestamp, pg_tz *tzp)
 
Datum timestamptz_trunc (PG_FUNCTION_ARGS)
 
Datum timestamptz_trunc_zone (PG_FUNCTION_ARGS)
 
Datum interval_trunc (PG_FUNCTION_ARGS)
 
int isoweek2j (int year, int week)
 
void isoweek2date (int woy, int *year, int *mon, int *mday)
 
void isoweekdate2date (int isoweek, int wday, int *year, int *mon, int *mday)
 
int date2isoweek (int year, int mon, int mday)
 
int date2isoyear (int year, int mon, int mday)
 
int date2isoyearday (int year, int mon, int mday)
 
static float8 NonFiniteTimestampTzPart (int type, int unit, char *lowunits, bool isNegative, bool isTz)
 
static Datum timestamp_part_common (PG_FUNCTION_ARGS, bool retnumeric)
 
Datum timestamp_part (PG_FUNCTION_ARGS)
 
Datum extract_timestamp (PG_FUNCTION_ARGS)
 
static Datum timestamptz_part_common (PG_FUNCTION_ARGS, bool retnumeric)
 
Datum timestamptz_part (PG_FUNCTION_ARGS)
 
Datum extract_timestamptz (PG_FUNCTION_ARGS)
 
static float8 NonFiniteIntervalPart (int type, int unit, char *lowunits, bool isNegative)
 
static Datum interval_part_common (PG_FUNCTION_ARGS, bool retnumeric)
 
Datum interval_part (PG_FUNCTION_ARGS)
 
Datum extract_interval (PG_FUNCTION_ARGS)
 
Datum timestamp_zone (PG_FUNCTION_ARGS)
 
Datum timestamp_izone (PG_FUNCTION_ARGS)
 
bool TimestampTimestampTzRequiresRewrite (void)
 
Datum timestamp_timestamptz (PG_FUNCTION_ARGS)
 
TimestampTz timestamp2timestamptz_opt_overflow (Timestamp timestamp, int *overflow)
 
Datum timestamptz_timestamp (PG_FUNCTION_ARGS)
 
Datum timestamptz_zone (PG_FUNCTION_ARGS)
 
Datum timestamptz_izone (PG_FUNCTION_ARGS)
 
Datum generate_series_timestamp (PG_FUNCTION_ARGS)
 
static Datum generate_series_timestamptz_internal (FunctionCallInfo fcinfo)
 
Datum generate_series_timestamptz (PG_FUNCTION_ARGS)
 
Datum generate_series_timestamptz_at_zone (PG_FUNCTION_ARGS)
 
Datum timestamp_at_local (PG_FUNCTION_ARGS)
 
Datum timestamptz_at_local (PG_FUNCTION_ARGS)
 

Variables

TimestampTz PgStartTime
 
TimestampTz PgReloadTime
 

Macro Definition Documentation

◆ IA_TOTAL_COUNT

#define IA_TOTAL_COUNT (   ia)     ((ia)->N + (ia)->pInfcount + (ia)->nInfcount)

Definition at line 87 of file timestamp.c.

◆ SAMESIGN

#define SAMESIGN (   a,
  b 
)    (((a) < 0) == ((b) < 0))

Definition at line 49 of file timestamp.c.

◆ TIMESTAMP_GT

#define TIMESTAMP_GT (   t1,
  t2 
)     DatumGetBool(DirectFunctionCall2(timestamp_gt,t1,t2))

◆ TIMESTAMP_LT

#define TIMESTAMP_LT (   t1,
  t2 
)     DatumGetBool(DirectFunctionCall2(timestamp_lt,t1,t2))

Typedef Documentation

◆ IntervalAggState

Function Documentation

◆ AdjustIntervalForTypmod()

static bool AdjustIntervalForTypmod ( Interval interval,
int32  typmod,
Node escontext 
)
static

Definition at line 1359 of file timestamp.c.

1361 {
1362  static const int64 IntervalScales[MAX_INTERVAL_PRECISION + 1] = {
1363  INT64CONST(1000000),
1364  INT64CONST(100000),
1365  INT64CONST(10000),
1366  INT64CONST(1000),
1367  INT64CONST(100),
1368  INT64CONST(10),
1369  INT64CONST(1)
1370  };
1371 
1372  static const int64 IntervalOffsets[MAX_INTERVAL_PRECISION + 1] = {
1373  INT64CONST(500000),
1374  INT64CONST(50000),
1375  INT64CONST(5000),
1376  INT64CONST(500),
1377  INT64CONST(50),
1378  INT64CONST(5),
1379  INT64CONST(0)
1380  };
1381 
1382  /* Typmod has no effect on infinite intervals */
1384  return true;
1385 
1386  /*
1387  * Unspecified range and precision? Then not necessary to adjust. Setting
1388  * typmod to -1 is the convention for all data types.
1389  */
1390  if (typmod >= 0)
1391  {
1392  int range = INTERVAL_RANGE(typmod);
1393  int precision = INTERVAL_PRECISION(typmod);
1394 
1395  /*
1396  * Our interpretation of intervals with a limited set of fields is
1397  * that fields to the right of the last one specified are zeroed out,
1398  * but those to the left of it remain valid. Thus for example there
1399  * is no operational difference between INTERVAL YEAR TO MONTH and
1400  * INTERVAL MONTH. In some cases we could meaningfully enforce that
1401  * higher-order fields are zero; for example INTERVAL DAY could reject
1402  * nonzero "month" field. However that seems a bit pointless when we
1403  * can't do it consistently. (We cannot enforce a range limit on the
1404  * highest expected field, since we do not have any equivalent of
1405  * SQL's <interval leading field precision>.) If we ever decide to
1406  * revisit this, interval_support will likely require adjusting.
1407  *
1408  * Note: before PG 8.4 we interpreted a limited set of fields as
1409  * actually causing a "modulo" operation on a given value, potentially
1410  * losing high-order as well as low-order information. But there is
1411  * no support for such behavior in the standard, and it seems fairly
1412  * undesirable on data consistency grounds anyway. Now we only
1413  * perform truncation or rounding of low-order fields.
1414  */
1415  if (range == INTERVAL_FULL_RANGE)
1416  {
1417  /* Do nothing... */
1418  }
1419  else if (range == INTERVAL_MASK(YEAR))
1420  {
1422  interval->day = 0;
1423  interval->time = 0;
1424  }
1425  else if (range == INTERVAL_MASK(MONTH))
1426  {
1427  interval->day = 0;
1428  interval->time = 0;
1429  }
1430  /* YEAR TO MONTH */
1431  else if (range == (INTERVAL_MASK(YEAR) | INTERVAL_MASK(MONTH)))
1432  {
1433  interval->day = 0;
1434  interval->time = 0;
1435  }
1436  else if (range == INTERVAL_MASK(DAY))
1437  {
1438  interval->time = 0;
1439  }
1440  else if (range == INTERVAL_MASK(HOUR))
1441  {
1444  }
1445  else if (range == INTERVAL_MASK(MINUTE))
1446  {
1449  }
1450  else if (range == INTERVAL_MASK(SECOND))
1451  {
1452  /* fractional-second rounding will be dealt with below */
1453  }
1454  /* DAY TO HOUR */
1455  else if (range == (INTERVAL_MASK(DAY) |
1456  INTERVAL_MASK(HOUR)))
1457  {
1460  }
1461  /* DAY TO MINUTE */
1462  else if (range == (INTERVAL_MASK(DAY) |
1463  INTERVAL_MASK(HOUR) |
1465  {
1468  }
1469  /* DAY TO SECOND */
1470  else if (range == (INTERVAL_MASK(DAY) |
1471  INTERVAL_MASK(HOUR) |
1474  {
1475  /* fractional-second rounding will be dealt with below */
1476  }
1477  /* HOUR TO MINUTE */
1478  else if (range == (INTERVAL_MASK(HOUR) |
1480  {
1483  }
1484  /* HOUR TO SECOND */
1485  else if (range == (INTERVAL_MASK(HOUR) |
1488  {
1489  /* fractional-second rounding will be dealt with below */
1490  }
1491  /* MINUTE TO SECOND */
1492  else if (range == (INTERVAL_MASK(MINUTE) |
1494  {
1495  /* fractional-second rounding will be dealt with below */
1496  }
1497  else
1498  elog(ERROR, "unrecognized interval typmod: %d", typmod);
1499 
1500  /* Need to adjust sub-second precision? */
1501  if (precision != INTERVAL_FULL_PRECISION)
1502  {
1503  if (precision < 0 || precision > MAX_INTERVAL_PRECISION)
1504  ereturn(escontext, false,
1505  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1506  errmsg("interval(%d) precision must be between %d and %d",
1507  precision, 0, MAX_INTERVAL_PRECISION)));
1508 
1509  if (interval->time >= INT64CONST(0))
1510  {
1512  IntervalOffsets[precision],
1513  &interval->time))
1514  ereturn(escontext, false,
1515  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1516  errmsg("interval out of range")));
1517  interval->time -= interval->time % IntervalScales[precision];
1518  }
1519  else
1520  {
1522  IntervalOffsets[precision],
1523  &interval->time))
1524  ereturn(escontext, false,
1525  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1526  errmsg("interval out of range")));
1527  interval->time -= interval->time % IntervalScales[precision];
1528  }
1529  }
1530  }
1531 
1532  return true;
1533 }
#define INTERVAL_NOT_FINITE(i)
Definition: timestamp.h:195
#define USECS_PER_HOUR
Definition: timestamp.h:132
#define MONTHS_PER_YEAR
Definition: timestamp.h:108
#define MAX_INTERVAL_PRECISION
Definition: timestamp.h:93
#define USECS_PER_MINUTE
Definition: timestamp.h:133
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define ereturn(context, dummy_value,...)
Definition: elog.h:276
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
#define MONTH
Definition: datetime.h:91
#define HOUR
Definition: datetime.h:100
#define DAY
Definition: datetime.h:93
#define YEAR
Definition: datetime.h:92
#define SECOND
Definition: datetime.h:102
#define MINUTE
Definition: datetime.h:101
static bool pg_sub_s64_overflow(int64 a, int64 b, int64 *result)
Definition: int.h:188
static bool pg_add_s64_overflow(int64 a, int64 b, int64 *result)
Definition: int.h:161
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
#define INTERVAL_FULL_RANGE
Definition: timestamp.h:76
#define INTERVAL_PRECISION(t)
Definition: timestamp.h:81
#define INTERVAL_RANGE(t)
Definition: timestamp.h:82
#define INTERVAL_MASK(b)
Definition: timestamp.h:73
#define INTERVAL_FULL_PRECISION
Definition: timestamp.h:78

References DAY, elog, ereturn, errcode(), errmsg(), ERROR, HOUR, INTERVAL_FULL_PRECISION, INTERVAL_FULL_RANGE, INTERVAL_MASK, INTERVAL_NOT_FINITE, INTERVAL_PRECISION, INTERVAL_RANGE, MAX_INTERVAL_PRECISION, MINUTE, MONTH, interval::month, MONTHS_PER_YEAR, pg_add_s64_overflow(), pg_sub_s64_overflow(), range(), SECOND, interval::time, USECS_PER_HOUR, USECS_PER_MINUTE, and YEAR.

Referenced by interval_in(), interval_recv(), and interval_scale().

◆ AdjustTimestampForTypmod()

bool AdjustTimestampForTypmod ( Timestamp time,
int32  typmod,
Node escontext 
)

Definition at line 366 of file timestamp.c.

367 {
368  static const int64 TimestampScales[MAX_TIMESTAMP_PRECISION + 1] = {
369  INT64CONST(1000000),
370  INT64CONST(100000),
371  INT64CONST(10000),
372  INT64CONST(1000),
373  INT64CONST(100),
374  INT64CONST(10),
375  INT64CONST(1)
376  };
377 
378  static const int64 TimestampOffsets[MAX_TIMESTAMP_PRECISION + 1] = {
379  INT64CONST(500000),
380  INT64CONST(50000),
381  INT64CONST(5000),
382  INT64CONST(500),
383  INT64CONST(50),
384  INT64CONST(5),
385  INT64CONST(0)
386  };
387 
388  if (!TIMESTAMP_NOT_FINITE(*time)
389  && (typmod != -1) && (typmod != MAX_TIMESTAMP_PRECISION))
390  {
391  if (typmod < 0 || typmod > MAX_TIMESTAMP_PRECISION)
392  ereturn(escontext, false,
393  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
394  errmsg("timestamp(%d) precision must be between %d and %d",
395  typmod, 0, MAX_TIMESTAMP_PRECISION)));
396 
397  if (*time >= INT64CONST(0))
398  {
399  *time = ((*time + TimestampOffsets[typmod]) / TimestampScales[typmod]) *
400  TimestampScales[typmod];
401  }
402  else
403  {
404  *time = -((((-*time) + TimestampOffsets[typmod]) / TimestampScales[typmod])
405  * TimestampScales[typmod]);
406  }
407  }
408 
409  return true;
410 }
#define MAX_TIMESTAMP_PRECISION
Definition: timestamp.h:92
#define TIMESTAMP_NOT_FINITE(j)
Definition: timestamp.h:169

References ereturn, errcode(), errmsg(), MAX_TIMESTAMP_PRECISION, and TIMESTAMP_NOT_FINITE.

Referenced by executeDateTimeMethod(), GetSQLCurrentTimestamp(), GetSQLLocalTimestamp(), parse_datetime(), timestamp_in(), timestamp_recv(), timestamp_scale(), timestamptz_in(), timestamptz_recv(), timestamptz_scale(), and to_timestamp().

◆ anytimestamp_typmod_check()

int32 anytimestamp_typmod_check ( bool  istz,
int32  typmod 
)

Definition at line 123 of file timestamp.c.

124 {
125  if (typmod < 0)
126  ereport(ERROR,
127  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
128  errmsg("TIMESTAMP(%d)%s precision must not be negative",
129  typmod, (istz ? " WITH TIME ZONE" : ""))));
130  if (typmod > MAX_TIMESTAMP_PRECISION)
131  {
133  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
134  errmsg("TIMESTAMP(%d)%s precision reduced to maximum allowed, %d",
135  typmod, (istz ? " WITH TIME ZONE" : ""),
137  typmod = MAX_TIMESTAMP_PRECISION;
138  }
139 
140  return typmod;
141 }
#define WARNING
Definition: elog.h:36
#define ereport(elevel,...)
Definition: elog.h:149

References ereport, errcode(), errmsg(), ERROR, MAX_TIMESTAMP_PRECISION, and WARNING.

Referenced by anytimestamp_typmodin(), executeDateTimeMethod(), and transformSQLValueFunction().

◆ anytimestamp_typmodin()

static int32 anytimestamp_typmodin ( bool  istz,
ArrayType ta 
)
static

Definition at line 102 of file timestamp.c.

103 {
104  int32 *tl;
105  int n;
106 
107  tl = ArrayGetIntegerTypmods(ta, &n);
108 
109  /*
110  * we're not too tense about good error message here because grammar
111  * shouldn't allow wrong number of modifiers for TIMESTAMP
112  */
113  if (n != 1)
114  ereport(ERROR,
115  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
116  errmsg("invalid type modifier")));
117 
118  return anytimestamp_typmod_check(istz, tl[0]);
119 }
int32 * ArrayGetIntegerTypmods(ArrayType *arr, int *n)
Definition: arrayutils.c:233
int32 anytimestamp_typmod_check(bool istz, int32 typmod)
Definition: timestamp.c:123
signed int int32
Definition: c.h:494

References anytimestamp_typmod_check(), ArrayGetIntegerTypmods(), ereport, errcode(), errmsg(), and ERROR.

Referenced by timestamptypmodin(), and timestamptztypmodin().

◆ anytimestamp_typmodout()

static char* anytimestamp_typmodout ( bool  istz,
int32  typmod 
)
static

Definition at line 145 of file timestamp.c.

146 {
147  const char *tz = istz ? " with time zone" : " without time zone";
148 
149  if (typmod >= 0)
150  return psprintf("(%d)%s", (int) typmod, tz);
151  else
152  return pstrdup(tz);
153 }
char * pstrdup(const char *in)
Definition: mcxt.c:1695
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46

References psprintf(), and pstrdup().

Referenced by timestamptypmodout(), and timestamptztypmodout().

◆ clock_timestamp()

Datum clock_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 1630 of file timestamp.c.

1631 {
1633 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1654
#define PG_RETURN_TIMESTAMPTZ(x)
Definition: timestamp.h:68

References GetCurrentTimestamp(), and PG_RETURN_TIMESTAMPTZ.

◆ date2isoweek()

int date2isoweek ( int  year,
int  mon,
int  mday 
)

Definition at line 5155 of file timestamp.c.

5156 {
5157  float8 result;
5158  int day0,
5159  day4,
5160  dayn;
5161 
5162  /* current day */
5163  dayn = date2j(year, mon, mday);
5164 
5165  /* fourth day of current year */
5166  day4 = date2j(year, 1, 4);
5167 
5168  /* day0 == offset to first day of week (Monday) */
5169  day0 = j2day(day4 - 1);
5170 
5171  /*
5172  * We need the first week containing a Thursday, otherwise this day falls
5173  * into the previous year for purposes of counting weeks
5174  */
5175  if (dayn < day4 - day0)
5176  {
5177  day4 = date2j(year - 1, 1, 4);
5178 
5179  /* day0 == offset to first day of week (Monday) */
5180  day0 = j2day(day4 - 1);
5181  }
5182 
5183  result = (dayn - (day4 - day0)) / 7 + 1;
5184 
5185  /*
5186  * Sometimes the last few days in a year will fall into the first week of
5187  * the next year, so check for this.
5188  */
5189  if (result >= 52)
5190  {
5191  day4 = date2j(year + 1, 1, 4);
5192 
5193  /* day0 == offset to first day of week (Monday) */
5194  day0 = j2day(day4 - 1);
5195 
5196  if (dayn >= day4 - day0)
5197  result = (dayn - (day4 - day0)) / 7 + 1;
5198  }
5199 
5200  return (int) result;
5201 }
int j2day(int date)
Definition: datetime.c:344
int date2j(int year, int month, int day)
Definition: datetime.c:286
double float8
Definition: c.h:630

References date2j(), and j2day().

Referenced by DCH_to_char(), extract_date(), timestamp_part_common(), timestamp_trunc(), timestamptz_part_common(), and timestamptz_trunc_internal().

◆ date2isoyear()

int date2isoyear ( int  year,
int  mon,
int  mday 
)

Definition at line 5210 of file timestamp.c.

5211 {
5212  float8 result;
5213  int day0,
5214  day4,
5215  dayn;
5216 
5217  /* current day */
5218  dayn = date2j(year, mon, mday);
5219 
5220  /* fourth day of current year */
5221  day4 = date2j(year, 1, 4);
5222 
5223  /* day0 == offset to first day of week (Monday) */
5224  day0 = j2day(day4 - 1);
5225 
5226  /*
5227  * We need the first week containing a Thursday, otherwise this day falls
5228  * into the previous year for purposes of counting weeks
5229  */
5230  if (dayn < day4 - day0)
5231  {
5232  day4 = date2j(year - 1, 1, 4);
5233 
5234  /* day0 == offset to first day of week (Monday) */
5235  day0 = j2day(day4 - 1);
5236 
5237  year--;
5238  }
5239 
5240  result = (dayn - (day4 - day0)) / 7 + 1;
5241 
5242  /*
5243  * Sometimes the last few days in a year will fall into the first week of
5244  * the next year, so check for this.
5245  */
5246  if (result >= 52)
5247  {
5248  day4 = date2j(year + 1, 1, 4);
5249 
5250  /* day0 == offset to first day of week (Monday) */
5251  day0 = j2day(day4 - 1);
5252 
5253  if (dayn >= day4 - day0)
5254  year++;
5255  }
5256 
5257  return year;
5258 }

References date2j(), and j2day().

Referenced by date2isoyearday(), DCH_to_char(), extract_date(), timestamp_part_common(), and timestamptz_part_common().

◆ date2isoyearday()

int date2isoyearday ( int  year,
int  mon,
int  mday 
)

Definition at line 5267 of file timestamp.c.

5268 {
5269  return date2j(year, mon, mday) - isoweek2j(date2isoyear(year, mon, mday), 1) + 1;
5270 }
int isoweek2j(int year, int week)
Definition: timestamp.c:5104
int date2isoyear(int year, int mon, int mday)
Definition: timestamp.c:5210

References date2isoyear(), date2j(), and isoweek2j().

Referenced by DCH_to_char().

◆ do_interval_accum()

static void do_interval_accum ( IntervalAggState state,
Interval newval 
)
static

Definition at line 3936 of file timestamp.c.

3937 {
3938  /* Infinite inputs are counted separately, and do not affect "N" */
3940  {
3941  state->nInfcount++;
3942  return;
3943  }
3944 
3946  {
3947  state->pInfcount++;
3948  return;
3949  }
3950 
3951  finite_interval_pl(&state->sumX, newval, &state->sumX);
3952  state->N++;
3953 }
static void finite_interval_pl(const Interval *span1, const Interval *span2, Interval *result)
Definition: timestamp.c:3435
#define INTERVAL_IS_NOBEGIN(i)
Definition: timestamp.h:182
#define INTERVAL_IS_NOEND(i)
Definition: timestamp.h:192
#define newval
Definition: regguts.h:323

References finite_interval_pl(), INTERVAL_IS_NOBEGIN, INTERVAL_IS_NOEND, and newval.

Referenced by interval_avg_accum().

◆ do_interval_discard()

static void do_interval_discard ( IntervalAggState state,
Interval newval 
)
static

Definition at line 3959 of file timestamp.c.

3960 {
3961  /* Infinite inputs are counted separately, and do not affect "N" */
3963  {
3964  state->nInfcount--;
3965  return;
3966  }
3967 
3969  {
3970  state->pInfcount--;
3971  return;
3972  }
3973 
3974  /* Handle the to-be-discarded finite value. */
3975  state->N--;
3976  if (state->N > 0)
3977  finite_interval_mi(&state->sumX, newval, &state->sumX);
3978  else
3979  {
3980  /* All values discarded, reset the state */
3981  Assert(state->N == 0);
3982  memset(&state->sumX, 0, sizeof(state->sumX));
3983  }
3984 }
static void finite_interval_mi(const Interval *span1, const Interval *span2, Interval *result)
Definition: timestamp.c:3491
#define Assert(condition)
Definition: c.h:858

References Assert, finite_interval_mi(), INTERVAL_IS_NOBEGIN, INTERVAL_IS_NOEND, and newval.

Referenced by interval_avg_accum_inv().

◆ dt2local()

static Timestamp dt2local ( Timestamp  dt,
int  timezone 
)
static

Definition at line 2134 of file timestamp.c.

2135 {
2136  dt -= (timezone * USECS_PER_SEC);
2137  return dt;
2138 }
#define USECS_PER_SEC
Definition: timestamp.h:134

References USECS_PER_SEC.

Referenced by make_timestamptz_at_timezone(), timestamp2timestamptz_opt_overflow(), timestamp_izone(), timestamp_zone(), timestamptz_izone(), timestamptz_zone(), and tm2timestamp().

◆ dt2time()

void dt2time ( Timestamp  jd,
int *  hour,
int *  min,
int *  sec,
fsec_t fsec 
)

Definition at line 1874 of file timestamp.c.

1875 {
1876  TimeOffset time;
1877 
1878  time = jd;
1879 
1880  *hour = time / USECS_PER_HOUR;
1881  time -= (*hour) * USECS_PER_HOUR;
1882  *min = time / USECS_PER_MINUTE;
1883  time -= (*min) * USECS_PER_MINUTE;
1884  *sec = time / USECS_PER_SEC;
1885  *fsec = time - (*sec * USECS_PER_SEC);
1886 } /* dt2time() */
int64 TimeOffset
Definition: timestamp.h:40

References USECS_PER_HOUR, USECS_PER_MINUTE, and USECS_PER_SEC.

Referenced by DecodeDateTime(), DecodeTimeOnly(), and timestamp2tm().

◆ EncodeSpecialInterval()

static void EncodeSpecialInterval ( const Interval interval,
char *  str 
)
static

Definition at line 1607 of file timestamp.c.

1608 {
1610  strcpy(str, EARLY);
1611  else if (INTERVAL_IS_NOEND(interval))
1612  strcpy(str, LATE);
1613  else /* shouldn't happen */
1614  elog(ERROR, "invalid argument for EncodeSpecialInterval");
1615 }
const char * str
#define EARLY
Definition: datetime.h:39
#define LATE
Definition: datetime.h:40

References EARLY, elog, ERROR, INTERVAL_IS_NOBEGIN, INTERVAL_IS_NOEND, LATE, and str.

Referenced by interval_out().

◆ EncodeSpecialTimestamp()

void EncodeSpecialTimestamp ( Timestamp  dt,
char *  str 
)

Definition at line 1596 of file timestamp.c.

1597 {
1598  if (TIMESTAMP_IS_NOBEGIN(dt))
1599  strcpy(str, EARLY);
1600  else if (TIMESTAMP_IS_NOEND(dt))
1601  strcpy(str, LATE);
1602  else /* shouldn't happen */
1603  elog(ERROR, "invalid argument for EncodeSpecialTimestamp");
1604 }
#define TIMESTAMP_IS_NOEND(j)
Definition: timestamp.h:167
#define TIMESTAMP_IS_NOBEGIN(j)
Definition: timestamp.h:162

References EARLY, elog, ERROR, LATE, str, TIMESTAMP_IS_NOBEGIN, and TIMESTAMP_IS_NOEND.

Referenced by JsonEncodeDateTime(), PGTYPEStimestamp_to_asc(), timestamp_out(), timestamptz_out(), and timestamptz_to_str().

◆ extract_interval()

Datum extract_interval ( PG_FUNCTION_ARGS  )

Definition at line 6137 of file timestamp.c.

6138 {
6139  return interval_part_common(fcinfo, true);
6140 }
static Datum interval_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition: timestamp.c:5939

References interval_part_common().

◆ extract_timestamp()

Datum extract_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 5605 of file timestamp.c.

5606 {
5607  return timestamp_part_common(fcinfo, true);
5608 }
static Datum timestamp_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition: timestamp.c:5341

References timestamp_part_common().

◆ extract_timestamptz()

Datum extract_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 5877 of file timestamp.c.

5878 {
5879  return timestamptz_part_common(fcinfo, true);
5880 }
static Datum timestamptz_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition: timestamp.c:5614

References timestamptz_part_common().

◆ finite_interval_mi()

static void finite_interval_mi ( const Interval span1,
const Interval span2,
Interval result 
)
static

Definition at line 3491 of file timestamp.c.

3492 {
3493  Assert(!INTERVAL_NOT_FINITE(span1));
3494  Assert(!INTERVAL_NOT_FINITE(span2));
3495 
3496  if (pg_sub_s32_overflow(span1->month, span2->month, &result->month) ||
3497  pg_sub_s32_overflow(span1->day, span2->day, &result->day) ||
3498  pg_sub_s64_overflow(span1->time, span2->time, &result->time) ||
3499  INTERVAL_NOT_FINITE(result))
3500  ereport(ERROR,
3501  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3502  errmsg("interval out of range")));
3503 }
static bool pg_sub_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:122
int32 day
Definition: timestamp.h:51
int32 month
Definition: timestamp.h:52
TimeOffset time
Definition: timestamp.h:49

References Assert, Interval::day, ereport, errcode(), errmsg(), ERROR, INTERVAL_NOT_FINITE, Interval::month, pg_sub_s32_overflow(), pg_sub_s64_overflow(), and Interval::time.

Referenced by do_interval_discard(), and interval_mi().

◆ finite_interval_pl()

static void finite_interval_pl ( const Interval span1,
const Interval span2,
Interval result 
)
static

Definition at line 3435 of file timestamp.c.

3436 {
3437  Assert(!INTERVAL_NOT_FINITE(span1));
3438  Assert(!INTERVAL_NOT_FINITE(span2));
3439 
3440  if (pg_add_s32_overflow(span1->month, span2->month, &result->month) ||
3441  pg_add_s32_overflow(span1->day, span2->day, &result->day) ||
3442  pg_add_s64_overflow(span1->time, span2->time, &result->time) ||
3443  INTERVAL_NOT_FINITE(result))
3444  ereport(ERROR,
3445  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3446  errmsg("interval out of range")));
3447 }
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:104

References Assert, Interval::day, ereport, errcode(), errmsg(), ERROR, INTERVAL_NOT_FINITE, Interval::month, pg_add_s32_overflow(), pg_add_s64_overflow(), and Interval::time.

Referenced by do_interval_accum(), interval_avg_combine(), and interval_pl().

◆ float8_timestamptz()

Datum float8_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 735 of file timestamp.c.

736 {
737  float8 seconds = PG_GETARG_FLOAT8(0);
738  TimestampTz result;
739 
740  /* Deal with NaN and infinite inputs ... */
741  if (isnan(seconds))
742  ereport(ERROR,
743  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
744  errmsg("timestamp cannot be NaN")));
745 
746  if (isinf(seconds))
747  {
748  if (seconds < 0)
749  TIMESTAMP_NOBEGIN(result);
750  else
751  TIMESTAMP_NOEND(result);
752  }
753  else
754  {
755  /* Out of range? */
756  if (seconds <
758  || seconds >=
760  ereport(ERROR,
761  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
762  errmsg("timestamp out of range: \"%g\"", seconds)));
763 
764  /* Convert UNIX epoch to Postgres epoch */
766 
767  seconds = rint(seconds * USECS_PER_SEC);
768  result = (int64) seconds;
769 
770  /* Recheck in case roundoff produces something just out of range */
771  if (!IS_VALID_TIMESTAMP(result))
772  ereport(ERROR,
773  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
774  errmsg("timestamp out of range: \"%g\"",
775  PG_GETARG_FLOAT8(0))));
776  }
777 
778  PG_RETURN_TIMESTAMP(result);
779 }
#define DATETIME_MIN_JULIAN
Definition: timestamp.h:251
int64 TimestampTz
Definition: timestamp.h:39
#define TIMESTAMP_NOBEGIN(j)
Definition: timestamp.h:159
#define TIMESTAMP_END_JULIAN
Definition: timestamp.h:253
#define IS_VALID_TIMESTAMP(t)
Definition: timestamp.h:267
#define UNIX_EPOCH_JDATE
Definition: timestamp.h:234
#define SECS_PER_DAY
Definition: timestamp.h:126
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:235
#define TIMESTAMP_NOEND(j)
Definition: timestamp.h:164
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:282
#define PG_RETURN_TIMESTAMP(x)
Definition: timestamp.h:67

References DATETIME_MIN_JULIAN, ereport, errcode(), errmsg(), ERROR, IS_VALID_TIMESTAMP, PG_GETARG_FLOAT8, PG_RETURN_TIMESTAMP, POSTGRES_EPOCH_JDATE, SECS_PER_DAY, TIMESTAMP_END_JULIAN, TIMESTAMP_NOBEGIN, TIMESTAMP_NOEND, UNIX_EPOCH_JDATE, and USECS_PER_SEC.

◆ generate_series_timestamp()

Datum generate_series_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 6494 of file timestamp.c.

6495 {
6496  FuncCallContext *funcctx;
6498  Timestamp result;
6499 
6500  /* stuff done only on the first call of the function */
6501  if (SRF_IS_FIRSTCALL())
6502  {
6504  Timestamp finish = PG_GETARG_TIMESTAMP(1);
6505  Interval *step = PG_GETARG_INTERVAL_P(2);
6506  MemoryContext oldcontext;
6507 
6508  /* create a function context for cross-call persistence */
6509  funcctx = SRF_FIRSTCALL_INIT();
6510 
6511  /*
6512  * switch to memory context appropriate for multiple function calls
6513  */
6514  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
6515 
6516  /* allocate memory for user context */
6519 
6520  /*
6521  * Use fctx to keep state from call to call. Seed current with the
6522  * original start value
6523  */
6524  fctx->current = start;
6525  fctx->finish = finish;
6526  fctx->step = *step;
6527 
6528  /* Determine sign of the interval */
6529  fctx->step_sign = interval_sign(&fctx->step);
6530 
6531  if (fctx->step_sign == 0)
6532  ereport(ERROR,
6533  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6534  errmsg("step size cannot equal zero")));
6535 
6536  if (INTERVAL_NOT_FINITE((&fctx->step)))
6537  ereport(ERROR,
6538  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6539  errmsg("step size cannot be infinite")));
6540 
6541  funcctx->user_fctx = fctx;
6542  MemoryContextSwitchTo(oldcontext);
6543  }
6544 
6545  /* stuff done on every call of the function */
6546  funcctx = SRF_PERCALL_SETUP();
6547 
6548  /*
6549  * get the saved state and use current as the result for this iteration
6550  */
6551  fctx = funcctx->user_fctx;
6552  result = fctx->current;
6553 
6554  if (fctx->step_sign > 0 ?
6555  timestamp_cmp_internal(result, fctx->finish) <= 0 :
6556  timestamp_cmp_internal(result, fctx->finish) >= 0)
6557  {
6558  /* increment current in preparation for next iteration */
6560  TimestampGetDatum(fctx->current),
6561  PointerGetDatum(&fctx->step)));
6562 
6563  /* do when there is more left to send */
6564  SRF_RETURN_NEXT(funcctx, TimestampGetDatum(result));
6565  }
6566  else
6567  {
6568  /* do when there is no more left */
6569  SRF_RETURN_DONE(funcctx);
6570  }
6571 }
int timestamp_cmp_internal(Timestamp dt1, Timestamp dt2)
Definition: timestamp.c:2210
Datum timestamp_pl_interval(PG_FUNCTION_ARGS)
Definition: timestamp.c:3049
static int interval_sign(const Interval *interval)
Definition: timestamp.c:2514
int64 Timestamp
Definition: timestamp.h:38
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:644
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:304
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:308
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:310
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:306
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:328
return str start
void * palloc(Size size)
Definition: mcxt.c:1316
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
MemoryContextSwitchTo(old_ctx)
void * user_fctx
Definition: funcapi.h:82
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:101
static Datum TimestampGetDatum(Timestamp X)
Definition: timestamp.h:46
#define PG_GETARG_TIMESTAMP(n)
Definition: timestamp.h:63
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:65
static Timestamp DatumGetTimestamp(Datum X)
Definition: timestamp.h:28

References generate_series_timestamp_fctx::current, DatumGetTimestamp(), DirectFunctionCall2, ereport, errcode(), errmsg(), ERROR, generate_series_timestamp_fctx::finish, INTERVAL_NOT_FINITE, interval_sign(), MemoryContextSwitchTo(), FuncCallContext::multi_call_memory_ctx, palloc(), PG_GETARG_INTERVAL_P, PG_GETARG_TIMESTAMP, PointerGetDatum(), SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, start, generate_series_timestamp_fctx::step, generate_series_timestamp_fctx::step_sign, timestamp_cmp_internal(), timestamp_pl_interval(), TimestampGetDatum(), and FuncCallContext::user_fctx.

◆ generate_series_timestamptz()

Datum generate_series_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 6660 of file timestamp.c.

6661 {
6662  return generate_series_timestamptz_internal(fcinfo);
6663 }
static Datum generate_series_timestamptz_internal(FunctionCallInfo fcinfo)
Definition: timestamp.c:6578

References generate_series_timestamptz_internal().

◆ generate_series_timestamptz_at_zone()

Datum generate_series_timestamptz_at_zone ( PG_FUNCTION_ARGS  )

Definition at line 6666 of file timestamp.c.

6667 {
6668  return generate_series_timestamptz_internal(fcinfo);
6669 }

References generate_series_timestamptz_internal().

◆ generate_series_timestamptz_internal()

static Datum generate_series_timestamptz_internal ( FunctionCallInfo  fcinfo)
static

Definition at line 6578 of file timestamp.c.

6579 {
6580  FuncCallContext *funcctx;
6582  TimestampTz result;
6583 
6584  /* stuff done only on the first call of the function */
6585  if (SRF_IS_FIRSTCALL())
6586  {
6588  TimestampTz finish = PG_GETARG_TIMESTAMPTZ(1);
6589  Interval *step = PG_GETARG_INTERVAL_P(2);
6590  text *zone = (PG_NARGS() == 4) ? PG_GETARG_TEXT_PP(3) : NULL;
6591  MemoryContext oldcontext;
6592 
6593  /* create a function context for cross-call persistence */
6594  funcctx = SRF_FIRSTCALL_INIT();
6595 
6596  /*
6597  * switch to memory context appropriate for multiple function calls
6598  */
6599  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
6600 
6601  /* allocate memory for user context */
6604 
6605  /*
6606  * Use fctx to keep state from call to call. Seed current with the
6607  * original start value
6608  */
6609  fctx->current = start;
6610  fctx->finish = finish;
6611  fctx->step = *step;
6613 
6614  /* Determine sign of the interval */
6615  fctx->step_sign = interval_sign(&fctx->step);
6616 
6617  if (fctx->step_sign == 0)
6618  ereport(ERROR,
6619  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6620  errmsg("step size cannot equal zero")));
6621 
6622  if (INTERVAL_NOT_FINITE((&fctx->step)))
6623  ereport(ERROR,
6624  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6625  errmsg("step size cannot be infinite")));
6626 
6627  funcctx->user_fctx = fctx;
6628  MemoryContextSwitchTo(oldcontext);
6629  }
6630 
6631  /* stuff done on every call of the function */
6632  funcctx = SRF_PERCALL_SETUP();
6633 
6634  /*
6635  * get the saved state and use current as the result for this iteration
6636  */
6637  fctx = funcctx->user_fctx;
6638  result = fctx->current;
6639 
6640  if (fctx->step_sign > 0 ?
6641  timestamp_cmp_internal(result, fctx->finish) <= 0 :
6642  timestamp_cmp_internal(result, fctx->finish) >= 0)
6643  {
6644  /* increment current in preparation for next iteration */
6646  &fctx->step,
6647  fctx->attimezone);
6648 
6649  /* do when there is more left to send */
6650  SRF_RETURN_NEXT(funcctx, TimestampTzGetDatum(result));
6651  }
6652  else
6653  {
6654  /* do when there is no more left */
6655  SRF_RETURN_DONE(funcctx);
6656  }
6657 }
static pg_tz * lookup_timezone(text *zone)
Definition: timestamp.c:558
static TimestampTz timestamptz_pl_interval_internal(TimestampTz timestamp, Interval *span, pg_tz *attimezone)
Definition: timestamp.c:3186
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_NARGS()
Definition: fmgr.h:203
PGDLLIMPORT pg_tz * session_timezone
Definition: pgtz.c:28
Definition: c.h:687
Definition: zic.c:94
static Datum TimestampTzGetDatum(TimestampTz X)
Definition: timestamp.h:52
#define PG_GETARG_TIMESTAMPTZ(n)
Definition: timestamp.h:64

References generate_series_timestamptz_fctx::attimezone, generate_series_timestamptz_fctx::current, ereport, errcode(), errmsg(), ERROR, generate_series_timestamptz_fctx::finish, INTERVAL_NOT_FINITE, interval_sign(), lookup_timezone(), MemoryContextSwitchTo(), FuncCallContext::multi_call_memory_ctx, palloc(), PG_GETARG_INTERVAL_P, PG_GETARG_TEXT_PP, PG_GETARG_TIMESTAMPTZ, PG_NARGS, session_timezone, SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, start, generate_series_timestamptz_fctx::step, generate_series_timestamptz_fctx::step_sign, timestamp_cmp_internal(), timestamptz_pl_interval_internal(), TimestampTzGetDatum(), and FuncCallContext::user_fctx.

Referenced by generate_series_timestamptz(), and generate_series_timestamptz_at_zone().

◆ GetCurrentTimestamp()

TimestampTz GetCurrentTimestamp ( void  )

Definition at line 1654 of file timestamp.c.

1655 {
1656  TimestampTz result;
1657  struct timeval tp;
1658 
1659  gettimeofday(&tp, NULL);
1660 
1661  result = (TimestampTz) tp.tv_sec -
1663  result = (result * USECS_PER_SEC) + tp.tv_usec;
1664 
1665  return result;
1666 }
int gettimeofday(struct timeval *tp, void *tzp)

References gettimeofday(), POSTGRES_EPOCH_JDATE, SECS_PER_DAY, UNIX_EPOCH_JDATE, and USECS_PER_SEC.

Referenced by ApplyLauncherMain(), asyncQueueFillWarning(), autoprewarm_main(), BackgroundWriterMain(), bbsink_copystream_archive_contents(), bbsink_copystream_end_archive(), bbsink_copystream_new(), bbsink_throttle_begin_backup(), check_log_duration(), CheckPointGuts(), CleanupBackgroundWorker(), clock_timestamp(), CreateCheckPoint(), CreateEndOfRecoveryRecord(), CreateOverwriteContrecordRecord(), CreateRestartPoint(), dblink_cancel_query(), DetermineSleepTime(), disable_timeout(), disable_timeouts(), do_analyze_rel(), do_start_bgworker(), do_start_worker(), enable_startup_progress_timeout(), enable_timeout_after(), enable_timeout_at(), enable_timeout_every(), enable_timeouts(), entry_alloc(), entry_reset(), get_role_password(), GetCurrentTransactionStopTimestamp(), GetReplicationApplyDelay(), handle_sig_alarm(), has_startup_progress_timeout_expired(), heap_vacuum_rel(), initialize_prng(), InitProcessGlobals(), KnownAssignedXidsCompress(), launcher_determine_sleep(), libpqsrv_cancel(), LockBufferForCleanup(), log_disconnections(), LogCheckpointEnd(), logicalrep_worker_launch(), LogicalRepApplyLoop(), maybe_start_bgworkers(), pa_send_data(), PerformWalRecovery(), pgfdw_abort_cleanup_begin(), pgfdw_cancel_query(), pgfdw_exec_cleanup_query(), pgfdw_finish_abort_cleanup(), pgfdw_get_cleanup_result(), pgss_shmem_startup(), pgstat_build_snapshot(), pgstat_report_activity(), pgstat_report_analyze(), pgstat_report_archiver(), pgstat_report_autovac(), pgstat_report_checksum_failures_in_db(), pgstat_report_stat(), pgstat_report_vacuum(), pgstat_reset(), pgstat_reset_after_failure(), pgstat_reset_counters(), pgstat_reset_of_kind(), pgstat_reset_slru(), PostgresSingleUserMain(), PostmasterMain(), PrepareForIncrementalBackup(), PrepareTransaction(), process_syncing_tables_for_apply(), ProcessConfigFileInternal(), ProcessPendingWrites(), ProcessRepliesIfAny(), ProcessStandbyReplyMessage(), ProcessWalSndrMessage(), ProcSleep(), rebuild_database_list(), RecordTransactionAbort(), RecordTransactionAbortPrepared(), RecordTransactionCommitPrepared(), recoveryApplyDelay(), ReplicationSlotRelease(), reschedule_timeouts(), ResolveRecoveryConflictWithBufferPin(), ResolveRecoveryConflictWithLock(), ResolveRecoveryConflictWithVirtualXIDs(), RestoreSlotFromDisk(), send_feedback(), SetCurrentStatementStartTimestamp(), SetupApplyOrSyncWorker(), StartTransaction(), test_pattern(), test_random(), throttle(), update_synced_slots_inactive_since(), UpdateWorkerStats(), WaitExceedsMaxStandbyDelay(), WaitForWalSummarization(), WaitForWALToBecomeAvailable(), WalReceiverMain(), WalSndKeepalive(), WalSndLoop(), WalSndUpdateProgress(), WalSndWaitForWal(), WalSndWriteData(), XLogBackgroundFlush(), XLogFileRead(), XLogPrefetchResetStats(), XLogPrefetchShmemInit(), XLogRestorePoint(), XLogSendPhysical(), XLogWalRcvSendHSFeedback(), and XLogWalRcvSendReply().

◆ GetEpochTime()

void GetEpochTime ( struct pg_tm tm)

Definition at line 2168 of file timestamp.c.

2169 {
2170  struct pg_tm *t0;
2171  pg_time_t epoch = 0;
2172 
2173  t0 = pg_gmtime(&epoch);
2174 
2175  if (t0 == NULL)
2176  elog(ERROR, "could not convert epoch to timestamp: %m");
2177 
2178  tm->tm_year = t0->tm_year;
2179  tm->tm_mon = t0->tm_mon;
2180  tm->tm_mday = t0->tm_mday;
2181  tm->tm_hour = t0->tm_hour;
2182  tm->tm_min = t0->tm_min;
2183  tm->tm_sec = t0->tm_sec;
2184 
2185  tm->tm_year += 1900;
2186  tm->tm_mon++;
2187 }
static struct pg_tm tm
Definition: localtime.c:104
struct pg_tm * pg_gmtime(const pg_time_t *timep)
Definition: localtime.c:1389
int64 pg_time_t
Definition: pgtime.h:23
Definition: pgtime.h:35
int tm_hour
Definition: pgtime.h:38
int tm_mday
Definition: pgtime.h:39
int tm_mon
Definition: pgtime.h:40
int tm_min
Definition: pgtime.h:37
int tm_sec
Definition: pgtime.h:36
int tm_year
Definition: pgtime.h:41
static const unsigned __int64 epoch

References elog, epoch, ERROR, pg_gmtime(), tm, pg_tm::tm_hour, pg_tm::tm_mday, pg_tm::tm_min, pg_tm::tm_mon, pg_tm::tm_sec, and pg_tm::tm_year.

Referenced by date_in(), PGTYPESdate_from_asc(), and SetEpochTimestamp().

◆ GetSQLCurrentTimestamp()

TimestampTz GetSQLCurrentTimestamp ( int32  typmod)

Definition at line 1672 of file timestamp.c.

1673 {
1674  TimestampTz ts;
1675 
1677  if (typmod >= 0)
1678  AdjustTimestampForTypmod(&ts, typmod, NULL);
1679  return ts;
1680 }
bool AdjustTimestampForTypmod(Timestamp *time, int32 typmod, Node *escontext)
Definition: timestamp.c:366
TimestampTz GetCurrentTransactionStartTimestamp(void)
Definition: xact.c:867

References AdjustTimestampForTypmod(), and GetCurrentTransactionStartTimestamp().

Referenced by ExecEvalSQLValueFunction().

◆ GetSQLLocalTimestamp()

Timestamp GetSQLLocalTimestamp ( int32  typmod)

Definition at line 1686 of file timestamp.c.

1687 {
1688  Timestamp ts;
1689 
1691  if (typmod >= 0)
1692  AdjustTimestampForTypmod(&ts, typmod, NULL);
1693  return ts;
1694 }
static Timestamp timestamptz2timestamp(TimestampTz timestamp)
Definition: timestamp.c:6361

References AdjustTimestampForTypmod(), GetCurrentTransactionStartTimestamp(), and timestamptz2timestamp().

Referenced by ExecEvalSQLValueFunction().

◆ in_range_interval_interval()

Datum in_range_interval_interval ( PG_FUNCTION_ARGS  )

Definition at line 3864 of file timestamp.c.

3865 {
3867  Interval *base = PG_GETARG_INTERVAL_P(1);
3868  Interval *offset = PG_GETARG_INTERVAL_P(2);
3869  bool sub = PG_GETARG_BOOL(3);
3870  bool less = PG_GETARG_BOOL(4);
3871  Interval *sum;
3872 
3873  if (interval_sign(offset) < 0)
3874  ereport(ERROR,
3875  (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
3876  errmsg("invalid preceding or following size in window function")));
3877 
3878  /*
3879  * Deal with cases where both base and offset are infinite, and computing
3880  * base +/- offset would cause an error. As for float and numeric types,
3881  * we assume that all values infinitely precede +infinity and infinitely
3882  * follow -infinity. See in_range_float8_float8() for reasoning.
3883  */
3884  if (INTERVAL_IS_NOEND(offset) &&
3885  (sub ? INTERVAL_IS_NOEND(base) : INTERVAL_IS_NOBEGIN(base)))
3886  PG_RETURN_BOOL(true);
3887 
3888  /* We don't currently bother to avoid overflow hazards here */
3889  if (sub)
3891  IntervalPGetDatum(base),
3892  IntervalPGetDatum(offset)));
3893  else
3895  IntervalPGetDatum(base),
3896  IntervalPGetDatum(offset)));
3897 
3898  if (less)
3900  else
3902 }
Datum interval_mi(PG_FUNCTION_ARGS)
Definition: timestamp.c:3506
Datum interval_pl(PG_FUNCTION_ARGS)
Definition: timestamp.c:3450
static int interval_cmp_internal(const Interval *interval1, const Interval *interval2)
Definition: timestamp.c:2505
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
long val
Definition: informix.c:670
static Datum IntervalPGetDatum(const Interval *X)
Definition: timestamp.h:58
static Interval * DatumGetIntervalP(Datum X)
Definition: timestamp.h:40

References DatumGetIntervalP(), DirectFunctionCall2, ereport, errcode(), errmsg(), ERROR, interval_cmp_internal(), INTERVAL_IS_NOBEGIN, INTERVAL_IS_NOEND, interval_mi(), interval_pl(), interval_sign(), IntervalPGetDatum(), PG_GETARG_BOOL, PG_GETARG_INTERVAL_P, PG_RETURN_BOOL, and val.

◆ in_range_timestamp_interval()

Datum in_range_timestamp_interval ( PG_FUNCTION_ARGS  )

Definition at line 3823 of file timestamp.c.

3824 {
3826  Timestamp base = PG_GETARG_TIMESTAMP(1);
3827  Interval *offset = PG_GETARG_INTERVAL_P(2);
3828  bool sub = PG_GETARG_BOOL(3);
3829  bool less = PG_GETARG_BOOL(4);
3830  Timestamp sum;
3831 
3832  if (interval_sign(offset) < 0)
3833  ereport(ERROR,
3834  (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
3835  errmsg("invalid preceding or following size in window function")));
3836 
3837  /*
3838  * Deal with cases where both base and offset are infinite, and computing
3839  * base +/- offset would cause an error. As for float and numeric types,
3840  * we assume that all values infinitely precede +infinity and infinitely
3841  * follow -infinity. See in_range_float8_float8() for reasoning.
3842  */
3843  if (INTERVAL_IS_NOEND(offset) &&
3844  (sub ? TIMESTAMP_IS_NOEND(base) : TIMESTAMP_IS_NOBEGIN(base)))
3845  PG_RETURN_BOOL(true);
3846 
3847  /* We don't currently bother to avoid overflow hazards here */
3848  if (sub)
3850  TimestampGetDatum(base),
3851  IntervalPGetDatum(offset)));
3852  else
3854  TimestampGetDatum(base),
3855  IntervalPGetDatum(offset)));
3856 
3857  if (less)
3858  PG_RETURN_BOOL(val <= sum);
3859  else
3860  PG_RETURN_BOOL(val >= sum);
3861 }
Datum timestamp_mi_interval(PG_FUNCTION_ARGS)
Definition: timestamp.c:3160

References DatumGetTimestamp(), DirectFunctionCall2, ereport, errcode(), errmsg(), ERROR, INTERVAL_IS_NOEND, interval_sign(), IntervalPGetDatum(), PG_GETARG_BOOL, PG_GETARG_INTERVAL_P, PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, TIMESTAMP_IS_NOBEGIN, TIMESTAMP_IS_NOEND, timestamp_mi_interval(), timestamp_pl_interval(), TimestampGetDatum(), and val.

Referenced by in_range_date_interval().

◆ in_range_timestamptz_interval()

Datum in_range_timestamptz_interval ( PG_FUNCTION_ARGS  )

Definition at line 3786 of file timestamp.c.

3787 {
3790  Interval *offset = PG_GETARG_INTERVAL_P(2);
3791  bool sub = PG_GETARG_BOOL(3);
3792  bool less = PG_GETARG_BOOL(4);
3793  TimestampTz sum;
3794 
3795  if (interval_sign(offset) < 0)
3796  ereport(ERROR,
3797  (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
3798  errmsg("invalid preceding or following size in window function")));
3799 
3800  /*
3801  * Deal with cases where both base and offset are infinite, and computing
3802  * base +/- offset would cause an error. As for float and numeric types,
3803  * we assume that all values infinitely precede +infinity and infinitely
3804  * follow -infinity. See in_range_float8_float8() for reasoning.
3805  */
3806  if (INTERVAL_IS_NOEND(offset) &&
3807  (sub ? TIMESTAMP_IS_NOEND(base) : TIMESTAMP_IS_NOBEGIN(base)))
3808  PG_RETURN_BOOL(true);
3809 
3810  /* We don't currently bother to avoid overflow hazards here */
3811  if (sub)
3812  sum = timestamptz_mi_interval_internal(base, offset, NULL);
3813  else
3814  sum = timestamptz_pl_interval_internal(base, offset, NULL);
3815 
3816  if (less)
3817  PG_RETURN_BOOL(val <= sum);
3818  else
3819  PG_RETURN_BOOL(val >= sum);
3820 }
static TimestampTz timestamptz_mi_interval_internal(TimestampTz timestamp, Interval *span, pg_tz *attimezone)
Definition: timestamp.c:3312

References ereport, errcode(), errmsg(), ERROR, INTERVAL_IS_NOEND, interval_sign(), PG_GETARG_BOOL, PG_GETARG_INTERVAL_P, PG_GETARG_TIMESTAMPTZ, PG_RETURN_BOOL, TIMESTAMP_IS_NOBEGIN, TIMESTAMP_IS_NOEND, timestamptz_mi_interval_internal(), timestamptz_pl_interval_internal(), and val.

◆ interval2itm()

void interval2itm ( Interval  span,
struct pg_itm itm 
)

Definition at line 2047 of file timestamp.c.

2048 {
2049  TimeOffset time;
2050  TimeOffset tfrac;
2051 
2052  itm->tm_year = span.month / MONTHS_PER_YEAR;
2053  itm->tm_mon = span.month % MONTHS_PER_YEAR;
2054  itm->tm_mday = span.day;
2055  time = span.time;
2056 
2057  tfrac = time / USECS_PER_HOUR;
2058  time -= tfrac * USECS_PER_HOUR;
2059  itm->tm_hour = tfrac;
2060  tfrac = time / USECS_PER_MINUTE;
2061  time -= tfrac * USECS_PER_MINUTE;
2062  itm->tm_min = (int) tfrac;
2063  tfrac = time / USECS_PER_SEC;
2064  time -= tfrac * USECS_PER_SEC;
2065  itm->tm_sec = (int) tfrac;
2066  itm->tm_usec = (int) time;
2067 }
int64 tm_hour
Definition: timestamp.h:70
int tm_year
Definition: timestamp.h:73
int tm_mon
Definition: timestamp.h:72
int tm_mday
Definition: timestamp.h:71
int tm_sec
Definition: timestamp.h:68
int tm_min
Definition: timestamp.h:69
int tm_usec
Definition: timestamp.h:67

References Interval::day, Interval::month, MONTHS_PER_YEAR, Interval::time, pg_itm::tm_hour, pg_itm::tm_mday, pg_itm::tm_min, pg_itm::tm_mon, pg_itm::tm_sec, pg_itm::tm_usec, pg_itm::tm_year, USECS_PER_HOUR, USECS_PER_MINUTE, and USECS_PER_SEC.

Referenced by interval_out(), interval_part_common(), interval_to_char(), and interval_trunc().

◆ interval_avg()

Datum interval_avg ( PG_FUNCTION_ARGS  )

Definition at line 4155 of file timestamp.c.

4156 {
4158 
4160 
4161  /* If there were no non-null inputs, return NULL */
4162  if (state == NULL || IA_TOTAL_COUNT(state) == 0)
4163  PG_RETURN_NULL();
4164 
4165  /*
4166  * Aggregating infinities that all have the same sign produces infinity
4167  * with that sign. Aggregating infinities with different signs results in
4168  * an error.
4169  */
4170  if (state->pInfcount > 0 || state->nInfcount > 0)
4171  {
4172  Interval *result;
4173 
4174  if (state->pInfcount > 0 && state->nInfcount > 0)
4175  ereport(ERROR,
4176  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4177  errmsg("interval out of range.")));
4178 
4179  result = (Interval *) palloc(sizeof(Interval));
4180  if (state->pInfcount > 0)
4181  INTERVAL_NOEND(result);
4182  else
4183  INTERVAL_NOBEGIN(result);
4184 
4185  PG_RETURN_INTERVAL_P(result);
4186  }
4187 
4189  IntervalPGetDatum(&state->sumX),
4190  Float8GetDatum((double) state->N));
4191 }
#define IA_TOTAL_COUNT(ia)
Definition: timestamp.c:87
Datum interval_div(PG_FUNCTION_ARGS)
Definition: timestamp.c:3685
#define INTERVAL_NOEND(i)
Definition: timestamp.h:185
#define INTERVAL_NOBEGIN(i)
Definition: timestamp.h:175
Datum Float8GetDatum(float8 X)
Definition: fmgr.c:1816
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:69

References DirectFunctionCall2, ereport, errcode(), errmsg(), ERROR, Float8GetDatum(), IA_TOTAL_COUNT, interval_div(), INTERVAL_NOBEGIN, INTERVAL_NOEND, IntervalPGetDatum(), palloc(), PG_ARGISNULL, PG_GETARG_POINTER, PG_RETURN_INTERVAL_P, and PG_RETURN_NULL.

◆ interval_avg_accum()

Datum interval_avg_accum ( PG_FUNCTION_ARGS  )

Definition at line 3990 of file timestamp.c.

3991 {
3993 
3995 
3996  /* Create the state data on the first call */
3997  if (state == NULL)
3998  state = makeIntervalAggState(fcinfo);
3999 
4000  if (!PG_ARGISNULL(1))
4002 
4004 }
static IntervalAggState * makeIntervalAggState(FunctionCallInfo fcinfo)
Definition: timestamp.c:3914
static void do_interval_accum(IntervalAggState *state, Interval *newval)
Definition: timestamp.c:3936
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361

References do_interval_accum(), makeIntervalAggState(), PG_ARGISNULL, PG_GETARG_INTERVAL_P, PG_GETARG_POINTER, and PG_RETURN_POINTER.

◆ interval_avg_accum_inv()

Datum interval_avg_accum_inv ( PG_FUNCTION_ARGS  )

Definition at line 4137 of file timestamp.c.

4138 {
4140 
4142 
4143  /* Should not get here with no state */
4144  if (state == NULL)
4145  elog(ERROR, "interval_avg_accum_inv called with NULL state");
4146 
4147  if (!PG_ARGISNULL(1))
4149 
4151 }
static void do_interval_discard(IntervalAggState *state, Interval *newval)
Definition: timestamp.c:3959

References do_interval_discard(), elog, ERROR, PG_ARGISNULL, PG_GETARG_INTERVAL_P, PG_GETARG_POINTER, and PG_RETURN_POINTER.

◆ interval_avg_combine()

Datum interval_avg_combine ( PG_FUNCTION_ARGS  )

Definition at line 4013 of file timestamp.c.

4014 {
4015  IntervalAggState *state1;
4016  IntervalAggState *state2;
4017 
4018  state1 = PG_ARGISNULL(0) ? NULL : (IntervalAggState *) PG_GETARG_POINTER(0);
4019  state2 = PG_ARGISNULL(1) ? NULL : (IntervalAggState *) PG_GETARG_POINTER(1);
4020 
4021  if (state2 == NULL)
4022  PG_RETURN_POINTER(state1);
4023 
4024  if (state1 == NULL)
4025  {
4026  /* manually copy all fields from state2 to state1 */
4027  state1 = makeIntervalAggState(fcinfo);
4028 
4029  state1->N = state2->N;
4030  state1->pInfcount = state2->pInfcount;
4031  state1->nInfcount = state2->nInfcount;
4032 
4033  state1->sumX.day = state2->sumX.day;
4034  state1->sumX.month = state2->sumX.month;
4035  state1->sumX.time = state2->sumX.time;
4036 
4037  PG_RETURN_POINTER(state1);
4038  }
4039 
4040  state1->N += state2->N;
4041  state1->pInfcount += state2->pInfcount;
4042  state1->nInfcount += state2->nInfcount;
4043 
4044  /* Accumulate finite interval values, if any. */
4045  if (state2->N > 0)
4046  finite_interval_pl(&state1->sumX, &state2->sumX, &state1->sumX);
4047 
4048  PG_RETURN_POINTER(state1);
4049 }
Interval sumX
Definition: timestamp.c:81

References Interval::day, finite_interval_pl(), makeIntervalAggState(), Interval::month, IntervalAggState::N, IntervalAggState::nInfcount, PG_ARGISNULL, PG_GETARG_POINTER, PG_RETURN_POINTER, IntervalAggState::pInfcount, IntervalAggState::sumX, and Interval::time.

◆ interval_avg_deserialize()

Datum interval_avg_deserialize ( PG_FUNCTION_ARGS  )

Definition at line 4094 of file timestamp.c.

4095 {
4096  bytea *sstate;
4097  IntervalAggState *result;
4099 
4100  if (!AggCheckCallContext(fcinfo, NULL))
4101  elog(ERROR, "aggregate function called in non-aggregate context");
4102 
4103  sstate = PG_GETARG_BYTEA_PP(0);
4104 
4105  /*
4106  * Initialize a StringInfo so that we can "receive" it using the standard
4107  * recv-function infrastructure.
4108  */
4110  VARSIZE_ANY_EXHDR(sstate));
4111 
4112  result = (IntervalAggState *) palloc0(sizeof(IntervalAggState));
4113 
4114  /* N */
4115  result->N = pq_getmsgint64(&buf);
4116 
4117  /* sumX */
4118  result->sumX.time = pq_getmsgint64(&buf);
4119  result->sumX.day = pq_getmsgint(&buf, 4);
4120  result->sumX.month = pq_getmsgint(&buf, 4);
4121 
4122  /* pInfcount */
4123  result->pInfcount = pq_getmsgint64(&buf);
4124 
4125  /* nInfcount */
4126  result->nInfcount = pq_getmsgint64(&buf);
4127 
4128  pq_getmsgend(&buf);
4129 
4130  PG_RETURN_POINTER(result);
4131 }
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
void * palloc0(Size size)
Definition: mcxt.c:1346
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4511
static char * buf
Definition: pg_test_fsync.c:73
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:415
void pq_getmsgend(StringInfo msg)
Definition: pqformat.c:635
int64 pq_getmsgint64(StringInfo msg)
Definition: pqformat.c:453
static void initReadOnlyStringInfo(StringInfo str, char *data, int len)
Definition: stringinfo.h:130
#define VARDATA_ANY(PTR)
Definition: varatt.h:324
#define VARSIZE_ANY_EXHDR(PTR)
Definition: varatt.h:317

References AggCheckCallContext(), buf, Interval::day, elog, ERROR, initReadOnlyStringInfo(), Interval::month, IntervalAggState::N, IntervalAggState::nInfcount, palloc0(), PG_GETARG_BYTEA_PP, PG_RETURN_POINTER, IntervalAggState::pInfcount, pq_getmsgend(), pq_getmsgint(), pq_getmsgint64(), IntervalAggState::sumX, Interval::time, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ interval_avg_serialize()

Datum interval_avg_serialize ( PG_FUNCTION_ARGS  )

Definition at line 4056 of file timestamp.c.

4057 {
4060  bytea *result;
4061 
4062  /* Ensure we disallow calling when not in aggregate context */
4063  if (!AggCheckCallContext(fcinfo, NULL))
4064  elog(ERROR, "aggregate function called in non-aggregate context");
4065 
4067 
4068  pq_begintypsend(&buf);
4069 
4070  /* N */
4071  pq_sendint64(&buf, state->N);
4072 
4073  /* sumX */
4074  pq_sendint64(&buf, state->sumX.time);
4075  pq_sendint32(&buf, state->sumX.day);
4076  pq_sendint32(&buf, state->sumX.month);
4077 
4078  /* pInfcount */
4079  pq_sendint64(&buf, state->pInfcount);
4080 
4081  /* nInfcount */
4082  pq_sendint64(&buf, state->nInfcount);
4083 
4084  result = pq_endtypsend(&buf);
4085 
4086  PG_RETURN_BYTEA_P(result);
4087 }
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:326
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:346
static void pq_sendint32(StringInfo buf, uint32 i)
Definition: pqformat.h:144
static void pq_sendint64(StringInfo buf, uint64 i)
Definition: pqformat.h:152

References AggCheckCallContext(), buf, elog, ERROR, PG_GETARG_POINTER, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendint32(), and pq_sendint64().

◆ interval_cmp()

Datum interval_cmp ( PG_FUNCTION_ARGS  )

Definition at line 2577 of file timestamp.c.

2578 {
2579  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2580  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2581 
2582  PG_RETURN_INT32(interval_cmp_internal(interval1, interval2));
2583 }
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_INT32.

Referenced by gbt_intvkey_cmp().

◆ interval_cmp_internal()

static int interval_cmp_internal ( const Interval interval1,
const Interval interval2 
)
static

Definition at line 2505 of file timestamp.c.

2506 {
2507  INT128 span1 = interval_cmp_value(interval1);
2508  INT128 span2 = interval_cmp_value(interval2);
2509 
2510  return int128_compare(span1, span2);
2511 }
static INT128 interval_cmp_value(const Interval *interval)
Definition: timestamp.c:2483
static int int128_compare(INT128 x, INT128 y)
Definition: int128.h:238
Definition: int128.h:108

References int128_compare(), and interval_cmp_value().

Referenced by in_range_interval_interval(), interval_cmp(), interval_eq(), interval_ge(), interval_gt(), interval_larger(), interval_le(), interval_lt(), interval_ne(), and interval_smaller().

◆ interval_cmp_value()

static INT128 interval_cmp_value ( const Interval interval)
inlinestatic

Definition at line 2483 of file timestamp.c.

2484 {
2485  INT128 span;
2486  int64 days;
2487 
2488  /*
2489  * Combine the month and day fields into an integral number of days.
2490  * Because the inputs are int32, int64 arithmetic suffices here.
2491  */
2492  days = interval->month * INT64CONST(30);
2493  days += interval->day;
2494 
2495  /* Widen time field to 128 bits */
2496  span = int64_to_int128(interval->time);
2497 
2498  /* Scale up days to microseconds, forming a 128-bit product */
2500 
2501  return span;
2502 }
const char *const days[]
Definition: datetime.c:84
#define USECS_PER_DAY
Definition: timestamp.h:131
static INT128 int64_to_int128(int64 v)
Definition: int128.h:255
static void int128_add_int64_mul_int64(INT128 *i128, int64 x, int64 y)
Definition: int128.h:177

References days, int128_add_int64_mul_int64(), int64_to_int128(), interval::month, interval::time, and USECS_PER_DAY.

Referenced by interval_cmp_internal(), interval_hash(), interval_hash_extended(), and interval_sign().

◆ interval_div()

Datum interval_div ( PG_FUNCTION_ARGS  )

Definition at line 3685 of file timestamp.c.

3686 {
3687  Interval *span = PG_GETARG_INTERVAL_P(0);
3688  float8 factor = PG_GETARG_FLOAT8(1);
3689  double month_remainder_days,
3690  sec_remainder,
3691  result_double;
3692  int32 orig_month = span->month,
3693  orig_day = span->day;
3694  Interval *result;
3695 
3696  result = (Interval *) palloc(sizeof(Interval));
3697 
3698  if (factor == 0.0)
3699  ereport(ERROR,
3700  (errcode(ERRCODE_DIVISION_BY_ZERO),
3701  errmsg("division by zero")));
3702 
3703  /*
3704  * Handle NaN and infinities.
3705  *
3706  * We treat "infinity / infinity" as an error, since the interval type has
3707  * nothing equivalent to NaN. Otherwise, dividing by infinity is handled
3708  * by the regular division code, causing all fields to be set to zero.
3709  */
3710  if (isnan(factor))
3711  goto out_of_range;
3712 
3713  if (INTERVAL_NOT_FINITE(span))
3714  {
3715  if (isinf(factor))
3716  goto out_of_range;
3717 
3718  if (factor < 0.0)
3719  interval_um_internal(span, result);
3720  else
3721  memcpy(result, span, sizeof(Interval));
3722 
3723  PG_RETURN_INTERVAL_P(result);
3724  }
3725 
3726  result_double = span->month / factor;
3727  if (isnan(result_double) || !FLOAT8_FITS_IN_INT32(result_double))
3728  goto out_of_range;
3729  result->month = (int32) result_double;
3730 
3731  result_double = span->day / factor;
3732  if (isnan(result_double) || !FLOAT8_FITS_IN_INT32(result_double))
3733  goto out_of_range;
3734  result->day = (int32) result_double;
3735 
3736  /*
3737  * Fractional months full days into days. See comment in interval_mul().
3738  */
3739  month_remainder_days = (orig_month / factor - result->month) * DAYS_PER_MONTH;
3740  month_remainder_days = TSROUND(month_remainder_days);
3741  sec_remainder = (orig_day / factor - result->day +
3742  month_remainder_days - (int) month_remainder_days) * SECS_PER_DAY;
3743  sec_remainder = TSROUND(sec_remainder);
3744  if (fabs(sec_remainder) >= SECS_PER_DAY)
3745  {
3746  if (pg_add_s32_overflow(result->day,
3747  (int) (sec_remainder / SECS_PER_DAY),
3748  &result->day))
3749  goto out_of_range;
3750  sec_remainder -= (int) (sec_remainder / SECS_PER_DAY) * SECS_PER_DAY;
3751  }
3752 
3753  /* cascade units down */
3754  if (pg_add_s32_overflow(result->day, (int32) month_remainder_days,
3755  &result->day))
3756  goto out_of_range;
3757  result_double = rint(span->time / factor + sec_remainder * USECS_PER_SEC);
3758  if (isnan(result_double) || !FLOAT8_FITS_IN_INT64(result_double))
3759  goto out_of_range;
3760  result->time = (int64) result_double;
3761 
3762  if (INTERVAL_NOT_FINITE(result))
3763  goto out_of_range;
3764 
3765  PG_RETURN_INTERVAL_P(result);
3766 
3767 out_of_range:
3768  ereport(ERROR,
3769  errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3770  errmsg("interval out of range"));
3771 
3772  PG_RETURN_NULL(); /* keep compiler quiet */
3773 }
static void interval_um_internal(const Interval *interval, Interval *result)
Definition: timestamp.c:3373
#define FLOAT8_FITS_IN_INT32(num)
Definition: c.h:1090
#define FLOAT8_FITS_IN_INT64(num)
Definition: c.h:1092
#define DAYS_PER_MONTH
Definition: timestamp.h:116
#define TSROUND(j)
Definition: timestamp.h:100

References Interval::day, DAYS_PER_MONTH, ereport, errcode(), errmsg(), ERROR, FLOAT8_FITS_IN_INT32, FLOAT8_FITS_IN_INT64, INTERVAL_NOT_FINITE, interval_um_internal(), Interval::month, palloc(), pg_add_s32_overflow(), PG_GETARG_FLOAT8, PG_GETARG_INTERVAL_P, PG_RETURN_INTERVAL_P, PG_RETURN_NULL, SECS_PER_DAY, Interval::time, TSROUND, and USECS_PER_SEC.

Referenced by interval_avg().

◆ interval_eq()

Datum interval_eq ( PG_FUNCTION_ARGS  )

Definition at line 2523 of file timestamp.c.

2524 {
2525  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2526  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2527 
2528  PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) == 0);
2529 }

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by gbt_intveq().

◆ interval_finite()

Datum interval_finite ( PG_FUNCTION_ARGS  )

Definition at line 2155 of file timestamp.c.

2156 {
2158 
2160 }

References INTERVAL_NOT_FINITE, PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

◆ interval_ge()

Datum interval_ge ( PG_FUNCTION_ARGS  )

Definition at line 2568 of file timestamp.c.

2569 {
2570  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2571  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2572 
2573  PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) >= 0);
2574 }

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by gbt_intvge().

◆ interval_gt()

Datum interval_gt ( PG_FUNCTION_ARGS  )

Definition at line 2550 of file timestamp.c.

2551 {
2552  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2553  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2554 
2555  PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) > 0);
2556 }

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by gbt_intvgt().

◆ interval_hash()

Datum interval_hash ( PG_FUNCTION_ARGS  )

Definition at line 2593 of file timestamp.c.

2594 {
2597  int64 span64;
2598 
2599  /*
2600  * Use only the least significant 64 bits for hashing. The upper 64 bits
2601  * seldom add any useful information, and besides we must do it like this
2602  * for compatibility with hashes calculated before use of INT128 was
2603  * introduced.
2604  */
2605  span64 = int128_to_int64(span);
2606 
2608 }
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:642
Datum hashint8(PG_FUNCTION_ARGS)
Definition: hashfunc.c:83
static int64 int128_to_int64(INT128 val)
Definition: int128.h:269
#define Int64GetDatumFast(X)
Definition: postgres.h:554

References DirectFunctionCall1, hashint8(), int128_to_int64(), Int64GetDatumFast, interval_cmp_value(), and PG_GETARG_INTERVAL_P.

◆ interval_hash_extended()

Datum interval_hash_extended ( PG_FUNCTION_ARGS  )

Definition at line 2611 of file timestamp.c.

2612 {
2615  int64 span64;
2616 
2617  /* Same approach as interval_hash */
2618  span64 = int128_to_int64(span);
2619 
2621  PG_GETARG_DATUM(1));
2622 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
Datum hashint8extended(PG_FUNCTION_ARGS)
Definition: hashfunc.c:103

References DirectFunctionCall2, hashint8extended(), int128_to_int64(), Int64GetDatumFast, interval_cmp_value(), PG_GETARG_DATUM, and PG_GETARG_INTERVAL_P.

◆ interval_in()

Datum interval_in ( PG_FUNCTION_ARGS  )

Definition at line 900 of file timestamp.c.

901 {
902  char *str = PG_GETARG_CSTRING(0);
903 #ifdef NOT_USED
904  Oid typelem = PG_GETARG_OID(1);
905 #endif
906  int32 typmod = PG_GETARG_INT32(2);
907  Node *escontext = fcinfo->context;
908  Interval *result;
909  struct pg_itm_in tt,
910  *itm_in = &tt;
911  int dtype;
912  int nf;
913  int range;
914  int dterr;
915  char *field[MAXDATEFIELDS];
916  int ftype[MAXDATEFIELDS];
917  char workbuf[256];
918  DateTimeErrorExtra extra;
919 
920  itm_in->tm_year = 0;
921  itm_in->tm_mon = 0;
922  itm_in->tm_mday = 0;
923  itm_in->tm_usec = 0;
924 
925  if (typmod >= 0)
926  range = INTERVAL_RANGE(typmod);
927  else
929 
930  dterr = ParseDateTime(str, workbuf, sizeof(workbuf), field,
931  ftype, MAXDATEFIELDS, &nf);
932  if (dterr == 0)
933  dterr = DecodeInterval(field, ftype, nf, range,
934  &dtype, itm_in);
935 
936  /* if those functions think it's a bad format, try ISO8601 style */
937  if (dterr == DTERR_BAD_FORMAT)
938  dterr = DecodeISO8601Interval(str,
939  &dtype, itm_in);
940 
941  if (dterr != 0)
942  {
943  if (dterr == DTERR_FIELD_OVERFLOW)
944  dterr = DTERR_INTERVAL_OVERFLOW;
945  DateTimeParseError(dterr, &extra, str, "interval", escontext);
946  PG_RETURN_NULL();
947  }
948 
949  result = (Interval *) palloc(sizeof(Interval));
950 
951  switch (dtype)
952  {
953  case DTK_DELTA:
954  if (itmin2interval(itm_in, result) != 0)
955  ereturn(escontext, (Datum) 0,
956  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
957  errmsg("interval out of range")));
958  break;
959 
960  case DTK_LATE:
961  INTERVAL_NOEND(result);
962  break;
963 
964  case DTK_EARLY:
965  INTERVAL_NOBEGIN(result);
966  break;
967 
968  default:
969  elog(ERROR, "unexpected dtype %d while parsing interval \"%s\"",
970  dtype, str);
971  }
972 
973  AdjustIntervalForTypmod(result, typmod, escontext);
974 
975  PG_RETURN_INTERVAL_P(result);
976 }
int ParseDateTime(const char *timestr, char *workbuf, size_t buflen, char **field, int *ftype, int maxfields, int *numfields)
Definition: datetime.c:754
void DateTimeParseError(int dterr, DateTimeErrorExtra *extra, const char *str, const char *datatype, Node *escontext)
Definition: datetime.c:4081
int DecodeInterval(char **field, int *ftype, int nf, int range, int *dtype, struct pg_itm_in *itm_in)
Definition: datetime.c:3353
int DecodeISO8601Interval(char *str, int *dtype, struct pg_itm_in *itm_in)
Definition: datetime.c:3818
int itmin2interval(struct pg_itm_in *itm_in, Interval *span)
Definition: timestamp.c:2115
static bool AdjustIntervalForTypmod(Interval *interval, int32 typmod, Node *escontext)
Definition: timestamp.c:1359
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define MAXDATEFIELDS
Definition: datetime.h:202
#define DTERR_INTERVAL_OVERFLOW
Definition: datetime.h:285
#define DTK_DELTA
Definition: datetime.h:159
#define DTK_LATE
Definition: datetime.h:151
#define DTERR_BAD_FORMAT
Definition: datetime.h:282
#define DTK_EARLY
Definition: datetime.h:150
#define DTERR_FIELD_OVERFLOW
Definition: datetime.h:283
uintptr_t Datum
Definition: postgres.h:64
unsigned int Oid
Definition: postgres_ext.h:31
Definition: nodes.h:129
int tm_mon
Definition: timestamp.h:86
int tm_year
Definition: timestamp.h:87
int tm_mday
Definition: timestamp.h:85
int64 tm_usec
Definition: timestamp.h:84

References AdjustIntervalForTypmod(), DateTimeParseError(), DecodeInterval(), DecodeISO8601Interval(), DTERR_BAD_FORMAT, DTERR_FIELD_OVERFLOW, DTERR_INTERVAL_OVERFLOW, DTK_DELTA, DTK_EARLY, DTK_LATE, elog, ereturn, errcode(), errmsg(), ERROR, INTERVAL_FULL_RANGE, INTERVAL_NOBEGIN, INTERVAL_NOEND, INTERVAL_RANGE, itmin2interval(), MAXDATEFIELDS, palloc(), ParseDateTime(), PG_GETARG_CSTRING, PG_GETARG_INT32, PG_GETARG_OID, PG_RETURN_INTERVAL_P, PG_RETURN_NULL, range(), str, pg_itm_in::tm_mday, pg_itm_in::tm_mon, pg_itm_in::tm_usec, and pg_itm_in::tm_year.

Referenced by check_timezone(), and flatten_set_variable_args().

◆ interval_justify_days()

Datum interval_justify_days ( PG_FUNCTION_ARGS  )

Definition at line 3002 of file timestamp.c.

3003 {
3004  Interval *span = PG_GETARG_INTERVAL_P(0);
3005  Interval *result;
3006  int32 wholemonth;
3007 
3008  result = (Interval *) palloc(sizeof(Interval));
3009  result->month = span->month;
3010  result->day = span->day;
3011  result->time = span->time;
3012 
3013  /* do nothing for infinite intervals */
3014  if (INTERVAL_NOT_FINITE(result))
3015  PG_RETURN_INTERVAL_P(result);
3016 
3017  wholemonth = result->day / DAYS_PER_MONTH;
3018  result->day -= wholemonth * DAYS_PER_MONTH;
3019  if (pg_add_s32_overflow(result->month, wholemonth, &result->month))
3020  ereport(ERROR,
3021  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3022  errmsg("interval out of range")));
3023 
3024  if (result->month > 0 && result->day < 0)
3025  {
3026  result->day += DAYS_PER_MONTH;
3027  result->month--;
3028  }
3029  else if (result->month < 0 && result->day > 0)
3030  {
3031  result->day -= DAYS_PER_MONTH;
3032  result->month++;
3033  }
3034 
3035  PG_RETURN_INTERVAL_P(result);
3036 }

References Interval::day, DAYS_PER_MONTH, ereport, errcode(), errmsg(), ERROR, INTERVAL_NOT_FINITE, Interval::month, palloc(), pg_add_s32_overflow(), PG_GETARG_INTERVAL_P, PG_RETURN_INTERVAL_P, and Interval::time.

◆ interval_justify_hours()

Datum interval_justify_hours ( PG_FUNCTION_ARGS  )

Definition at line 2960 of file timestamp.c.

2961 {
2962  Interval *span = PG_GETARG_INTERVAL_P(0);
2963  Interval *result;
2964  TimeOffset wholeday;
2965 
2966  result = (Interval *) palloc(sizeof(Interval));
2967  result->month = span->month;
2968  result->day = span->day;
2969  result->time = span->time;
2970 
2971  /* do nothing for infinite intervals */
2972  if (INTERVAL_NOT_FINITE(result))
2973  PG_RETURN_INTERVAL_P(result);
2974 
2975  TMODULO(result->time, wholeday, USECS_PER_DAY);
2976  if (pg_add_s32_overflow(result->day, wholeday, &result->day))
2977  ereport(ERROR,
2978  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2979  errmsg("interval out of range")));
2980 
2981  if (result->day > 0 && result->time < 0)
2982  {
2983  result->time += USECS_PER_DAY;
2984  result->day--;
2985  }
2986  else if (result->day < 0 && result->time > 0)
2987  {
2988  result->time -= USECS_PER_DAY;
2989  result->day++;
2990  }
2991 
2992  PG_RETURN_INTERVAL_P(result);
2993 }
#define TMODULO(t, q, u)
Definition: datetime.h:248

References Interval::day, ereport, errcode(), errmsg(), ERROR, INTERVAL_NOT_FINITE, Interval::month, palloc(), pg_add_s32_overflow(), PG_GETARG_INTERVAL_P, PG_RETURN_INTERVAL_P, Interval::time, TMODULO, and USECS_PER_DAY.

Referenced by timestamp_mi().

◆ interval_justify_interval()

Datum interval_justify_interval ( PG_FUNCTION_ARGS  )

Definition at line 2880 of file timestamp.c.

2881 {
2882  Interval *span = PG_GETARG_INTERVAL_P(0);
2883  Interval *result;
2884  TimeOffset wholeday;
2885  int32 wholemonth;
2886 
2887  result = (Interval *) palloc(sizeof(Interval));
2888  result->month = span->month;
2889  result->day = span->day;
2890  result->time = span->time;
2891 
2892  /* do nothing for infinite intervals */
2893  if (INTERVAL_NOT_FINITE(result))
2894  PG_RETURN_INTERVAL_P(result);
2895 
2896  /* pre-justify days if it might prevent overflow */
2897  if ((result->day > 0 && result->time > 0) ||
2898  (result->day < 0 && result->time < 0))
2899  {
2900  wholemonth = result->day / DAYS_PER_MONTH;
2901  result->day -= wholemonth * DAYS_PER_MONTH;
2902  if (pg_add_s32_overflow(result->month, wholemonth, &result->month))
2903  ereport(ERROR,
2904  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2905  errmsg("interval out of range")));
2906  }
2907 
2908  /*
2909  * Since TimeOffset is int64, abs(wholeday) can't exceed about 1.07e8. If
2910  * we pre-justified then abs(result->day) is less than DAYS_PER_MONTH, so
2911  * this addition can't overflow. If we didn't pre-justify, then day and
2912  * time are of different signs, so it still can't overflow.
2913  */
2914  TMODULO(result->time, wholeday, USECS_PER_DAY);
2915  result->day += wholeday;
2916 
2917  wholemonth = result->day / DAYS_PER_MONTH;
2918  result->day -= wholemonth * DAYS_PER_MONTH;
2919  if (pg_add_s32_overflow(result->month, wholemonth, &result->month))
2920  ereport(ERROR,
2921  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2922  errmsg("interval out of range")));
2923 
2924  if (result->month > 0 &&
2925  (result->day < 0 || (result->day == 0 && result->time < 0)))
2926  {
2927  result->day += DAYS_PER_MONTH;
2928  result->month--;
2929  }
2930  else if (result->month < 0 &&
2931  (result->day > 0 || (result->day == 0 && result->time > 0)))
2932  {
2933  result->day -= DAYS_PER_MONTH;
2934  result->month++;
2935  }
2936 
2937  if (result->day > 0 && result->time < 0)
2938  {
2939  result->time += USECS_PER_DAY;
2940  result->day--;
2941  }
2942  else if (result->day < 0 && result->time > 0)
2943  {
2944  result->time -= USECS_PER_DAY;
2945  result->day++;
2946  }
2947 
2948  PG_RETURN_INTERVAL_P(result);
2949 }

References Interval::day, DAYS_PER_MONTH, ereport, errcode(), errmsg(), ERROR, INTERVAL_NOT_FINITE, Interval::month, palloc(), pg_add_s32_overflow(), PG_GETARG_INTERVAL_P, PG_RETURN_INTERVAL_P, Interval::time, TMODULO, and USECS_PER_DAY.

◆ interval_larger()

Datum interval_larger ( PG_FUNCTION_ARGS  )

Definition at line 3421 of file timestamp.c.

3422 {
3423  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
3424  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
3425  Interval *result;
3426 
3427  if (interval_cmp_internal(interval1, interval2) > 0)
3428  result = interval1;
3429  else
3430  result = interval2;
3431  PG_RETURN_INTERVAL_P(result);
3432 }

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_INTERVAL_P.

◆ interval_le()

Datum interval_le ( PG_FUNCTION_ARGS  )

Definition at line 2559 of file timestamp.c.

2560 {
2561  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2562  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2563 
2564  PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) <= 0);
2565 }

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by gbt_intvle().

◆ interval_lt()

Datum interval_lt ( PG_FUNCTION_ARGS  )

Definition at line 2541 of file timestamp.c.

2542 {
2543  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2544  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2545 
2546  PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) < 0);
2547 }

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by abs_interval(), and gbt_intvlt().

◆ interval_mi()

Datum interval_mi ( PG_FUNCTION_ARGS  )

Definition at line 3506 of file timestamp.c.

3507 {
3508  Interval *span1 = PG_GETARG_INTERVAL_P(0);
3509  Interval *span2 = PG_GETARG_INTERVAL_P(1);
3510  Interval *result;
3511 
3512  result = (Interval *) palloc(sizeof(Interval));
3513 
3514  /*
3515  * Handle infinities.
3516  *
3517  * We treat anything that amounts to "infinity - infinity" as an error,
3518  * since the interval type has nothing equivalent to NaN.
3519  */
3520  if (INTERVAL_IS_NOBEGIN(span1))
3521  {
3522  if (INTERVAL_IS_NOBEGIN(span2))
3523  ereport(ERROR,
3524  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3525  errmsg("interval out of range")));
3526  else
3527  INTERVAL_NOBEGIN(result);
3528  }
3529  else if (INTERVAL_IS_NOEND(span1))
3530  {
3531  if (INTERVAL_IS_NOEND(span2))
3532  ereport(ERROR,
3533  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3534  errmsg("interval out of range")));
3535  else
3536  INTERVAL_NOEND(result);
3537  }
3538  else if (INTERVAL_IS_NOBEGIN(span2))
3539  INTERVAL_NOEND(result);
3540  else if (INTERVAL_IS_NOEND(span2))
3541  INTERVAL_NOBEGIN(result);
3542  else
3543  finite_interval_mi(span1, span2, result);
3544 
3545  PG_RETURN_INTERVAL_P(result);
3546 }

References ereport, errcode(), errmsg(), ERROR, finite_interval_mi(), INTERVAL_IS_NOBEGIN, INTERVAL_IS_NOEND, INTERVAL_NOBEGIN, INTERVAL_NOEND, palloc(), PG_GETARG_INTERVAL_P, and PG_RETURN_INTERVAL_P.

Referenced by in_range_interval_interval(), interval_dist(), and interval_lerp().

◆ interval_mul()

Datum interval_mul ( PG_FUNCTION_ARGS  )

Definition at line 3555 of file timestamp.c.

3556 {
3557  Interval *span = PG_GETARG_INTERVAL_P(0);
3558  float8 factor = PG_GETARG_FLOAT8(1);
3559  double month_remainder_days,
3560  sec_remainder,
3561  result_double;
3562  int32 orig_month = span->month,
3563  orig_day = span->day;
3564  Interval *result;
3565 
3566  result = (Interval *) palloc(sizeof(Interval));
3567 
3568  /*
3569  * Handle NaN and infinities.
3570  *
3571  * We treat "0 * infinity" and "infinity * 0" as errors, since the
3572  * interval type has nothing equivalent to NaN.
3573  */
3574  if (isnan(factor))
3575  goto out_of_range;
3576 
3577  if (INTERVAL_NOT_FINITE(span))
3578  {
3579  if (factor == 0.0)
3580  goto out_of_range;
3581 
3582  if (factor < 0.0)
3583  interval_um_internal(span, result);
3584  else
3585  memcpy(result, span, sizeof(Interval));
3586 
3587  PG_RETURN_INTERVAL_P(result);
3588  }
3589  if (isinf(factor))
3590  {
3591  int isign = interval_sign(span);
3592 
3593  if (isign == 0)
3594  goto out_of_range;
3595 
3596  if (factor * isign < 0)
3597  INTERVAL_NOBEGIN(result);
3598  else
3599  INTERVAL_NOEND(result);
3600 
3601  PG_RETURN_INTERVAL_P(result);
3602  }
3603 
3604  result_double = span->month * factor;
3605  if (isnan(result_double) || !FLOAT8_FITS_IN_INT32(result_double))
3606  goto out_of_range;
3607  result->month = (int32) result_double;
3608 
3609  result_double = span->day * factor;
3610  if (isnan(result_double) || !FLOAT8_FITS_IN_INT32(result_double))
3611  goto out_of_range;
3612  result->day = (int32) result_double;
3613 
3614  /*
3615  * The above correctly handles the whole-number part of the month and day
3616  * products, but we have to do something with any fractional part
3617  * resulting when the factor is non-integral. We cascade the fractions
3618  * down to lower units using the conversion factors DAYS_PER_MONTH and
3619  * SECS_PER_DAY. Note we do NOT cascade up, since we are not forced to do
3620  * so by the representation. The user can choose to cascade up later,
3621  * using justify_hours and/or justify_days.
3622  */
3623 
3624  /*
3625  * Fractional months full days into days.
3626  *
3627  * Floating point calculation are inherently imprecise, so these
3628  * calculations are crafted to produce the most reliable result possible.
3629  * TSROUND() is needed to more accurately produce whole numbers where
3630  * appropriate.
3631  */
3632  month_remainder_days = (orig_month * factor - result->month) * DAYS_PER_MONTH;
3633  month_remainder_days = TSROUND(month_remainder_days);
3634  sec_remainder = (orig_day * factor - result->day +
3635  month_remainder_days - (int) month_remainder_days) * SECS_PER_DAY;
3636  sec_remainder = TSROUND(sec_remainder);
3637 
3638  /*
3639  * Might have 24:00:00 hours due to rounding, or >24 hours because of time
3640  * cascade from months and days. It might still be >24 if the combination
3641  * of cascade and the seconds factor operation itself.
3642  */
3643  if (fabs(sec_remainder) >= SECS_PER_DAY)
3644  {
3645  if (pg_add_s32_overflow(result->day,
3646  (int) (sec_remainder / SECS_PER_DAY),
3647  &result->day))
3648  goto out_of_range;
3649  sec_remainder -= (int) (sec_remainder / SECS_PER_DAY) * SECS_PER_DAY;
3650  }
3651 
3652  /* cascade units down */
3653  if (pg_add_s32_overflow(result->day, (int32) month_remainder_days,
3654  &result->day))
3655  goto out_of_range;
3656  result_double = rint(span->time * factor + sec_remainder * USECS_PER_SEC);
3657  if (isnan(result_double) || !FLOAT8_FITS_IN_INT64(result_double))
3658  goto out_of_range;
3659  result->time = (int64) result_double;
3660 
3661  if (INTERVAL_NOT_FINITE(result))
3662  goto out_of_range;
3663 
3664  PG_RETURN_INTERVAL_P(result);
3665 
3666 out_of_range:
3667  ereport(ERROR,
3668  errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3669  errmsg("interval out of range"));
3670 
3671  PG_RETURN_NULL(); /* keep compiler quiet */
3672 }

References Interval::day, DAYS_PER_MONTH, ereport, errcode(), errmsg(), ERROR, FLOAT8_FITS_IN_INT32, FLOAT8_FITS_IN_INT64, INTERVAL_NOBEGIN, INTERVAL_NOEND, INTERVAL_NOT_FINITE, interval_sign(), interval_um_internal(), Interval::month, palloc(), pg_add_s32_overflow(), PG_GETARG_FLOAT8, PG_GETARG_INTERVAL_P, PG_RETURN_INTERVAL_P, PG_RETURN_NULL, SECS_PER_DAY, Interval::time, TSROUND, and USECS_PER_SEC.

Referenced by interval_lerp(), and mul_d_interval().

◆ interval_ne()

Datum interval_ne ( PG_FUNCTION_ARGS  )

Definition at line 2532 of file timestamp.c.

2533 {
2534  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2535  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2536 
2537  PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) != 0);
2538 }

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

◆ interval_out()

Datum interval_out ( PG_FUNCTION_ARGS  )

Definition at line 982 of file timestamp.c.

983 {
984  Interval *span = PG_GETARG_INTERVAL_P(0);
985  char *result;
986  struct pg_itm tt,
987  *itm = &tt;
988  char buf[MAXDATELEN + 1];
989 
990  if (INTERVAL_NOT_FINITE(span))
991  EncodeSpecialInterval(span, buf);
992  else
993  {
994  interval2itm(*span, itm);
996  }
997 
998  result = pstrdup(buf);
999  PG_RETURN_CSTRING(result);
1000 }
void EncodeInterval(struct pg_itm *itm, int style, char *str)
Definition: datetime.c:4574
static void EncodeSpecialInterval(const Interval *interval, char *str)
Definition: timestamp.c:1607
void interval2itm(Interval span, struct pg_itm *itm)
Definition: timestamp.c:2047
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
int IntervalStyle
Definition: globals.c:124
#define MAXDATELEN
Definition: datetime.h:200

References buf, EncodeInterval(), EncodeSpecialInterval(), interval2itm(), INTERVAL_NOT_FINITE, IntervalStyle, MAXDATELEN, PG_GETARG_INTERVAL_P, PG_RETURN_CSTRING, and pstrdup().

Referenced by flatten_set_variable_args(), timestamp_izone(), timestamptz_izone(), and timetz_izone().

◆ interval_part()

Datum interval_part ( PG_FUNCTION_ARGS  )

Definition at line 6131 of file timestamp.c.

6132 {
6133  return interval_part_common(fcinfo, false);
6134 }

References interval_part_common().

◆ interval_part_common()

static Datum interval_part_common ( PG_FUNCTION_ARGS  ,
bool  retnumeric 
)
static

Definition at line 5939 of file timestamp.c.

5940 {
5941  text *units = PG_GETARG_TEXT_PP(0);
5943  int64 intresult;
5944  int type,
5945  val;
5946  char *lowunits;
5947  struct pg_itm tt,
5948  *tm = &tt;
5949 
5950  lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
5951  VARSIZE_ANY_EXHDR(units),
5952  false);
5953 
5954  type = DecodeUnits(0, lowunits, &val);
5955  if (type == UNKNOWN_FIELD)
5956  type = DecodeSpecial(0, lowunits, &val);
5957 
5959  {
5960  double r = NonFiniteIntervalPart(type, val, lowunits,
5962 
5963  if (r != 0.0)
5964  {
5965  if (retnumeric)
5966  {
5967  if (r < 0)
5969  CStringGetDatum("-Infinity"),
5971  Int32GetDatum(-1));
5972  else if (r > 0)
5974  CStringGetDatum("Infinity"),
5976  Int32GetDatum(-1));
5977  }
5978  else
5979  PG_RETURN_FLOAT8(r);
5980  }
5981  else
5982  PG_RETURN_NULL();
5983  }
5984 
5985  if (type == UNITS)
5986  {
5988  switch (val)
5989  {
5990  case DTK_MICROSEC:
5991  intresult = tm->tm_sec * INT64CONST(1000000) + tm->tm_usec;
5992  break;
5993 
5994  case DTK_MILLISEC:
5995  if (retnumeric)
5996  /*---
5997  * tm->tm_sec * 1000 + fsec / 1000
5998  * = (tm->tm_sec * 1'000'000 + fsec) / 1000
5999  */
6000  PG_RETURN_NUMERIC(int64_div_fast_to_numeric(tm->tm_sec * INT64CONST(1000000) + tm->tm_usec, 3));
6001  else
6002  PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + tm->tm_usec / 1000.0);
6003  break;
6004 
6005  case DTK_SECOND:
6006  if (retnumeric)
6007  /*---
6008  * tm->tm_sec + fsec / 1'000'000
6009  * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
6010  */
6011  PG_RETURN_NUMERIC(int64_div_fast_to_numeric(tm->tm_sec * INT64CONST(1000000) + tm->tm_usec, 6));
6012  else
6013  PG_RETURN_FLOAT8(tm->tm_sec + tm->tm_usec / 1000000.0);
6014  break;
6015 
6016  case DTK_MINUTE:
6017  intresult = tm->tm_min;
6018  break;
6019 
6020  case DTK_HOUR:
6021  intresult = tm->tm_hour;
6022  break;
6023 
6024  case DTK_DAY:
6025  intresult = tm->tm_mday;
6026  break;
6027 
6028  case DTK_MONTH:
6029  intresult = tm->tm_mon;
6030  break;
6031 
6032  case DTK_QUARTER:
6033  intresult = (tm->tm_mon / 3) + 1;
6034  break;
6035 
6036  case DTK_YEAR:
6037  intresult = tm->tm_year;
6038  break;
6039 
6040  case DTK_DECADE:
6041  /* caution: C division may have negative remainder */
6042  intresult = tm->tm_year / 10;
6043  break;
6044 
6045  case DTK_CENTURY:
6046  /* caution: C division may have negative remainder */
6047  intresult = tm->tm_year / 100;
6048  break;
6049 
6050  case DTK_MILLENNIUM:
6051  /* caution: C division may have negative remainder */
6052  intresult = tm->tm_year / 1000;
6053  break;
6054 
6055  default:
6056  ereport(ERROR,
6057  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6058  errmsg("unit \"%s\" not supported for type %s",
6059  lowunits, format_type_be(INTERVALOID))));
6060  intresult = 0;
6061  }
6062  }
6063  else if (type == RESERV && val == DTK_EPOCH)
6064  {
6065  if (retnumeric)
6066  {
6067  Numeric result;
6068  int64 secs_from_day_month;
6069  int64 val;
6070 
6071  /*
6072  * To do this calculation in integer arithmetic even though
6073  * DAYS_PER_YEAR is fractional, multiply everything by 4 and then
6074  * divide by 4 again at the end. This relies on DAYS_PER_YEAR
6075  * being a multiple of 0.25 and on SECS_PER_DAY being a multiple
6076  * of 4.
6077  */
6078  secs_from_day_month = ((int64) (4 * DAYS_PER_YEAR) * (interval->month / MONTHS_PER_YEAR) +
6079  (int64) (4 * DAYS_PER_MONTH) * (interval->month % MONTHS_PER_YEAR) +
6080  (int64) 4 * interval->day) * (SECS_PER_DAY / 4);
6081 
6082  /*---
6083  * result = secs_from_day_month + interval->time / 1'000'000
6084  * = (secs_from_day_month * 1'000'000 + interval->time) / 1'000'000
6085  */
6086 
6087  /*
6088  * Try the computation inside int64; if it overflows, do it in
6089  * numeric (slower). This overflow happens around 10^9 days, so
6090  * not common in practice.
6091  */
6092  if (!pg_mul_s64_overflow(secs_from_day_month, 1000000, &val) &&
6094  result = int64_div_fast_to_numeric(val, 6);
6095  else
6096  result =
6098  int64_to_numeric(secs_from_day_month),
6099  NULL);
6100 
6101  PG_RETURN_NUMERIC(result);
6102  }
6103  else
6104  {
6105  float8 result;
6106 
6107  result = interval->time / 1000000.0;
6108  result += ((double) DAYS_PER_YEAR * SECS_PER_DAY) * (interval->month / MONTHS_PER_YEAR);
6109  result += ((double) DAYS_PER_MONTH * SECS_PER_DAY) * (interval->month % MONTHS_PER_YEAR);
6110  result += ((double) SECS_PER_DAY) * interval->day;
6111 
6112  PG_RETURN_FLOAT8(result);
6113  }
6114  }
6115  else
6116  {
6117  ereport(ERROR,
6118  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6119  errmsg("unit \"%s\" not recognized for type %s",
6120  lowunits, format_type_be(INTERVALOID))));
6121  intresult = 0;
6122  }
6123 
6124  if (retnumeric)
6125  PG_RETURN_NUMERIC(int64_to_numeric(intresult));
6126  else
6127  PG_RETURN_FLOAT8(intresult);
6128 }
int DecodeUnits(int field, const char *lowtoken, int *val)
Definition: datetime.c:4036
int DecodeSpecial(int field, const char *lowtoken, int *val)
Definition: datetime.c:3137
Numeric int64_to_numeric(int64 val)
Definition: numeric.c:4283
Numeric int64_div_fast_to_numeric(int64 val1, int log10val2)
Definition: numeric.c:4304
Datum numeric_in(PG_FUNCTION_ARGS)
Definition: numeric.c:628
Numeric numeric_add_opt_error(Numeric num1, Numeric num2, bool *have_error)
Definition: numeric.c:2867
static float8 NonFiniteIntervalPart(int type, int unit, char *lowunits, bool isNegative)
Definition: timestamp.c:5894
#define DAYS_PER_YEAR
Definition: timestamp.h:107
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:367
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:646
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
#define DTK_EPOCH
Definition: datetime.h:152
#define UNKNOWN_FIELD
Definition: datetime.h:124
#define DTK_DECADE
Definition: datetime.h:168
#define DTK_SECOND
Definition: datetime.h:160
#define DTK_QUARTER
Definition: datetime.h:166
#define DTK_CENTURY
Definition: datetime.h:169
#define DTK_DAY
Definition: datetime.h:163
#define RESERV
Definition: datetime.h:90
#define DTK_MILLENNIUM
Definition: datetime.h:170
#define DTK_HOUR
Definition: datetime.h:162
#define DTK_MICROSEC
Definition: datetime.h:172
#define DTK_YEAR
Definition: datetime.h:167
#define DTK_MILLISEC
Definition: datetime.h:171
#define DTK_MONTH
Definition: datetime.h:165
#define DTK_MINUTE
Definition: datetime.h:161
#define UNITS
Definition: datetime.h:107
static bool pg_mul_s64_overflow(int64 a, int64 b, int64 *result)
Definition: int.h:219
#define PG_RETURN_NUMERIC(x)
Definition: numeric.h:80
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:212
#define InvalidOid
Definition: postgres_ext.h:36
char * downcase_truncate_identifier(const char *ident, int len, bool warn)
Definition: scansup.c:37
const char * type

References CStringGetDatum(), DAYS_PER_MONTH, DAYS_PER_YEAR, DecodeSpecial(), DecodeUnits(), DirectFunctionCall3, downcase_truncate_identifier(), DTK_CENTURY, DTK_DAY, DTK_DECADE, DTK_EPOCH, DTK_HOUR, DTK_MICROSEC, DTK_MILLENNIUM, DTK_MILLISEC, DTK_MINUTE, DTK_MONTH, DTK_QUARTER, DTK_SECOND, DTK_YEAR, ereport, errcode(), errmsg(), ERROR, format_type_be(), Int32GetDatum(), int64_div_fast_to_numeric(), int64_to_numeric(), interval2itm(), INTERVAL_IS_NOBEGIN, INTERVAL_NOT_FINITE, InvalidOid, interval::month, MONTHS_PER_YEAR, NonFiniteIntervalPart(), numeric_add_opt_error(), numeric_in(), ObjectIdGetDatum(), pg_add_s64_overflow(), PG_GETARG_INTERVAL_P, PG_GETARG_TEXT_PP, pg_mul_s64_overflow(), PG_RETURN_FLOAT8, PG_RETURN_NULL, PG_RETURN_NUMERIC, RESERV, SECS_PER_DAY, interval::time, tm, pg_tm::tm_hour, pg_tm::tm_mday, pg_tm::tm_min, pg_tm::tm_mon, pg_tm::tm_sec, pg_tm::tm_year, type, UNITS, UNKNOWN_FIELD, val, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by extract_interval(), and interval_part().

◆ interval_pl()

Datum interval_pl ( PG_FUNCTION_ARGS  )

Definition at line 3450 of file timestamp.c.

3451 {
3452  Interval *span1 = PG_GETARG_INTERVAL_P(0);
3453  Interval *span2 = PG_GETARG_INTERVAL_P(1);
3454  Interval *result;
3455 
3456  result = (Interval *) palloc(sizeof(Interval));
3457 
3458  /*
3459  * Handle infinities.
3460  *
3461  * We treat anything that amounts to "infinity - infinity" as an error,
3462  * since the interval type has nothing equivalent to NaN.
3463  */
3464  if (INTERVAL_IS_NOBEGIN(span1))
3465  {
3466  if (INTERVAL_IS_NOEND(span2))
3467  ereport(ERROR,
3468  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3469  errmsg("interval out of range")));
3470  else
3471  INTERVAL_NOBEGIN(result);
3472  }
3473  else if (INTERVAL_IS_NOEND(span1))
3474  {
3475  if (INTERVAL_IS_NOBEGIN(span2))
3476  ereport(ERROR,
3477  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3478  errmsg("interval out of range")));
3479  else
3480  INTERVAL_NOEND(result);
3481  }
3482  else if (INTERVAL_NOT_FINITE(span2))
3483  memcpy(result, span2, sizeof(Interval));
3484  else
3485  finite_interval_pl(span1, span2, result);
3486 
3487  PG_RETURN_INTERVAL_P(result);
3488 }

References ereport, errcode(), errmsg(), ERROR, finite_interval_pl(), INTERVAL_IS_NOBEGIN, INTERVAL_IS_NOEND, INTERVAL_NOBEGIN, INTERVAL_NOEND, INTERVAL_NOT_FINITE, palloc(), PG_GETARG_INTERVAL_P, and PG_RETURN_INTERVAL_P.

Referenced by in_range_interval_interval(), and interval_lerp().

◆ interval_recv()

Datum interval_recv ( PG_FUNCTION_ARGS  )

Definition at line 1006 of file timestamp.c.

1007 {
1009 
1010 #ifdef NOT_USED
1011  Oid typelem = PG_GETARG_OID(1);
1012 #endif
1013  int32 typmod = PG_GETARG_INT32(2);
1014  Interval *interval;
1015 
1016  interval = (Interval *) palloc(sizeof(Interval));
1017 
1019  interval->day = pq_getmsgint(buf, sizeof(interval->day));
1020  interval->month = pq_getmsgint(buf, sizeof(interval->month));
1021 
1022  AdjustIntervalForTypmod(interval, typmod, NULL);
1023 
1025 }
StringInfoData * StringInfo
Definition: stringinfo.h:54

References AdjustIntervalForTypmod(), buf, interval::month, palloc(), PG_GETARG_INT32, PG_GETARG_OID, PG_GETARG_POINTER, PG_RETURN_INTERVAL_P, pq_getmsgint(), pq_getmsgint64(), and interval::time.

◆ interval_scale()

Datum interval_scale ( PG_FUNCTION_ARGS  )

Definition at line 1337 of file timestamp.c.

1338 {
1340  int32 typmod = PG_GETARG_INT32(1);
1341  Interval *result;
1342 
1343  result = palloc(sizeof(Interval));
1344  *result = *interval;
1345 
1346  AdjustIntervalForTypmod(result, typmod, NULL);
1347 
1348  PG_RETURN_INTERVAL_P(result);
1349 }

References AdjustIntervalForTypmod(), palloc(), PG_GETARG_INT32, PG_GETARG_INTERVAL_P, and PG_RETURN_INTERVAL_P.

◆ interval_send()

◆ interval_sign()

static int interval_sign ( const Interval interval)
static

◆ interval_smaller()

Datum interval_smaller ( PG_FUNCTION_ARGS  )

Definition at line 3406 of file timestamp.c.

3407 {
3408  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
3409  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
3410  Interval *result;
3411 
3412  /* use interval_cmp_internal to be sure this agrees with comparisons */
3413  if (interval_cmp_internal(interval1, interval2) < 0)
3414  result = interval1;
3415  else
3416  result = interval2;
3417  PG_RETURN_INTERVAL_P(result);
3418 }

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_INTERVAL_P.

◆ interval_sum()

Datum interval_sum ( PG_FUNCTION_ARGS  )

Definition at line 4195 of file timestamp.c.

4196 {
4198  Interval *result;
4199 
4201 
4202  /* If there were no non-null inputs, return NULL */
4203  if (state == NULL || IA_TOTAL_COUNT(state) == 0)
4204  PG_RETURN_NULL();
4205 
4206  /*
4207  * Aggregating infinities that all have the same sign produces infinity
4208  * with that sign. Aggregating infinities with different signs results in
4209  * an error.
4210  */
4211  if (state->pInfcount > 0 && state->nInfcount > 0)
4212  ereport(ERROR,
4213  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4214  errmsg("interval out of range.")));
4215 
4216  result = (Interval *) palloc(sizeof(Interval));
4217 
4218  if (state->pInfcount > 0)
4219  INTERVAL_NOEND(result);
4220  else if (state->nInfcount > 0)
4221  INTERVAL_NOBEGIN(result);
4222  else
4223  memcpy(result, &state->sumX, sizeof(Interval));
4224 
4225  PG_RETURN_INTERVAL_P(result);
4226 }

References ereport, errcode(), errmsg(), ERROR, IA_TOTAL_COUNT, INTERVAL_NOBEGIN, INTERVAL_NOEND, palloc(), PG_ARGISNULL, PG_GETARG_POINTER, PG_RETURN_INTERVAL_P, and PG_RETURN_NULL.

◆ interval_support()

Datum interval_support ( PG_FUNCTION_ARGS  )

Definition at line 1274 of file timestamp.c.

1275 {
1276  Node *rawreq = (Node *) PG_GETARG_POINTER(0);
1277  Node *ret = NULL;
1278 
1279  if (IsA(rawreq, SupportRequestSimplify))
1280  {
1282  FuncExpr *expr = req->fcall;
1283  Node *typmod;
1284 
1285  Assert(list_length(expr->args) >= 2);
1286 
1287  typmod = (Node *) lsecond(expr->args);
1288 
1289  if (IsA(typmod, Const) && !((Const *) typmod)->constisnull)
1290  {
1291  Node *source = (Node *) linitial(expr->args);
1292  int32 new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
1293  bool noop;
1294 
1295  if (new_typmod < 0)
1296  noop = true;
1297  else
1298  {
1299  int32 old_typmod = exprTypmod(source);
1300  int old_least_field;
1301  int new_least_field;
1302  int old_precis;
1303  int new_precis;
1304 
1305  old_least_field = intervaltypmodleastfield(old_typmod);
1306  new_least_field = intervaltypmodleastfield(new_typmod);
1307  if (old_typmod < 0)
1308  old_precis = INTERVAL_FULL_PRECISION;
1309  else
1310  old_precis = INTERVAL_PRECISION(old_typmod);
1311  new_precis = INTERVAL_PRECISION(new_typmod);
1312 
1313  /*
1314  * Cast is a no-op if least field stays the same or decreases
1315  * while precision stays the same or increases. But
1316  * precision, which is to say, sub-second precision, only
1317  * affects ranges that include SECOND.
1318  */
1319  noop = (new_least_field <= old_least_field) &&
1320  (old_least_field > 0 /* SECOND */ ||
1321  new_precis >= MAX_INTERVAL_PRECISION ||
1322  new_precis >= old_precis);
1323  }
1324  if (noop)
1325  ret = relabel_to_typmod(source, new_typmod);
1326  }
1327  }
1328 
1329  PG_RETURN_POINTER(ret);
1330 }
static int intervaltypmodleastfield(int32 typmod)
Definition: timestamp.c:1221
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:298
Node * relabel_to_typmod(Node *expr, int32 typmod)
Definition: nodeFuncs.c:684
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
static int list_length(const List *l)
Definition: pg_list.h:152
#define linitial(l)
Definition: pg_list.h:178
#define lsecond(l)
Definition: pg_list.h:183
static rewind_source * source
Definition: pg_rewind.c:89
static int32 DatumGetInt32(Datum X)
Definition: postgres.h:202
List * args
Definition: primnodes.h:738

References FuncExpr::args, Assert, DatumGetInt32(), exprTypmod(), SupportRequestSimplify::fcall, INTERVAL_FULL_PRECISION, INTERVAL_PRECISION, intervaltypmodleastfield(), IsA, linitial, list_length(), lsecond, MAX_INTERVAL_PRECISION, PG_GETARG_POINTER, PG_RETURN_POINTER, relabel_to_typmod(), and source.

◆ interval_trunc()

Datum interval_trunc ( PG_FUNCTION_ARGS  )

Definition at line 5005 of file timestamp.c.

5006 {
5007  text *units = PG_GETARG_TEXT_PP(0);
5009  Interval *result;
5010  int type,
5011  val;
5012  char *lowunits;
5013  struct pg_itm tt,
5014  *tm = &tt;
5015 
5016  result = (Interval *) palloc(sizeof(Interval));
5017 
5019  {
5020  memcpy(result, interval, sizeof(Interval));
5021  PG_RETURN_INTERVAL_P(result);
5022  }
5023 
5024  lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
5025  VARSIZE_ANY_EXHDR(units),
5026  false);
5027 
5028  type = DecodeUnits(0, lowunits, &val);
5029 
5030  if (type == UNITS)
5031  {
5033  switch (val)
5034  {
5035  case DTK_MILLENNIUM:
5036  /* caution: C division may have negative remainder */
5037  tm->tm_year = (tm->tm_year / 1000) * 1000;
5038  /* FALL THRU */
5039  case DTK_CENTURY:
5040  /* caution: C division may have negative remainder */
5041  tm->tm_year = (tm->tm_year / 100) * 100;
5042  /* FALL THRU */
5043  case DTK_DECADE:
5044  /* caution: C division may have negative remainder */
5045  tm->tm_year = (tm->tm_year / 10) * 10;
5046  /* FALL THRU */
5047  case DTK_YEAR:
5048  tm->tm_mon = 0;
5049  /* FALL THRU */
5050  case DTK_QUARTER:
5051  tm->tm_mon = 3 * (tm->tm_mon / 3);
5052  /* FALL THRU */
5053  case DTK_MONTH:
5054  tm->tm_mday = 0;
5055  /* FALL THRU */
5056  case DTK_DAY:
5057  tm->tm_hour = 0;
5058  /* FALL THRU */
5059  case DTK_HOUR:
5060  tm->tm_min = 0;
5061  /* FALL THRU */
5062  case DTK_MINUTE:
5063  tm->tm_sec = 0;
5064  /* FALL THRU */
5065  case DTK_SECOND:
5066  tm->tm_usec = 0;
5067  break;
5068  case DTK_MILLISEC:
5069  tm->tm_usec = (tm->tm_usec / 1000) * 1000;
5070  break;
5071  case DTK_MICROSEC:
5072  break;
5073 
5074  default:
5075  ereport(ERROR,
5076  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5077  errmsg("unit \"%s\" not supported for type %s",
5078  lowunits, format_type_be(INTERVALOID)),
5079  (val == DTK_WEEK) ? errdetail("Months usually have fractional weeks.") : 0));
5080  }
5081 
5082  if (itm2interval(tm, result) != 0)
5083  ereport(ERROR,
5084  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
5085  errmsg("interval out of range")));
5086  }
5087  else
5088  {
5089  ereport(ERROR,
5090  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5091  errmsg("unit \"%s\" not recognized for type %s",
5092  lowunits, format_type_be(INTERVALOID))));
5093  }
5094 
5095  PG_RETURN_INTERVAL_P(result);
5096 }
int itm2interval(struct pg_itm *itm, Interval *span)
Definition: timestamp.c:2077
int errdetail(const char *fmt,...)
Definition: elog.c:1205
#define DTK_WEEK
Definition: datetime.h:164

References DecodeUnits(), downcase_truncate_identifier(), DTK_CENTURY, DTK_DAY, DTK_DECADE, DTK_HOUR, DTK_MICROSEC, DTK_MILLENNIUM, DTK_MILLISEC, DTK_MINUTE, DTK_MONTH, DTK_QUARTER, DTK_SECOND, DTK_WEEK, DTK_YEAR, ereport, errcode(), errdetail(), errmsg(), ERROR, format_type_be(), interval2itm(), INTERVAL_NOT_FINITE, itm2interval(), palloc(), PG_GETARG_INTERVAL_P, PG_GETARG_TEXT_PP, PG_RETURN_INTERVAL_P, tm, pg_tm::tm_hour, pg_tm::tm_mday, pg_tm::tm_min, pg_tm::tm_mon, pg_tm::tm_sec, pg_tm::tm_year, type, UNITS, val, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ interval_um()

Datum interval_um ( PG_FUNCTION_ARGS  )

Definition at line 3393 of file timestamp.c.

3394 {
3396  Interval *result;
3397 
3398  result = (Interval *) palloc(sizeof(Interval));
3399  interval_um_internal(interval, result);
3400 
3401  PG_RETURN_INTERVAL_P(result);
3402 }

References interval_um_internal(), palloc(), PG_GETARG_INTERVAL_P, and PG_RETURN_INTERVAL_P.

Referenced by abs_interval().

◆ interval_um_internal()

static void interval_um_internal ( const Interval interval,
Interval result 
)
static

Definition at line 3373 of file timestamp.c.

3374 {
3376  INTERVAL_NOEND(result);
3377  else if (INTERVAL_IS_NOEND(interval))
3378  INTERVAL_NOBEGIN(result);
3379  else
3380  {
3381  /* Negate each field, guarding against overflow */
3382  if (pg_sub_s64_overflow(INT64CONST(0), interval->time, &result->time) ||
3383  pg_sub_s32_overflow(0, interval->day, &result->day) ||
3384  pg_sub_s32_overflow(0, interval->month, &result->month) ||
3385  INTERVAL_NOT_FINITE(result))
3386  ereport(ERROR,
3387  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3388  errmsg("interval out of range")));
3389  }
3390 }

References Interval::day, ereport, errcode(), errmsg(), ERROR, INTERVAL_IS_NOBEGIN, INTERVAL_IS_NOEND, INTERVAL_NOBEGIN, INTERVAL_NOEND, INTERVAL_NOT_FINITE, Interval::month, interval::month, pg_sub_s32_overflow(), pg_sub_s64_overflow(), Interval::time, and interval::time.

Referenced by interval_div(), interval_mul(), interval_um(), timestamp_mi_interval(), and timestamptz_mi_interval_internal().

◆ intervaltypmodin()

Datum intervaltypmodin ( PG_FUNCTION_ARGS  )

Definition at line 1056 of file timestamp.c.

1057 {
1059  int32 *tl;
1060  int n;
1061  int32 typmod;
1062 
1063  tl = ArrayGetIntegerTypmods(ta, &n);
1064 
1065  /*
1066  * tl[0] - interval range (fields bitmask) tl[1] - precision (optional)
1067  *
1068  * Note we must validate tl[0] even though it's normally guaranteed
1069  * correct by the grammar --- consider SELECT 'foo'::"interval"(1000).
1070  */
1071  if (n > 0)
1072  {
1073  switch (tl[0])
1074  {
1075  case INTERVAL_MASK(YEAR):
1076  case INTERVAL_MASK(MONTH):
1077  case INTERVAL_MASK(DAY):
1078  case INTERVAL_MASK(HOUR):
1079  case INTERVAL_MASK(MINUTE):
1080  case INTERVAL_MASK(SECOND):
1088  case INTERVAL_FULL_RANGE:
1089  /* all OK */
1090  break;
1091  default:
1092  ereport(ERROR,
1093  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1094  errmsg("invalid INTERVAL type modifier")));
1095  }
1096  }
1097 
1098  if (n == 1)
1099  {
1100  if (tl[0] != INTERVAL_FULL_RANGE)
1101  typmod = INTERVAL_TYPMOD(INTERVAL_FULL_PRECISION, tl[0]);
1102  else
1103  typmod = -1;
1104  }
1105  else if (n == 2)
1106  {
1107  if (tl[1] < 0)
1108  ereport(ERROR,
1109  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1110  errmsg("INTERVAL(%d) precision must not be negative",
1111  tl[1])));
1112  if (tl[1] > MAX_INTERVAL_PRECISION)
1113  {
1114  ereport(WARNING,
1115  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1116  errmsg("INTERVAL(%d) precision reduced to maximum allowed, %d",
1117  tl[1], MAX_INTERVAL_PRECISION)));
1118  typmod = INTERVAL_TYPMOD(MAX_INTERVAL_PRECISION, tl[0]);
1119  }
1120  else
1121  typmod = INTERVAL_TYPMOD(tl[1], tl[0]);
1122  }
1123  else
1124  {
1125  ereport(ERROR,
1126  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1127  errmsg("invalid INTERVAL type modifier")));
1128  typmod = 0; /* keep compiler quiet */
1129  }
1130 
1131  PG_RETURN_INT32(typmod);
1132 }
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:263
#define INTERVAL_TYPMOD(p, r)
Definition: timestamp.h:80

References ArrayGetIntegerTypmods(), DAY, ereport, errcode(), errmsg(), ERROR, HOUR, INTERVAL_FULL_PRECISION, INTERVAL_FULL_RANGE, INTERVAL_MASK, INTERVAL_TYPMOD, MAX_INTERVAL_PRECISION, MINUTE, MONTH, PG_GETARG_ARRAYTYPE_P, PG_RETURN_INT32, SECOND, WARNING, and YEAR.

◆ intervaltypmodleastfield()

static int intervaltypmodleastfield ( int32  typmod)
static

Definition at line 1221 of file timestamp.c.

1222 {
1223  if (typmod < 0)
1224  return 0; /* SECOND */
1225 
1226  switch (INTERVAL_RANGE(typmod))
1227  {
1228  case INTERVAL_MASK(YEAR):
1229  return 5; /* YEAR */
1230  case INTERVAL_MASK(MONTH):
1231  return 4; /* MONTH */
1232  case INTERVAL_MASK(DAY):
1233  return 3; /* DAY */
1234  case INTERVAL_MASK(HOUR):
1235  return 2; /* HOUR */
1236  case INTERVAL_MASK(MINUTE):
1237  return 1; /* MINUTE */
1238  case INTERVAL_MASK(SECOND):
1239  return 0; /* SECOND */
1241  return 4; /* MONTH */
1243  return 2; /* HOUR */
1245  return 1; /* MINUTE */
1247  return 0; /* SECOND */
1249  return 1; /* MINUTE */
1251  return 0; /* SECOND */
1253  return 0; /* SECOND */
1254  case INTERVAL_FULL_RANGE:
1255  return 0; /* SECOND */
1256  default:
1257  elog(ERROR, "invalid INTERVAL typmod: 0x%x", typmod);
1258  break;
1259  }
1260  return 0; /* can't get here, but keep compiler quiet */
1261 }

References DAY, elog, ERROR, HOUR, INTERVAL_FULL_RANGE, INTERVAL_MASK, INTERVAL_RANGE, MINUTE, MONTH, SECOND, and YEAR.

Referenced by interval_support().

◆ intervaltypmodout()

Datum intervaltypmodout ( PG_FUNCTION_ARGS  )

Definition at line 1135 of file timestamp.c.

1136 {
1137  int32 typmod = PG_GETARG_INT32(0);
1138  char *res = (char *) palloc(64);
1139  int fields;
1140  int precision;
1141  const char *fieldstr;
1142 
1143  if (typmod < 0)
1144  {
1145  *res = '\0';
1147  }
1148 
1149  fields = INTERVAL_RANGE(typmod);
1150  precision = INTERVAL_PRECISION(typmod);
1151 
1152  switch (fields)
1153  {
1154  case INTERVAL_MASK(YEAR):
1155  fieldstr = " year";
1156  break;
1157  case INTERVAL_MASK(MONTH):
1158  fieldstr = " month";
1159  break;
1160  case INTERVAL_MASK(DAY):
1161  fieldstr = " day";
1162  break;
1163  case INTERVAL_MASK(HOUR):
1164  fieldstr = " hour";
1165  break;
1166  case INTERVAL_MASK(MINUTE):
1167  fieldstr = " minute";
1168  break;
1169  case INTERVAL_MASK(SECOND):
1170  fieldstr = " second";
1171  break;
1173  fieldstr = " year to month";
1174  break;
1176  fieldstr = " day to hour";
1177  break;
1179  fieldstr = " day to minute";
1180  break;
1182  fieldstr = " day to second";
1183  break;
1185  fieldstr = " hour to minute";
1186  break;
1188  fieldstr = " hour to second";
1189  break;
1191  fieldstr = " minute to second";
1192  break;
1193  case INTERVAL_FULL_RANGE:
1194  fieldstr = "";
1195  break;
1196  default:
1197  elog(ERROR, "invalid INTERVAL typmod: 0x%x", typmod);
1198  fieldstr = "";
1199  break;
1200  }
1201 
1202  if (precision != INTERVAL_FULL_PRECISION)
1203  snprintf(res, 64, "%s(%d)", fieldstr, precision);
1204  else
1205  snprintf(res, 64, "%s", fieldstr);
1206 
1208 }
#define snprintf
Definition: port.h:238

References DAY, elog, ERROR, HOUR, INTERVAL_FULL_PRECISION, INTERVAL_FULL_RANGE, INTERVAL_MASK, INTERVAL_PRECISION, INTERVAL_RANGE, MINUTE, MONTH, palloc(), PG_GETARG_INT32, PG_RETURN_CSTRING, res, SECOND, snprintf, and YEAR.

◆ isoweek2date()

void isoweek2date ( int  woy,
int *  year,
int *  mon,
int *  mday 
)

Definition at line 5124 of file timestamp.c.

5125 {
5126  j2date(isoweek2j(*year, woy), year, mon, mday);
5127 }
void j2date(int jd, int *year, int *month, int *day)
Definition: datetime.c:311

References isoweek2j(), and j2date().

Referenced by do_to_timestamp(), timestamp_trunc(), and timestamptz_trunc_internal().

◆ isoweek2j()

int isoweek2j ( int  year,
int  week 
)

Definition at line 5104 of file timestamp.c.

5105 {
5106  int day0,
5107  day4;
5108 
5109  /* fourth day of current year */
5110  day4 = date2j(year, 1, 4);
5111 
5112  /* day0 == offset to first day of week (Monday) */
5113  day0 = j2day(day4 - 1);
5114 
5115  return ((week - 1) * 7) + (day4 - day0);
5116 }

References date2j(), and j2day().

Referenced by date2isoyearday(), do_to_timestamp(), isoweek2date(), and isoweekdate2date().

◆ isoweekdate2date()

void isoweekdate2date ( int  isoweek,
int  wday,
int *  year,
int *  mon,
int *  mday 
)

Definition at line 5137 of file timestamp.c.

5138 {
5139  int jday;
5140 
5141  jday = isoweek2j(*year, isoweek);
5142  /* convert Gregorian week start (Sunday=1) to ISO week start (Monday=1) */
5143  if (wday > 1)
5144  jday += wday - 2;
5145  else
5146  jday += 6;
5147  j2date(jday, year, mon, mday);
5148 }

References isoweek2j(), and j2date().

Referenced by do_to_timestamp().

◆ itm2interval()

int itm2interval ( struct pg_itm itm,
Interval span 
)

Definition at line 2077 of file timestamp.c.

2078 {
2079  int64 total_months = (int64) itm->tm_year * MONTHS_PER_YEAR + itm->tm_mon;
2080 
2081  if (total_months > INT_MAX || total_months < INT_MIN)
2082  return -1;
2083  span->month = (int32) total_months;
2084  span->day = itm->tm_mday;
2086  &span->time))
2087  return -1;
2088  /* tm_min, tm_sec are 32 bits, so intermediate products can't overflow */
2089  if (pg_add_s64_overflow(span->time, itm->tm_min * USECS_PER_MINUTE,
2090  &span->time))
2091  return -1;
2092  if (pg_add_s64_overflow(span->time, itm->tm_sec * USECS_PER_SEC,
2093  &span->time))
2094  return -1;
2095  if (pg_add_s64_overflow(span->time, itm->tm_usec,
2096  &span->time))
2097  return -1;
2098  if (INTERVAL_NOT_FINITE(span))
2099  return -1;
2100  return 0;
2101 }
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77

References Interval::day, if(), INTERVAL_NOT_FINITE, Interval::month, MONTHS_PER_YEAR, pg_add_s64_overflow(), pg_mul_s64_overflow(), Interval::time, pg_itm::tm_hour, pg_itm::tm_mday, pg_itm::tm_min, pg_itm::tm_mon, pg_itm::tm_sec, pg_itm::tm_usec, pg_itm::tm_year, USECS_PER_HOUR, USECS_PER_MINUTE, and USECS_PER_SEC.

Referenced by interval_trunc(), timestamp_age(), and timestamptz_age().

◆ itmin2interval()

int itmin2interval ( struct pg_itm_in itm_in,
Interval span 
)

Definition at line 2115 of file timestamp.c.

2116 {
2117  int64 total_months = (int64) itm_in->tm_year * MONTHS_PER_YEAR + itm_in->tm_mon;
2118 
2119  if (total_months > INT_MAX || total_months < INT_MIN)
2120  return -1;
2121  span->month = (int32) total_months;
2122  span->day = itm_in->tm_mday;
2123  span->time = itm_in->tm_usec;
2124  return 0;
2125 }

References Interval::day, if(), Interval::month, MONTHS_PER_YEAR, Interval::time, pg_itm_in::tm_mday, pg_itm_in::tm_mon, pg_itm_in::tm_usec, and pg_itm_in::tm_year.

Referenced by interval_in(), and pg_timezone_abbrevs().

◆ lookup_timezone()

static pg_tz* lookup_timezone ( text zone)
static

Definition at line 558 of file timestamp.c.

559 {
560  char tzname[TZ_STRLEN_MAX + 1];
561 
562  text_to_cstring_buffer(zone, tzname, sizeof(tzname));
563 
564  return DecodeTimezoneNameToTz(tzname);
565 }
pg_tz * DecodeTimezoneNameToTz(const char *tzname)
Definition: datetime.c:3234
#define TZ_STRLEN_MAX
Definition: pgtime.h:54
void text_to_cstring_buffer(const text *src, char *dst, size_t dst_len)
Definition: varlena.c:248

References DecodeTimezoneNameToTz(), text_to_cstring_buffer(), and TZ_STRLEN_MAX.

Referenced by generate_series_timestamptz_internal(), timestamptz_mi_interval_at_zone(), timestamptz_pl_interval_at_zone(), and timestamptz_trunc_zone().

◆ make_interval()

Datum make_interval ( PG_FUNCTION_ARGS  )

Definition at line 1539 of file timestamp.c.

1540 {
1541  int32 years = PG_GETARG_INT32(0);
1543  int32 weeks = PG_GETARG_INT32(2);
1544  int32 days = PG_GETARG_INT32(3);
1545  int32 hours = PG_GETARG_INT32(4);
1546  int32 mins = PG_GETARG_INT32(5);
1547  double secs = PG_GETARG_FLOAT8(6);
1548  Interval *result;
1549 
1550  /*
1551  * Reject out-of-range inputs. We reject any input values that cause
1552  * integer overflow of the corresponding interval fields.
1553  */
1554  if (isinf(secs) || isnan(secs))
1555  goto out_of_range;
1556 
1557  result = (Interval *) palloc(sizeof(Interval));
1558 
1559  /* years and months -> months */
1560  if (pg_mul_s32_overflow(years, MONTHS_PER_YEAR, &result->month) ||
1561  pg_add_s32_overflow(result->month, months, &result->month))
1562  goto out_of_range;
1563 
1564  /* weeks and days -> days */
1565  if (pg_mul_s32_overflow(weeks, DAYS_PER_WEEK, &result->day) ||
1566  pg_add_s32_overflow(result->day, days, &result->day))
1567  goto out_of_range;
1568 
1569  /* hours and mins -> usecs (cannot overflow 64-bit) */
1570  result->time = hours * USECS_PER_HOUR + mins * USECS_PER_MINUTE;
1571 
1572  /* secs -> usecs */
1573  secs = rint(float8_mul(secs, USECS_PER_SEC));
1574  if (!FLOAT8_FITS_IN_INT64(secs) ||
1575  pg_add_s64_overflow(result->time, (int64) secs, &result->time))
1576  goto out_of_range;
1577 
1578  /* make sure that the result is finite */
1579  if (INTERVAL_NOT_FINITE(result))
1580  goto out_of_range;
1581 
1582  PG_RETURN_INTERVAL_P(result);
1583 
1584 out_of_range:
1585  ereport(ERROR,
1586  errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1587  errmsg("interval out of range"));
1588 
1589  PG_RETURN_NULL(); /* keep compiler quiet */
1590 }
const char *const months[]
Definition: datetime.c:81
#define DAYS_PER_WEEK
Definition: timestamp.h:117
static float8 float8_mul(const float8 val1, const float8 val2)
Definition: float.h:208
static bool pg_mul_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:140

References Interval::day, days, DAYS_PER_WEEK, ereport, errcode(), errmsg(), ERROR, FLOAT8_FITS_IN_INT64, float8_mul(), INTERVAL_NOT_FINITE, Interval::month, months, MONTHS_PER_YEAR, palloc(), pg_add_s32_overflow(), pg_add_s64_overflow(), PG_GETARG_FLOAT8, PG_GETARG_INT32, pg_mul_s32_overflow(), PG_RETURN_INTERVAL_P, PG_RETURN_NULL, Interval::time, USECS_PER_HOUR, USECS_PER_MINUTE, and USECS_PER_SEC.

◆ make_timestamp()

Datum make_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 654 of file timestamp.c.

655 {
656  int32 year = PG_GETARG_INT32(0);
657  int32 month = PG_GETARG_INT32(1);
658  int32 mday = PG_GETARG_INT32(2);
659  int32 hour = PG_GETARG_INT32(3);
660  int32 min = PG_GETARG_INT32(4);
661  float8 sec = PG_GETARG_FLOAT8(5);
662  Timestamp result;
663 
664  result = make_timestamp_internal(year, month, mday,
665  hour, min, sec);
666 
667  PG_RETURN_TIMESTAMP(result);
668 }
static Timestamp make_timestamp_internal(int year, int month, int day, int hour, int min, double sec)
Definition: timestamp.c:572

References make_timestamp_internal(), PG_GETARG_FLOAT8, PG_GETARG_INT32, and PG_RETURN_TIMESTAMP.

◆ make_timestamp_internal()

static Timestamp make_timestamp_internal ( int  year,
int  month,
int  day,
int  hour,
int  min,
double  sec 
)
static

Definition at line 572 of file timestamp.c.

574 {
575  struct pg_tm tm;
577  TimeOffset time;
578  int dterr;
579  bool bc = false;
580  Timestamp result;
581 
582  tm.tm_year = year;
583  tm.tm_mon = month;
584  tm.tm_mday = day;
585 
586  /* Handle negative years as BC */
587  if (tm.tm_year < 0)
588  {
589  bc = true;
590  tm.tm_year = -tm.tm_year;
591  }
592 
593  dterr = ValidateDate(DTK_DATE_M, false, false, bc, &tm);
594 
595  if (dterr != 0)
596  ereport(ERROR,
597  (errcode(ERRCODE_DATETIME_FIELD_OVERFLOW),
598  errmsg("date field value out of range: %d-%02d-%02d",
599  year, month, day)));
600 
602  ereport(ERROR,
603  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
604  errmsg("date out of range: %d-%02d-%02d",
605  year, month, day)));
606 
608 
609  /* Check for time overflow */
610  if (float_time_overflows(hour, min, sec))
611  ereport(ERROR,
612  (errcode(ERRCODE_DATETIME_FIELD_OVERFLOW),
613  errmsg("time field value out of range: %d:%02d:%02g",
614  hour, min, sec)));
615 
616  /* This should match tm2time */
617  time = (((hour * MINS_PER_HOUR + min) * SECS_PER_MINUTE)
618  * USECS_PER_SEC) + (int64) rint(sec * USECS_PER_SEC);
619 
620  result = date * USECS_PER_DAY + time;
621  /* check for major overflow */
622  if ((result - time) / USECS_PER_DAY != date)
623  ereport(ERROR,
624  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
625  errmsg("timestamp out of range: %d-%02d-%02d %d:%02d:%02g",
626  year, month, day,
627  hour, min, sec)));
628 
629  /* check for just-barely overflow (okay except time-of-day wraps) */
630  /* caution: we want to allow 1999-12-31 24:00:00 */
631  if ((result < 0 && date > 0) ||
632  (result > 0 && date < -1))
633  ereport(ERROR,
634  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
635  errmsg("timestamp out of range: %d-%02d-%02d %d:%02d:%02g",
636  year, month, day,
637  hour, min, sec)));
638 
639  /* final range check catches just-out-of-range timestamps */
640  if (!IS_VALID_TIMESTAMP(result))
641  ereport(ERROR,
642  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
643  errmsg("timestamp out of range: %d-%02d-%02d %d:%02d:%02g",
644  year, month, day,
645  hour, min, sec)));
646 
647  return result;
648 }
int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc, struct pg_tm *tm)
Definition: datetime.c:2497
#define MINS_PER_HOUR
Definition: timestamp.h:129
#define IS_VALID_JULIAN(y, m, d)
Definition: timestamp.h:227
#define SECS_PER_MINUTE
Definition: timestamp.h:128
bool float_time_overflows(int hour, int min, double sec)
Definition: date.c:1451
#define DTK_DATE_M
Definition: datetime.h:191
long date
Definition: pgtypes_date.h:9

References date2j(), DTK_DATE_M, ereport, errcode(), errmsg(), ERROR, float_time_overflows(), IS_VALID_JULIAN, IS_VALID_TIMESTAMP, MINS_PER_HOUR, POSTGRES_EPOCH_JDATE, SECS_PER_MINUTE, tm, pg_tm::tm_mday, pg_tm::tm_mon, pg_tm::tm_year, USECS_PER_DAY, USECS_PER_SEC, and ValidateDate().

Referenced by make_timestamp(), make_timestamptz(), and make_timestamptz_at_timezone().

◆ make_timestamptz()

Datum make_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 674 of file timestamp.c.

675 {
676  int32 year = PG_GETARG_INT32(0);
677  int32 month = PG_GETARG_INT32(1);
678  int32 mday = PG_GETARG_INT32(2);
679  int32 hour = PG_GETARG_INT32(3);
680  int32 min = PG_GETARG_INT32(4);
681  float8 sec = PG_GETARG_FLOAT8(5);
682  Timestamp result;
683 
684  result = make_timestamp_internal(year, month, mday,
685  hour, min, sec);
686 
688 }
static TimestampTz timestamp2timestamptz(Timestamp timestamp)
Definition: timestamp.c:6344

References make_timestamp_internal(), PG_GETARG_FLOAT8, PG_GETARG_INT32, PG_RETURN_TIMESTAMPTZ, and timestamp2timestamptz().

◆ make_timestamptz_at_timezone()

Datum make_timestamptz_at_timezone ( PG_FUNCTION_ARGS  )

Definition at line 695 of file timestamp.c.

696 {
697  int32 year = PG_GETARG_INT32(0);
698  int32 month = PG_GETARG_INT32(1);
699  int32 mday = PG_GETARG_INT32(2);
700  int32 hour = PG_GETARG_INT32(3);
701  int32 min = PG_GETARG_INT32(4);
702  float8 sec = PG_GETARG_FLOAT8(5);
704  TimestampTz result;
706  struct pg_tm tt;
707  int tz;
708  fsec_t fsec;
709 
710  timestamp = make_timestamp_internal(year, month, mday,
711  hour, min, sec);
712 
713  if (timestamp2tm(timestamp, NULL, &tt, &fsec, NULL, NULL) != 0)
714  ereport(ERROR,
715  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
716  errmsg("timestamp out of range")));
717 
718  tz = parse_sane_timezone(&tt, zone);
719 
720  result = dt2local(timestamp, -tz);
721 
722  if (!IS_VALID_TIMESTAMP(result))
723  ereport(ERROR,
724  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
725  errmsg("timestamp out of range")));
726 
727  PG_RETURN_TIMESTAMPTZ(result);
728 }
static Timestamp dt2local(Timestamp dt, int timezone)
Definition: timestamp.c:2134
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition: timestamp.c:1901
static int parse_sane_timezone(struct pg_tm *tm, text *zone)
Definition: timestamp.c:489
int32 fsec_t
Definition: timestamp.h:41
int64 timestamp

References dt2local(), ereport, errcode(), errmsg(), ERROR, IS_VALID_TIMESTAMP, make_timestamp_internal(), parse_sane_timezone(), PG_GETARG_FLOAT8, PG_GETARG_INT32, PG_GETARG_TEXT_PP, PG_RETURN_TIMESTAMPTZ, and timestamp2tm().

◆ makeIntervalAggState()

static IntervalAggState* makeIntervalAggState ( FunctionCallInfo  fcinfo)
static

Definition at line 3914 of file timestamp.c.

3915 {
3917  MemoryContext agg_context;
3918  MemoryContext old_context;
3919 
3920  if (!AggCheckCallContext(fcinfo, &agg_context))
3921  elog(ERROR, "aggregate function called in non-aggregate context");
3922 
3923  old_context = MemoryContextSwitchTo(agg_context);
3924 
3926 
3927  MemoryContextSwitchTo(old_context);
3928 
3929  return state;
3930 }

References AggCheckCallContext(), elog, ERROR, MemoryContextSwitchTo(), and palloc0().

Referenced by interval_avg_accum(), and interval_avg_combine().

◆ mul_d_interval()

Datum mul_d_interval ( PG_FUNCTION_ARGS  )

Definition at line 3675 of file timestamp.c.

3676 {
3677  /* Args are float8 and Interval *, but leave them as generic Datum */
3678  Datum factor = PG_GETARG_DATUM(0);
3679  Datum span = PG_GETARG_DATUM(1);
3680 
3681  return DirectFunctionCall2(interval_mul, span, factor);
3682 }
Datum interval_mul(PG_FUNCTION_ARGS)
Definition: timestamp.c:3555

References DirectFunctionCall2, interval_mul(), and PG_GETARG_DATUM.

◆ NonFiniteIntervalPart()

static float8 NonFiniteIntervalPart ( int  type,
int  unit,
char *  lowunits,
bool  isNegative 
)
static

Definition at line 5894 of file timestamp.c.

5895 {
5896  if ((type != UNITS) && (type != RESERV))
5897  ereport(ERROR,
5898  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5899  errmsg("unit \"%s\" not recognized for type %s",
5900  lowunits, format_type_be(INTERVALOID))));
5901 
5902  switch (unit)
5903  {
5904  /* Oscillating units */
5905  case DTK_MICROSEC:
5906  case DTK_MILLISEC:
5907  case DTK_SECOND:
5908  case DTK_MINUTE:
5909  case DTK_MONTH:
5910  case DTK_QUARTER:
5911  return 0.0;
5912 
5913  /* Monotonically-increasing units */
5914  case DTK_HOUR:
5915  case DTK_DAY:
5916  case DTK_YEAR:
5917  case DTK_DECADE:
5918  case DTK_CENTURY:
5919  case DTK_MILLENNIUM:
5920  case DTK_EPOCH:
5921  if (isNegative)
5922  return -get_float8_infinity();
5923  else
5924  return get_float8_infinity();
5925 
5926  default:
5927  ereport(ERROR,
5928  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5929  errmsg("unit \"%s\" not supported for type %s",
5930  lowunits, format_type_be(INTERVALOID))));
5931  return 0.0; /* keep compiler quiet */
5932  }
5933 }
static float8 get_float8_infinity(void)
Definition: float.h:94

References DTK_CENTURY, DTK_DAY, DTK_DECADE, DTK_EPOCH, DTK_HOUR, DTK_MICROSEC, DTK_MILLENNIUM, DTK_MILLISEC, DTK_MINUTE, DTK_MONTH, DTK_QUARTER, DTK_SECOND, DTK_YEAR, ereport, errcode(), errmsg(), ERROR, format_type_be(), get_float8_infinity(), RESERV, type, and UNITS.

Referenced by interval_part_common().

◆ NonFiniteTimestampTzPart()

static float8 NonFiniteTimestampTzPart ( int  type,
int  unit,
char *  lowunits,
bool  isNegative,
bool  isTz 
)
static

Definition at line 5284 of file timestamp.c.

5286 {
5287  if ((type != UNITS) && (type != RESERV))
5288  ereport(ERROR,
5289  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5290  errmsg("unit \"%s\" not recognized for type %s",
5291  lowunits,
5292  format_type_be(isTz ? TIMESTAMPTZOID : TIMESTAMPOID))));
5293 
5294  switch (unit)
5295  {
5296  /* Oscillating units */
5297  case DTK_MICROSEC:
5298  case DTK_MILLISEC:
5299  case DTK_SECOND:
5300  case DTK_MINUTE:
5301  case DTK_HOUR:
5302  case DTK_DAY:
5303  case DTK_MONTH:
5304  case DTK_QUARTER:
5305  case DTK_WEEK:
5306  case DTK_DOW:
5307  case DTK_ISODOW:
5308  case DTK_DOY:
5309  case DTK_TZ:
5310  case DTK_TZ_MINUTE:
5311  case DTK_TZ_HOUR:
5312  return 0.0;
5313 
5314  /* Monotonically-increasing units */
5315  case DTK_YEAR:
5316  case DTK_DECADE:
5317  case DTK_CENTURY:
5318  case DTK_MILLENNIUM:
5319  case DTK_JULIAN:
5320  case DTK_ISOYEAR:
5321  case DTK_EPOCH:
5322  if (isNegative)
5323  return -get_float8_infinity();
5324  else
5325  return get_float8_infinity();
5326 
5327  default:
5328  ereport(ERROR,
5329  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5330  errmsg("unit \"%s\" not supported for type %s",
5331  lowunits,
5332  format_type_be(isTz ? TIMESTAMPTZOID : TIMESTAMPOID))));
5333  return 0.0; /* keep compiler quiet */
5334  }
5335 }
#define DTK_JULIAN
Definition: datetime.h:173
#define DTK_TZ_HOUR
Definition: datetime.h:177
#define DTK_TZ_MINUTE
Definition: datetime.h:178
#define DTK_ISODOW
Definition: datetime.h:180
#define DTK_ISOYEAR
Definition: datetime.h:179
#define DTK_DOY
Definition: datetime.h:176
#define DTK_TZ
Definition: datetime.h:146
#define DTK_DOW
Definition: datetime.h:175

References DTK_CENTURY, DTK_DAY, DTK_DECADE, DTK_DOW, DTK_DOY, DTK_EPOCH, DTK_HOUR, DTK_ISODOW, DTK_ISOYEAR, DTK_JULIAN, DTK_MICROSEC, DTK_MILLENNIUM, DTK_MILLISEC, DTK_MINUTE, DTK_MONTH, DTK_QUARTER, DTK_SECOND, DTK_TZ, DTK_TZ_HOUR, DTK_TZ_MINUTE, DTK_WEEK, DTK_YEAR, ereport, errcode(), errmsg(), ERROR, format_type_be(), get_float8_infinity(), RESERV, type, and UNITS.

Referenced by timestamp_part_common(), and timestamptz_part_common().

◆ now()

Definition at line 1618 of file timestamp.c.

References GetCurrentTransactionStartTimestamp(), and PG_RETURN_TIMESTAMPTZ.

Referenced by advanceConnectionState(), ApplyLauncherMain(), BackgroundWriterMain(), bbsink_copystream_archive_contents(), CalculateCopyStreamSleeptime(), CheckArchiveTimeout(), CheckpointerMain(), doLog(), doRetry(), dumpTimestamp(), enable_timeout(), enable_timeout_after(), enable_timeout_at(), enable_timeout_every(), enable_timeouts(), executeMetaCommand(), flushAndSendFeedback(), handle_sig_alarm(), HandleCopyStream(), has_startup_progress_timeout_expired(), initialize_prng(), IsCheckpointOnSchedule(), LagTrackerRead(), launch_worker(), libpqsrv_cancel(), LockBufferForCleanup(), logicalrep_worker_launch(), LogicalRepApplyLoop(), LogRecoveryConflict(), maybe_start_bgworkers(), mxid_age(), OutputFsync(), PerformRadiusTransaction(), pg_clock_gettime_ns(), pg_time_now(), pg_time_now_lazy(), pg_timezone_abbrevs(), pgfdw_get_cleanup_result(), pgstat_report_archiver(), pgstat_report_stat(), PQsocketPoll(), pqTraceFormatTimestamp(), printProgressReport(), printVerboseErrorMessages(), process_syncing_tables_for_apply(), ProcessKeepaliveMsg(), ProcessStandbyReplyMessage(), processXactStats(), ProcSleep(), progress_report(), ReplicationSlotRelease(), RequestXLogStreaming(), ResolveRecoveryConflictWithLock(), ResolveRecoveryConflictWithVirtualXIDs(), schedule_alarm(), send_feedback(), sendFeedback(), ServerLoop(), set_next_rotation_time(), StreamLogicalLog(), SysLoggerMain(), threadRun(), timetz_zone(), update_synced_slots_inactive_since(), WaitForWalSummarization(), WaitForWALToBecomeAvailable(), WalRcvComputeNextWakeup(), WalRcvRunning(), WalRcvStreaming(), WalReceiverMain(), WalSndComputeSleeptime(), WalSndUpdateProgress(), WalSndWriteData(), xid_age(), XLogBackgroundFlush(), XLogWalRcvSendHSFeedback(), and XLogWalRcvSendReply().

◆ overlaps_timestamp()

Datum overlaps_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2631 of file timestamp.c.

2632 {
2633  /*
2634  * The arguments are Timestamps, but we leave them as generic Datums to
2635  * avoid unnecessary conversions between value and reference forms --- not
2636  * to mention possible dereferences of null pointers.
2637  */
2638  Datum ts1 = PG_GETARG_DATUM(0);
2639  Datum te1 = PG_GETARG_DATUM(1);
2640  Datum ts2 = PG_GETARG_DATUM(2);
2641  Datum te2 = PG_GETARG_DATUM(3);
2642  bool ts1IsNull = PG_ARGISNULL(0);
2643  bool te1IsNull = PG_ARGISNULL(1);
2644  bool ts2IsNull = PG_ARGISNULL(2);
2645  bool te2IsNull = PG_ARGISNULL(3);
2646 
2647 #define TIMESTAMP_GT(t1,t2) \
2648  DatumGetBool(DirectFunctionCall2(timestamp_gt,t1,t2))
2649 #define TIMESTAMP_LT(t1,t2) \
2650  DatumGetBool(DirectFunctionCall2(timestamp_lt,t1,t2))
2651 
2652  /*
2653  * If both endpoints of interval 1 are null, the result is null (unknown).
2654  * If just one endpoint is null, take ts1 as the non-null one. Otherwise,
2655  * take ts1 as the lesser endpoint.
2656  */
2657  if (ts1IsNull)
2658  {
2659  if (te1IsNull)
2660  PG_RETURN_NULL();
2661  /* swap null for non-null */
2662  ts1 = te1;
2663  te1IsNull = true;
2664  }
2665  else if (!te1IsNull)
2666  {
2667  if (TIMESTAMP_GT(ts1, te1))
2668  {
2669  Datum tt = ts1;
2670 
2671  ts1 = te1;
2672  te1 = tt;
2673  }
2674  }
2675 
2676  /* Likewise for interval 2. */
2677  if (ts2IsNull)
2678  {
2679  if (te2IsNull)
2680  PG_RETURN_NULL();
2681  /* swap null for non-null */
2682  ts2 = te2;
2683  te2IsNull = true;
2684  }
2685  else if (!te2IsNull)
2686  {
2687  if (TIMESTAMP_GT(ts2, te2))
2688  {
2689  Datum tt = ts2;
2690 
2691  ts2 = te2;
2692  te2 = tt;
2693  }
2694  }
2695 
2696  /*
2697  * At this point neither ts1 nor ts2 is null, so we can consider three
2698  * cases: ts1 > ts2, ts1 < ts2, ts1 = ts2
2699  */
2700  if (TIMESTAMP_GT(ts1, ts2))
2701  {
2702  /*
2703  * This case is ts1 < te2 OR te1 < te2, which may look redundant but
2704  * in the presence of nulls it's not quite completely so.
2705  */
2706  if (te2IsNull)
2707  PG_RETURN_NULL();
2708  if (TIMESTAMP_LT(ts1, te2))
2709  PG_RETURN_BOOL(true);
2710  if (te1IsNull)
2711  PG_RETURN_NULL();
2712 
2713  /*
2714  * If te1 is not null then we had ts1 <= te1 above, and we just found
2715  * ts1 >= te2, hence te1 >= te2.
2716  */
2717  PG_RETURN_BOOL(false);
2718  }
2719  else if (TIMESTAMP_LT(ts1, ts2))
2720  {
2721  /* This case is ts2 < te1 OR te2 < te1 */
2722  if (te1IsNull)
2723  PG_RETURN_NULL();
2724  if (TIMESTAMP_LT(ts2, te1))
2725  PG_RETURN_BOOL(true);
2726  if (te2IsNull)
2727  PG_RETURN_NULL();
2728 
2729  /*
2730  * If te2 is not null then we had ts2 <= te2 above, and we just found
2731  * ts2 >= te1, hence te2 >= te1.
2732  */
2733  PG_RETURN_BOOL(false);
2734  }
2735  else
2736  {
2737  /*
2738  * For ts1 = ts2 the spec says te1 <> te2 OR te1 = te2, which is a
2739  * rather silly way of saying "true if both are non-null, else null".
2740  */
2741  if (te1IsNull || te2IsNull)
2742  PG_RETURN_NULL();
2743  PG_RETURN_BOOL(true);
2744  }
2745 
2746 #undef TIMESTAMP_GT
2747 #undef TIMESTAMP_LT
2748 }
#define TIMESTAMP_GT(t1, t2)
#define TIMESTAMP_LT(t1, t2)

References PG_ARGISNULL, PG_GETARG_DATUM, PG_RETURN_BOOL, PG_RETURN_NULL, TIMESTAMP_GT, and TIMESTAMP_LT.

◆ parse_sane_timezone()

static int parse_sane_timezone ( struct pg_tm tm,
text zone 
)
static

Definition at line 489 of file timestamp.c.

490 {
491  char tzname[TZ_STRLEN_MAX + 1];
492  int dterr;
493  int tz;
494 
495  text_to_cstring_buffer(zone, tzname, sizeof(tzname));
496 
497  /*
498  * Look up the requested timezone. First we try to interpret it as a
499  * numeric timezone specification; if DecodeTimezone decides it doesn't
500  * like the format, we try timezone abbreviations and names.
501  *
502  * Note pg_tzset happily parses numeric input that DecodeTimezone would
503  * reject. To avoid having it accept input that would otherwise be seen
504  * as invalid, it's enough to disallow having a digit in the first
505  * position of our input string.
506  */
507  if (isdigit((unsigned char) *tzname))
508  ereport(ERROR,
509  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
510  errmsg("invalid input syntax for type %s: \"%s\"",
511  "numeric time zone", tzname),
512  errhint("Numeric time zones must have \"-\" or \"+\" as first character.")));
513 
514  dterr = DecodeTimezone(tzname, &tz);
515  if (dterr != 0)
516  {
517  int type,
518  val;
519  pg_tz *tzp;
520 
521  if (dterr == DTERR_TZDISP_OVERFLOW)
522  ereport(ERROR,
523  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
524  errmsg("numeric time zone \"%s\" out of range", tzname)));
525  else if (dterr != DTERR_BAD_FORMAT)
526  ereport(ERROR,
527  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
528  errmsg("time zone \"%s\" not recognized", tzname)));
529 
530  type = DecodeTimezoneName(tzname, &val, &tzp);
531 
532  if (type == TZNAME_FIXED_OFFSET)
533  {
534  /* fixed-offset abbreviation */
535  tz = -val;
536  }
537  else if (type == TZNAME_DYNTZ)
538  {
539  /* dynamic-offset abbreviation, resolve using specified time */
540  tz = DetermineTimeZoneAbbrevOffset(tm, tzname, tzp);
541  }
542  else
543  {
544  /* full zone name */
545  tz = DetermineTimeZoneOffset(tm, tzp);
546  }
547  }
548 
549  return tz;
550 }
int DetermineTimeZoneOffset(struct pg_tm *tm, pg_tz *tzp)
Definition: datetime.c:1585
int DecodeTimezone(const char *str, int *tzp)
Definition: datetime.c:2996
int DecodeTimezoneName(const char *tzname, int *offset, pg_tz **tz)
Definition: datetime.c:3179
int DetermineTimeZoneAbbrevOffset(struct pg_tm *tm, const char *abbr, pg_tz *tzp)
Definition: datetime.c:1746
int errhint(const char *fmt,...)
Definition: elog.c:1319
#define TZNAME_FIXED_OFFSET
Definition: datetime.h:299
#define TZNAME_DYNTZ
Definition: datetime.h:300
#define DTERR_TZDISP_OVERFLOW
Definition: datetime.h:286
Definition: pgtz.h:66

References DecodeTimezone(), DecodeTimezoneName(), DetermineTimeZoneAbbrevOffset(), DetermineTimeZoneOffset(), DTERR_BAD_FORMAT, DTERR_TZDISP_OVERFLOW, ereport, errcode(), errhint(), errmsg(), ERROR, text_to_cstring_buffer(), tm, type, TZ_STRLEN_MAX, TZNAME_DYNTZ, TZNAME_FIXED_OFFSET, and val.

Referenced by make_timestamptz_at_timezone().

◆ pg_conf_load_time()

Datum pg_conf_load_time ( PG_FUNCTION_ARGS  )

Definition at line 1642 of file timestamp.c.

1643 {
1645 }
TimestampTz PgReloadTime
Definition: timestamp.c:55

References PG_RETURN_TIMESTAMPTZ, and PgReloadTime.

◆ pg_postmaster_start_time()

Datum pg_postmaster_start_time ( PG_FUNCTION_ARGS  )

Definition at line 1636 of file timestamp.c.

1637 {
1639 }
TimestampTz PgStartTime
Definition: timestamp.c:52

References PG_RETURN_TIMESTAMPTZ, and PgStartTime.

◆ SetEpochTimestamp()

Timestamp SetEpochTimestamp ( void  )

Definition at line 2190 of file timestamp.c.

2191 {
2192  Timestamp dt;
2193  struct pg_tm tt,
2194  *tm = &tt;
2195 
2196  GetEpochTime(tm);
2197  /* we don't bother to test for failure ... */
2198  tm2timestamp(tm, 0, NULL, &dt);
2199 
2200  return dt;
2201 } /* SetEpochTimestamp() */
void GetEpochTime(struct pg_tm *tm)
Definition: timestamp.c:2168
int tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result)
Definition: timestamp.c:1997

References GetEpochTime(), tm, and tm2timestamp().

Referenced by dttofmtasc_replace(), PGTYPEStimestamp_from_asc(), timestamp_in(), timestamp_part_common(), timestamptz_in(), and timestamptz_part_common().

◆ statement_timestamp()

Datum statement_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 1624 of file timestamp.c.

1625 {
1627 }
TimestampTz GetCurrentStatementStartTimestamp(void)
Definition: xact.c:876

References GetCurrentStatementStartTimestamp(), and PG_RETURN_TIMESTAMPTZ.

◆ time2t()

static TimeOffset time2t ( const int  hour,
const int  min,
const int  sec,
const fsec_t  fsec 
)
static

Definition at line 2128 of file timestamp.c.

2129 {
2130  return (((((hour * MINS_PER_HOUR) + min) * SECS_PER_MINUTE) + sec) * USECS_PER_SEC) + fsec;
2131 }

References MINS_PER_HOUR, SECS_PER_MINUTE, and USECS_PER_SEC.

Referenced by tm2timestamp().

◆ time_t_to_timestamptz()

TimestampTz time_t_to_timestamptz ( pg_time_t  tm)

Definition at line 1811 of file timestamp.c.

1812 {
1813  TimestampTz result;
1814 
1815  result = (TimestampTz) tm -
1817  result *= USECS_PER_SEC;
1818 
1819  return result;
1820 }

References POSTGRES_EPOCH_JDATE, SECS_PER_DAY, tm, UNIX_EPOCH_JDATE, and USECS_PER_SEC.

Referenced by pg_control_checkpoint(), pg_control_system(), pg_ls_dir_files(), and pg_stat_file().

◆ timeofday()

Datum timeofday ( PG_FUNCTION_ARGS  )

Definition at line 1700 of file timestamp.c.

1701 {
1702  struct timeval tp;
1703  char templ[128];
1704  char buf[128];
1705  pg_time_t tt;
1706 
1707  gettimeofday(&tp, NULL);
1708  tt = (pg_time_t) tp.tv_sec;
1709  pg_strftime(templ, sizeof(templ), "%a %b %d %H:%M:%S.%%06d %Y %Z",
1711  snprintf(buf, sizeof(buf), templ, tp.tv_usec);
1712 
1714 }
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition: localtime.c:1344
size_t pg_strftime(char *s, size_t maxsize, const char *format, const struct pg_tm *t)
Definition: strftime.c:128
Definition: lexi.c:60
text * cstring_to_text(const char *s)
Definition: varlena.c:184

References buf, cstring_to_text(), gettimeofday(), pg_localtime(), PG_RETURN_TEXT_P, pg_strftime(), session_timezone, and snprintf.

◆ timestamp2timestamptz()

static TimestampTz timestamp2timestamptz ( Timestamp  timestamp)
static

Definition at line 6344 of file timestamp.c.

6345 {
6347 }
TimestampTz timestamp2timestamptz_opt_overflow(Timestamp timestamp, int *overflow)
Definition: timestamp.c:6292

References timestamp2timestamptz_opt_overflow().

Referenced by make_timestamptz(), and timestamp_timestamptz().

◆ timestamp2timestamptz_opt_overflow()

TimestampTz timestamp2timestamptz_opt_overflow ( Timestamp  timestamp,
int *  overflow 
)

Definition at line 6292 of file timestamp.c.

6293 {
6294  TimestampTz result;
6295  struct pg_tm tt,
6296  *tm = &tt;
6297  fsec_t fsec;
6298  int tz;
6299 
6300  if (overflow)
6301  *overflow = 0;
6302 
6304  return timestamp;
6305 
6306  /* We don't expect this to fail, but check it pro forma */
6307  if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0)
6308  {
6310 
6311  result = dt2local(timestamp, -tz);
6312 
6313  if (IS_VALID_TIMESTAMP(result))
6314  {
6315  return result;
6316  }
6317  else if (overflow)
6318  {
6319  if (result < MIN_TIMESTAMP)
6320  {
6321  *overflow = -1;
6322  TIMESTAMP_NOBEGIN(result);
6323  }
6324  else
6325  {
6326  *overflow = 1;
6327  TIMESTAMP_NOEND(result);
6328  }
6329  return result;
6330  }
6331  }
6332 
6333  ereport(ERROR,
6334  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6335  errmsg("timestamp out of range")));
6336 
6337  return 0;
6338 }
#define MIN_TIMESTAMP
Definition: timestamp.h:256

References DetermineTimeZoneOffset(), dt2local(), ereport, errcode(), errmsg(), ERROR, IS_VALID_TIMESTAMP, MIN_TIMESTAMP, session_timezone, timestamp2tm(), TIMESTAMP_NOBEGIN, TIMESTAMP_NOEND, TIMESTAMP_NOT_FINITE, and tm.

Referenced by timestamp2timestamptz(), and timestamp_cmp_timestamptz_internal().

◆ timestamp2tm()

int timestamp2tm ( Timestamp  dt,
int *  tzp,
struct pg_tm tm,
fsec_t fsec,
const char **  tzn,
pg_tz attimezone 
)

Definition at line 1901 of file timestamp.c.

1902 {
1903  Timestamp date;
1904  Timestamp time;
1905  pg_time_t utime;
1906 
1907  /* Use session timezone if caller asks for default */
1908  if (attimezone == NULL)
1909  attimezone = session_timezone;
1910 
1911  time = dt;
1912  TMODULO(time, date, USECS_PER_DAY);
1913 
1914  if (time < INT64CONST(0))
1915  {
1916  time += USECS_PER_DAY;
1917  date -= 1;
1918  }
1919 
1920  /* add offset to go from J2000 back to standard Julian date */
1922 
1923  /* Julian day routine does not work for negative Julian days */
1924  if (date < 0 || date > (Timestamp) INT_MAX)
1925  return -1;
1926 
1927  j2date((int) date, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
1928  dt2time(time, &tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
1929 
1930  /* Done if no TZ conversion wanted */
1931  if (tzp == NULL)
1932  {
1933  tm->tm_isdst = -1;
1934  tm->tm_gmtoff = 0;
1935  tm->tm_zone = NULL;
1936  if (tzn != NULL)
1937  *tzn = NULL;
1938  return 0;
1939  }
1940 
1941  /*
1942  * If the time falls within the range of pg_time_t, use pg_localtime() to
1943  * rotate to the local time zone.
1944  *
1945  * First, convert to an integral timestamp, avoiding possibly
1946  * platform-specific roundoff-in-wrong-direction errors, and adjust to
1947  * Unix epoch. Then see if we can convert to pg_time_t without loss. This
1948  * coding avoids hardwiring any assumptions about the width of pg_time_t,
1949  * so it should behave sanely on machines without int64.
1950  */
1951  dt = (dt - *fsec) / USECS_PER_SEC +
1953  utime = (pg_time_t) dt;
1954  if ((Timestamp) utime == dt)
1955  {
1956  struct pg_tm *tx = pg_localtime(&utime, attimezone);
1957 
1958  tm->tm_year = tx->tm_year + 1900;
1959  tm->tm_mon = tx->tm_mon + 1;
1960  tm->tm_mday = tx->tm_mday;
1961  tm->tm_hour = tx->tm_hour;
1962  tm->tm_min = tx->tm_min;
1963  tm->tm_sec = tx->tm_sec;
1964  tm->tm_isdst = tx->tm_isdst;
1965  tm->tm_gmtoff = tx->tm_gmtoff;
1966  tm->tm_zone = tx->tm_zone;
1967  *tzp = -tm->tm_gmtoff;
1968  if (tzn != NULL)
1969  *tzn = tm->tm_zone;
1970  }
1971  else
1972  {
1973  /*
1974  * When out of range of pg_time_t, treat as GMT
1975  */
1976  *tzp = 0;
1977  /* Mark this as *no* time zone available */
1978  tm->tm_isdst = -1;
1979  tm->tm_gmtoff = 0;
1980  tm->tm_zone = NULL;
1981  if (tzn != NULL)
1982  *tzn = NULL;
1983  }
1984 
1985  return 0;
1986 }
void dt2time(Timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec)
Definition: timestamp.c:1874
const char * tm_zone
Definition: pgtime.h:46
int tm_isdst
Definition: pgtime.h:44
long int tm_gmtoff
Definition: pgtime.h:45

References dt2time(), j2date(), pg_localtime(), POSTGRES_EPOCH_JDATE, SECS_PER_DAY, session_timezone, tm, pg_tm::tm_gmtoff, pg_tm::tm_hour, pg_tm::tm_isdst, pg_tm::tm_mday, pg_tm::tm_min, pg_tm::tm_mon, pg_tm::tm_sec, pg_tm::tm_year, pg_tm::tm_zone, TMODULO, UNIX_EPOCH_JDATE, USECS_PER_DAY, and USECS_PER_SEC.

Referenced by DetermineTimeZoneAbbrevOffsetTS(), GetCurrentTimeUsec(), JsonEncodeDateTime(), make_timestamptz_at_timezone(), map_sql_value_to_xml_value(), PGTYPEStimestamp_add_interval(), PGTYPEStimestamp_fmt_asc(), PGTYPEStimestamp_to_asc(), timestamp2timestamptz_opt_overflow(), timestamp_age(), timestamp_date(), timestamp_out(), timestamp_part_common(), timestamp_pl_interval(), timestamp_recv(), timestamp_time(), timestamp_to_char(), timestamp_trunc(), timestamp_zone(), timestamptz2timestamp(), timestamptz_age(), timestamptz_date(), timestamptz_out(), timestamptz_part_common(), timestamptz_pl_interval_internal(), timestamptz_recv(), timestamptz_time(), timestamptz_timetz(), timestamptz_to_char(), timestamptz_to_str(), timestamptz_trunc_internal(), timestamptz_zone(), and timetz_zone().

◆ timestamp_age()

Datum timestamp_age ( PG_FUNCTION_ARGS  )

Definition at line 4235 of file timestamp.c.

4236 {
4237  Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
4238  Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
4239  Interval *result;
4240  fsec_t fsec1,
4241  fsec2;
4242  struct pg_itm tt,
4243  *tm = &tt;
4244  struct pg_tm tt1,
4245  *tm1 = &tt1;
4246  struct pg_tm tt2,
4247  *tm2 = &tt2;
4248 
4249  result = (Interval *) palloc(sizeof(Interval));
4250 
4251  /*
4252  * Handle infinities.
4253  *
4254  * We treat anything that amounts to "infinity - infinity" as an error,
4255  * since the interval type has nothing equivalent to NaN.
4256  */
4257  if (TIMESTAMP_IS_NOBEGIN(dt1))
4258  {
4259  if (TIMESTAMP_IS_NOBEGIN(dt2))
4260  ereport(ERROR,
4261  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4262  errmsg("interval out of range")));
4263  else
4264  INTERVAL_NOBEGIN(result);
4265  }
4266  else if (TIMESTAMP_IS_NOEND(dt1))
4267  {
4268  if (TIMESTAMP_IS_NOEND(dt2))
4269  ereport(ERROR,
4270  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4271  errmsg("interval out of range")));
4272  else
4273  INTERVAL_NOEND(result);
4274  }
4275  else if (TIMESTAMP_IS_NOBEGIN(dt2))
4276  INTERVAL_NOEND(result);
4277  else if (TIMESTAMP_IS_NOEND(dt2))
4278  INTERVAL_NOBEGIN(result);
4279  else if (timestamp2tm(dt1, NULL, tm1, &fsec1, NULL, NULL) == 0 &&
4280  timestamp2tm(dt2, NULL, tm2, &fsec2, NULL, NULL) == 0)
4281  {
4282  /* form the symbolic difference */
4283  tm->tm_usec = fsec1 - fsec2;
4284  tm->tm_sec = tm1->tm_sec - tm2->tm_sec;
4285  tm->tm_min = tm1->tm_min - tm2->tm_min;
4286  tm->tm_hour = tm1->tm_hour - tm2->tm_hour;
4287  tm->tm_mday = tm1->tm_mday - tm2->tm_mday;
4288  tm->tm_mon = tm1->tm_mon - tm2->tm_mon;
4289  tm->tm_year = tm1->tm_year - tm2->tm_year;
4290 
4291  /* flip sign if necessary... */
4292  if (dt1 < dt2)
4293  {
4294  tm->tm_usec = -tm->tm_usec;
4295  tm->tm_sec = -tm->tm_sec;
4296  tm->tm_min = -tm->tm_min;
4297  tm->tm_hour = -tm->tm_hour;
4298  tm->tm_mday = -tm->tm_mday;
4299  tm->tm_mon = -tm->tm_mon;
4300  tm->tm_year = -tm->tm_year;
4301  }
4302 
4303  /* propagate any negative fields into the next higher field */
4304  while (tm->tm_usec < 0)
4305  {
4306  tm->tm_usec += USECS_PER_SEC;
4307  tm->tm_sec--;
4308  }
4309 
4310  while (tm->tm_sec < 0)
4311  {
4313  tm->tm_min--;
4314  }
4315 
4316  while (tm->tm_min < 0)
4317  {
4318  tm->tm_min += MINS_PER_HOUR;
4319  tm->tm_hour--;
4320  }
4321 
4322  while (tm->tm_hour < 0)
4323  {
4324  tm->tm_hour += HOURS_PER_DAY;
4325  tm->tm_mday--;
4326  }
4327 
4328  while (tm->tm_mday < 0)
4329  {
4330  if (dt1 < dt2)
4331  {
4332  tm->tm_mday += day_tab[isleap(tm1->tm_year)][tm1->tm_mon - 1];
4333  tm->tm_mon--;
4334  }
4335  else
4336  {
4337  tm->tm_mday += day_tab[isleap(tm2->tm_year)][tm2->tm_mon - 1];
4338  tm->tm_mon--;
4339  }
4340  }
4341 
4342  while (tm->tm_mon < 0)
4343  {
4345  tm->tm_year--;
4346  }
4347 
4348  /* recover sign if necessary... */
4349  if (dt1 < dt2)
4350  {
4351  tm->tm_usec = -tm->tm_usec;
4352  tm->tm_sec = -tm->tm_sec;
4353  tm->tm_min = -tm->tm_min;
4354  tm->tm_hour = -tm->tm_hour;
4355  tm->tm_mday = -tm->tm_mday;
4356  tm->tm_mon = -tm->tm_mon;
4357  tm->tm_year = -tm->tm_year;
4358  }
4359 
4360  if (itm2interval(tm, result) != 0)
4361  ereport(ERROR,
4362  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4363  errmsg("interval out of range")));
4364  }
4365  else
4366  ereport(ERROR,
4367  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4368  errmsg("timestamp out of range")));
4369 
4370  PG_RETURN_INTERVAL_P(result);
4371 }
const int day_tab[2][13]
Definition: datetime.c:75
#define HOURS_PER_DAY
Definition: timestamp.h:118
#define isleap(y)
Definition: datetime.h:271

References day_tab, ereport, errcode(), errmsg(), ERROR, HOURS_PER_DAY, INTERVAL_NOBEGIN, INTERVAL_NOEND, isleap, itm2interval(), MINS_PER_HOUR, MONTHS_PER_YEAR, palloc(), PG_GETARG_TIMESTAMP, PG_RETURN_INTERVAL_P, SECS_PER_MINUTE, timestamp2tm(), TIMESTAMP_IS_NOBEGIN, TIMESTAMP_IS_NOEND, tm, pg_tm::tm_hour, pg_tm::tm_mday, pg_tm::tm_min, pg_tm::tm_mon, pg_tm::tm_sec, pg_tm::tm_year, and USECS_PER_SEC.

◆ timestamp_at_local()

Datum timestamp_at_local ( PG_FUNCTION_ARGS  )

Definition at line 6680 of file timestamp.c.

6681 {
6682  return timestamp_timestamptz(fcinfo);
6683 }
Datum timestamp_timestamptz(PG_FUNCTION_ARGS)
Definition: timestamp.c:6274

References timestamp_timestamptz().

◆ timestamp_bin()

Datum timestamp_bin ( PG_FUNCTION_ARGS  )

Definition at line 4535 of file timestamp.c.

4536 {
4537  Interval *stride = PG_GETARG_INTERVAL_P(0);
4539  Timestamp origin = PG_GETARG_TIMESTAMP(2);
4540  Timestamp result,
4541  stride_usecs,
4542  tm_diff,
4543  tm_modulo,
4544  tm_delta;
4545 
4548 
4549  if (TIMESTAMP_NOT_FINITE(origin))
4550  ereport(ERROR,
4551  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4552  errmsg("origin out of range")));
4553 
4554  if (INTERVAL_NOT_FINITE(stride))
4555  ereport(ERROR,
4556  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4557  errmsg("timestamps cannot be binned into infinite intervals")));
4558 
4559  if (stride->month != 0)
4560  ereport(ERROR,
4561  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4562  errmsg("timestamps cannot be binned into intervals containing months or years")));
4563 
4564  if (unlikely(pg_mul_s64_overflow(stride->day, USECS_PER_DAY, &stride_usecs)) ||
4565  unlikely(pg_add_s64_overflow(stride_usecs, stride->time, &stride_usecs)))
4566  ereport(ERROR,
4567  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4568  errmsg("interval out of range")));
4569 
4570  if (stride_usecs <= 0)
4571  ereport(ERROR,
4572  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4573  errmsg("stride must be greater than zero")));
4574 
4575  if (unlikely(pg_sub_s64_overflow(timestamp, origin, &tm_diff)))
4576  ereport(ERROR,
4577  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4578  errmsg("interval out of range")));
4579 
4580  /* These calculations cannot overflow */
4581  tm_modulo = tm_diff % stride_usecs;
4582  tm_delta = tm_diff - tm_modulo;
4583  result = origin + tm_delta;
4584 
4585  /*
4586  * We want to round towards -infinity, not 0, when tm_diff is negative and
4587  * not a multiple of stride_usecs. This adjustment *can* cause overflow,
4588  * since the result might now be out of the range origin .. timestamp.
4589  */
4590  if (tm_modulo < 0)
4591  {
4592  if (unlikely(pg_sub_s64_overflow(result, stride_usecs, &result)) ||
4593  !IS_VALID_TIMESTAMP(result))
4594  ereport(ERROR,
4595  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4596  errmsg("timestamp out of range")));
4597  }
4598 
4599  PG_RETURN_TIMESTAMP(result);
4600 }
#define unlikely(x)
Definition: c.h:311

References Interval::day, ereport, errcode(), errmsg(), ERROR, INTERVAL_NOT_FINITE, IS_VALID_TIMESTAMP, Interval::month, pg_add_s64_overflow(), PG_GETARG_INTERVAL_P, PG_GETARG_TIMESTAMP, pg_mul_s64_overflow(), PG_RETURN_TIMESTAMP, pg_sub_s64_overflow(), Interval::time, TIMESTAMP_NOT_FINITE, unlikely, and USECS_PER_DAY.

◆ timestamp_cmp()

Datum timestamp_cmp ( PG_FUNCTION_ARGS  )

Definition at line 2270 of file timestamp.c.

2271 {
2272  Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
2273  Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
2274 
2276 }

References PG_GETARG_TIMESTAMP, PG_RETURN_INT32, and timestamp_cmp_internal().

Referenced by compareDatetime(), and gbt_tskey_cmp().

◆ timestamp_cmp_internal()

int timestamp_cmp_internal ( Timestamp  dt1,
Timestamp  dt2 
)

◆ timestamp_cmp_timestamptz()

Datum timestamp_cmp_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 2400 of file timestamp.c.

2401 {
2402  Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2404 
2406 }
int32 timestamp_cmp_timestamptz_internal(Timestamp timestampVal, TimestampTz dt2)
Definition: timestamp.c:2325

References PG_GETARG_TIMESTAMP, PG_GETARG_TIMESTAMPTZ, PG_RETURN_INT32, and timestamp_cmp_timestamptz_internal().

◆ timestamp_cmp_timestamptz_internal()

int32 timestamp_cmp_timestamptz_internal ( Timestamp  timestampVal,
TimestampTz  dt2 
)

Definition at line 2325 of file timestamp.c.

2326 {
2327  TimestampTz dt1;
2328  int overflow;
2329 
2330  dt1 = timestamp2timestamptz_opt_overflow(timestampVal, &overflow);
2331  if (overflow > 0)
2332  {
2333  /* dt1 is larger than any finite timestamp, but less than infinity */
2334  return TIMESTAMP_IS_NOEND(dt2) ? -1 : +1;
2335  }
2336  if (overflow < 0)
2337  {
2338  /* dt1 is less than any finite timestamp, but more than -infinity */
2339  return TIMESTAMP_IS_NOBEGIN(dt2) ? +1 : -1;
2340  }
2341 
2342  return timestamptz_cmp_internal(dt1, dt2);
2343 }
#define timestamptz_cmp_internal(dt1, dt2)
Definition: timestamp.h:131

References timestamp2timestamptz_opt_overflow(), TIMESTAMP_IS_NOBEGIN, TIMESTAMP_IS_NOEND, and timestamptz_cmp_internal.

Referenced by cmpTimestampToTimestampTz(), timestamp_cmp_timestamptz(), timestamp_eq_timestamptz(), timestamp_ge_timestamptz(), timestamp_gt_timestamptz(), timestamp_le_timestamptz(), timestamp_lt_timestamptz(), timestamp_ne_timestamptz(), timestamptz_cmp_timestamp(), timestamptz_eq_timestamp(), timestamptz_ge_timestamp(), timestamptz_gt_timestamp(), timestamptz_le_timestamp(), timestamptz_lt_timestamp(), and timestamptz_ne_timestamp().

◆ timestamp_eq()

Datum timestamp_eq ( PG_FUNCTION_ARGS  )

Definition at line 2216 of file timestamp.c.

2217 {
2218  Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
2219  Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
2220 
2221  PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) == 0);
2222 }

References PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, and timestamp_cmp_internal().

Referenced by gbt_tseq().

◆ timestamp_eq_timestamptz()

Datum timestamp_eq_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 2346 of file timestamp.c.

2347 {
2348  Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2350 
2351  PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) == 0);
2352 }

References PG_GETARG_TIMESTAMP, PG_GETARG_TIMESTAMPTZ, PG_RETURN_BOOL, and timestamp_cmp_timestamptz_internal().

◆ timestamp_fastcmp()

static int timestamp_fastcmp ( Datum  x,
Datum  y,
SortSupport  ssup 
)
static

Definition at line 2281 of file timestamp.c.

2282 {
2285 
2286  return timestamp_cmp_internal(a, b);
2287 }
int y
Definition: isn.c:72
int b
Definition: isn.c:70
int x
Definition: isn.c:71
int a
Definition: isn.c:69

References a, b, DatumGetTimestamp(), timestamp_cmp_internal(), x, and y.

Referenced by timestamp_sortsupport().

◆ timestamp_finite()

Datum timestamp_finite ( PG_FUNCTION_ARGS  )

Definition at line 2147 of file timestamp.c.

2148 {
2150 
2152 }

References PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, and TIMESTAMP_NOT_FINITE.

◆ timestamp_ge()

Datum timestamp_ge ( PG_FUNCTION_ARGS  )

Definition at line 2261 of file timestamp.c.

2262 {
2263  Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
2264  Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
2265 
2266  PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) >= 0);
2267 }

References PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, and timestamp_cmp_internal().

Referenced by gbt_tsge().

◆ timestamp_ge_timestamptz()

Datum timestamp_ge_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 2391 of file timestamp.c.

2392 {
2393  Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2395 
2396  PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) >= 0);
2397 }

References PG_GETARG_TIMESTAMP, PG_GETARG_TIMESTAMPTZ, PG_RETURN_BOOL, and timestamp_cmp_timestamptz_internal().

◆ timestamp_gt()

Datum timestamp_gt ( PG_FUNCTION_ARGS  )

Definition at line 2243 of file timestamp.c.

2244 {
2245  Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
2246  Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
2247 
2248  PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) > 0);
2249 }

References PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, and timestamp_cmp_internal().

Referenced by gbt_tsgt().

◆ timestamp_gt_timestamptz()

Datum timestamp_gt_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 2373 of file timestamp.c.

2374 {
2375  Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2377 
2378  PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) > 0);
2379 }

References PG_GETARG_TIMESTAMP, PG_GETARG_TIMESTAMPTZ, PG_RETURN_BOOL, and timestamp_cmp_timestamptz_internal().

◆ timestamp_hash()

Datum timestamp_hash ( PG_FUNCTION_ARGS  )

Definition at line 2309 of file timestamp.c.

2310 {
2311  return hashint8(fcinfo);
2312 }

References hashint8().

◆ timestamp_hash_extended()

Datum timestamp_hash_extended ( PG_FUNCTION_ARGS  )

Definition at line 2315 of file timestamp.c.

2316 {
2317  return hashint8extended(fcinfo);
2318 }

References hashint8extended().

◆ timestamp_in()

Datum timestamp_in ( PG_FUNCTION_ARGS  )

Definition at line 164 of file timestamp.c.

165 {
166  char *str = PG_GETARG_CSTRING(0);
167 #ifdef NOT_USED
168  Oid typelem = PG_GETARG_OID(1);
169 #endif
170  int32 typmod = PG_GETARG_INT32(2);
171  Node *escontext = fcinfo->context;
172  Timestamp result;
173  fsec_t fsec;
174  struct pg_tm tt,
175  *tm = &tt;
176  int tz;
177  int dtype;
178  int nf;
179  int dterr;
180  char *field[MAXDATEFIELDS];
181  int ftype[MAXDATEFIELDS];
182  char workbuf[MAXDATELEN + MAXDATEFIELDS];
183  DateTimeErrorExtra extra;
184 
185  dterr = ParseDateTime(str, workbuf, sizeof(workbuf),
186  field, ftype, MAXDATEFIELDS, &nf);
187  if (dterr == 0)
188  dterr = DecodeDateTime(field, ftype, nf,
189  &dtype, tm, &fsec, &tz, &extra);
190  if (dterr != 0)
191  {
192  DateTimeParseError(dterr, &extra, str, "timestamp", escontext);
193  PG_RETURN_NULL();
194  }
195 
196  switch (dtype)
197  {
198  case DTK_DATE:
199  if (tm2timestamp(tm, fsec, NULL, &result) != 0)
200  ereturn(escontext, (Datum) 0,
201  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
202  errmsg("timestamp out of range: \"%s\"", str)));
203  break;
204 
205  case DTK_EPOCH:
206  result = SetEpochTimestamp();
207  break;
208 
209  case DTK_LATE:
210  TIMESTAMP_NOEND(result);
211  break;
212 
213  case DTK_EARLY:
214  TIMESTAMP_NOBEGIN(result);
215  break;
216 
217  default:
218  elog(ERROR, "unexpected dtype %d while parsing timestamp \"%s\"",
219  dtype, str);
220  TIMESTAMP_NOEND(result);
221  }
222 
223  AdjustTimestampForTypmod(&result, typmod, escontext);
224 
225  PG_RETURN_TIMESTAMP(result);
226 }
int DecodeDateTime(char **field, int *ftype, int nf, int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp, DateTimeErrorExtra *extra)
Definition: datetime.c:978
Timestamp SetEpochTimestamp(void)
Definition: timestamp.c:2190
#define DTK_DATE
Definition: datetime.h:144

References AdjustTimestampForTypmod(), DateTimeParseError(), DecodeDateTime(), DTK_DATE, DTK_EARLY, DTK_EPOCH, DTK_LATE, elog, ereturn, errcode(), errmsg(), ERROR, MAXDATEFIELDS, MAXDATELEN, ParseDateTime(), PG_GETARG_CSTRING, PG_GETARG_INT32, PG_GETARG_OID, PG_RETURN_NULL, PG_RETURN_TIMESTAMP, SetEpochTimestamp(), str, TIMESTAMP_NOBEGIN, TIMESTAMP_NOEND, tm, and tm2timestamp().

Referenced by moddatetime().

◆ timestamp_izone()

Datum timestamp_izone ( PG_FUNCTION_ARGS  )

Definition at line 6217 of file timestamp.c.

6218 {
6221  TimestampTz result;
6222  int tz;
6223 
6226 
6228  ereport(ERROR,
6229  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6230  errmsg("interval time zone \"%s\" must be finite",
6232  PointerGetDatum(zone))))));
6233 
6234  if (zone->month != 0 || zone->day != 0)
6235  ereport(ERROR,
6236  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6237  errmsg("interval time zone \"%s\" must not include months or days",
6239  PointerGetDatum(zone))))));
6240 
6241  tz = zone->time / USECS_PER_SEC;
6242 
6243  result = dt2local(timestamp, tz);
6244 
6245  if (!IS_VALID_TIMESTAMP(result))
6246  ereport(ERROR,
6247  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6248  errmsg("timestamp out of range")));
6249 
6250  PG_RETURN_TIMESTAMPTZ(result);
6251 } /* timestamp_izone() */
Datum interval_out(PG_FUNCTION_ARGS)
Definition: timestamp.c:982
static char * DatumGetCString(Datum X)
Definition: postgres.h:335

References DatumGetCString(), DirectFunctionCall1, dt2local(), ereport, errcode(), errmsg(), ERROR, INTERVAL_NOT_FINITE, interval_out(), IS_VALID_TIMESTAMP, PG_GETARG_INTERVAL_P, PG_GETARG_TIMESTAMP, PG_RETURN_TIMESTAMPTZ, PointerGetDatum(), TIMESTAMP_NOT_FINITE, and USECS_PER_SEC.

◆ timestamp_larger()

Datum timestamp_larger ( PG_FUNCTION_ARGS  )

Definition at line 2771 of file timestamp.c.

2772 {
2773  Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
2774  Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
2775  Timestamp result;
2776 
2777  if (timestamp_cmp_internal(dt1, dt2) > 0)
2778  result = dt1;
2779  else
2780  result = dt2;
2781  PG_RETURN_TIMESTAMP(result);
2782 }

References PG_GETARG_TIMESTAMP, PG_RETURN_TIMESTAMP, and timestamp_cmp_internal().

◆ timestamp_le()

Datum timestamp_le ( PG_FUNCTION_ARGS  )

Definition at line 2252 of file timestamp.c.

2253 {
2254  Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
2255  Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
2256 
2257  PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) <= 0);
2258 }

References PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, and timestamp_cmp_internal().

Referenced by gbt_tsle().

◆ timestamp_le_timestamptz()

Datum timestamp_le_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 2382 of file timestamp.c.

2383 {
2384  Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2386 
2387  PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) <= 0);
2388 }

References PG_GETARG_TIMESTAMP, PG_GETARG_TIMESTAMPTZ, PG_RETURN_BOOL, and timestamp_cmp_timestamptz_internal().

◆ timestamp_lt()

Datum timestamp_lt ( PG_FUNCTION_ARGS  )

Definition at line 2234 of file timestamp.c.

2235 {
2236  Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
2237  Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
2238 
2239  PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) < 0);
2240 }

References PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, and timestamp_cmp_internal().

Referenced by gbt_tslt().

◆ timestamp_lt_timestamptz()

Datum timestamp_lt_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 2364 of file timestamp.c.

2365 {
2366  Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2368 
2369  PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) < 0);
2370 }

References PG_GETARG_TIMESTAMP, PG_GETARG_TIMESTAMPTZ, PG_RETURN_BOOL, and timestamp_cmp_timestamptz_internal().

◆ timestamp_mi()

Datum timestamp_mi ( PG_FUNCTION_ARGS  )

Definition at line 2786 of file timestamp.c.

2787 {
2788  Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
2789  Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
2790  Interval *result;
2791 
2792  result = (Interval *) palloc(sizeof(Interval));
2793 
2794  /*
2795  * Handle infinities.
2796  *
2797  * We treat anything that amounts to "infinity - infinity" as an error,
2798  * since the interval type has nothing equivalent to NaN.
2799  */
2800  if (TIMESTAMP_NOT_FINITE(dt1) || TIMESTAMP_NOT_FINITE(dt2))
2801  {
2802  if (TIMESTAMP_IS_NOBEGIN(dt1))
2803  {
2804  if (TIMESTAMP_IS_NOBEGIN(dt2))
2805  ereport(ERROR,
2806  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2807  errmsg("interval out of range")));
2808  else
2809  INTERVAL_NOBEGIN(result);
2810  }
2811  else if (TIMESTAMP_IS_NOEND(dt1))
2812  {
2813  if (TIMESTAMP_IS_NOEND(dt2))
2814  ereport(ERROR,
2815  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2816  errmsg("interval out of range")));
2817  else
2818  INTERVAL_NOEND(result);
2819  }
2820  else if (TIMESTAMP_IS_NOBEGIN(dt2))
2821  INTERVAL_NOEND(result);
2822  else /* TIMESTAMP_IS_NOEND(dt2) */
2823  INTERVAL_NOBEGIN(result);
2824 
2825  PG_RETURN_INTERVAL_P(result);
2826  }
2827 
2828  if (unlikely(pg_sub_s64_overflow(dt1, dt2, &result->time)))
2829  ereport(ERROR,
2830  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2831  errmsg("interval out of range")));
2832 
2833  result->month = 0;
2834  result->day = 0;
2835 
2836  /*----------
2837  * This is wrong, but removing it breaks a lot of regression tests.
2838  * For example:
2839  *
2840  * test=> SET timezone = 'EST5EDT';
2841  * test=> SELECT
2842  * test-> ('2005-10-30 13:22:00-05'::timestamptz -
2843  * test(> '2005-10-29 13:22:00-04'::timestamptz);
2844  * ?column?
2845  * ----------------
2846  * 1 day 01:00:00
2847  * (1 row)
2848  *
2849  * so adding that to the first timestamp gets:
2850  *
2851  * test=> SELECT
2852  * test-> ('2005-10-29 13:22:00-04'::timestamptz +
2853  * test(> ('2005-10-30 13:22:00-05'::timestamptz -
2854  * test(> '2005-10-29 13:22:00-04'::timestamptz)) at time zone 'EST';
2855  * timezone
2856  * --------------------
2857  * 2005-10-30 14:22:00
2858  * (1 row)
2859  *----------
2860  */
2862  IntervalPGetDatum(result)));
2863 
2864  PG_RETURN_INTERVAL_P(result);
2865 }
Datum interval_justify_hours(PG_FUNCTION_ARGS)
Definition: timestamp.c:2960

References DatumGetIntervalP(), Interval::day, DirectFunctionCall1, ereport, errcode(), errmsg(), ERROR, interval_justify_hours(), INTERVAL_NOBEGIN, INTERVAL_NOEND, IntervalPGetDatum(), Interval::month, palloc(), PG_GETARG_TIMESTAMP, PG_RETURN_INTERVAL_P, pg_sub_s64_overflow(), Interval::time, TIMESTAMP_IS_NOBEGIN, TIMESTAMP_IS_NOEND, TIMESTAMP_NOT_FINITE, and unlikely.

Referenced by gbt_ts_dist(), ts_dist(), and tstz_dist().

◆ timestamp_mi_interval()

◆ timestamp_ne()

Datum timestamp_ne ( PG_FUNCTION_ARGS  )

Definition at line 2225 of file timestamp.c.

2226 {
2227  Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
2228  Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
2229 
2230  PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) != 0);
2231 }

References PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, and timestamp_cmp_internal().

◆ timestamp_ne_timestamptz()

Datum timestamp_ne_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 2355 of file timestamp.c.

2356 {
2357  Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2359 
2360  PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) != 0);
2361 }

References PG_GETARG_TIMESTAMP, PG_GETARG_TIMESTAMPTZ, PG_RETURN_BOOL, and timestamp_cmp_timestamptz_internal().

◆ timestamp_out()

Datum timestamp_out ( PG_FUNCTION_ARGS  )

Definition at line 232 of file timestamp.c.

233 {
235  char *result;
236  struct pg_tm tt,
237  *tm = &tt;
238  fsec_t fsec;
239  char buf[MAXDATELEN + 1];
240 
243  else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0)
244  EncodeDateTime(tm, fsec, false, 0, NULL, DateStyle, buf);
245  else
246  ereport(ERROR,
247  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
248  errmsg("timestamp out of range")));
249 
250  result = pstrdup(buf);
251  PG_RETURN_CSTRING(result);
252 }
void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str)
Definition: datetime.c:4331
void EncodeSpecialTimestamp(Timestamp dt, char *str)
Definition: timestamp.c:1596
int DateStyle
Definition: globals.c:122

References buf, DateStyle, EncodeDateTime(), EncodeSpecialTimestamp(), ereport, errcode(), errmsg(), ERROR, MAXDATELEN, PG_GETARG_TIMESTAMP, PG_RETURN_CSTRING, pstrdup(), timestamp2tm(), TIMESTAMP_NOT_FINITE, and tm.

Referenced by ExecGetJsonValueItemString(), and executeItemOptUnwrapTarget().

◆ timestamp_part()

Datum timestamp_part ( PG_FUNCTION_ARGS  )

Definition at line 5599 of file timestamp.c.

5600 {
5601  return timestamp_part_common(fcinfo, false);
5602 }

References timestamp_part_common().

◆ timestamp_part_common()

static Datum timestamp_part_common ( PG_FUNCTION_ARGS  ,
bool  retnumeric 
)
static

Definition at line 5341 of file timestamp.c.

5342 {
5343  text *units = PG_GETARG_TEXT_PP(0);
5345  int64 intresult;
5346  Timestamp epoch;
5347  int type,
5348  val;
5349  char *lowunits;
5350  fsec_t fsec;
5351  struct pg_tm tt,
5352  *tm = &tt;
5353 
5354  lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
5355  VARSIZE_ANY_EXHDR(units),
5356  false);
5357 
5358  type = DecodeUnits(0, lowunits, &val);
5359  if (type == UNKNOWN_FIELD)
5360  type = DecodeSpecial(0, lowunits, &val);
5361 
5363  {
5364  double r = NonFiniteTimestampTzPart(type, val, lowunits,
5366  false);
5367 
5368  if (r != 0.0)
5369  {
5370  if (retnumeric)
5371  {
5372  if (r < 0)
5374  CStringGetDatum("-Infinity"),
5376  Int32GetDatum(-1));
5377  else if (r > 0)
5379  CStringGetDatum("Infinity"),
5381  Int32GetDatum(-1));
5382  }
5383  else
5384  PG_RETURN_FLOAT8(r);
5385  }
5386  else
5387  PG_RETURN_NULL();
5388  }
5389 
5390  if (type == UNITS)
5391  {
5392  if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
5393  ereport(ERROR,
5394  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
5395  errmsg("timestamp out of range")));
5396 
5397  switch (val)
5398  {
5399  case DTK_MICROSEC:
5400  intresult = tm->tm_sec * INT64CONST(1000000) + fsec;
5401  break;
5402 
5403  case DTK_MILLISEC:
5404  if (retnumeric)
5405  /*---
5406  * tm->tm_sec * 1000 + fsec / 1000
5407  * = (tm->tm_sec * 1'000'000 + fsec) / 1000
5408  */
5409  PG_RETURN_NUMERIC(int64_div_fast_to_numeric(tm->tm_sec * INT64CONST(1000000) + fsec, 3));
5410  else
5411  PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0);
5412  break;
5413 
5414  case DTK_SECOND:
5415  if (retnumeric)
5416  /*---
5417  * tm->tm_sec + fsec / 1'000'000
5418  * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
5419  */
5420  PG_RETURN_NUMERIC(int64_div_fast_to_numeric(tm->tm_sec * INT64CONST(1000000) + fsec, 6));
5421  else
5422  PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0);
5423  break;
5424 
5425  case DTK_MINUTE:
5426  intresult = tm->tm_min;
5427  break;
5428 
5429  case DTK_HOUR:
5430  intresult = tm->tm_hour;
5431  break;
5432 
5433  case DTK_DAY:
5434  intresult = tm->tm_mday;
5435  break;
5436 
5437  case DTK_MONTH:
5438  intresult = tm->tm_mon;
5439  break;
5440 
5441  case DTK_QUARTER:
5442  intresult = (tm->tm_mon - 1) / 3 + 1;
5443  break;
5444 
5445  case DTK_WEEK:
5446  intresult = date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday);
5447  break;
5448 
5449  case DTK_YEAR:
5450  if (tm->tm_year > 0)
5451  intresult = tm->tm_year;
5452  else
5453  /* there is no year 0, just 1 BC and 1 AD */
5454  intresult = tm->tm_year - 1;
5455  break;
5456 
5457  case DTK_DECADE:
5458 
5459  /*
5460  * what is a decade wrt dates? let us assume that decade 199
5461  * is 1990 thru 1999... decade 0 starts on year 1 BC, and -1
5462  * is 11 BC thru 2 BC...
5463  */
5464  if (tm->tm_year >= 0)
5465  intresult = tm->tm_year / 10;
5466  else
5467  intresult = -((8 - (tm->tm_year - 1)) / 10);
5468  break;
5469 
5470  case DTK_CENTURY:
5471 
5472  /* ----
5473  * centuries AD, c>0: year in [ (c-1)* 100 + 1 : c*100 ]
5474  * centuries BC, c<0: year in [ c*100 : (c+1) * 100 - 1]
5475  * there is no number 0 century.
5476  * ----
5477  */
5478  if (tm->tm_year > 0)
5479  intresult = (tm->tm_year + 99) / 100;
5480  else
5481  /* caution: C division may have negative remainder */
5482  intresult = -((99 - (tm->tm_year - 1)) / 100);
5483  break;
5484 
5485  case DTK_MILLENNIUM:
5486  /* see comments above. */
5487  if (tm->tm_year > 0)
5488  intresult = (tm->tm_year + 999) / 1000;
5489  else
5490  intresult = -((999 - (tm->tm_year - 1)) / 1000);
5491  break;
5492 
5493  case DTK_JULIAN:
5494  if (retnumeric)
5496  numeric_div_opt_error(int64_to_numeric(((((tm->tm_hour * MINS_PER_HOUR) + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec) * INT64CONST(1000000) + fsec),
5497  int64_to_numeric(SECS_PER_DAY * INT64CONST(1000000)),
5498  NULL),
5499  NULL));
5500  else
5502  ((((tm->tm_hour * MINS_PER_HOUR) + tm->tm_min) * SECS_PER_MINUTE) +
5503  tm->tm_sec + (fsec / 1000000.0)) / (double) SECS_PER_DAY);
5504  break;
5505 
5506  case DTK_ISOYEAR:
5507  intresult = date2isoyear(tm->tm_year, tm->tm_mon, tm->tm_mday);
5508  /* Adjust BC years */
5509  if (intresult <= 0)
5510  intresult -= 1;
5511  break;
5512 
5513  case DTK_DOW:
5514  case DTK_ISODOW:
5515  intresult = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday));
5516  if (val == DTK_ISODOW && intresult == 0)
5517  intresult = 7;
5518  break;
5519 
5520  case DTK_DOY:
5521  intresult = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)
5522  - date2j(tm->tm_year, 1, 1) + 1);
5523  break;
5524 
5525  case DTK_TZ:
5526  case DTK_TZ_MINUTE:
5527  case DTK_TZ_HOUR:
5528  default:
5529  ereport(ERROR,
5530  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5531  errmsg("unit \"%s\" not supported for type %s",
5532  lowunits, format_type_be(TIMESTAMPOID))));
5533  intresult = 0;
5534  }
5535  }
5536  else if (type == RESERV)
5537  {
5538  switch (val)
5539  {
5540  case DTK_EPOCH:
5542  /* (timestamp - epoch) / 1000000 */
5543  if (retnumeric)
5544  {
5545  Numeric result;
5546 
5547  if (timestamp < (PG_INT64_MAX + epoch))
5548  result = int64_div_fast_to_numeric(timestamp - epoch, 6);
5549  else
5550  {
5553  NULL),
5554  int64_to_numeric(1000000),
5555  NULL);
5557  NumericGetDatum(result),
5558  Int32GetDatum(6)));
5559  }
5560  PG_RETURN_NUMERIC(result);
5561  }
5562  else
5563  {
5564  float8 result;
5565 
5566  /* try to avoid precision loss in subtraction */
5567  if (timestamp < (PG_INT64_MAX + epoch))
5568  result = (timestamp - epoch) / 1000000.0;
5569  else
5570  result = ((float8) timestamp - epoch) / 1000000.0;
5571  PG_RETURN_FLOAT8(result);
5572  }
5573  break;
5574 
5575  default:
5576  ereport(ERROR,
5577  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5578  errmsg("unit \"%s\" not supported for type %s",
5579  lowunits, format_type_be(TIMESTAMPOID))));
5580  intresult = 0;
5581  }
5582  }
5583  else
5584  {
5585  ereport(ERROR,
5586  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5587  errmsg("unit \"%s\" not recognized for type %s",
5588  lowunits, format_type_be(TIMESTAMPOID))));
5589  intresult = 0;
5590  }
5591 
5592  if (retnumeric)
5593  PG_RETURN_NUMERIC(int64_to_numeric(intresult));
5594  else
5595  PG_RETURN_FLOAT8(intresult);
5596 }
Datum numeric_round(PG_FUNCTION_ARGS)
Definition: numeric.c:1534
Numeric numeric_div_opt_error(Numeric num1, Numeric num2, bool *have_error)
Definition: numeric.c:3144
Numeric numeric_sub_opt_error(Numeric num1, Numeric num2, bool *have_error)
Definition: numeric.c:2945
static float8 NonFiniteTimestampTzPart(int type, int unit, char *lowunits, bool isNegative, bool isTz)
Definition: timestamp.c:5284
int date2isoweek(int year, int mon, int mday)
Definition: timestamp.c:5155
#define PG_INT64_MAX
Definition: c.h:592
static Numeric DatumGetNumeric(Datum X)
Definition: numeric.h:61
static Datum NumericGetDatum(Numeric X)
Definition: numeric.h:73

References CStringGetDatum(), date2isoweek(), date2isoyear(), date2j(), DatumGetNumeric(), DecodeSpecial(), DecodeUnits(), DirectFunctionCall2, DirectFunctionCall3, downcase_truncate_identifier(), DTK_CENTURY, DTK_DAY, DTK_DECADE, DTK_DOW, DTK_DOY, DTK_EPOCH, DTK_HOUR, DTK_ISODOW, DTK_ISOYEAR, DTK_JULIAN, DTK_MICROSEC, DTK_MILLENNIUM, DTK_MILLISEC, DTK_MINUTE, DTK_MONTH, DTK_QUARTER, DTK_SECOND, DTK_TZ, DTK_TZ_HOUR, DTK_TZ_MINUTE, DTK_WEEK, DTK_YEAR, epoch, ereport, errcode(), errmsg(), ERROR, format_type_be(), Int32GetDatum(), int64_div_fast_to_numeric(), int64_to_numeric(), InvalidOid, j2day(), MINS_PER_HOUR, NonFiniteTimestampTzPart(), numeric_add_opt_error(), numeric_div_opt_error(), numeric_in(), numeric_round(), numeric_sub_opt_error(), NumericGetDatum(), ObjectIdGetDatum(), PG_GETARG_TEXT_PP, PG_GETARG_TIMESTAMP, PG_INT64_MAX, PG_RETURN_FLOAT8, PG_RETURN_NULL, PG_RETURN_NUMERIC, RESERV, SECS_PER_DAY, SECS_PER_MINUTE, SetEpochTimestamp(), timestamp2tm(), TIMESTAMP_IS_NOBEGIN, TIMESTAMP_NOT_FINITE, tm, pg_tm::tm_hour, pg_tm::tm_mday, pg_tm::tm_min, pg_tm::tm_mon, pg_tm::tm_sec, pg_tm::tm_year, type, UNITS, UNKNOWN_FIELD, val, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by extract_timestamp(), and timestamp_part().

◆ timestamp_pl_interval()

Datum timestamp_pl_interval ( PG_FUNCTION_ARGS  )

Definition at line 3049 of file timestamp.c.

3050 {
3052  Interval *span = PG_GETARG_INTERVAL_P(1);
3053  Timestamp result;
3054 
3055  /*
3056  * Handle infinities.
3057  *
3058  * We treat anything that amounts to "infinity - infinity" as an error,
3059  * since the timestamp type has nothing equivalent to NaN.
3060  */
3061  if (INTERVAL_IS_NOBEGIN(span))
3062  {
3064  ereport(ERROR,
3065  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3066  errmsg("timestamp out of range")));
3067  else
3068  TIMESTAMP_NOBEGIN(result);
3069  }
3070  else if (INTERVAL_IS_NOEND(span))
3071  {
3073  ereport(ERROR,
3074  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3075  errmsg("timestamp out of range")));
3076  else
3077  TIMESTAMP_NOEND(result);
3078  }
3079  else if (TIMESTAMP_NOT_FINITE(timestamp))
3080  result = timestamp;
3081  else
3082  {
3083  if (span->month != 0)
3084  {
3085  struct pg_tm tt,
3086  *tm = &tt;
3087  fsec_t fsec;
3088 
3089  if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
3090  ereport(ERROR,
3091  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3092  errmsg("timestamp out of range")));
3093 
3094  tm->tm_mon += span->month;
3095  if (tm->tm_mon > MONTHS_PER_YEAR)
3096  {
3097  tm->tm_year += (tm->tm_mon - 1) / MONTHS_PER_YEAR;
3098  tm->tm_mon = ((tm->tm_mon - 1) % MONTHS_PER_YEAR) + 1;
3099  }
3100  else if (tm->tm_mon < 1)
3101  {
3102  tm->tm_year += tm->tm_mon / MONTHS_PER_YEAR - 1;
3104  }
3105 
3106  /* adjust for end of month boundary problems... */
3107  if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
3108  tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]);
3109 
3110  if (tm2timestamp(tm, fsec, NULL, &timestamp) != 0)
3111  ereport(ERROR,
3112  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3113  errmsg("timestamp out of range")));
3114  }
3115 
3116  if (span->day != 0)
3117  {
3118  struct pg_tm tt,
3119  *tm = &tt;
3120  fsec_t fsec;
3121  int julian;
3122 
3123  if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
3124  ereport(ERROR,
3125  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3126  errmsg("timestamp out of range")));
3127 
3128  /*
3129  * Add days by converting to and from Julian. We need an overflow
3130  * check here since j2date expects a non-negative integer input.
3131  */
3132  julian = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday);
3133  if (pg_add_s32_overflow(julian, span->day, &julian) ||
3134  julian < 0)
3135  ereport(ERROR,
3136  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3137  errmsg("timestamp out of range")));
3138  j2date(julian, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
3139 
3140  if (tm2timestamp(tm, fsec, NULL, &timestamp) != 0)
3141  ereport(ERROR,
3142  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3143  errmsg("timestamp out of range")));
3144  }
3145 
3146  timestamp += span->time;
3147 
3149  ereport(ERROR,
3150  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3151  errmsg("timestamp out of range")));
3152 
3153  result = timestamp;
3154  }
3155 
3156  PG_RETURN_TIMESTAMP(result);
3157 }

References date2j(), Interval::day, day_tab, ereport, errcode(), errmsg(), ERROR, INTERVAL_IS_NOBEGIN, INTERVAL_IS_NOEND, IS_VALID_TIMESTAMP, isleap, j2date(), Interval::month, MONTHS_PER_YEAR, pg_add_s32_overflow(), PG_GETARG_INTERVAL_P, PG_GETARG_TIMESTAMP, PG_RETURN_TIMESTAMP, Interval::time, timestamp2tm(), TIMESTAMP_IS_NOBEGIN, TIMESTAMP_IS_NOEND, TIMESTAMP_NOBEGIN, TIMESTAMP_NOEND, TIMESTAMP_NOT_FINITE, tm, tm2timestamp(), pg_tm::tm_mday, pg_tm::tm_mon, and pg_tm::tm_year.

Referenced by date_pl_interval(), generate_series_timestamp(), in_range_timestamp_interval(), and timestamp_mi_interval().

◆ timestamp_recv()

Datum timestamp_recv ( PG_FUNCTION_ARGS  )

Definition at line 258 of file timestamp.c.

259 {
261 
262 #ifdef NOT_USED
263  Oid typelem = PG_GETARG_OID(1);
264 #endif
265  int32 typmod = PG_GETARG_INT32(2);
267  struct pg_tm tt,
268  *tm = &tt;
269  fsec_t fsec;
270 
272 
273  /* range check: see if timestamp_out would like it */
275  /* ok */ ;
276  else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0 ||
278  ereport(ERROR,
279  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
280  errmsg("timestamp out of range")));
281 
282  AdjustTimestampForTypmod(&timestamp, typmod, NULL);
283 
285 }

References AdjustTimestampForTypmod(), buf, ereport, errcode(), errmsg(), ERROR, IS_VALID_TIMESTAMP, PG_GETARG_INT32, PG_GETARG_OID, PG_GETARG_POINTER, PG_RETURN_TIMESTAMP, pq_getmsgint64(), timestamp2tm(), TIMESTAMP_NOT_FINITE, and tm.

◆ timestamp_scale()

Datum timestamp_scale ( PG_FUNCTION_ARGS  )

Definition at line 345 of file timestamp.c.

346 {
348  int32 typmod = PG_GETARG_INT32(1);
349  Timestamp result;
350 
351  result = timestamp;
352 
353  AdjustTimestampForTypmod(&result, typmod, NULL);
354 
355  PG_RETURN_TIMESTAMP(result);
356 }

References AdjustTimestampForTypmod(), PG_GETARG_INT32, PG_GETARG_TIMESTAMP, and PG_RETURN_TIMESTAMP.

◆ timestamp_send()

◆ timestamp_smaller()

Datum timestamp_smaller ( PG_FUNCTION_ARGS  )

Definition at line 2756 of file timestamp.c.

2757 {
2758  Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
2759  Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
2760  Timestamp result;
2761 
2762  /* use timestamp_cmp_internal to be sure this agrees with comparisons */
2763  if (timestamp_cmp_internal(dt1, dt2) < 0)
2764  result = dt1;
2765  else
2766  result = dt2;
2767  PG_RETURN_TIMESTAMP(result);
2768 }

References PG_GETARG_TIMESTAMP, PG_RETURN_TIMESTAMP, and timestamp_cmp_internal().

◆ timestamp_sortsupport()

Datum timestamp_sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 2291 of file timestamp.c.

2292 {
2294 
2295 #if SIZEOF_DATUM >= 8
2296 
2297  /*
2298  * If this build has pass-by-value timestamps, then we can use a standard
2299  * comparator function.
2300  */
2301  ssup->comparator = ssup_datum_signed_cmp;
2302 #else
2303  ssup->comparator = timestamp_fastcmp;
2304 #endif
2305  PG_RETURN_VOID();
2306 }
static int timestamp_fastcmp(Datum x, Datum y, SortSupport ssup)
Definition: timestamp.c:2281
#define PG_RETURN_VOID()
Definition: fmgr.h:349
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
int(* comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:106

References SortSupportData::comparator, PG_GETARG_POINTER, PG_RETURN_VOID, and timestamp_fastcmp().

◆ timestamp_support()

Datum timestamp_support ( PG_FUNCTION_ARGS  )

Definition at line 325 of file timestamp.c.

326 {
327  Node *rawreq = (Node *) PG_GETARG_POINTER(0);
328  Node *ret = NULL;
329 
330  if (IsA(rawreq, SupportRequestSimplify))
331  {
333 
335  }
336 
337  PG_RETURN_POINTER(ret);
338 }
Node * TemporalSimplify(int32 max_precis, Node *node)
Definition: datetime.c:4829

References SupportRequestSimplify::fcall, IsA, MAX_TIMESTAMP_PRECISION, PG_GETARG_POINTER, PG_RETURN_POINTER, and TemporalSimplify().

◆ timestamp_timestamptz()

Datum timestamp_timestamptz ( PG_FUNCTION_ARGS  )

◆ timestamp_trunc()

Datum timestamp_trunc ( PG_FUNCTION_ARGS  )

Definition at line 4606 of file timestamp.c.

4607 {
4608  text *units = PG_GETARG_TEXT_PP(0);
4610  Timestamp result;
4611  int type,
4612  val;
4613  char *lowunits;
4614  fsec_t fsec;
4615  struct pg_tm tt,
4616  *tm = &tt;
4617 
4620 
4621  lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
4622  VARSIZE_ANY_EXHDR(units),
4623  false);
4624 
4625  type = DecodeUnits(0, lowunits, &val);
4626 
4627  if (type == UNITS)
4628  {
4629  if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
4630  ereport(ERROR,
4631  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4632  errmsg("timestamp out of range")));
4633 
4634  switch (val)
4635  {
4636  case DTK_WEEK:
4637  {
4638  int woy;
4639 
4640  woy = date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday);
4641 
4642  /*
4643  * If it is week 52/53 and the month is January, then the
4644  * week must belong to the previous year. Also, some
4645  * December dates belong to the next year.
4646  */
4647  if (woy >= 52 && tm->tm_mon == 1)
4648  --tm->tm_year;
4649  if (woy <= 1 && tm->tm_mon == MONTHS_PER_YEAR)
4650  ++tm->tm_year;
4651  isoweek2date(woy, &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
4652  tm->tm_hour = 0;
4653  tm->tm_min = 0;
4654  tm->tm_sec = 0;
4655  fsec = 0;
4656  break;
4657  }
4658  case DTK_MILLENNIUM:
4659  /* see comments in timestamptz_trunc */
4660  if (tm->tm_year > 0)
4661  tm->tm_year = ((tm->tm_year + 999) / 1000) * 1000 - 999;
4662  else
4663  tm->tm_year = -((999 - (tm->tm_year - 1)) / 1000) * 1000 + 1;
4664  /* FALL THRU */
4665  case DTK_CENTURY:
4666  /* see comments in timestamptz_trunc */
4667  if (tm->tm_year > 0)
4668  tm->tm_year = ((tm->tm_year + 99) / 100) * 100 - 99;
4669  else
4670  tm->tm_year = -((99 - (tm->tm_year - 1)) / 100) * 100 + 1;
4671  /* FALL THRU */
4672  case DTK_DECADE:
4673  /* see comments in timestamptz_trunc */
4674  if (val != DTK_MILLENNIUM && val != DTK_CENTURY)
4675  {
4676  if (tm->tm_year > 0)
4677  tm->tm_year = (tm->tm_year / 10) * 10;
4678  else
4679  tm->tm_year = -((8 - (tm->tm_year - 1)) / 10) * 10;
4680  }
4681  /* FALL THRU */
4682  case DTK_YEAR:
4683  tm->tm_mon = 1;
4684  /* FALL THRU */
4685  case DTK_QUARTER:
4686  tm->tm_mon = (3 * ((tm->tm_mon - 1) / 3)) + 1;
4687  /* FALL THRU */
4688  case DTK_MONTH:
4689  tm->tm_mday = 1;
4690  /* FALL THRU */
4691  case DTK_DAY:
4692  tm->tm_hour = 0;
4693  /* FALL THRU */
4694  case DTK_HOUR:
4695  tm->tm_min = 0;
4696  /* FALL THRU */
4697  case DTK_MINUTE:
4698  tm->tm_sec = 0;
4699  /* FALL THRU */
4700  case DTK_SECOND:
4701  fsec = 0;
4702  break;
4703 
4704  case DTK_MILLISEC:
4705  fsec = (fsec / 1000) * 1000;
4706  break;
4707 
4708  case DTK_MICROSEC:
4709  break;
4710 
4711  default:
4712  ereport(ERROR,
4713  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4714  errmsg("unit \"%s\" not supported for type %s",
4715  lowunits, format_type_be(TIMESTAMPOID))));
4716  result = 0;
4717  }
4718 
4719  if (tm2timestamp(tm, fsec, NULL, &result) != 0)
4720  ereport(ERROR,
4721  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4722  errmsg("timestamp out of range")));
4723  }
4724  else
4725  {
4726  ereport(ERROR,
4727  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4728  errmsg("unit \"%s\" not recognized for type %s",
4729  lowunits, format_type_be(TIMESTAMPOID))));
4730  result = 0;
4731  }
4732 
4733  PG_RETURN_TIMESTAMP(result);
4734 }
void isoweek2date(int woy, int *year, int *mon, int *mday)
Definition: timestamp.c:5124

References date2isoweek(), DecodeUnits(), downcase_truncate_identifier(), DTK_CENTURY, DTK_DAY, DTK_DECADE, DTK_HOUR, DTK_MICROSEC, DTK_MILLENNIUM, DTK_MILLISEC, DTK_MINUTE, DTK_MONTH, DTK_QUARTER, DTK_SECOND, DTK_WEEK, DTK_YEAR, ereport, errcode(), errmsg(), ERROR, format_type_be(), isoweek2date(), MONTHS_PER_YEAR, PG_GETARG_TEXT_PP, PG_GETARG_TIMESTAMP, PG_RETURN_TIMESTAMP, timestamp2tm(), TIMESTAMP_NOT_FINITE, tm, tm2timestamp(), pg_tm::tm_hour, pg_tm::tm_mday, pg_tm::tm_min, pg_tm::tm_mon, pg_tm::tm_sec, pg_tm::tm_year, type, UNITS, val, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ timestamp_zone()

Datum timestamp_zone ( PG_FUNCTION_ARGS  )

Definition at line 6152 of file timestamp.c.

6153 {
6154  text *zone = PG_GETARG_TEXT_PP(0);
6156  TimestampTz result;
6157  int tz;
6158  char tzname[TZ_STRLEN_MAX + 1];
6159  int type,
6160  val;
6161  pg_tz *tzp;
6162  struct pg_tm tm;
6163  fsec_t fsec;
6164 
6167 
6168  /*
6169  * Look up the requested timezone.
6170  */
6171  text_to_cstring_buffer(zone, tzname, sizeof(tzname));
6172 
6173  type = DecodeTimezoneName(tzname, &val, &tzp);
6174 
6175  if (type == TZNAME_FIXED_OFFSET)
6176  {
6177  /* fixed-offset abbreviation */
6178  tz = val;
6179  result = dt2local(timestamp, tz);
6180  }
6181  else if (type == TZNAME_DYNTZ)
6182  {
6183  /* dynamic-offset abbreviation, resolve using specified time */
6184  if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, tzp) != 0)
6185  ereport(ERROR,
6186  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6187  errmsg("timestamp out of range")));
6188  tz = -DetermineTimeZoneAbbrevOffset(&tm, tzname, tzp);
6189  result = dt2local(timestamp, tz);
6190  }
6191  else
6192  {
6193  /* full zone name, rotate to that zone */
6194  if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, tzp) != 0)
6195  ereport(ERROR,
6196  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6197  errmsg("timestamp out of range")));
6198  tz = DetermineTimeZoneOffset(&tm, tzp);
6199  if (tm2timestamp(&tm, fsec, &tz, &result) != 0)
6200  ereport(ERROR,
6201  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6202  errmsg("timestamp out of range")));
6203  }
6204 
6205  if (!IS_VALID_TIMESTAMP(result))
6206  ereport(ERROR,
6207  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6208  errmsg("timestamp out of range")));
6209 
6210  PG_RETURN_TIMESTAMPTZ(result);
6211 }

References DecodeTimezoneName(), DetermineTimeZoneAbbrevOffset(), DetermineTimeZoneOffset(), dt2local(), ereport, errcode(), errmsg(), ERROR, IS_VALID_TIMESTAMP, PG_GETARG_TEXT_PP, PG_GETARG_TIMESTAMP, PG_RETURN_TIMESTAMPTZ, text_to_cstring_buffer(), timestamp2tm(), TIMESTAMP_NOT_FINITE, tm, tm2timestamp(), type, TZ_STRLEN_MAX, TZNAME_DYNTZ, TZNAME_FIXED_OFFSET, and val.

◆ TimestampDifference()

void TimestampDifference ( TimestampTz  start_time,
TimestampTz  stop_time,
long *  secs,
int *  microsecs 
)

Definition at line 1730 of file timestamp.c.

1732 {
1733  TimestampTz diff = stop_time - start_time;
1734 
1735  if (diff <= 0)
1736  {
1737  *secs = 0;
1738  *microsecs = 0;
1739  }
1740  else
1741  {
1742  *secs = (long) (diff / USECS_PER_SEC);
1743  *microsecs = (int) (diff % USECS_PER_SEC);
1744  }
1745 }
static time_t start_time
Definition: pg_ctl.c:94

References start_time, and USECS_PER_SEC.

Referenced by check_log_duration(), has_startup_progress_timeout_expired(), heap_vacuum_rel(), launcher_determine_sleep(), log_disconnections(), LogRecoveryConflict(), pgstat_report_activity(), pgstat_update_dbstats(), ProcSleep(), and schedule_alarm().

◆ TimestampDifferenceExceeds()

◆ TimestampDifferenceMilliseconds()

long TimestampDifferenceMilliseconds ( TimestampTz  start_time,
TimestampTz  stop_time 
)

Definition at line 1766 of file timestamp.c.

1767 {
1768  TimestampTz diff;
1769 
1770  /* Deal with zero or negative elapsed time quickly. */
1771  if (start_time >= stop_time)
1772  return 0;
1773  /* To not fail with timestamp infinities, we must detect overflow. */
1774  if (pg_sub_s64_overflow(stop_time, start_time, &diff))
1775  return (long) INT_MAX;
1776  if (diff >= (INT_MAX * INT64CONST(1000) - 999))
1777  return (long) INT_MAX;
1778  else
1779  return (long) ((diff + 999) / 1000);
1780 }

References pg_sub_s64_overflow(), and start_time.

Referenced by ApplyLauncherMain(), autoprewarm_main(), bbsink_copystream_archive_contents(), DetermineSleepTime(), do_analyze_rel(), GetReplicationApplyDelay(), GetReplicationTransferLatency(), libpqsrv_cancel(), LogCheckpointEnd(), pgfdw_get_cleanup_result(), PrepareForIncrementalBackup(), recoveryApplyDelay(), WaitForWalSummarization(), WaitForWALToBecomeAvailable(), WalReceiverMain(), and WalSndComputeSleeptime().

◆ TimestampTimestampTzRequiresRewrite()

bool TimestampTimestampTzRequiresRewrite ( void  )

Definition at line 6261 of file timestamp.c.

6262 {
6263  long offset;
6264 
6265  if (pg_get_timezone_offset(session_timezone, &offset) && offset == 0)
6266  return false;
6267  return true;
6268 }
bool pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff)
Definition: localtime.c:1851

References pg_get_timezone_offset(), and session_timezone.

Referenced by ATColumnChangeRequiresRewrite().

◆ timestamptypmodin()

Datum timestamptypmodin ( PG_FUNCTION_ARGS  )

Definition at line 302 of file timestamp.c.

303 {
305 
307 }
static int32 anytimestamp_typmodin(bool istz, ArrayType *ta)
Definition: timestamp.c:102

References anytimestamp_typmodin(), PG_GETARG_ARRAYTYPE_P, and PG_RETURN_INT32.

◆ timestamptypmodout()

Datum timestamptypmodout ( PG_FUNCTION_ARGS  )

Definition at line 310 of file timestamp.c.

311 {
312  int32 typmod = PG_GETARG_INT32(0);
313 
315 }
static char * anytimestamp_typmodout(bool istz, int32 typmod)
Definition: timestamp.c:145

References anytimestamp_typmodout(), PG_GETARG_INT32, and PG_RETURN_CSTRING.

◆ timestamptz2timestamp()

static Timestamp timestamptz2timestamp ( TimestampTz  timestamp)
static

Definition at line 6361 of file timestamp.c.

6362 {
6363  Timestamp result;
6364  struct pg_tm tt,
6365  *tm = &tt;
6366  fsec_t fsec;
6367  int tz;
6368 
6370  result = timestamp;
6371  else
6372  {
6373  if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
6374  ereport(ERROR,
6375  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6376  errmsg("timestamp out of range")));
6377  if (tm2timestamp(tm, fsec, NULL, &result) != 0)
6378  ereport(ERROR,
6379  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6380  errmsg("timestamp out of range")));
6381  }
6382  return result;
6383 }

References ereport, errcode(), errmsg(), ERROR, timestamp2tm(), TIMESTAMP_NOT_FINITE, tm, and tm2timestamp().

Referenced by GetSQLLocalTimestamp(), and timestamptz_timestamp().

◆ timestamptz_age()

Datum timestamptz_age ( PG_FUNCTION_ARGS  )

Definition at line 4381 of file timestamp.c.

4382 {
4385  Interval *result;
4386  fsec_t fsec1,
4387  fsec2;
4388  struct pg_itm tt,
4389  *tm = &tt;
4390  struct pg_tm tt1,
4391  *tm1 = &tt1;
4392  struct pg_tm tt2,
4393  *tm2 = &tt2;
4394  int tz1;
4395  int tz2;
4396 
4397  result = (Interval *) palloc(sizeof(Interval));
4398 
4399  /*
4400  * Handle infinities.
4401  *
4402  * We treat anything that amounts to "infinity - infinity" as an error,
4403  * since the interval type has nothing equivalent to NaN.
4404  */
4405  if (TIMESTAMP_IS_NOBEGIN(dt1))
4406  {
4407  if (TIMESTAMP_IS_NOBEGIN(dt2))
4408  ereport(ERROR,
4409  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4410  errmsg("interval out of range")));
4411  else
4412  INTERVAL_NOBEGIN(result);
4413  }
4414  else if (TIMESTAMP_IS_NOEND(dt1))
4415  {
4416  if (TIMESTAMP_IS_NOEND(dt2))
4417  ereport(ERROR,
4418  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4419  errmsg("interval out of range")));
4420  else
4421  INTERVAL_NOEND(result);
4422  }
4423  else if (TIMESTAMP_IS_NOBEGIN(dt2))
4424  INTERVAL_NOEND(result);
4425  else if (TIMESTAMP_IS_NOEND(dt2))
4426  INTERVAL_NOBEGIN(result);
4427  else if (timestamp2tm(dt1, &tz1, tm1, &fsec1, NULL, NULL) == 0 &&
4428  timestamp2tm(dt2, &tz2, tm2, &fsec2, NULL, NULL) == 0)
4429  {
4430  /* form the symbolic difference */
4431  tm->tm_usec = fsec1 - fsec2;
4432  tm->tm_sec = tm1->tm_sec - tm2->tm_sec;
4433  tm->tm_min = tm1->tm_min - tm2->tm_min;
4434  tm->tm_hour = tm1->tm_hour - tm2->tm_hour;
4435  tm->tm_mday = tm1->tm_mday - tm2->tm_mday;
4436  tm->tm_mon = tm1->tm_mon - tm2->tm_mon;
4437  tm->tm_year = tm1->tm_year - tm2->tm_year;
4438 
4439  /* flip sign if necessary... */
4440  if (dt1 < dt2)
4441  {
4442  tm->tm_usec = -tm->tm_usec;
4443  tm->tm_sec = -tm->tm_sec;
4444  tm->tm_min = -tm->tm_min;
4445  tm->tm_hour = -tm->tm_hour;
4446  tm->tm_mday = -tm->tm_mday;
4447  tm->tm_mon = -tm->tm_mon;
4448  tm->tm_year = -tm->tm_year;
4449  }
4450 
4451  /* propagate any negative fields into the next higher field */
4452  while (tm->tm_usec < 0)
4453  {
4454  tm->tm_usec += USECS_PER_SEC;
4455  tm->tm_sec--;
4456  }
4457 
4458  while (tm->tm_sec < 0)
4459  {
4461  tm->tm_min--;
4462  }
4463 
4464  while (tm->tm_min < 0)
4465  {
4466  tm->tm_min += MINS_PER_HOUR;
4467  tm->tm_hour--;
4468  }
4469 
4470  while (tm->tm_hour < 0)
4471  {
4472  tm->tm_hour += HOURS_PER_DAY;
4473  tm->tm_mday--;
4474  }
4475 
4476  while (tm->tm_mday < 0)
4477  {
4478  if (dt1 < dt2)
4479  {
4480  tm->tm_mday += day_tab[isleap(tm1->tm_year)][tm1->tm_mon - 1];
4481  tm->tm_mon--;
4482  }
4483  else
4484  {
4485  tm->tm_mday += day_tab[isleap(tm2->tm_year)][tm2->tm_mon - 1];
4486  tm->tm_mon--;
4487  }
4488  }
4489 
4490  while (tm->tm_mon < 0)
4491  {
4493  tm->tm_year--;
4494  }
4495 
4496  /*
4497  * Note: we deliberately ignore any difference between tz1 and tz2.
4498  */
4499 
4500  /* recover sign if necessary... */
4501  if (dt1 < dt2)
4502  {
4503  tm->tm_usec = -tm->tm_usec;
4504  tm->tm_sec = -tm->tm_sec;
4505  tm->tm_min = -tm->tm_min;
4506  tm->tm_hour = -tm->tm_hour;
4507  tm->tm_mday = -tm->tm_mday;
4508  tm->tm_mon = -tm->tm_mon;
4509  tm->tm_year = -tm->tm_year;
4510  }
4511 
4512  if (itm2interval(tm, result) != 0)
4513  ereport(ERROR,
4514  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4515  errmsg("interval out of range")));
4516  }
4517  else
4518  ereport(ERROR,
4519  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4520  errmsg("timestamp out of range")));
4521 
4522  PG_RETURN_INTERVAL_P(result);
4523 }

References day_tab, ereport, errcode(), errmsg(), ERROR, HOURS_PER_DAY, INTERVAL_NOBEGIN, INTERVAL_NOEND, isleap, itm2interval(), MINS_PER_HOUR, MONTHS_PER_YEAR, palloc(), PG_GETARG_TIMESTAMPTZ, PG_RETURN_INTERVAL_P, SECS_PER_MINUTE, timestamp2tm(), TIMESTAMP_IS_NOBEGIN, TIMESTAMP_IS_NOEND, tm, pg_tm::tm_hour, pg_tm::tm_mday, pg_tm::tm_min, pg_tm::tm_mon, pg_tm::tm_sec, pg_tm::tm_year, and USECS_PER_SEC.

◆ timestamptz_at_local()

Datum timestamptz_at_local ( PG_FUNCTION_ARGS  )

Definition at line 6686 of file timestamp.c.

6687 {
6688  return timestamptz_timestamp(fcinfo);
6689 }
Datum timestamptz_timestamp(PG_FUNCTION_ARGS)
Definition: timestamp.c:6353

References timestamptz_timestamp().

◆ timestamptz_bin()

Datum timestamptz_bin ( PG_FUNCTION_ARGS  )

Definition at line 4740 of file timestamp.c.

4741 {
4742  Interval *stride = PG_GETARG_INTERVAL_P(0);
4744  TimestampTz origin = PG_GETARG_TIMESTAMPTZ(2);
4745  TimestampTz result,
4746  stride_usecs,
4747  tm_diff,
4748  tm_modulo,
4749  tm_delta;
4750 
4753 
4754  if (TIMESTAMP_NOT_FINITE(origin))
4755  ereport(ERROR,
4756  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4757  errmsg("origin out of range")));
4758 
4759  if (INTERVAL_NOT_FINITE(stride))
4760  ereport(ERROR,
4761  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4762  errmsg("timestamps cannot be binned into infinite intervals")));
4763 
4764  if (stride->month != 0)
4765  ereport(ERROR,
4766  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4767  errmsg("timestamps cannot be binned into intervals containing months or years")));
4768 
4769  if (unlikely(pg_mul_s64_overflow(stride->day, USECS_PER_DAY, &stride_usecs)) ||
4770  unlikely(pg_add_s64_overflow(stride_usecs, stride->time, &stride_usecs)))
4771  ereport(ERROR,
4772  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4773  errmsg("interval out of range")));
4774 
4775  if (stride_usecs <= 0)
4776  ereport(ERROR,
4777  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4778  errmsg("stride must be greater than zero")));
4779 
4780  if (unlikely(pg_sub_s64_overflow(timestamp, origin, &tm_diff)))
4781  ereport(ERROR,
4782  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4783  errmsg("interval out of range")));
4784 
4785  /* These calculations cannot overflow */
4786  tm_modulo = tm_diff % stride_usecs;
4787  tm_delta = tm_diff - tm_modulo;
4788  result = origin + tm_delta;
4789 
4790  /*
4791  * We want to round towards -infinity, not 0, when tm_diff is negative and
4792  * not a multiple of stride_usecs. This adjustment *can* cause overflow,
4793  * since the result might now be out of the range origin .. timestamp.
4794  */
4795  if (tm_modulo < 0)
4796  {
4797  if (unlikely(pg_sub_s64_overflow(result, stride_usecs, &result)) ||
4798  !IS_VALID_TIMESTAMP(result))
4799  ereport(ERROR,
4800  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4801  errmsg("timestamp out of range")));
4802  }
4803 
4804  PG_RETURN_TIMESTAMPTZ(result);
4805 }

References Interval::day, ereport, errcode(), errmsg(), ERROR, INTERVAL_NOT_FINITE, IS_VALID_TIMESTAMP, Interval::month, pg_add_s64_overflow(), PG_GETARG_INTERVAL_P, PG_GETARG_TIMESTAMPTZ, pg_mul_s64_overflow(), PG_RETURN_TIMESTAMPTZ, pg_sub_s64_overflow(), Interval::time, TIMESTAMP_NOT_FINITE, unlikely, and USECS_PER_DAY.

◆ timestamptz_cmp_timestamp()

Datum timestamptz_cmp_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2463 of file timestamp.c.

2464 {
2466  Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
2467 
2469 }

References PG_GETARG_TIMESTAMP, PG_GETARG_TIMESTAMPTZ, PG_RETURN_INT32, and timestamp_cmp_timestamptz_internal().

◆ timestamptz_eq_timestamp()

Datum timestamptz_eq_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2409 of file timestamp.c.

2410 {
2412  Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
2413 
2414  PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) == 0);
2415 }

References PG_GETARG_TIMESTAMP, PG_GETARG_TIMESTAMPTZ, PG_RETURN_BOOL, and timestamp_cmp_timestamptz_internal().

◆ timestamptz_ge_timestamp()

Datum timestamptz_ge_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2454 of file timestamp.c.

2455 {
2457  Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
2458 
2459  PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) <= 0);
2460 }

References PG_GETARG_TIMESTAMP, PG_GETARG_TIMESTAMPTZ, PG_RETURN_BOOL, and timestamp_cmp_timestamptz_internal().

◆ timestamptz_gt_timestamp()

Datum timestamptz_gt_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2436 of file timestamp.c.

2437 {
2439  Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
2440 
2441  PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) < 0);
2442 }

References PG_GETARG_TIMESTAMP, PG_GETARG_TIMESTAMPTZ, PG_RETURN_BOOL, and timestamp_cmp_timestamptz_internal().

◆ timestamptz_in()

Datum timestamptz_in ( PG_FUNCTION_ARGS  )

Definition at line 416 of file timestamp.c.

417 {
418  char *str = PG_GETARG_CSTRING(0);
419 #ifdef NOT_USED
420  Oid typelem = PG_GETARG_OID(1);
421 #endif
422  int32 typmod = PG_GETARG_INT32(2);
423  Node *escontext = fcinfo->context;
424  TimestampTz result;
425  fsec_t fsec;
426  struct pg_tm tt,
427  *tm = &tt;
428  int tz;
429  int dtype;
430  int nf;
431  int dterr;
432  char *field[MAXDATEFIELDS];
433  int ftype[MAXDATEFIELDS];
434  char workbuf[MAXDATELEN + MAXDATEFIELDS];
435  DateTimeErrorExtra extra;
436 
437  dterr = ParseDateTime(str, workbuf, sizeof(workbuf),
438  field, ftype, MAXDATEFIELDS, &nf);
439  if (dterr == 0)
440  dterr = DecodeDateTime(field, ftype, nf,
441  &dtype, tm, &fsec, &tz, &extra);
442  if (dterr != 0)
443  {
444  DateTimeParseError(dterr, &extra, str, "timestamp with time zone",
445  escontext);
446  PG_RETURN_NULL();
447  }
448 
449  switch (dtype)
450  {
451  case DTK_DATE:
452  if (tm2timestamp(tm, fsec, &tz, &result) != 0)
453  ereturn(escontext, (Datum) 0,
454  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
455  errmsg("timestamp out of range: \"%s\"", str)));
456  break;
457 
458  case DTK_EPOCH:
459  result = SetEpochTimestamp();
460  break;
461 
462  case DTK_LATE:
463  TIMESTAMP_NOEND(result);
464  break;
465 
466  case DTK_EARLY:
467  TIMESTAMP_NOBEGIN(result);
468  break;
469 
470  default:
471  elog(ERROR, "unexpected dtype %d while parsing timestamptz \"%s\"",
472  dtype, str);
473  TIMESTAMP_NOEND(result);
474  }
475 
476  AdjustTimestampForTypmod(&result, typmod, escontext);
477 
478  PG_RETURN_TIMESTAMPTZ(result);
479 }

References AdjustTimestampForTypmod(), DateTimeParseError(), DecodeDateTime(), DTK_DATE, DTK_EARLY, DTK_EPOCH, DTK_LATE, elog, ereturn, errcode(), errmsg(), ERROR, MAXDATEFIELDS, MAXDATELEN, ParseDateTime(), PG_GETARG_CSTRING, PG_GETARG_INT32, PG_GETARG_OID, PG_RETURN_NULL, PG_RETURN_TIMESTAMPTZ, SetEpochTimestamp(), str, TIMESTAMP_NOBEGIN, TIMESTAMP_NOEND, tm, and tm2timestamp().

Referenced by AlterRole(), CreateRole(), moddatetime(), and validateRecoveryParameters().

◆ timestamptz_izone()

Datum timestamptz_izone ( PG_FUNCTION_ARGS  )

Definition at line 6454 of file timestamp.c.

6455 {
6458  Timestamp result;
6459  int tz;
6460 
6463 
6465  ereport(ERROR,
6466  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6467  errmsg("interval time zone \"%s\" must be finite",
6469  PointerGetDatum(zone))))));
6470 
6471  if (zone->month != 0 || zone->day != 0)
6472  ereport(ERROR,
6473  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6474  errmsg("interval time zone \"%s\" must not include months or days",
6476  PointerGetDatum(zone))))));
6477 
6478  tz = -(zone->time / USECS_PER_SEC);
6479 
6480  result = dt2local(timestamp, tz);
6481 
6482  if (!IS_VALID_TIMESTAMP(result))
6483  ereport(ERROR,
6484  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6485  errmsg("timestamp out of range")));
6486 
6487  PG_RETURN_TIMESTAMP(result);
6488 }

References DatumGetCString(), DirectFunctionCall1, dt2local(), ereport, errcode(), errmsg(), ERROR, INTERVAL_NOT_FINITE, interval_out(), IS_VALID_TIMESTAMP, PG_GETARG_INTERVAL_P, PG_GETARG_TIMESTAMPTZ, PG_RETURN_TIMESTAMP, PointerGetDatum(), TIMESTAMP_NOT_FINITE, and USECS_PER_SEC.

◆ timestamptz_le_timestamp()

Datum timestamptz_le_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2445 of file timestamp.c.

2446 {
2448  Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
2449 
2450  PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) >= 0);
2451 }

References PG_GETARG_TIMESTAMP, PG_GETARG_TIMESTAMPTZ, PG_RETURN_BOOL, and timestamp_cmp_timestamptz_internal().

◆ timestamptz_lt_timestamp()

Datum timestamptz_lt_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2427 of file timestamp.c.

2428 {
2430  Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
2431 
2432  PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) > 0);
2433 }

References PG_GETARG_TIMESTAMP, PG_GETARG_TIMESTAMPTZ, PG_RETURN_BOOL, and timestamp_cmp_timestamptz_internal().

◆ timestamptz_mi_interval()

◆ timestamptz_mi_interval_at_zone()

Datum timestamptz_mi_interval_at_zone ( PG_FUNCTION_ARGS  )

◆ timestamptz_mi_interval_internal()

static TimestampTz timestamptz_mi_interval_internal ( TimestampTz  timestamp,
Interval span,
pg_tz attimezone 
)
static

Definition at line 3312 of file timestamp.c.

3315 {
3316  Interval tspan;
3317 
3318  interval_um_internal(span, &tspan);
3319 
3320  return timestamptz_pl_interval_internal(timestamp, &tspan, attimezone);
3321 }

References interval_um_internal(), and timestamptz_pl_interval_internal().

Referenced by in_range_timestamptz_interval(), timestamptz_mi_interval(), and timestamptz_mi_interval_at_zone().

◆ timestamptz_ne_timestamp()

Datum timestamptz_ne_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2418 of file timestamp.c.

2419 {
2421  Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
2422 
2423  PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) != 0);
2424 }

References PG_GETARG_TIMESTAMP, PG_GETARG_TIMESTAMPTZ, PG_RETURN_BOOL, and timestamp_cmp_timestamptz_internal().

◆ timestamptz_out()

Datum timestamptz_out ( PG_FUNCTION_ARGS  )

Definition at line 785 of file timestamp.c.

786 {
788  char *result;
789  int tz;
790  struct pg_tm tt,
791  *tm = &tt;
792  fsec_t fsec;
793  const char *tzn;
794  char buf[MAXDATELEN + 1];
795 
796  if (TIMESTAMP_NOT_FINITE(dt))
798  else if (timestamp2tm(dt, &tz, tm, &fsec, &tzn, NULL) == 0)
799  EncodeDateTime(tm, fsec, true, tz, tzn, DateStyle, buf);
800  else
801  ereport(ERROR,
802  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
803  errmsg("timestamp out of range")));
804 
805  result = pstrdup(buf);
806  PG_RETURN_CSTRING(result);
807 }

References buf, DateStyle, EncodeDateTime(), EncodeSpecialTimestamp(), ereport, errcode(), errmsg(), ERROR, MAXDATELEN, PG_GETARG_TIMESTAMPTZ, PG_RETURN_CSTRING, pstrdup(), timestamp2tm(), TIMESTAMP_NOT_FINITE, and tm.

Referenced by ExecGetJsonValueItemString(), and executeItemOptUnwrapTarget().

◆ timestamptz_part()

Datum timestamptz_part ( PG_FUNCTION_ARGS  )

Definition at line 5871 of file timestamp.c.

5872 {
5873  return timestamptz_part_common(fcinfo, false);
5874 }

References timestamptz_part_common().

◆ timestamptz_part_common()

static Datum timestamptz_part_common ( PG_FUNCTION_ARGS  ,
bool  retnumeric 
)
static

Definition at line 5614 of file timestamp.c.

5615 {
5616  text *units = PG_GETARG_TEXT_PP(0);
5618  int64 intresult;
5619  Timestamp epoch;
5620  int tz;
5621  int type,
5622  val;
5623  char *lowunits;
5624  fsec_t fsec;
5625  struct pg_tm tt,
5626  *tm = &tt;
5627 
5628  lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
5629  VARSIZE_ANY_EXHDR(units),
5630  false);
5631 
5632  type = DecodeUnits(0, lowunits, &val);
5633  if (type == UNKNOWN_FIELD)
5634  type = DecodeSpecial(0, lowunits, &val);
5635 
5637  {
5638  double r = NonFiniteTimestampTzPart(type, val, lowunits,
5640  true);
5641 
5642  if (r != 0.0)
5643  {
5644  if (retnumeric)
5645  {
5646  if (r < 0)
5648  CStringGetDatum("-Infinity"),
5650  Int32GetDatum(-1));
5651  else if (r > 0)
5653  CStringGetDatum("Infinity"),
5655  Int32GetDatum(-1));
5656  }
5657  else
5658  PG_RETURN_FLOAT8(r);
5659  }
5660  else
5661  PG_RETURN_NULL();
5662  }
5663 
5664  if (type == UNITS)
5665  {
5666  if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
5667  ereport(ERROR,
5668  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
5669  errmsg("timestamp out of range")));
5670 
5671  switch (val)
5672  {
5673  case DTK_TZ:
5674  intresult = -tz;
5675  break;
5676 
5677  case DTK_TZ_MINUTE:
5678  intresult = (-tz / SECS_PER_MINUTE) % MINS_PER_HOUR;
5679  break;
5680 
5681  case DTK_TZ_HOUR:
5682  intresult = -tz / SECS_PER_HOUR;
5683  break;
5684 
5685  case DTK_MICROSEC:
5686  intresult = tm->tm_sec * INT64CONST(1000000) + fsec;
5687  break;
5688 
5689  case DTK_MILLISEC:
5690  if (retnumeric)
5691  /*---
5692  * tm->tm_sec * 1000 + fsec / 1000
5693  * = (tm->tm_sec * 1'000'000 + fsec) / 1000
5694  */
5695  PG_RETURN_NUMERIC(int64_div_fast_to_numeric(tm->tm_sec * INT64CONST(1000000) + fsec, 3));
5696  else
5697  PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0);
5698  break;
5699 
5700  case DTK_SECOND:
5701  if (retnumeric)
5702  /*---
5703  * tm->tm_sec + fsec / 1'000'000
5704  * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
5705  */
5706  PG_RETURN_NUMERIC(int64_div_fast_to_numeric(tm->tm_sec * INT64CONST(1000000) + fsec, 6));
5707  else
5708  PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0);
5709  break;
5710 
5711  case DTK_MINUTE:
5712  intresult = tm->tm_min;
5713  break;
5714 
5715  case DTK_HOUR:
5716  intresult = tm->tm_hour;
5717  break;
5718 
5719  case DTK_DAY:
5720  intresult = tm->tm_mday;
5721  break;
5722 
5723  case DTK_MONTH:
5724  intresult = tm->tm_mon;
5725  break;
5726 
5727  case DTK_QUARTER:
5728  intresult = (tm->tm_mon - 1) / 3 + 1;
5729  break;
5730 
5731  case DTK_WEEK:
5732  intresult = date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday);
5733  break;
5734 
5735  case DTK_YEAR:
5736  if (tm->tm_year > 0)
5737  intresult = tm->tm_year;
5738  else
5739  /* there is no year 0, just 1 BC and 1 AD */
5740  intresult = tm->tm_year - 1;
5741  break;
5742 
5743  case DTK_DECADE:
5744  /* see comments in timestamp_part */
5745  if (tm->tm_year > 0)
5746  intresult = tm->tm_year / 10;
5747  else
5748  intresult = -((8 - (tm->tm_year - 1)) / 10);
5749  break;
5750 
5751  case DTK_CENTURY:
5752  /* see comments in timestamp_part */
5753  if (tm->tm_year > 0)
5754  intresult = (tm->tm_year + 99) / 100;
5755  else
5756  intresult = -((99 - (tm->tm_year - 1)) / 100);
5757  break;
5758 
5759  case DTK_MILLENNIUM:
5760  /* see comments in timestamp_part */
5761  if (tm->tm_year > 0)
5762  intresult = (tm->tm_year + 999) / 1000;
5763  else
5764  intresult = -((999 - (tm->tm_year - 1)) / 1000);
5765  break;
5766 
5767  case DTK_JULIAN:
5768  if (retnumeric)
5770  numeric_div_opt_error(int64_to_numeric(((((tm->tm_hour * MINS_PER_HOUR) + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec) * INT64CONST(1000000) + fsec),
5771  int64_to_numeric(SECS_PER_DAY * INT64CONST(1000000)),
5772  NULL),
5773  NULL));
5774  else
5776  ((((tm->tm_hour * MINS_PER_HOUR) + tm->tm_min) * SECS_PER_MINUTE) +
5777  tm->tm_sec + (fsec / 1000000.0)) / (double) SECS_PER_DAY);
5778  break;
5779 
5780  case DTK_ISOYEAR:
5781  intresult = date2isoyear(tm->tm_year, tm->tm_mon, tm->tm_mday);
5782  /* Adjust BC years */
5783  if (intresult <= 0)
5784  intresult -= 1;
5785  break;
5786 
5787  case DTK_DOW:
5788  case DTK_ISODOW:
5789  intresult = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday));
5790  if (val == DTK_ISODOW && intresult == 0)
5791  intresult = 7;
5792  break;
5793 
5794  case DTK_DOY:
5795  intresult = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)
5796  - date2j(tm->tm_year, 1, 1) + 1);
5797  break;
5798 
5799  default:
5800  ereport(ERROR,
5801  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5802  errmsg("unit \"%s\" not supported for type %s",
5803  lowunits, format_type_be(TIMESTAMPTZOID))));
5804  intresult = 0;
5805  }
5806  }
5807  else if (type == RESERV)
5808  {
5809  switch (val)
5810  {
5811  case DTK_EPOCH:
5813  /* (timestamp - epoch) / 1000000 */
5814  if (retnumeric)
5815  {
5816  Numeric result;
5817 
5818  if (timestamp < (PG_INT64_MAX + epoch))
5819  result = int64_div_fast_to_numeric(timestamp - epoch, 6);
5820  else
5821  {
5824  NULL),
5825  int64_to_numeric(1000000),
5826  NULL);
5828  NumericGetDatum(result),
5829  Int32GetDatum(6)));
5830  }
5831  PG_RETURN_NUMERIC(result);
5832  }
5833  else
5834  {
5835  float8 result;
5836 
5837  /* try to avoid precision loss in subtraction */
5838  if (timestamp < (PG_INT64_MAX + epoch))
5839  result = (timestamp - epoch) / 1000000.0;
5840  else
5841  result = ((float8) timestamp - epoch) / 1000000.0;
5842  PG_RETURN_FLOAT8(result);
5843  }
5844  break;
5845 
5846  default:
5847  ereport(ERROR,
5848  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5849  errmsg("unit \"%s\" not supported for type %s",
5850  lowunits, format_type_be(TIMESTAMPTZOID))));
5851  intresult = 0;
5852  }
5853  }
5854  else
5855  {
5856  ereport(ERROR,
5857  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5858  errmsg("unit \"%s\" not recognized for type %s",
5859  lowunits, format_type_be(TIMESTAMPTZOID))));
5860 
5861  intresult = 0;
5862  }
5863 
5864  if (retnumeric)
5865  PG_RETURN_NUMERIC(int64_to_numeric(intresult));
5866  else
5867  PG_RETURN_FLOAT8(intresult);
5868 }
#define SECS_PER_HOUR
Definition: timestamp.h:127

References CStringGetDatum(), date2isoweek(), date2isoyear(), date2j(), DatumGetNumeric(), DecodeSpecial(), DecodeUnits(), DirectFunctionCall2, DirectFunctionCall3, downcase_truncate_identifier(), DTK_CENTURY, DTK_DAY, DTK_DECADE, DTK_DOW, DTK_DOY, DTK_EPOCH, DTK_HOUR, DTK_ISODOW, DTK_ISOYEAR, DTK_JULIAN, DTK_MICROSEC, DTK_MILLENNIUM, DTK_MILLISEC, DTK_MINUTE, DTK_MONTH, DTK_QUARTER, DTK_SECOND, DTK_TZ, DTK_TZ_HOUR, DTK_TZ_MINUTE, DTK_WEEK, DTK_YEAR, epoch, ereport, errcode(), errmsg(), ERROR, format_type_be(), Int32GetDatum(), int64_div_fast_to_numeric(), int64_to_numeric(), InvalidOid, j2day(), MINS_PER_HOUR, NonFiniteTimestampTzPart(), numeric_add_opt_error(), numeric_div_opt_error(), numeric_in(), numeric_round(), numeric_sub_opt_error(), NumericGetDatum(), ObjectIdGetDatum(), PG_GETARG_TEXT_PP, PG_GETARG_TIMESTAMPTZ, PG_INT64_MAX, PG_RETURN_FLOAT8, PG_RETURN_NULL, PG_RETURN_NUMERIC, RESERV, SECS_PER_DAY, SECS_PER_HOUR, SECS_PER_MINUTE, SetEpochTimestamp(), timestamp2tm(), TIMESTAMP_IS_NOBEGIN, TIMESTAMP_NOT_FINITE, tm, pg_tm::tm_hour, pg_tm::tm_mday, pg_tm::tm_min, pg_tm::tm_mon, pg_tm::tm_sec, pg_tm::tm_year, type, UNITS, UNKNOWN_FIELD, val, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by extract_timestamptz(), and timestamptz_part().

◆ timestamptz_pl_interval()

◆ timestamptz_pl_interval_at_zone()

Datum timestamptz_pl_interval_at_zone ( PG_FUNCTION_ARGS  )

◆ timestamptz_pl_interval_internal()

static TimestampTz timestamptz_pl_interval_internal ( TimestampTz  timestamp,
Interval span,
pg_tz attimezone 
)
static

Definition at line 3186 of file timestamp.c.

3189 {
3190  TimestampTz result;
3191  int tz;
3192 
3193  /*
3194  * Handle infinities.
3195  *
3196  * We treat anything that amounts to "infinity - infinity" as an error,
3197  * since the timestamptz type has nothing equivalent to NaN.
3198  */
3199  if (INTERVAL_IS_NOBEGIN(span))
3200  {
3202  ereport(ERROR,
3203  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3204  errmsg("timestamp out of range")));
3205  else
3206  TIMESTAMP_NOBEGIN(result);
3207  }
3208  else if (INTERVAL_IS_NOEND(span))
3209  {
3211  ereport(ERROR,
3212  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3213  errmsg("timestamp out of range")));
3214  else
3215  TIMESTAMP_NOEND(result);
3216  }
3217  else if (TIMESTAMP_NOT_FINITE(timestamp))
3218  result = timestamp;
3219  else
3220  {
3221  /* Use session timezone if caller asks for default */
3222  if (attimezone == NULL)
3223  attimezone = session_timezone;
3224 
3225  if (span->month != 0)
3226  {
3227  struct pg_tm tt,
3228  *tm = &tt;
3229  fsec_t fsec;
3230 
3231  if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, attimezone) != 0)
3232  ereport(ERROR,
3233  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3234  errmsg("timestamp out of range")));
3235 
3236  tm->tm_mon += span->month;
3237  if (tm->tm_mon > MONTHS_PER_YEAR)
3238  {
3239  tm->tm_year += (tm->tm_mon - 1) / MONTHS_PER_YEAR;
3240  tm->tm_mon = ((tm->tm_mon - 1) % MONTHS_PER_YEAR) + 1;
3241  }
3242  else if (tm->tm_mon < 1)
3243  {
3244  tm->tm_year += tm->tm_mon / MONTHS_PER_YEAR - 1;
3246  }
3247 
3248  /* adjust for end of month boundary problems... */
3249  if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
3250  tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]);
3251 
3252  tz = DetermineTimeZoneOffset(tm, attimezone);
3253 
3254  if (tm2timestamp(tm, fsec, &tz, &timestamp) != 0)
3255  ereport(ERROR,
3256  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3257  errmsg("timestamp out of range")));
3258  }
3259 
3260  if (span->day != 0)
3261  {
3262  struct pg_tm tt,
3263  *tm = &tt;
3264  fsec_t fsec;
3265  int julian;
3266 
3267  if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, attimezone) != 0)
3268  ereport(ERROR,
3269  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3270  errmsg("timestamp out of range")));
3271 
3272  /*
3273  * Add days by converting to and from Julian. We need an overflow
3274  * check here since j2date expects a non-negative integer input.
3275  * In practice though, it will give correct answers for small
3276  * negative Julian dates; we should allow -1 to avoid
3277  * timezone-dependent failures, as discussed in timestamp.h.
3278  */
3279  julian = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday);
3280  if (pg_add_s32_overflow(julian, span->day, &julian) ||
3281  julian < -1)
3282  ereport(ERROR,
3283  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3284  errmsg("timestamp out of range")));
3285  j2date(julian, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
3286 
3287  tz = DetermineTimeZoneOffset(tm, attimezone);
3288 
3289  if (tm2timestamp(tm, fsec, &tz, &timestamp) != 0)
3290  ereport(ERROR,
3291  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3292  errmsg("timestamp out of range")));
3293  }
3294 
3295  timestamp += span->time;
3296 
3298  ereport(ERROR,
3299  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3300  errmsg("timestamp out of range")));
3301 
3302  result = timestamp;
3303  }
3304 
3305  return result;
3306 }

References date2j(), Interval::day, day_tab, DetermineTimeZoneOffset(), ereport, errcode(), errmsg(), ERROR, INTERVAL_IS_NOBEGIN, INTERVAL_IS_NOEND, IS_VALID_TIMESTAMP, isleap, j2date(), Interval::month, MONTHS_PER_YEAR, pg_add_s32_overflow(), session_timezone, Interval::time, timestamp2tm(), TIMESTAMP_IS_NOBEGIN, TIMESTAMP_IS_NOEND, TIMESTAMP_NOBEGIN, TIMESTAMP_NOEND, TIMESTAMP_NOT_FINITE, tm, tm2timestamp(), pg_tm::tm_mday, pg_tm::tm_mon, and pg_tm::tm_year.

Referenced by generate_series_timestamptz_internal(), in_range_timestamptz_interval(), timestamptz_mi_interval_internal(), timestamptz_pl_interval(), and timestamptz_pl_interval_at_zone().

◆ timestamptz_recv()

Datum timestamptz_recv ( PG_FUNCTION_ARGS  )

Definition at line 813 of file timestamp.c.

814 {
816 
817 #ifdef NOT_USED
818  Oid typelem = PG_GETARG_OID(1);
819 #endif
820  int32 typmod = PG_GETARG_INT32(2);
822  int tz;
823  struct pg_tm tt,
824  *tm = &tt;
825  fsec_t fsec;
826 
828 
829  /* range check: see if timestamptz_out would like it */
831  /* ok */ ;
832  else if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0 ||
834  ereport(ERROR,
835  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
836  errmsg("timestamp out of range")));
837 
838  AdjustTimestampForTypmod(&timestamp, typmod, NULL);
839 
841 }

References AdjustTimestampForTypmod(), buf, ereport, errcode(), errmsg(), ERROR, IS_VALID_TIMESTAMP, PG_GETARG_INT32, PG_GETARG_OID, PG_GETARG_POINTER, PG_RETURN_TIMESTAMPTZ, pq_getmsgint64(), timestamp2tm(), TIMESTAMP_NOT_FINITE, and tm.

◆ timestamptz_scale()

Datum timestamptz_scale ( PG_FUNCTION_ARGS  )

Definition at line 879 of file timestamp.c.

880 {
882  int32 typmod = PG_GETARG_INT32(1);
883  TimestampTz result;
884 
885  result = timestamp;
886 
887  AdjustTimestampForTypmod(&result, typmod, NULL);
888 
889  PG_RETURN_TIMESTAMPTZ(result);
890 }

References AdjustTimestampForTypmod(), PG_GETARG_INT32, PG_GETARG_TIMESTAMPTZ, and PG_RETURN_TIMESTAMPTZ.

◆ timestamptz_send()

◆ timestamptz_timestamp()

Datum timestamptz_timestamp ( PG_FUNCTION_ARGS  )

◆ timestamptz_to_str()

const char* timestamptz_to_str ( TimestampTz  t)

Definition at line 1853 of file timestamp.c.

1854 {
1855  static char buf[MAXDATELEN + 1];
1856  int tz;
1857  struct pg_tm tt,
1858  *tm = &tt;
1859  fsec_t fsec;
1860  const char *tzn;
1861 
1862  if (TIMESTAMP_NOT_FINITE(t))
1864  else if (timestamp2tm(t, &tz, tm, &fsec, &tzn, NULL) == 0)
1865  EncodeDateTime(tm, fsec, true, tz, tzn, USE_ISO_DATES, buf);
1866  else
1867  strlcpy(buf, "(timestamp out of range)", sizeof(buf));
1868 
1869  return buf;
1870 }
#define USE_ISO_DATES
Definition: miscadmin.h:235
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45

References buf, EncodeDateTime(), EncodeSpecialTimestamp(), MAXDATELEN, strlcpy(), timestamp2tm(), TIMESTAMP_NOT_FINITE, tm, and USE_ISO_DATES.

Referenced by CreateRestartPoint(), getRecoveryStopReason(), InitWalRecovery(), PerformWalRecovery(), pg_decode_commit_prepared_txn(), pg_decode_commit_txn(), pg_decode_prepare_txn(), pg_decode_rollback_prepared_txn(), pg_decode_stream_commit(), pg_decode_stream_prepare(), ProcessStandbyHSFeedbackMessage(), ProcessStandbyReplyMessage(), ProcessWalSndrMessage(), recoveryStopsAfter(), recoveryStopsBefore(), xact_desc_abort(), xact_desc_commit(), xact_desc_prepare(), xlog_desc(), and xlogrecovery_redo().

◆ timestamptz_to_time_t()

pg_time_t timestamptz_to_time_t ( TimestampTz  t)

Definition at line 1833 of file timestamp.c.

1834 {
1835  pg_time_t result;
1836 
1837  result = (pg_time_t) (t / USECS_PER_SEC +
1839 
1840  return result;
1841 }

References POSTGRES_EPOCH_JDATE, SECS_PER_DAY, UNIX_EPOCH_JDATE, and USECS_PER_SEC.

Referenced by DetermineTimeZoneAbbrevOffsetTS(), and InitProcessGlobals().

◆ timestamptz_trunc()

Datum timestamptz_trunc ( PG_FUNCTION_ARGS  )

Definition at line 4958 of file timestamp.c.

4959 {
4960  text *units = PG_GETARG_TEXT_PP(0);
4962  TimestampTz result;
4963 
4966 
4968 
4969  PG_RETURN_TIMESTAMPTZ(result);
4970 }
static TimestampTz timestamptz_trunc_internal(text *units, TimestampTz timestamp, pg_tz *tzp)
Definition: timestamp.c:4814

References PG_GETARG_TEXT_PP, PG_GETARG_TIMESTAMPTZ, PG_RETURN_TIMESTAMPTZ, session_timezone, TIMESTAMP_NOT_FINITE, and timestamptz_trunc_internal().

◆ timestamptz_trunc_internal()

static TimestampTz timestamptz_trunc_internal ( text units,
TimestampTz  timestamp,
pg_tz tzp 
)
static

Definition at line 4814 of file timestamp.c.

4815 {
4816  TimestampTz result;
4817  int tz;
4818  int type,
4819  val;
4820  bool redotz = false;
4821  char *lowunits;
4822  fsec_t fsec;
4823  struct pg_tm tt,
4824  *tm = &tt;
4825 
4826  lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
4827  VARSIZE_ANY_EXHDR(units),
4828  false);
4829 
4830  type = DecodeUnits(0, lowunits, &val);
4831 
4832  if (type == UNITS)
4833  {
4834  if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, tzp) != 0)
4835  ereport(ERROR,
4836  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4837  errmsg("timestamp out of range")));
4838 
4839  switch (val)
4840  {
4841  case DTK_WEEK:
4842  {
4843  int woy;
4844 
4845  woy = date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday);
4846 
4847  /*
4848  * If it is week 52/53 and the month is January, then the
4849  * week must belong to the previous year. Also, some
4850  * December dates belong to the next year.
4851  */
4852  if (woy >= 52 && tm->tm_mon == 1)
4853  --tm->tm_year;
4854  if (woy <= 1 && tm->tm_mon == MONTHS_PER_YEAR)
4855  ++tm->tm_year;
4856  isoweek2date(woy, &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
4857  tm->tm_hour = 0;
4858  tm->tm_min = 0;
4859  tm->tm_sec = 0;
4860  fsec = 0;
4861  redotz = true;
4862  break;
4863  }
4864  /* one may consider DTK_THOUSAND and DTK_HUNDRED... */
4865  case DTK_MILLENNIUM:
4866 
4867  /*
4868  * truncating to the millennium? what is this supposed to
4869  * mean? let us put the first year of the millennium... i.e.
4870  * -1000, 1, 1001, 2001...
4871  */
4872  if (tm->tm_year > 0)
4873  tm->tm_year = ((tm->tm_year + 999) / 1000) * 1000 - 999;
4874  else
4875  tm->tm_year = -((999 - (tm->tm_year - 1)) / 1000) * 1000 + 1;
4876  /* FALL THRU */
4877  case DTK_CENTURY:
4878  /* truncating to the century? as above: -100, 1, 101... */
4879  if (tm->tm_year > 0)
4880  tm->tm_year = ((tm->tm_year + 99) / 100) * 100 - 99;
4881  else
4882  tm->tm_year = -((99 - (tm->tm_year - 1)) / 100) * 100 + 1;
4883  /* FALL THRU */
4884  case DTK_DECADE:
4885 
4886  /*
4887  * truncating to the decade? first year of the decade. must
4888  * not be applied if year was truncated before!
4889  */
4890  if (val != DTK_MILLENNIUM && val != DTK_CENTURY)
4891  {
4892  if (tm->tm_year > 0)
4893  tm->tm_year = (tm->tm_year / 10) * 10;
4894  else
4895  tm->tm_year = -((8 - (tm->tm_year - 1)) / 10) * 10;
4896  }
4897  /* FALL THRU */
4898  case DTK_YEAR:
4899  tm->tm_mon = 1;
4900  /* FALL THRU */
4901  case DTK_QUARTER:
4902  tm->tm_mon = (3 * ((tm->tm_mon - 1) / 3)) + 1;
4903  /* FALL THRU */
4904  case DTK_MONTH:
4905  tm->tm_mday = 1;
4906  /* FALL THRU */
4907  case DTK_DAY:
4908  tm->tm_hour = 0;
4909  redotz = true; /* for all cases >= DAY */
4910  /* FALL THRU */
4911  case DTK_HOUR:
4912  tm->tm_min = 0;
4913  /* FALL THRU */
4914  case DTK_MINUTE:
4915  tm->tm_sec = 0;
4916  /* FALL THRU */
4917  case DTK_SECOND:
4918  fsec = 0;
4919  break;
4920  case DTK_MILLISEC:
4921  fsec = (fsec / 1000) * 1000;
4922  break;
4923  case DTK_MICROSEC:
4924  break;
4925 
4926  default:
4927  ereport(ERROR,
4928  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4929  errmsg("unit \"%s\" not supported for type %s",
4930  lowunits, format_type_be(TIMESTAMPTZOID))));
4931  result = 0;
4932  }
4933 
4934  if (redotz)
4935  tz = DetermineTimeZoneOffset(tm, tzp);
4936 
4937  if (tm2timestamp(tm, fsec, &tz, &result) != 0)
4938  ereport(ERROR,
4939  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4940  errmsg("timestamp out of range")));
4941  }
4942  else
4943  {
4944  ereport(ERROR,
4945  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4946  errmsg("unit \"%s\" not recognized for type %s",
4947  lowunits, format_type_be(TIMESTAMPTZOID))));
4948  result = 0;
4949  }
4950 
4951  return result;
4952 }

References date2isoweek(), DecodeUnits(), DetermineTimeZoneOffset(), downcase_truncate_identifier(), DTK_CENTURY, DTK_DAY, DTK_DECADE, DTK_HOUR, DTK_MICROSEC, DTK_MILLENNIUM, DTK_MILLISEC, DTK_MINUTE, DTK_MONTH, DTK_QUARTER, DTK_SECOND, DTK_WEEK, DTK_YEAR, ereport, errcode(), errmsg(), ERROR, format_type_be(), isoweek2date(), MONTHS_PER_YEAR, timestamp2tm(), tm, tm2timestamp(), pg_tm::tm_hour, pg_tm::tm_mday, pg_tm::tm_min, pg_tm::tm_mon, pg_tm::tm_sec, pg_tm::tm_year, type, UNITS, val, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by timestamptz_trunc(), and timestamptz_trunc_zone().

◆ timestamptz_trunc_zone()

Datum timestamptz_trunc_zone ( PG_FUNCTION_ARGS  )

Definition at line 4976 of file timestamp.c.

4977 {
4978  text *units = PG_GETARG_TEXT_PP(0);
4980  text *zone = PG_GETARG_TEXT_PP(2);
4981  TimestampTz result;
4982  pg_tz *tzp;
4983 
4984  /*
4985  * timestamptz_zone() doesn't look up the zone for infinite inputs, so we
4986  * don't do so here either.
4987  */
4990 
4991  /*
4992  * Look up the requested timezone.
4993  */
4994  tzp = lookup_timezone(zone);
4995 
4996  result = timestamptz_trunc_internal(units, timestamp, tzp);
4997 
4998  PG_RETURN_TIMESTAMPTZ(result);
4999 }

References lookup_timezone(), PG_GETARG_TEXT_PP, PG_GETARG_TIMESTAMPTZ, PG_RETURN_TIMESTAMP, PG_RETURN_TIMESTAMPTZ, TIMESTAMP_NOT_FINITE, and timestamptz_trunc_internal().

◆ timestamptz_zone()

Datum timestamptz_zone ( PG_FUNCTION_ARGS  )

Definition at line 6390 of file timestamp.c.

6391 {
6392  text *zone = PG_GETARG_TEXT_PP(0);
6394  Timestamp result;
6395  int tz;
6396  char tzname[TZ_STRLEN_MAX + 1];
6397  int type,
6398  val;
6399  pg_tz *tzp;
6400 
6403 
6404  /*
6405  * Look up the requested timezone.
6406  */
6407  text_to_cstring_buffer(zone, tzname, sizeof(tzname));
6408 
6409  type = DecodeTimezoneName(tzname, &val, &tzp);
6410 
6411  if (type == TZNAME_FIXED_OFFSET)
6412  {
6413  /* fixed-offset abbreviation */
6414  tz = -val;
6415  result = dt2local(timestamp, tz);
6416  }
6417  else if (type == TZNAME_DYNTZ)
6418  {
6419  /* dynamic-offset abbreviation, resolve using specified time */
6420  int isdst;
6421 
6422  tz = DetermineTimeZoneAbbrevOffsetTS(timestamp, tzname, tzp, &isdst);
6423  result = dt2local(timestamp, tz);
6424  }
6425  else
6426  {
6427  /* full zone name, rotate from that zone */
6428  struct pg_tm tm;
6429  fsec_t fsec;
6430 
6431  if (timestamp2tm(timestamp, &tz, &tm, &fsec, NULL, tzp) != 0)
6432  ereport(ERROR,
6433  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6434  errmsg("timestamp out of range")));
6435  if (tm2timestamp(&tm, fsec, NULL, &result) != 0)
6436  ereport(ERROR,
6437  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6438  errmsg("timestamp out of range")));
6439  }
6440 
6441  if (!IS_VALID_TIMESTAMP(result))
6442  ereport(ERROR,
6443  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6444  errmsg("timestamp out of range")));
6445 
6446  PG_RETURN_TIMESTAMP(result);
6447 }
int DetermineTimeZoneAbbrevOffsetTS(TimestampTz ts, const char *abbr, pg_tz *tzp, int *isdst)
Definition: datetime.c:1784

References DecodeTimezoneName(), DetermineTimeZoneAbbrevOffsetTS(), dt2local(), ereport, errcode(), errmsg(), ERROR, IS_VALID_TIMESTAMP, PG_GETARG_TEXT_PP, PG_GETARG_TIMESTAMPTZ, PG_RETURN_TIMESTAMP, text_to_cstring_buffer(), timestamp2tm(), TIMESTAMP_NOT_FINITE, tm, tm2timestamp(), type, TZ_STRLEN_MAX, TZNAME_DYNTZ, TZNAME_FIXED_OFFSET, and val.

◆ timestamptztypmodin()

Datum timestamptztypmodin ( PG_FUNCTION_ARGS  )

Definition at line 858 of file timestamp.c.

859 {
861 
863 }

References anytimestamp_typmodin(), PG_GETARG_ARRAYTYPE_P, and PG_RETURN_INT32.

◆ timestamptztypmodout()

Datum timestamptztypmodout ( PG_FUNCTION_ARGS  )

Definition at line 866 of file timestamp.c.

867 {
868  int32 typmod = PG_GETARG_INT32(0);
869 
871 }

References anytimestamp_typmodout(), PG_GETARG_INT32, and PG_RETURN_CSTRING.

◆ tm2timestamp()

int tm2timestamp ( struct pg_tm tm,
fsec_t  fsec,
int *  tzp,
Timestamp result 
)

Definition at line 1997 of file timestamp.c.

1998 {
1999  TimeOffset date;
2000  TimeOffset time;
2001 
2002  /* Prevent overflow in Julian-day routines */
2004  {
2005  *result = 0; /* keep compiler quiet */
2006  return -1;
2007  }
2008 
2010  time = time2t(tm->tm_hour, tm->tm_min, tm->tm_sec, fsec);
2011 
2012  *result = date * USECS_PER_DAY + time;
2013  /* check for major overflow */
2014  if ((*result - time) / USECS_PER_DAY != date)
2015  {
2016  *result = 0; /* keep compiler quiet */
2017  return -1;
2018  }
2019  /* check for just-barely overflow (okay except time-of-day wraps) */
2020  /* caution: we want to allow 1999-12-31 24:00:00 */
2021  if ((*result < 0 && date > 0) ||
2022  (*result > 0 && date < -1))
2023  {
2024  *result = 0; /* keep compiler quiet */
2025  return -1;
2026  }
2027  if (tzp != NULL)
2028  *result = dt2local(*result, -(*tzp));
2029 
2030  /* final range check catches just-out-of-range timestamps */
2031  if (!IS_VALID_TIMESTAMP(*result))
2032  {
2033  *result = 0; /* keep compiler quiet */
2034  return -1;
2035  }
2036 
2037  return 0;
2038 }
static TimeOffset time2t(const int hour, const int min, const int sec, const fsec_t fsec)
Definition: timestamp.c:2128

References date2j(), dt2local(), IS_VALID_JULIAN, IS_VALID_TIMESTAMP, POSTGRES_EPOCH_JDATE, time2t(), tm, pg_tm::tm_hour, pg_tm::tm_mday, pg_tm::tm_min, pg_tm::tm_mon, pg_tm::tm_sec, pg_tm::tm_year, and USECS_PER_DAY.

Referenced by check_recovery_target_time(), parse_datetime(), PGTYPEStimestamp_add_interval(), PGTYPEStimestamp_current(), PGTYPEStimestamp_defmt_scan(), PGTYPEStimestamp_from_asc(), SetEpochTimestamp(), timestamp_in(), timestamp_pl_interval(), timestamp_trunc(), timestamp_zone(), timestamptz2timestamp(), timestamptz_in(), timestamptz_pl_interval_internal(), timestamptz_trunc_internal(), timestamptz_zone(), and to_timestamp().

Variable Documentation

◆ PgReloadTime

TimestampTz PgReloadTime

Definition at line 55 of file timestamp.c.

Referenced by pg_conf_load_time(), and ProcessConfigFileInternal().

◆ PgStartTime

TimestampTz PgStartTime

Definition at line 52 of file timestamp.c.

Referenced by pg_postmaster_start_time(), PostgresSingleUserMain(), and PostmasterMain().