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:857
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#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 5167 of file timestamp.c.

5168 {
5169  float8 result;
5170  int day0,
5171  day4,
5172  dayn;
5173 
5174  /* current day */
5175  dayn = date2j(year, mon, mday);
5176 
5177  /* fourth day of current year */
5178  day4 = date2j(year, 1, 4);
5179 
5180  /* day0 == offset to first day of week (Monday) */
5181  day0 = j2day(day4 - 1);
5182 
5183  /*
5184  * We need the first week containing a Thursday, otherwise this day falls
5185  * into the previous year for purposes of counting weeks
5186  */
5187  if (dayn < day4 - day0)
5188  {
5189  day4 = date2j(year - 1, 1, 4);
5190 
5191  /* day0 == offset to first day of week (Monday) */
5192  day0 = j2day(day4 - 1);
5193  }
5194 
5195  result = (dayn - (day4 - day0)) / 7 + 1;
5196 
5197  /*
5198  * Sometimes the last few days in a year will fall into the first week of
5199  * the next year, so check for this.
5200  */
5201  if (result >= 52)
5202  {
5203  day4 = date2j(year + 1, 1, 4);
5204 
5205  /* day0 == offset to first day of week (Monday) */
5206  day0 = j2day(day4 - 1);
5207 
5208  if (dayn >= day4 - day0)
5209  result = (dayn - (day4 - day0)) / 7 + 1;
5210  }
5211 
5212  return (int) result;
5213 }
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 5222 of file timestamp.c.

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

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 5279 of file timestamp.c.

5280 {
5281  return date2j(year, mon, mday) - isoweek2j(date2isoyear(year, mon, mday), 1) + 1;
5282 }
int isoweek2j(int year, int week)
Definition: timestamp.c:5116
int date2isoyear(int year, int mon, int mday)
Definition: timestamp.c:5222

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 3948 of file timestamp.c.

3949 {
3950  /* Infinite inputs are counted separately, and do not affect "N" */
3952  {
3953  state->nInfcount++;
3954  return;
3955  }
3956 
3958  {
3959  state->pInfcount++;
3960  return;
3961  }
3962 
3963  finite_interval_pl(&state->sumX, newval, &state->sumX);
3964  state->N++;
3965 }
static void finite_interval_pl(const Interval *span1, const Interval *span2, Interval *result)
Definition: timestamp.c:3447
#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 3971 of file timestamp.c.

3972 {
3973  /* Infinite inputs are counted separately, and do not affect "N" */
3975  {
3976  state->nInfcount--;
3977  return;
3978  }
3979 
3981  {
3982  state->pInfcount--;
3983  return;
3984  }
3985 
3986  /* Handle the to-be-discarded finite value. */
3987  state->N--;
3988  if (state->N > 0)
3989  finite_interval_mi(&state->sumX, newval, &state->sumX);
3990  else
3991  {
3992  /* All values discarded, reset the state */
3993  Assert(state->N == 0);
3994  memset(&state->sumX, 0, sizeof(state->sumX));
3995  }
3996 }
static void finite_interval_mi(const Interval *span1, const Interval *span2, Interval *result)
Definition: timestamp.c:3503
#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 6149 of file timestamp.c.

6150 {
6151  return interval_part_common(fcinfo, true);
6152 }
static Datum interval_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition: timestamp.c:5951

References interval_part_common().

◆ extract_timestamp()

Datum extract_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 5617 of file timestamp.c.

5618 {
5619  return timestamp_part_common(fcinfo, true);
5620 }
static Datum timestamp_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition: timestamp.c:5353

References timestamp_part_common().

◆ extract_timestamptz()

Datum extract_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 5889 of file timestamp.c.

5890 {
5891  return timestamptz_part_common(fcinfo, true);
5892 }
static Datum timestamptz_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition: timestamp.c:5626

References timestamptz_part_common().

◆ finite_interval_mi()

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

Definition at line 3503 of file timestamp.c.

3504 {
3505  Assert(!INTERVAL_NOT_FINITE(span1));
3506  Assert(!INTERVAL_NOT_FINITE(span2));
3507 
3508  if (pg_sub_s32_overflow(span1->month, span2->month, &result->month) ||
3509  pg_sub_s32_overflow(span1->day, span2->day, &result->day) ||
3510  pg_sub_s64_overflow(span1->time, span2->time, &result->time) ||
3511  INTERVAL_NOT_FINITE(result))
3512  ereport(ERROR,
3513  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3514  errmsg("interval out of range")));
3515 }
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 3447 of file timestamp.c.

3448 {
3449  Assert(!INTERVAL_NOT_FINITE(span1));
3450  Assert(!INTERVAL_NOT_FINITE(span2));
3451 
3452  if (pg_add_s32_overflow(span1->month, span2->month, &result->month) ||
3453  pg_add_s32_overflow(span1->day, span2->day, &result->day) ||
3454  pg_add_s64_overflow(span1->time, span2->time, &result->time) ||
3455  INTERVAL_NOT_FINITE(result))
3456  ereport(ERROR,
3457  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3458  errmsg("interval out of range")));
3459 }
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 6506 of file timestamp.c.

6507 {
6508  FuncCallContext *funcctx;
6510  Timestamp result;
6511 
6512  /* stuff done only on the first call of the function */
6513  if (SRF_IS_FIRSTCALL())
6514  {
6516  Timestamp finish = PG_GETARG_TIMESTAMP(1);
6517  Interval *step = PG_GETARG_INTERVAL_P(2);
6518  MemoryContext oldcontext;
6519 
6520  /* create a function context for cross-call persistence */
6521  funcctx = SRF_FIRSTCALL_INIT();
6522 
6523  /*
6524  * switch to memory context appropriate for multiple function calls
6525  */
6526  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
6527 
6528  /* allocate memory for user context */
6531 
6532  /*
6533  * Use fctx to keep state from call to call. Seed current with the
6534  * original start value
6535  */
6536  fctx->current = start;
6537  fctx->finish = finish;
6538  fctx->step = *step;
6539 
6540  /* Determine sign of the interval */
6541  fctx->step_sign = interval_sign(&fctx->step);
6542 
6543  if (fctx->step_sign == 0)
6544  ereport(ERROR,
6545  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6546  errmsg("step size cannot equal zero")));
6547 
6548  if (INTERVAL_NOT_FINITE((&fctx->step)))
6549  ereport(ERROR,
6550  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6551  errmsg("step size cannot be infinite")));
6552 
6553  funcctx->user_fctx = fctx;
6554  MemoryContextSwitchTo(oldcontext);
6555  }
6556 
6557  /* stuff done on every call of the function */
6558  funcctx = SRF_PERCALL_SETUP();
6559 
6560  /*
6561  * get the saved state and use current as the result for this iteration
6562  */
6563  fctx = funcctx->user_fctx;
6564  result = fctx->current;
6565 
6566  if (fctx->step_sign > 0 ?
6567  timestamp_cmp_internal(result, fctx->finish) <= 0 :
6568  timestamp_cmp_internal(result, fctx->finish) >= 0)
6569  {
6570  /* increment current in preparation for next iteration */
6572  TimestampGetDatum(fctx->current),
6573  PointerGetDatum(&fctx->step)));
6574 
6575  /* do when there is more left to send */
6576  SRF_RETURN_NEXT(funcctx, TimestampGetDatum(result));
6577  }
6578  else
6579  {
6580  /* do when there is no more left */
6581  SRF_RETURN_DONE(funcctx);
6582  }
6583 }
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 6672 of file timestamp.c.

6673 {
6674  return generate_series_timestamptz_internal(fcinfo);
6675 }
static Datum generate_series_timestamptz_internal(FunctionCallInfo fcinfo)
Definition: timestamp.c:6590

References generate_series_timestamptz_internal().

◆ generate_series_timestamptz_at_zone()

Datum generate_series_timestamptz_at_zone ( PG_FUNCTION_ARGS  )

Definition at line 6678 of file timestamp.c.

6679 {
6680  return generate_series_timestamptz_internal(fcinfo);
6681 }

References generate_series_timestamptz_internal().

◆ generate_series_timestamptz_internal()

static Datum generate_series_timestamptz_internal ( FunctionCallInfo  fcinfo)
static

Definition at line 6590 of file timestamp.c.

6591 {
6592  FuncCallContext *funcctx;
6594  TimestampTz result;
6595 
6596  /* stuff done only on the first call of the function */
6597  if (SRF_IS_FIRSTCALL())
6598  {
6600  TimestampTz finish = PG_GETARG_TIMESTAMPTZ(1);
6601  Interval *step = PG_GETARG_INTERVAL_P(2);
6602  text *zone = (PG_NARGS() == 4) ? PG_GETARG_TEXT_PP(3) : NULL;
6603  MemoryContext oldcontext;
6604 
6605  /* create a function context for cross-call persistence */
6606  funcctx = SRF_FIRSTCALL_INIT();
6607 
6608  /*
6609  * switch to memory context appropriate for multiple function calls
6610  */
6611  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
6612 
6613  /* allocate memory for user context */
6616 
6617  /*
6618  * Use fctx to keep state from call to call. Seed current with the
6619  * original start value
6620  */
6621  fctx->current = start;
6622  fctx->finish = finish;
6623  fctx->step = *step;
6625 
6626  /* Determine sign of the interval */
6627  fctx->step_sign = interval_sign(&fctx->step);
6628 
6629  if (fctx->step_sign == 0)
6630  ereport(ERROR,
6631  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6632  errmsg("step size cannot equal zero")));
6633 
6634  if (INTERVAL_NOT_FINITE((&fctx->step)))
6635  ereport(ERROR,
6636  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6637  errmsg("step size cannot be infinite")));
6638 
6639  funcctx->user_fctx = fctx;
6640  MemoryContextSwitchTo(oldcontext);
6641  }
6642 
6643  /* stuff done on every call of the function */
6644  funcctx = SRF_PERCALL_SETUP();
6645 
6646  /*
6647  * get the saved state and use current as the result for this iteration
6648  */
6649  fctx = funcctx->user_fctx;
6650  result = fctx->current;
6651 
6652  if (fctx->step_sign > 0 ?
6653  timestamp_cmp_internal(result, fctx->finish) <= 0 :
6654  timestamp_cmp_internal(result, fctx->finish) >= 0)
6655  {
6656  /* increment current in preparation for next iteration */
6658  &fctx->step,
6659  fctx->attimezone);
6660 
6661  /* do when there is more left to send */
6662  SRF_RETURN_NEXT(funcctx, TimestampTzGetDatum(result));
6663  }
6664  else
6665  {
6666  /* do when there is no more left */
6667  SRF_RETURN_DONE(funcctx);
6668  }
6669 }
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:3192
#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:6373

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

Referenced by ExecEvalSQLValueFunction().

◆ in_range_interval_interval()

Datum in_range_interval_interval ( PG_FUNCTION_ARGS  )

Definition at line 3876 of file timestamp.c.

3877 {
3879  Interval *base = PG_GETARG_INTERVAL_P(1);
3880  Interval *offset = PG_GETARG_INTERVAL_P(2);
3881  bool sub = PG_GETARG_BOOL(3);
3882  bool less = PG_GETARG_BOOL(4);
3883  Interval *sum;
3884 
3885  if (interval_sign(offset) < 0)
3886  ereport(ERROR,
3887  (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
3888  errmsg("invalid preceding or following size in window function")));
3889 
3890  /*
3891  * Deal with cases where both base and offset are infinite, and computing
3892  * base +/- offset would cause an error. As for float and numeric types,
3893  * we assume that all values infinitely precede +infinity and infinitely
3894  * follow -infinity. See in_range_float8_float8() for reasoning.
3895  */
3896  if (INTERVAL_IS_NOEND(offset) &&
3897  (sub ? INTERVAL_IS_NOEND(base) : INTERVAL_IS_NOBEGIN(base)))
3898  PG_RETURN_BOOL(true);
3899 
3900  /* We don't currently bother to avoid overflow hazards here */
3901  if (sub)
3903  IntervalPGetDatum(base),
3904  IntervalPGetDatum(offset)));
3905  else
3907  IntervalPGetDatum(base),
3908  IntervalPGetDatum(offset)));
3909 
3910  if (less)
3912  else
3914 }
Datum interval_mi(PG_FUNCTION_ARGS)
Definition: timestamp.c:3518
Datum interval_pl(PG_FUNCTION_ARGS)
Definition: timestamp.c:3462
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 3835 of file timestamp.c.

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

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 3798 of file timestamp.c.

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

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 4167 of file timestamp.c.

4168 {
4170 
4172 
4173  /* If there were no non-null inputs, return NULL */
4174  if (state == NULL || IA_TOTAL_COUNT(state) == 0)
4175  PG_RETURN_NULL();
4176 
4177  /*
4178  * Aggregating infinities that all have the same sign produces infinity
4179  * with that sign. Aggregating infinities with different signs results in
4180  * an error.
4181  */
4182  if (state->pInfcount > 0 || state->nInfcount > 0)
4183  {
4184  Interval *result;
4185 
4186  if (state->pInfcount > 0 && state->nInfcount > 0)
4187  ereport(ERROR,
4188  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4189  errmsg("interval out of range.")));
4190 
4191  result = (Interval *) palloc(sizeof(Interval));
4192  if (state->pInfcount > 0)
4193  INTERVAL_NOEND(result);
4194  else
4195  INTERVAL_NOBEGIN(result);
4196 
4197  PG_RETURN_INTERVAL_P(result);
4198  }
4199 
4201  IntervalPGetDatum(&state->sumX),
4202  Float8GetDatum((double) state->N));
4203 }
#define IA_TOTAL_COUNT(ia)
Definition: timestamp.c:87
Datum interval_div(PG_FUNCTION_ARGS)
Definition: timestamp.c:3697
#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 4002 of file timestamp.c.

4003 {
4005 
4007 
4008  /* Create the state data on the first call */
4009  if (state == NULL)
4010  state = makeIntervalAggState(fcinfo);
4011 
4012  if (!PG_ARGISNULL(1))
4014 
4016 }
static IntervalAggState * makeIntervalAggState(FunctionCallInfo fcinfo)
Definition: timestamp.c:3926
static void do_interval_accum(IntervalAggState *state, Interval *newval)
Definition: timestamp.c:3948
#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 4149 of file timestamp.c.

4150 {
4152 
4154 
4155  /* Should not get here with no state */
4156  if (state == NULL)
4157  elog(ERROR, "interval_avg_accum_inv called with NULL state");
4158 
4159  if (!PG_ARGISNULL(1))
4161 
4163 }
static void do_interval_discard(IntervalAggState *state, Interval *newval)
Definition: timestamp.c:3971

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 4025 of file timestamp.c.

4026 {
4027  IntervalAggState *state1;
4028  IntervalAggState *state2;
4029 
4030  state1 = PG_ARGISNULL(0) ? NULL : (IntervalAggState *) PG_GETARG_POINTER(0);
4031  state2 = PG_ARGISNULL(1) ? NULL : (IntervalAggState *) PG_GETARG_POINTER(1);
4032 
4033  if (state2 == NULL)
4034  PG_RETURN_POINTER(state1);
4035 
4036  if (state1 == NULL)
4037  {
4038  /* manually copy all fields from state2 to state1 */
4039  state1 = makeIntervalAggState(fcinfo);
4040 
4041  state1->N = state2->N;
4042  state1->pInfcount = state2->pInfcount;
4043  state1->nInfcount = state2->nInfcount;
4044 
4045  state1->sumX.day = state2->sumX.day;
4046  state1->sumX.month = state2->sumX.month;
4047  state1->sumX.time = state2->sumX.time;
4048 
4049  PG_RETURN_POINTER(state1);
4050  }
4051 
4052  state1->N += state2->N;
4053  state1->pInfcount += state2->pInfcount;
4054  state1->nInfcount += state2->nInfcount;
4055 
4056  /* Accumulate finite interval values, if any. */
4057  if (state2->N > 0)
4058  finite_interval_pl(&state1->sumX, &state2->sumX, &state1->sumX);
4059 
4060  PG_RETURN_POINTER(state1);
4061 }
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 4106 of file timestamp.c.

4107 {
4108  bytea *sstate;
4109  IntervalAggState *result;
4111 
4112  if (!AggCheckCallContext(fcinfo, NULL))
4113  elog(ERROR, "aggregate function called in non-aggregate context");
4114 
4115  sstate = PG_GETARG_BYTEA_PP(0);
4116 
4117  /*
4118  * Initialize a StringInfo so that we can "receive" it using the standard
4119  * recv-function infrastructure.
4120  */
4122  VARSIZE_ANY_EXHDR(sstate));
4123 
4124  result = (IntervalAggState *) palloc0(sizeof(IntervalAggState));
4125 
4126  /* N */
4127  result->N = pq_getmsgint64(&buf);
4128 
4129  /* sumX */
4130  result->sumX.time = pq_getmsgint64(&buf);
4131  result->sumX.day = pq_getmsgint(&buf, 4);
4132  result->sumX.month = pq_getmsgint(&buf, 4);
4133 
4134  /* pInfcount */
4135  result->pInfcount = pq_getmsgint64(&buf);
4136 
4137  /* nInfcount */
4138  result->nInfcount = pq_getmsgint64(&buf);
4139 
4140  pq_getmsgend(&buf);
4141 
4142  PG_RETURN_POINTER(result);
4143 }
#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 4068 of file timestamp.c.

4069 {
4072  bytea *result;
4073 
4074  /* Ensure we disallow calling when not in aggregate context */
4075  if (!AggCheckCallContext(fcinfo, NULL))
4076  elog(ERROR, "aggregate function called in non-aggregate context");
4077 
4079 
4080  pq_begintypsend(&buf);
4081 
4082  /* N */
4083  pq_sendint64(&buf, state->N);
4084 
4085  /* sumX */
4086  pq_sendint64(&buf, state->sumX.time);
4087  pq_sendint32(&buf, state->sumX.day);
4088  pq_sendint32(&buf, state->sumX.month);
4089 
4090  /* pInfcount */
4091  pq_sendint64(&buf, state->pInfcount);
4092 
4093  /* nInfcount */
4094  pq_sendint64(&buf, state->nInfcount);
4095 
4096  result = pq_endtypsend(&buf);
4097 
4098  PG_RETURN_BYTEA_P(result);
4099 }
#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 3697 of file timestamp.c.

3698 {
3699  Interval *span = PG_GETARG_INTERVAL_P(0);
3700  float8 factor = PG_GETARG_FLOAT8(1);
3701  double month_remainder_days,
3702  sec_remainder,
3703  result_double;
3704  int32 orig_month = span->month,
3705  orig_day = span->day;
3706  Interval *result;
3707 
3708  result = (Interval *) palloc(sizeof(Interval));
3709 
3710  if (factor == 0.0)
3711  ereport(ERROR,
3712  (errcode(ERRCODE_DIVISION_BY_ZERO),
3713  errmsg("division by zero")));
3714 
3715  /*
3716  * Handle NaN and infinities.
3717  *
3718  * We treat "infinity / infinity" as an error, since the interval type has
3719  * nothing equivalent to NaN. Otherwise, dividing by infinity is handled
3720  * by the regular division code, causing all fields to be set to zero.
3721  */
3722  if (isnan(factor))
3723  goto out_of_range;
3724 
3725  if (INTERVAL_NOT_FINITE(span))
3726  {
3727  if (isinf(factor))
3728  goto out_of_range;
3729 
3730  if (factor < 0.0)
3731  interval_um_internal(span, result);
3732  else
3733  memcpy(result, span, sizeof(Interval));
3734 
3735  PG_RETURN_INTERVAL_P(result);
3736  }
3737 
3738  result_double = span->month / factor;
3739  if (isnan(result_double) || !FLOAT8_FITS_IN_INT32(result_double))
3740  goto out_of_range;
3741  result->month = (int32) result_double;
3742 
3743  result_double = span->day / factor;
3744  if (isnan(result_double) || !FLOAT8_FITS_IN_INT32(result_double))
3745  goto out_of_range;
3746  result->day = (int32) result_double;
3747 
3748  /*
3749  * Fractional months full days into days. See comment in interval_mul().
3750  */
3751  month_remainder_days = (orig_month / factor - result->month) * DAYS_PER_MONTH;
3752  month_remainder_days = TSROUND(month_remainder_days);
3753  sec_remainder = (orig_day / factor - result->day +
3754  month_remainder_days - (int) month_remainder_days) * SECS_PER_DAY;
3755  sec_remainder = TSROUND(sec_remainder);
3756  if (fabs(sec_remainder) >= SECS_PER_DAY)
3757  {
3758  if (pg_add_s32_overflow(result->day,
3759  (int) (sec_remainder / SECS_PER_DAY),
3760  &result->day))
3761  goto out_of_range;
3762  sec_remainder -= (int) (sec_remainder / SECS_PER_DAY) * SECS_PER_DAY;
3763  }
3764 
3765  /* cascade units down */
3766  if (pg_add_s32_overflow(result->day, (int32) month_remainder_days,
3767  &result->day))
3768  goto out_of_range;
3769  result_double = rint(span->time / factor + sec_remainder * USECS_PER_SEC);
3770  if (isnan(result_double) || !FLOAT8_FITS_IN_INT64(result_double))
3771  goto out_of_range;
3772  result->time = (int64) result_double;
3773 
3774  if (INTERVAL_NOT_FINITE(result))
3775  goto out_of_range;
3776 
3777  PG_RETURN_INTERVAL_P(result);
3778 
3779 out_of_range:
3780  ereport(ERROR,
3781  errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3782  errmsg("interval out of range"));
3783 
3784  PG_RETURN_NULL(); /* keep compiler quiet */
3785 }
static void interval_um_internal(const Interval *interval, Interval *result)
Definition: timestamp.c:3385
#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:4092
int DecodeInterval(char **field, int *ftype, int nf, int range, int *dtype, struct pg_itm_in *itm_in)
Definition: datetime.c:3364
int DecodeISO8601Interval(char *str, int *dtype, struct pg_itm_in *itm_in)
Definition: datetime.c:3829
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 3433 of file timestamp.c.

3434 {
3435  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
3436  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
3437  Interval *result;
3438 
3439  if (interval_cmp_internal(interval1, interval2) > 0)
3440  result = interval1;
3441  else
3442  result = interval2;
3443  PG_RETURN_INTERVAL_P(result);
3444 }

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 3518 of file timestamp.c.

3519 {
3520  Interval *span1 = PG_GETARG_INTERVAL_P(0);
3521  Interval *span2 = PG_GETARG_INTERVAL_P(1);
3522  Interval *result;
3523 
3524  result = (Interval *) palloc(sizeof(Interval));
3525 
3526  /*
3527  * Handle infinities.
3528  *
3529  * We treat anything that amounts to "infinity - infinity" as an error,
3530  * since the interval type has nothing equivalent to NaN.
3531  */
3532  if (INTERVAL_IS_NOBEGIN(span1))
3533  {
3534  if (INTERVAL_IS_NOBEGIN(span2))
3535  ereport(ERROR,
3536  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3537  errmsg("interval out of range")));
3538  else
3539  INTERVAL_NOBEGIN(result);
3540  }
3541  else if (INTERVAL_IS_NOEND(span1))
3542  {
3543  if (INTERVAL_IS_NOEND(span2))
3544  ereport(ERROR,
3545  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3546  errmsg("interval out of range")));
3547  else
3548  INTERVAL_NOEND(result);
3549  }
3550  else if (INTERVAL_IS_NOBEGIN(span2))
3551  INTERVAL_NOEND(result);
3552  else if (INTERVAL_IS_NOEND(span2))
3553  INTERVAL_NOBEGIN(result);
3554  else
3555  finite_interval_mi(span1, span2, result);
3556 
3557  PG_RETURN_INTERVAL_P(result);
3558 }

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 3567 of file timestamp.c.

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

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:4585
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 6143 of file timestamp.c.

6144 {
6145  return interval_part_common(fcinfo, false);
6146 }

References interval_part_common().

◆ interval_part_common()

static Datum interval_part_common ( PG_FUNCTION_ARGS  ,
bool  retnumeric 
)
static

Definition at line 5951 of file timestamp.c.

5952 {
5953  text *units = PG_GETARG_TEXT_PP(0);
5955  int64 intresult;
5956  int type,
5957  val;
5958  char *lowunits;
5959  struct pg_itm tt,
5960  *tm = &tt;
5961 
5962  lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
5963  VARSIZE_ANY_EXHDR(units),
5964  false);
5965 
5966  type = DecodeUnits(0, lowunits, &val);
5967  if (type == UNKNOWN_FIELD)
5968  type = DecodeSpecial(0, lowunits, &val);
5969 
5971  {
5972  double r = NonFiniteIntervalPart(type, val, lowunits,
5974 
5975  if (r != 0.0)
5976  {
5977  if (retnumeric)
5978  {
5979  if (r < 0)
5981  CStringGetDatum("-Infinity"),
5983  Int32GetDatum(-1));
5984  else if (r > 0)
5986  CStringGetDatum("Infinity"),
5988  Int32GetDatum(-1));
5989  }
5990  else
5991  PG_RETURN_FLOAT8(r);
5992  }
5993  else
5994  PG_RETURN_NULL();
5995  }
5996 
5997  if (type == UNITS)
5998  {
6000  switch (val)
6001  {
6002  case DTK_MICROSEC:
6003  intresult = tm->tm_sec * INT64CONST(1000000) + tm->tm_usec;
6004  break;
6005 
6006  case DTK_MILLISEC:
6007  if (retnumeric)
6008  /*---
6009  * tm->tm_sec * 1000 + fsec / 1000
6010  * = (tm->tm_sec * 1'000'000 + fsec) / 1000
6011  */
6012  PG_RETURN_NUMERIC(int64_div_fast_to_numeric(tm->tm_sec * INT64CONST(1000000) + tm->tm_usec, 3));
6013  else
6014  PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + tm->tm_usec / 1000.0);
6015  break;
6016 
6017  case DTK_SECOND:
6018  if (retnumeric)
6019  /*---
6020  * tm->tm_sec + fsec / 1'000'000
6021  * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
6022  */
6023  PG_RETURN_NUMERIC(int64_div_fast_to_numeric(tm->tm_sec * INT64CONST(1000000) + tm->tm_usec, 6));
6024  else
6025  PG_RETURN_FLOAT8(tm->tm_sec + tm->tm_usec / 1000000.0);
6026  break;
6027 
6028  case DTK_MINUTE:
6029  intresult = tm->tm_min;
6030  break;
6031 
6032  case DTK_HOUR:
6033  intresult = tm->tm_hour;
6034  break;
6035 
6036  case DTK_DAY:
6037  intresult = tm->tm_mday;
6038  break;
6039 
6040  case DTK_MONTH:
6041  intresult = tm->tm_mon;
6042  break;
6043 
6044  case DTK_QUARTER:
6045  intresult = (tm->tm_mon / 3) + 1;
6046  break;
6047 
6048  case DTK_YEAR:
6049  intresult = tm->tm_year;
6050  break;
6051 
6052  case DTK_DECADE:
6053  /* caution: C division may have negative remainder */
6054  intresult = tm->tm_year / 10;
6055  break;
6056 
6057  case DTK_CENTURY:
6058  /* caution: C division may have negative remainder */
6059  intresult = tm->tm_year / 100;
6060  break;
6061 
6062  case DTK_MILLENNIUM:
6063  /* caution: C division may have negative remainder */
6064  intresult = tm->tm_year / 1000;
6065  break;
6066 
6067  default:
6068  ereport(ERROR,
6069  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6070  errmsg("unit \"%s\" not supported for type %s",
6071  lowunits, format_type_be(INTERVALOID))));
6072  intresult = 0;
6073  }
6074  }
6075  else if (type == RESERV && val == DTK_EPOCH)
6076  {
6077  if (retnumeric)
6078  {
6079  Numeric result;
6080  int64 secs_from_day_month;
6081  int64 val;
6082 
6083  /*
6084  * To do this calculation in integer arithmetic even though
6085  * DAYS_PER_YEAR is fractional, multiply everything by 4 and then
6086  * divide by 4 again at the end. This relies on DAYS_PER_YEAR
6087  * being a multiple of 0.25 and on SECS_PER_DAY being a multiple
6088  * of 4.
6089  */
6090  secs_from_day_month = ((int64) (4 * DAYS_PER_YEAR) * (interval->month / MONTHS_PER_YEAR) +
6091  (int64) (4 * DAYS_PER_MONTH) * (interval->month % MONTHS_PER_YEAR) +
6092  (int64) 4 * interval->day) * (SECS_PER_DAY / 4);
6093 
6094  /*---
6095  * result = secs_from_day_month + interval->time / 1'000'000
6096  * = (secs_from_day_month * 1'000'000 + interval->time) / 1'000'000
6097  */
6098 
6099  /*
6100  * Try the computation inside int64; if it overflows, do it in
6101  * numeric (slower). This overflow happens around 10^9 days, so
6102  * not common in practice.
6103  */
6104  if (!pg_mul_s64_overflow(secs_from_day_month, 1000000, &val) &&
6106  result = int64_div_fast_to_numeric(val, 6);
6107  else
6108  result =
6110  int64_to_numeric(secs_from_day_month),
6111  NULL);
6112 
6113  PG_RETURN_NUMERIC(result);
6114  }
6115  else
6116  {
6117  float8 result;
6118 
6119  result = interval->time / 1000000.0;
6120  result += ((double) DAYS_PER_YEAR * SECS_PER_DAY) * (interval->month / MONTHS_PER_YEAR);
6121  result += ((double) DAYS_PER_MONTH * SECS_PER_DAY) * (interval->month % MONTHS_PER_YEAR);
6122  result += ((double) SECS_PER_DAY) * interval->day;
6123 
6124  PG_RETURN_FLOAT8(result);
6125  }
6126  }
6127  else
6128  {
6129  ereport(ERROR,
6130  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6131  errmsg("unit \"%s\" not recognized for type %s",
6132  lowunits, format_type_be(INTERVALOID))));
6133  intresult = 0;
6134  }
6135 
6136  if (retnumeric)
6137  PG_RETURN_NUMERIC(int64_to_numeric(intresult));
6138  else
6139  PG_RETURN_FLOAT8(intresult);
6140 }
int DecodeUnits(int field, const char *lowtoken, int *val)
Definition: datetime.c:4047
int DecodeSpecial(int field, const char *lowtoken, int *val)
Definition: datetime.c:3148
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:5906
#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 3462 of file timestamp.c.

3463 {
3464  Interval *span1 = PG_GETARG_INTERVAL_P(0);
3465  Interval *span2 = PG_GETARG_INTERVAL_P(1);
3466  Interval *result;
3467 
3468  result = (Interval *) palloc(sizeof(Interval));
3469 
3470  /*
3471  * Handle infinities.
3472  *
3473  * We treat anything that amounts to "infinity - infinity" as an error,
3474  * since the interval type has nothing equivalent to NaN.
3475  */
3476  if (INTERVAL_IS_NOBEGIN(span1))
3477  {
3478  if (INTERVAL_IS_NOEND(span2))
3479  ereport(ERROR,
3480  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3481  errmsg("interval out of range")));
3482  else
3483  INTERVAL_NOBEGIN(result);
3484  }
3485  else if (INTERVAL_IS_NOEND(span1))
3486  {
3487  if (INTERVAL_IS_NOBEGIN(span2))
3488  ereport(ERROR,
3489  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3490  errmsg("interval out of range")));
3491  else
3492  INTERVAL_NOEND(result);
3493  }
3494  else if (INTERVAL_NOT_FINITE(span2))
3495  memcpy(result, span2, sizeof(Interval));
3496  else
3497  finite_interval_pl(span1, span2, result);
3498 
3499  PG_RETURN_INTERVAL_P(result);
3500 }

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 3418 of file timestamp.c.

3419 {
3420  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
3421  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
3422  Interval *result;
3423 
3424  /* use interval_cmp_internal to be sure this agrees with comparisons */
3425  if (interval_cmp_internal(interval1, interval2) < 0)
3426  result = interval1;
3427  else
3428  result = interval2;
3429  PG_RETURN_INTERVAL_P(result);
3430 }

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_INTERVAL_P.

◆ interval_sum()

Datum interval_sum ( PG_FUNCTION_ARGS  )

Definition at line 4207 of file timestamp.c.

4208 {
4210  Interval *result;
4211 
4213 
4214  /* If there were no non-null inputs, return NULL */
4215  if (state == NULL || IA_TOTAL_COUNT(state) == 0)
4216  PG_RETURN_NULL();
4217 
4218  /*
4219  * Aggregating infinities that all have the same sign produces infinity
4220  * with that sign. Aggregating infinities with different signs results in
4221  * an error.
4222  */
4223  if (state->pInfcount > 0 && state->nInfcount > 0)
4224  ereport(ERROR,
4225  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4226  errmsg("interval out of range.")));
4227 
4228  result = (Interval *) palloc(sizeof(Interval));
4229 
4230  if (state->pInfcount > 0)
4231  INTERVAL_NOEND(result);
4232  else if (state->nInfcount > 0)
4233  INTERVAL_NOBEGIN(result);
4234  else
4235  memcpy(result, &state->sumX, sizeof(Interval));
4236 
4237  PG_RETURN_INTERVAL_P(result);
4238 }

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:768

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 5017 of file timestamp.c.

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

3406 {
3408  Interval *result;
3409 
3410  result = (Interval *) palloc(sizeof(Interval));
3411  interval_um_internal(interval, result);
3412 
3413  PG_RETURN_INTERVAL_P(result);
3414 }

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 3385 of file timestamp.c.

3386 {
3388  INTERVAL_NOEND(result);
3389  else if (INTERVAL_IS_NOEND(interval))
3390  INTERVAL_NOBEGIN(result);
3391  else
3392  {
3393  /* Negate each field, guarding against overflow */
3394  if (pg_sub_s64_overflow(INT64CONST(0), interval->time, &result->time) ||
3395  pg_sub_s32_overflow(0, interval->day, &result->day) ||
3396  pg_sub_s32_overflow(0, interval->month, &result->month) ||
3397  INTERVAL_NOT_FINITE(result))
3398  ereport(ERROR,
3399  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3400  errmsg("interval out of range")));
3401  }
3402 }

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 5136 of file timestamp.c.

5137 {
5138  j2date(isoweek2j(*year, woy), year, mon, mday);
5139 }
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 5116 of file timestamp.c.

5117 {
5118  int day0,
5119  day4;
5120 
5121  /* fourth day of current year */
5122  day4 = date2j(year, 1, 4);
5123 
5124  /* day0 == offset to first day of week (Monday) */
5125  day0 = j2day(day4 - 1);
5126 
5127  return ((week - 1) * 7) + (day4 - day0);
5128 }

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 5149 of file timestamp.c.

5150 {
5151  int jday;
5152 
5153  jday = isoweek2j(*year, isoweek);
5154  /* convert Gregorian week start (Sunday=1) to ISO week start (Monday=1) */
5155  if (wday > 1)
5156  jday += wday - 2;
5157  else
5158  jday += 6;
5159  j2date(jday, year, mon, mday);
5160 }

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:3245
#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:2508
#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:6356

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 3926 of file timestamp.c.

3927 {
3929  MemoryContext agg_context;
3930  MemoryContext old_context;
3931 
3932  if (!AggCheckCallContext(fcinfo, &agg_context))
3933  elog(ERROR, "aggregate function called in non-aggregate context");
3934 
3935  old_context = MemoryContextSwitchTo(agg_context);
3936 
3938 
3939  MemoryContextSwitchTo(old_context);
3940 
3941  return state;
3942 }

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 3687 of file timestamp.c.

3688 {
3689  /* Args are float8 and Interval *, but leave them as generic Datum */
3690  Datum factor = PG_GETARG_DATUM(0);
3691  Datum span = PG_GETARG_DATUM(1);
3692 
3693  return DirectFunctionCall2(interval_mul, span, factor);
3694 }
Datum interval_mul(PG_FUNCTION_ARGS)
Definition: timestamp.c:3567

References DirectFunctionCall2, interval_mul(), and PG_GETARG_DATUM.

◆ NonFiniteIntervalPart()

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

Definition at line 5906 of file timestamp.c.

5907 {
5908  if ((type != UNITS) && (type != RESERV))
5909  ereport(ERROR,
5910  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5911  errmsg("unit \"%s\" not recognized for type %s",
5912  lowunits, format_type_be(INTERVALOID))));
5913 
5914  switch (unit)
5915  {
5916  /* Oscillating units */
5917  case DTK_MICROSEC:
5918  case DTK_MILLISEC:
5919  case DTK_SECOND:
5920  case DTK_MINUTE:
5921  case DTK_MONTH:
5922  case DTK_QUARTER:
5923  return 0.0;
5924 
5925  /* Monotonically-increasing units */
5926  case DTK_HOUR:
5927  case DTK_DAY:
5928  case DTK_YEAR:
5929  case DTK_DECADE:
5930  case DTK_CENTURY:
5931  case DTK_MILLENNIUM:
5932  case DTK_EPOCH:
5933  if (isNegative)
5934  return -get_float8_infinity();
5935  else
5936  return get_float8_infinity();
5937 
5938  default:
5939  ereport(ERROR,
5940  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5941  errmsg("unit \"%s\" not supported for type %s",
5942  lowunits, format_type_be(INTERVALOID))));
5943  return 0.0; /* keep compiler quiet */
5944  }
5945 }
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 5296 of file timestamp.c.

5298 {
5299  if ((type != UNITS) && (type != RESERV))
5300  ereport(ERROR,
5301  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5302  errmsg("unit \"%s\" not recognized for type %s",
5303  lowunits,
5304  format_type_be(isTz ? TIMESTAMPTZOID : TIMESTAMPOID))));
5305 
5306  switch (unit)
5307  {
5308  /* Oscillating units */
5309  case DTK_MICROSEC:
5310  case DTK_MILLISEC:
5311  case DTK_SECOND:
5312  case DTK_MINUTE:
5313  case DTK_HOUR:
5314  case DTK_DAY:
5315  case DTK_MONTH:
5316  case DTK_QUARTER:
5317  case DTK_WEEK:
5318  case DTK_DOW:
5319  case DTK_ISODOW:
5320  case DTK_DOY:
5321  case DTK_TZ:
5322  case DTK_TZ_MINUTE:
5323  case DTK_TZ_HOUR:
5324  return 0.0;
5325 
5326  /* Monotonically-increasing units */
5327  case DTK_YEAR:
5328  case DTK_DECADE:
5329  case DTK_CENTURY:
5330  case DTK_MILLENNIUM:
5331  case DTK_JULIAN:
5332  case DTK_ISOYEAR:
5333  case DTK_EPOCH:
5334  if (isNegative)
5335  return -get_float8_infinity();
5336  else
5337  return get_float8_infinity();
5338 
5339  default:
5340  ereport(ERROR,
5341  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5342  errmsg("unit \"%s\" not supported for type %s",
5343  lowunits,
5344  format_type_be(isTz ? TIMESTAMPTZOID : TIMESTAMPOID))));
5345  return 0.0; /* keep compiler quiet */
5346  }
5347 }
#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:3007
int DecodeTimezoneName(const char *tzname, int *offset, pg_tz **tz)
Definition: datetime.c:3190
int DetermineTimeZoneAbbrevOffset(struct pg_tm *tm, const char *abbr, pg_tz *tzp)
Definition: datetime.c:1746
int errhint(const char *fmt,...)
Definition: elog.c:1317
#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 6356 of file timestamp.c.

6357 {
6359 }
TimestampTz timestamp2timestamptz_opt_overflow(Timestamp timestamp, int *overflow)
Definition: timestamp.c:6304

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 6304 of file timestamp.c.

6305 {
6306  TimestampTz result;