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 "optimizer/optimizer.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))
 
#define INTERVAL_TO_MICROSECONDS(i)   ((((double) (i)->month * DAYS_PER_MONTH + (i)->day)) * USECS_PER_DAY + (i)->time)
 

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 generate_series_timestamp_support (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 88 of file timestamp.c.

◆ INTERVAL_TO_MICROSECONDS

#define INTERVAL_TO_MICROSECONDS (   i)    ((((double) (i)->month * DAYS_PER_MONTH + (i)->day)) * USECS_PER_DAY + (i)->time)

◆ SAMESIGN

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

Definition at line 50 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 1360 of file timestamp.c.

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

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

125 {
126  if (typmod < 0)
127  ereport(ERROR,
128  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
129  errmsg("TIMESTAMP(%d)%s precision must not be negative",
130  typmod, (istz ? " WITH TIME ZONE" : ""))));
131  if (typmod > MAX_TIMESTAMP_PRECISION)
132  {
134  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
135  errmsg("TIMESTAMP(%d)%s precision reduced to maximum allowed, %d",
136  typmod, (istz ? " WITH TIME ZONE" : ""),
138  typmod = MAX_TIMESTAMP_PRECISION;
139  }
140 
141  return typmod;
142 }
#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 103 of file timestamp.c.

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

147 {
148  const char *tz = istz ? " with time zone" : " without time zone";
149 
150  if (typmod >= 0)
151  return psprintf("(%d)%s", (int) typmod, tz);
152  else
153  return pstrdup(tz);
154 }
char * pstrdup(const char *in)
Definition: mcxt.c:1696
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 1631 of file timestamp.c.

1632 {
1634 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1655
#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 5168 of file timestamp.c.

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

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

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

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

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

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

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

2136 {
2137  dt -= (timezone * USECS_PER_SEC);
2138  return dt;
2139 }
#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 1875 of file timestamp.c.

1876 {
1877  TimeOffset time;
1878 
1879  time = jd;
1880 
1881  *hour = time / USECS_PER_HOUR;
1882  time -= (*hour) * USECS_PER_HOUR;
1883  *min = time / USECS_PER_MINUTE;
1884  time -= (*min) * USECS_PER_MINUTE;
1885  *sec = time / USECS_PER_SEC;
1886  *fsec = time - (*sec * USECS_PER_SEC);
1887 } /* 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 1608 of file timestamp.c.

1609 {
1611  strcpy(str, EARLY);
1612  else if (INTERVAL_IS_NOEND(interval))
1613  strcpy(str, LATE);
1614  else /* shouldn't happen */
1615  elog(ERROR, "invalid argument for EncodeSpecialInterval");
1616 }
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 1597 of file timestamp.c.

1598 {
1599  if (TIMESTAMP_IS_NOBEGIN(dt))
1600  strcpy(str, EARLY);
1601  else if (TIMESTAMP_IS_NOEND(dt))
1602  strcpy(str, LATE);
1603  else /* shouldn't happen */
1604  elog(ERROR, "invalid argument for EncodeSpecialTimestamp");
1605 }
#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 6150 of file timestamp.c.

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

References interval_part_common().

◆ extract_timestamp()

Datum extract_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 5618 of file timestamp.c.

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

References timestamp_part_common().

◆ extract_timestamptz()

Datum extract_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 5890 of file timestamp.c.

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

References timestamptz_part_common().

◆ finite_interval_mi()

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

Definition at line 3504 of file timestamp.c.

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

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

737 {
738  float8 seconds = PG_GETARG_FLOAT8(0);
739  TimestampTz result;
740 
741  /* Deal with NaN and infinite inputs ... */
742  if (isnan(seconds))
743  ereport(ERROR,
744  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
745  errmsg("timestamp cannot be NaN")));
746 
747  if (isinf(seconds))
748  {
749  if (seconds < 0)
750  TIMESTAMP_NOBEGIN(result);
751  else
752  TIMESTAMP_NOEND(result);
753  }
754  else
755  {
756  /* Out of range? */
757  if (seconds <
759  || seconds >=
761  ereport(ERROR,
762  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
763  errmsg("timestamp out of range: \"%g\"", seconds)));
764 
765  /* Convert UNIX epoch to Postgres epoch */
767 
768  seconds = rint(seconds * USECS_PER_SEC);
769  result = (int64) seconds;
770 
771  /* Recheck in case roundoff produces something just out of range */
772  if (!IS_VALID_TIMESTAMP(result))
773  ereport(ERROR,
774  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
775  errmsg("timestamp out of range: \"%g\"",
776  PG_GETARG_FLOAT8(0))));
777  }
778 
779  PG_RETURN_TIMESTAMP(result);
780 }
#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 6507 of file timestamp.c.

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

Datum generate_series_timestamp_support ( PG_FUNCTION_ARGS  )

Definition at line 6688 of file timestamp.c.

6689 {
6690  Node *rawreq = (Node *) PG_GETARG_POINTER(0);
6691  Node *ret = NULL;
6692 
6693  if (IsA(rawreq, SupportRequestRows))
6694  {
6695  /* Try to estimate the number of rows returned */
6696  SupportRequestRows *req = (SupportRequestRows *) rawreq;
6697 
6698  if (is_funcclause(req->node)) /* be paranoid */
6699  {
6700  List *args = ((FuncExpr *) req->node)->args;
6701  Node *arg1,
6702  *arg2,
6703  *arg3;
6704 
6705  /* We can use estimated argument values here */
6707  arg2 = estimate_expression_value(req->root, lsecond(args));
6708  arg3 = estimate_expression_value(req->root, lthird(args));
6709 
6710  /*
6711  * If any argument is constant NULL, we can safely assume that
6712  * zero rows are returned. Otherwise, if they're all non-NULL
6713  * constants, we can calculate the number of rows that will be
6714  * returned.
6715  */
6716  if ((IsA(arg1, Const) && ((Const *) arg1)->constisnull) ||
6717  (IsA(arg2, Const) && ((Const *) arg2)->constisnull) ||
6718  (IsA(arg3, Const) && ((Const *) arg3)->constisnull))
6719  {
6720  req->rows = 0;
6721  ret = (Node *) req;
6722  }
6723  else if (IsA(arg1, Const) && IsA(arg2, Const) && IsA(arg3, Const))
6724  {
6725  Timestamp start,
6726  finish;
6727  Interval *step;
6728  Datum diff;
6729  double dstep;
6730  int64 dummy;
6731 
6732  start = DatumGetTimestamp(((Const *) arg1)->constvalue);
6733  finish = DatumGetTimestamp(((Const *) arg2)->constvalue);
6734  step = DatumGetIntervalP(((Const *) arg3)->constvalue);
6735 
6736  /*
6737  * Perform some prechecks which could cause timestamp_mi to
6738  * raise an ERROR. It's much better to just return some
6739  * default estimate than error out in a support function.
6740  */
6741  if (!TIMESTAMP_NOT_FINITE(start) && !TIMESTAMP_NOT_FINITE(finish) &&
6742  !pg_sub_s64_overflow(finish, start, &dummy))
6743  {
6745  TimestampGetDatum(finish),
6747 
6748 #define INTERVAL_TO_MICROSECONDS(i) ((((double) (i)->month * DAYS_PER_MONTH + (i)->day)) * USECS_PER_DAY + (i)->time)
6749 
6750  dstep = INTERVAL_TO_MICROSECONDS(step);
6751 
6752  /* This equation works for either sign of step */
6753  if (dstep != 0.0)
6754  {
6755  Interval *idiff = DatumGetIntervalP(diff);
6756  double ddiff = INTERVAL_TO_MICROSECONDS(idiff);
6757 
6758  req->rows = floor(ddiff / dstep + 1.0);
6759  ret = (Node *) req;
6760  }
6761 #undef INTERVAL_TO_MICROSECONDS
6762  }
6763  }
6764  }
6765  }
6766 
6767  PG_RETURN_POINTER(ret);
6768 }
Datum timestamp_mi(PG_FUNCTION_ARGS)
Definition: timestamp.c:2787
#define INTERVAL_TO_MICROSECONDS(i)
Node * estimate_expression_value(PlannerInfo *root, Node *node)
Definition: clauses.c:2395
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
static bool is_funcclause(const void *clause)
Definition: nodeFuncs.h:67
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
#define lthird(l)
Definition: pg_list.h:188
#define linitial(l)
Definition: pg_list.h:178
#define lsecond(l)
Definition: pg_list.h:183
uintptr_t Datum
Definition: postgres.h:64
Definition: pg_list.h:54
Definition: nodes.h:129
struct PlannerInfo * root
Definition: supportnodes.h:163
static Interval * DatumGetIntervalP(Datum X)
Definition: timestamp.h:40

References generate_unaccent_rules::args, DatumGetIntervalP(), DatumGetTimestamp(), DirectFunctionCall2, estimate_expression_value(), INTERVAL_TO_MICROSECONDS, is_funcclause(), IsA, linitial, lsecond, lthird, SupportRequestRows::node, PG_GETARG_POINTER, PG_RETURN_POINTER, pg_sub_s64_overflow(), SupportRequestRows::root, SupportRequestRows::rows, start, timestamp_mi(), TIMESTAMP_NOT_FINITE, and TimestampGetDatum().

◆ generate_series_timestamptz()

Datum generate_series_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 6673 of file timestamp.c.

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

References generate_series_timestamptz_internal().

◆ generate_series_timestamptz_at_zone()

Datum generate_series_timestamptz_at_zone ( PG_FUNCTION_ARGS  )

Definition at line 6679 of file timestamp.c.

6680 {
6681  return generate_series_timestamptz_internal(fcinfo);
6682 }

References generate_series_timestamptz_internal().

◆ generate_series_timestamptz_internal()

static Datum generate_series_timestamptz_internal ( FunctionCallInfo  fcinfo)
static

Definition at line 6591 of file timestamp.c.

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

1656 {
1657  TimestampTz result;
1658  struct timeval tp;
1659 
1660  gettimeofday(&tp, NULL);
1661 
1662  result = (TimestampTz) tp.tv_sec -
1664  result = (result * USECS_PER_SEC) + tp.tv_usec;
1665 
1666  return result;
1667 }
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(), 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 2169 of file timestamp.c.

2170 {
2171  struct pg_tm *t0;
2172  pg_time_t epoch = 0;
2173 
2174  t0 = pg_gmtime(&epoch);
2175 
2176  if (t0 == NULL)
2177  elog(ERROR, "could not convert epoch to timestamp: %m");
2178 
2179  tm->tm_year = t0->tm_year;
2180  tm->tm_mon = t0->tm_mon;
2181  tm->tm_mday = t0->tm_mday;
2182  tm->tm_hour = t0->tm_hour;
2183  tm->tm_min = t0->tm_min;
2184  tm->tm_sec = t0->tm_sec;
2185 
2186  tm->tm_year += 1900;
2187  tm->tm_mon++;
2188 }
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 1673 of file timestamp.c.

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

References AdjustTimestampForTypmod(), and GetCurrentTransactionStartTimestamp().

Referenced by ExecEvalSQLValueFunction().

◆ GetSQLLocalTimestamp()

Timestamp GetSQLLocalTimestamp ( int32  typmod)

Definition at line 1687 of file timestamp.c.

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

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

Referenced by ExecEvalSQLValueFunction().

◆ in_range_interval_interval()

Datum in_range_interval_interval ( PG_FUNCTION_ARGS  )

Definition at line 3877 of file timestamp.c.

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

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

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

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

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

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

2049 {
2050  TimeOffset time;
2051  TimeOffset tfrac;
2052 
2053  itm->tm_year = span.month / MONTHS_PER_YEAR;
2054  itm->tm_mon = span.month % MONTHS_PER_YEAR;
2055  itm->tm_mday = span.day;
2056  time = span.time;
2057 
2058  tfrac = time / USECS_PER_HOUR;
2059  time -= tfrac * USECS_PER_HOUR;
2060  itm->tm_hour = tfrac;
2061  tfrac = time / USECS_PER_MINUTE;
2062  time -= tfrac * USECS_PER_MINUTE;
2063  itm->tm_min = (int) tfrac;
2064  tfrac = time / USECS_PER_SEC;
2065  time -= tfrac * USECS_PER_SEC;
2066  itm->tm_sec = (int) tfrac;
2067  itm->tm_usec = (int) time;
2068 }
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 4168 of file timestamp.c.

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

4004 {
4006 
4008 
4009  /* Create the state data on the first call */
4010  if (state == NULL)
4011  state = makeIntervalAggState(fcinfo);
4012 
4013  if (!PG_ARGISNULL(1))
4015 
4017 }
static IntervalAggState * makeIntervalAggState(FunctionCallInfo fcinfo)
Definition: timestamp.c:3927
static void do_interval_accum(IntervalAggState *state, Interval *newval)
Definition: timestamp.c:3949

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

4151 {
4153 
4155 
4156  /* Should not get here with no state */
4157  if (state == NULL)
4158  elog(ERROR, "interval_avg_accum_inv called with NULL state");
4159 
4160  if (!PG_ARGISNULL(1))
4162 
4164 }
static void do_interval_discard(IntervalAggState *state, Interval *newval)
Definition: timestamp.c:3972

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

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

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

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

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

2579 {
2580  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2581  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2582 
2583  PG_RETURN_INT32(interval_cmp_internal(interval1, interval2));
2584 }
#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 2506 of file timestamp.c.

2507 {
2508  INT128 span1 = interval_cmp_value(interval1);
2509  INT128 span2 = interval_cmp_value(interval2);
2510 
2511  return int128_compare(span1, span2);
2512 }
static INT128 interval_cmp_value(const Interval *interval)
Definition: timestamp.c:2484
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 2484 of file timestamp.c.

2485 {
2486  INT128 span;
2487  int64 days;
2488 
2489  /*
2490  * Combine the month and day fields into an integral number of days.
2491  * Because the inputs are int32, int64 arithmetic suffices here.
2492  */
2493  days = interval->month * INT64CONST(30);
2494  days += interval->day;
2495 
2496  /* Widen time field to 128 bits */
2497  span = int64_to_int128(interval->time);
2498 
2499  /* Scale up days to microseconds, forming a 128-bit product */
2501 
2502  return span;
2503 }
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 3698 of file timestamp.c.

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

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

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

2157 {
2159 
2161 }

References INTERVAL_NOT_FINITE, PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

◆ interval_ge()

Datum interval_ge ( PG_FUNCTION_ARGS  )

Definition at line 2569 of file timestamp.c.

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

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

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

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

2595 {
2598  int64 span64;
2599 
2600  /*
2601  * Use only the least significant 64 bits for hashing. The upper 64 bits
2602  * seldom add any useful information, and besides we must do it like this
2603  * for compatibility with hashes calculated before use of INT128 was
2604  * introduced.
2605  */
2606  span64 = int128_to_int64(span);
2607 
2609 }
#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 2612 of file timestamp.c.

2613 {
2616  int64 span64;
2617 
2618  /* Same approach as interval_hash */
2619  span64 = int128_to_int64(span);
2620 
2622  PG_GETARG_DATUM(1));
2623 }
#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 901 of file timestamp.c.

902 {
903  char *str = PG_GETARG_CSTRING(0);
904 #ifdef NOT_USED
905  Oid typelem = PG_GETARG_OID(1);
906 #endif
907  int32 typmod = PG_GETARG_INT32(2);
908  Node *escontext = fcinfo->context;
909  Interval *result;
910  struct pg_itm_in tt,
911  *itm_in = &tt;
912  int dtype;
913  int nf;
914  int range;
915  int dterr;
916  char *field[MAXDATEFIELDS];
917  int ftype[MAXDATEFIELDS];
918  char workbuf[256];
919  DateTimeErrorExtra extra;
920 
921  itm_in->tm_year = 0;
922  itm_in->tm_mon = 0;
923  itm_in->tm_mday = 0;
924  itm_in->tm_usec = 0;
925 
926  if (typmod >= 0)
927  range = INTERVAL_RANGE(typmod);
928  else
930 
931  dterr = ParseDateTime(str, workbuf, sizeof(workbuf), field,
932  ftype, MAXDATEFIELDS, &nf);
933  if (dterr == 0)
934  dterr = DecodeInterval(field, ftype, nf, range,
935  &dtype, itm_in);
936 
937  /* if those functions think it's a bad format, try ISO8601 style */
938  if (dterr == DTERR_BAD_FORMAT)
939  dterr = DecodeISO8601Interval(str,
940  &dtype, itm_in);
941 
942  if (dterr != 0)
943  {
944  if (dterr == DTERR_FIELD_OVERFLOW)
945  dterr = DTERR_INTERVAL_OVERFLOW;
946  DateTimeParseError(dterr, &extra, str, "interval", escontext);
947  PG_RETURN_NULL();
948  }
949 
950  result = (Interval *) palloc(sizeof(Interval));
951 
952  switch (dtype)
953  {
954  case DTK_DELTA:
955  if (itmin2interval(itm_in, result) != 0)
956  ereturn(escontext, (Datum) 0,
957  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
958  errmsg("interval out of range")));
959  break;
960 
961  case DTK_LATE:
962  INTERVAL_NOEND(result);
963  break;
964 
965  case DTK_EARLY:
966  INTERVAL_NOBEGIN(result);
967  break;
968 
969  default:
970  elog(ERROR, "unexpected dtype %d while parsing interval \"%s\"",
971  dtype, str);
972  }
973 
974  AdjustIntervalForTypmod(result, typmod, escontext);
975 
976  PG_RETURN_INTERVAL_P(result);
977 }
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:2116
static bool AdjustIntervalForTypmod(Interval *interval, int32 typmod, Node *escontext)
Definition: timestamp.c:1360
#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
unsigned int Oid
Definition: postgres_ext.h:31
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 3003 of file timestamp.c.

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

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

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

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

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

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

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_INTERVAL_P.

◆ interval_le()

Datum interval_le ( PG_FUNCTION_ARGS  )

Definition at line 2560 of file timestamp.c.

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

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

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

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

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

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

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

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

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

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

◆ interval_out()

Datum interval_out ( PG_FUNCTION_ARGS  )

Definition at line 983 of file timestamp.c.

984 {
985  Interval *span = PG_GETARG_INTERVAL_P(0);
986  char *result;
987  struct pg_itm tt,
988  *itm = &tt;
989  char buf[MAXDATELEN + 1];
990 
991  if (INTERVAL_NOT_FINITE(span))
992  EncodeSpecialInterval(span, buf);
993  else
994  {
995  interval2itm(*span, itm);
997  }
998 
999  result = pstrdup(buf);
1000  PG_RETURN_CSTRING(result);
1001 }
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:1608
void interval2itm(Interval span, struct pg_itm *itm)
Definition: timestamp.c:2048
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
int IntervalStyle
Definition: globals.c:125
#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 6144 of file timestamp.c.

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

References interval_part_common().

◆ interval_part_common()

static Datum interval_part_common ( PG_FUNCTION_ARGS  ,
bool  retnumeric 
)
static

Definition at line 5952 of file timestamp.c.

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

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

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

1008 {
1010 
1011 #ifdef NOT_USED
1012  Oid typelem = PG_GETARG_OID(1);
1013 #endif
1014  int32 typmod = PG_GETARG_INT32(2);
1015  Interval *interval;
1016 
1017  interval = (Interval *) palloc(sizeof(Interval));
1018 
1020  interval->day = pq_getmsgint(buf, sizeof(interval->day));
1021  interval->month = pq_getmsgint(buf, sizeof(interval->month));
1022 
1023  AdjustIntervalForTypmod(interval, typmod, NULL);
1024 
1026 }
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 1338 of file timestamp.c.

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

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

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

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_INTERVAL_P.

◆ interval_sum()

Datum interval_sum ( PG_FUNCTION_ARGS  )

Definition at line 4208 of file timestamp.c.

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

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

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

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

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

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

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

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

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

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

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

1137 {
1138  int32 typmod = PG_GETARG_INT32(0);
1139  char *res = (char *) palloc(64);
1140  int fields;
1141  int precision;
1142  const char *fieldstr;
1143 
1144  if (typmod < 0)
1145  {
1146  *res = '\0';
1148  }
1149 
1150  fields = INTERVAL_RANGE(typmod);
1151  precision = INTERVAL_PRECISION(typmod);
1152 
1153  switch (fields)
1154  {
1155  case INTERVAL_MASK(YEAR):
1156  fieldstr = " year";
1157  break;
1158  case INTERVAL_MASK(MONTH):
1159  fieldstr = " month";
1160  break;
1161  case INTERVAL_MASK(DAY):
1162  fieldstr = " day";
1163  break;
1164  case INTERVAL_MASK(HOUR):
1165  fieldstr = " hour";
1166  break;
1167  case INTERVAL_MASK(MINUTE):
1168  fieldstr = " minute";
1169  break;
1170  case INTERVAL_MASK(SECOND):
1171  fieldstr = " second";
1172  break;
1174  fieldstr = " year to month";
1175  break;
1177  fieldstr = " day to hour";
1178  break;
1180  fieldstr = " day to minute";
1181  break;
1183  fieldstr = " day to second";
1184  break;
1186  fieldstr = " hour to minute";
1187  break;
1189  fieldstr = " hour to second";
1190  break;
1192  fieldstr = " minute to second";
1193  break;
1194  case INTERVAL_FULL_RANGE:
1195  fieldstr = "";
1196  break;
1197  default:
1198  elog(ERROR, "invalid INTERVAL typmod: 0x%x", typmod);
1199  fieldstr = "";
1200  break;
1201  }
1202 
1203  if (precision != INTERVAL_FULL_PRECISION)
1204  snprintf(res, 64, "%s(%d)", fieldstr, precision);
1205  else
1206  snprintf(res, 64, "%s", fieldstr);
1207 
1209 }
#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 5137 of file timestamp.c.

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

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

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

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

References isoweek2j(), and j2date().

Referenced by do_to_timestamp().

◆ itm2interval()

int itm2interval ( struct pg_itm itm,
Interval span 
)

Definition at line 2078 of file timestamp.c.

2079 {
2080  int64 total_months = (int64) itm->tm_year * MONTHS_PER_YEAR + itm->tm_mon;
2081 
2082  if (total_months > INT_MAX || total_months < INT_MIN)
2083  return -1;
2084  span->month = (int32) total_months;
2085  span->day = itm->tm_mday;
2087  &span->time))
2088  return -1;
2089  /* tm_min, tm_sec are 32 bits, so intermediate products can't overflow */
2090  if (pg_add_s64_overflow(span->time, itm->tm_min * USECS_PER_MINUTE,
2091  &span->time))
2092  return -1;
2093  if (pg_add_s64_overflow(span->time, itm->tm_sec * USECS_PER_SEC,
2094  &span->time))
2095  return -1;
2096  if (pg_add_s64_overflow(span->time, itm->tm_usec,
2097  &span->time))
2098  return -1;
2099  if (INTERVAL_NOT_FINITE(span))
2100  return -1;
2101  return 0;
2102 }
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 2116 of file timestamp.c.

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

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

560 {
561  char tzname[TZ_STRLEN_MAX + 1];
562 
563  text_to_cstring_buffer(zone, tzname, sizeof(tzname));
564 
565  return DecodeTimezoneNameToTz(tzname);
566 }
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 1540 of file timestamp.c.

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

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

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

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

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

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

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

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

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

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

References DirectFunctionCall2, interval_mul(), and PG_GETARG_DATUM.

◆ NonFiniteIntervalPart()

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

Definition at line 5907 of file timestamp.c.

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

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

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

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

1644 {
1646 }
TimestampTz PgReloadTime
Definition: timestamp.c:56

References PG_RETURN_TIMESTAMPTZ, and PgReloadTime.

◆ pg_postmaster_start_time()

Datum pg_postmaster_start_time ( PG_FUNCTION_ARGS  )

Definition at line 1637 of file timestamp.c.

1638 {
1640 }
TimestampTz PgStartTime
Definition: timestamp.c:53

References PG_RETURN_TIMESTAMPTZ, and PgStartTime.

◆ SetEpochTimestamp()

Timestamp SetEpochTimestamp ( void  )

Definition at line 2191 of file timestamp.c.

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

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

1626 {
1628 }
TimestampTz GetCurrentStatementStartTimestamp(void)
Definition: xact.c:877

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

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

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

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

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

1702 {
1703  struct timeval tp;
1704  char templ[128];
1705  char buf[128];
1706  pg_time_t tt;
1707 
1708  gettimeofday(&tp, NULL);
1709  tt = (pg_time_t) tp.tv_sec;
1710  pg_strftime(templ, sizeof(templ), "%a %b %d %H:%M:%S.%%06d %Y %Z",
1712  snprintf(buf, sizeof(buf), templ, tp.tv_usec);
1713 
1715 }
#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 6357 of file timestamp.c.

6358 {
6360 }
TimestampTz timestamp2timestamptz_opt_overflow(Timestamp timestamp, int *overflow)
Definition: timestamp.c:6305

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

6306 {
6307  TimestampTz result;
6308  struct pg_tm tt,
6309  *tm = &tt;
6310  fsec_t fsec;
6311  int tz;
6312 
6313  if (overflow)
6314  *overflow = 0;
6315 
6317  return timestamp;
6318 
6319  /* We don't expect this to fail, but check it pro forma */
6320  if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0)
6321  {
6323 
6324  result = dt2local(timestamp, -tz);
6325 
6326  if (IS_VALID_TIMESTAMP(result))
6327  {
6328  return result;
6329  }
6330  else if (overflow)
6331  {
6332  if (result < MIN_TIMESTAMP)
6333  {
6334  *overflow = -1;
6335  TIMESTAMP_NOBEGIN(result);
6336  }
6337  else
6338  {
6339  *overflow = 1;
6340  TIMESTAMP_NOEND(result);
6341  }
6342  return result;
6343  }
6344  }
6345 
6346  ereport(ERROR,
6347  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6348  errmsg("timestamp out of range")));
6349 
6350  return 0;
6351 }
#define MIN_TIMESTAMP
Definition: timestamp.h:256

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

Referenced by timestamp2timestamptz(), and timestamp_cmp_timestamptz_internal().

◆ timestamp2tm()

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

Definition at line 1902 of file timestamp.c.

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

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

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

◆ timestamp_age()

Datum timestamp_age ( PG_FUNCTION_ARGS  )

Definition at line 4248 of file timestamp.c.

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

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

◆ timestamp_at_local()

Datum timestamp_at_local ( PG_FUNCTION_ARGS  )

Definition at line 6780 of file timestamp.c.

6781 {
6782  return timestamp_timestamptz(fcinfo);
6783 }
Datum timestamp_timestamptz(PG_FUNCTION_ARGS)
Definition: timestamp.c:6287

References timestamp_timestamptz().

◆ timestamp_bin()

Datum timestamp_bin ( PG_FUNCTION_ARGS  )

Definition at line 4548 of file timestamp.c.

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

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

◆ timestamp_cmp()

Datum timestamp_cmp ( PG_FUNCTION_ARGS  )

Definition at line 2271 of file timestamp.c.

2272 {
2273  Timestamp dt1 = PG_GETARG_TIMESTAMP(0);
2274  Timestamp dt2 = PG_GETARG_TIMESTAMP(1);
2275 
2277 }

References PG_GETARG_TIMESTAMP, PG_RETURN_INT32, and timestamp_cmp_internal().

Referenced by compareDatetime(), and gbt_tskey_cmp().

◆ timestamp_cmp_internal()

int timestamp_cmp_internal ( Timestamp  dt1,
Timestamp  dt2 
)

◆ timestamp_cmp_timestamptz()

Datum timestamp_cmp_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 2401 of file timestamp.c.

2402 {
2403  Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2405 
2407 }
int32 timestamp_cmp_timestamptz_internal(Timestamp timestampVal, TimestampTz dt2)
Definition: timestamp.c:2326

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

◆ timestamp_cmp_timestamptz_internal()

int32 timestamp_cmp_timestamptz_internal ( Timestamp  timestampVal,
TimestampTz  dt2 
)

Definition at line 2326 of file timestamp.c.

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

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

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

◆ timestamp_eq()

Datum timestamp_eq ( PG_FUNCTION_ARGS  )

Definition at line 2217 of file timestamp.c.

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

References PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, and timestamp_cmp_internal().

Referenced by gbt_tseq().

◆ timestamp_eq_timestamptz()

Datum timestamp_eq_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 2347 of file timestamp.c.

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

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

◆ timestamp_fastcmp()

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

Definition at line 2282 of file timestamp.c.

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

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

Referenced by timestamp_sortsupport().

◆ timestamp_finite()

Datum timestamp_finite ( PG_FUNCTION_ARGS  )

Definition at line 2148 of file timestamp.c.

2149 {
2151 
2153 }

References PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, and TIMESTAMP_NOT_FINITE.

◆ timestamp_ge()

Datum timestamp_ge ( PG_FUNCTION_ARGS  )

Definition at line 2262 of file timestamp.c.

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

References PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, and timestamp_cmp_internal().

Referenced by gbt_tsge().

◆ timestamp_ge_timestamptz()

Datum timestamp_ge_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 2392 of file timestamp.c.

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

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

◆ timestamp_gt()

Datum timestamp_gt ( PG_FUNCTION_ARGS  )

Definition at line 2244 of file timestamp.c.

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

References PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, and timestamp_cmp_internal().

Referenced by gbt_tsgt().

◆ timestamp_gt_timestamptz()

Datum timestamp_gt_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 2374 of file timestamp.c.

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

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

◆ timestamp_hash()

Datum timestamp_hash ( PG_FUNCTION_ARGS  )

Definition at line 2310 of file timestamp.c.

2311 {
2312  return hashint8(fcinfo);
2313 }

References hashint8().

◆ timestamp_hash_extended()

Datum timestamp_hash_extended ( PG_FUNCTION_ARGS  )

Definition at line 2316 of file timestamp.c.

2317 {
2318  return hashint8extended(fcinfo);
2319 }

References hashint8extended().

◆ timestamp_in()

Datum timestamp_in ( PG_FUNCTION_ARGS  )

Definition at line 165 of file timestamp.c.

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

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

Referenced by moddatetime().

◆ timestamp_izone()

Datum timestamp_izone ( PG_FUNCTION_ARGS  )

Definition at line 6230 of file timestamp.c.

6231 {
6234  TimestampTz result;
6235  int tz;
6236 
6239 
6241  ereport(ERROR,
6242  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6243  errmsg("interval time zone \"%s\" must be finite",
6245  PointerGetDatum(zone))))));
6246 
6247  if (zone->month != 0 || zone->day != 0)
6248  ereport(ERROR,
6249  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6250  errmsg("interval time zone \"%s\" must not include months or days",
6252  PointerGetDatum(zone))))));
6253 
6254  tz = zone->time / USECS_PER_SEC;
6255 
6256  result = dt2local(timestamp, tz);
6257 
6258  if (!IS_VALID_TIMESTAMP(result))
6259  ereport(ERROR,
6260  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6261  errmsg("timestamp out of range")));
6262 
6263  PG_RETURN_TIMESTAMPTZ(result);
6264 } /* timestamp_izone() */
Datum interval_out(PG_FUNCTION_ARGS)
Definition: timestamp.c:983
static char * DatumGetCString(Datum X)
Definition: postgres.h:335

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

◆ timestamp_larger()

Datum timestamp_larger ( PG_FUNCTION_ARGS  )

Definition at line 2772 of file timestamp.c.

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

References PG_GETARG_TIMESTAMP, PG_RETURN_TIMESTAMP, and timestamp_cmp_internal().

◆ timestamp_le()

Datum timestamp_le ( PG_FUNCTION_ARGS  )

Definition at line 2253 of file timestamp.c.

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

References PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, and timestamp_cmp_internal().

Referenced by gbt_tsle().

◆ timestamp_le_timestamptz()

Datum timestamp_le_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 2383 of file timestamp.c.

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

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

◆ timestamp_lt()

Datum timestamp_lt ( PG_FUNCTION_ARGS  )

Definition at line 2235 of file timestamp.c.

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

References PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, and timestamp_cmp_internal().

Referenced by gbt_tslt().

◆ timestamp_lt_timestamptz()

Datum timestamp_lt_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 2365 of file timestamp.c.

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

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

◆ timestamp_mi()

Datum timestamp_mi ( PG_FUNCTION_ARGS  )

Definition at line 2787 of file timestamp.c.

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

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

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

◆ timestamp_mi_interval()

◆ timestamp_ne()

Datum timestamp_ne ( PG_FUNCTION_ARGS  )

Definition at line 2226 of file timestamp.c.

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

References PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, and timestamp_cmp_internal().

◆ timestamp_ne_timestamptz()

Datum timestamp_ne_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 2356 of file timestamp.c.

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

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

◆ timestamp_out()

Datum timestamp_out ( PG_FUNCTION_ARGS  )

Definition at line 233 of file timestamp.c.

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

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

Referenced by ExecGetJsonValueItemString(), and executeItemOptUnwrapTarget().

◆ timestamp_part()

Datum timestamp_part ( PG_FUNCTION_ARGS  )

Definition at line 5612 of file timestamp.c.

5613 {
5614  return timestamp_part_common(fcinfo, false);
5615 }

References timestamp_part_common().

◆ timestamp_part_common()

static Datum timestamp_part_common ( PG_FUNCTION_ARGS  ,
bool  retnumeric 
)
static

Definition at line 5354 of file timestamp.c.

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

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

Referenced by extract_timestamp(), and timestamp_part().

◆ timestamp_pl_interval()

Datum timestamp_pl_interval ( PG_FUNCTION_ARGS  )

Definition at line 3050 of file timestamp.c.

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

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

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

◆ timestamp_recv()

Datum timestamp_recv ( PG_FUNCTION_ARGS  )

Definition at line 259 of file timestamp.c.

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

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

◆ timestamp_scale()

Datum timestamp_scale ( PG_FUNCTION_ARGS  )

Definition at line 346 of file timestamp.c.

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

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

◆ timestamp_send()

◆ timestamp_smaller()

Datum timestamp_smaller ( PG_FUNCTION_ARGS  )

Definition at line 2757 of file timestamp.c.

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

References PG_GETARG_TIMESTAMP, PG_RETURN_TIMESTAMP, and timestamp_cmp_internal().

◆ timestamp_sortsupport()

Datum timestamp_sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 2292 of file timestamp.c.

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

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

◆ timestamp_support()

Datum timestamp_support ( PG_FUNCTION_ARGS  )

Definition at line 326 of file timestamp.c.

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

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

◆ timestamp_timestamptz()

Datum timestamp_timestamptz ( PG_FUNCTION_ARGS  )

◆ timestamp_trunc()

Datum timestamp_trunc ( PG_FUNCTION_ARGS  )

Definition at line 4619 of file timestamp.c.

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

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

◆ timestamp_zone()

Datum timestamp_zone ( PG_FUNCTION_ARGS  )

Definition at line 6165 of file timestamp.c.

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

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

◆ TimestampDifference()

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

Definition at line 1731 of file timestamp.c.

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

References start_time, and USECS_PER_SEC.

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

◆ TimestampDifferenceExceeds()

◆ TimestampDifferenceMilliseconds()

long TimestampDifferenceMilliseconds ( TimestampTz  start_time,
TimestampTz  stop_time 
)

Definition at line 1767 of file timestamp.c.

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

References pg_sub_s64_overflow(), and start_time.

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

◆ TimestampTimestampTzRequiresRewrite()

bool TimestampTimestampTzRequiresRewrite ( void  )

Definition at line 6274 of file timestamp.c.

6275 {
6276  long offset;
6277 
6278  if (pg_get_timezone_offset(session_timezone, &offset) && offset == 0)
6279  return false;
6280  return true;
6281 }
bool pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff)
Definition: localtime.c:1851

References pg_get_timezone_offset(), and session_timezone.

Referenced by ATColumnChangeRequiresRewrite().

◆ timestamptypmodin()

Datum timestamptypmodin ( PG_FUNCTION_ARGS  )

Definition at line 303 of file timestamp.c.

304 {
306 
308 }
static int32 anytimestamp_typmodin(bool istz, ArrayType *ta)
Definition: timestamp.c:103

References anytimestamp_typmodin(), PG_GETARG_ARRAYTYPE_P, and PG_RETURN_INT32.

◆ timestamptypmodout()

Datum timestamptypmodout ( PG_FUNCTION_ARGS  )

Definition at line 311 of file timestamp.c.

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

References anytimestamp_typmodout(), PG_GETARG_INT32, and PG_RETURN_CSTRING.

◆ timestamptz2timestamp()

static Timestamp timestamptz2timestamp ( TimestampTz  timestamp)
static

Definition at line 6374 of file timestamp.c.

6375 {
6376  Timestamp result;
6377  struct pg_tm tt,
6378  *tm = &tt;
6379  fsec_t fsec;
6380  int tz;
6381 
6383  result = timestamp;
6384  else
6385  {
6386  if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
6387  ereport(ERROR,
6388  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6389  errmsg("timestamp out of range")));
6390  if (tm2timestamp(tm, fsec, NULL, &result) != 0)
6391  ereport(ERROR,
6392  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6393  errmsg("timestamp out of range")));
6394  }
6395  return result;
6396 }

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

Referenced by GetSQLLocalTimestamp(), and timestamptz_timestamp().

◆ timestamptz_age()

Datum timestamptz_age ( PG_FUNCTION_ARGS  )

Definition at line 4394 of file timestamp.c.

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

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

◆ timestamptz_at_local()

Datum timestamptz_at_local ( PG_FUNCTION_ARGS  )

Definition at line 6786 of file timestamp.c.

6787 {
6788  return timestamptz_timestamp(fcinfo);
6789 }
Datum timestamptz_timestamp(PG_FUNCTION_ARGS)
Definition: timestamp.c:6366

References timestamptz_timestamp().

◆ timestamptz_bin()

Datum timestamptz_bin ( PG_FUNCTION_ARGS  )

Definition at line 4753 of file timestamp.c.

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

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

◆ timestamptz_cmp_timestamp()

Datum timestamptz_cmp_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2464 of file timestamp.c.

2465 {
2467  Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
2468 
2470 }

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

◆ timestamptz_eq_timestamp()

Datum timestamptz_eq_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2410 of file timestamp.c.

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

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

◆ timestamptz_ge_timestamp()

Datum timestamptz_ge_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2455 of file timestamp.c.

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

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

◆ timestamptz_gt_timestamp()

Datum timestamptz_gt_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2437 of file timestamp.c.

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

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

◆ timestamptz_in()

Datum timestamptz_in ( PG_FUNCTION_ARGS  )

Definition at line 417 of file timestamp.c.

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

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

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

◆ timestamptz_izone()

Datum timestamptz_izone ( PG_FUNCTION_ARGS  )

Definition at line 6467 of file timestamp.c.

6468 {
6471  Timestamp result;
6472  int tz;
6473 
6476 
6478  ereport(ERROR,
6479  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6480  errmsg("interval time zone \"%s\" must be finite",
6482  PointerGetDatum(zone))))));
6483 
6484  if (zone->month != 0 || zone->day != 0)
6485  ereport(ERROR,
6486  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6487  errmsg("interval time zone \"%s\" must not include months or days",
6489  PointerGetDatum(zone))))));
6490 
6491  tz = -(zone->time / USECS_PER_SEC);
6492 
6493  result = dt2local(timestamp, tz);
6494 
6495  if (!IS_VALID_TIMESTAMP(result))
6496  ereport(ERROR,
6497  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6498  errmsg("timestamp out of range")));
6499 
6500  PG_RETURN_TIMESTAMP(result);
6501 }

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

◆ timestamptz_le_timestamp()

Datum timestamptz_le_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2446 of file timestamp.c.

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

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

◆ timestamptz_lt_timestamp()

Datum timestamptz_lt_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2428 of file timestamp.c.

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

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

◆ timestamptz_mi_interval()

◆ timestamptz_mi_interval_at_zone()

Datum timestamptz_mi_interval_at_zone ( PG_FUNCTION_ARGS  )

◆ timestamptz_mi_interval_internal()

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

Definition at line 3325 of file timestamp.c.

3328 {
3329  Interval tspan;
3330 
3331  interval_um_internal(span, &tspan);
3332 
3333  return timestamptz_pl_interval_internal(timestamp, &tspan, attimezone);
3334 }

References interval_um_internal(), and timestamptz_pl_interval_internal().

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

◆ timestamptz_ne_timestamp()

Datum timestamptz_ne_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2419 of file timestamp.c.

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

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

◆ timestamptz_out()

Datum timestamptz_out ( PG_FUNCTION_ARGS  )

Definition at line 786 of file timestamp.c.

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

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

Referenced by ExecGetJsonValueItemString(), and executeItemOptUnwrapTarget().

◆ timestamptz_part()

Datum timestamptz_part ( PG_FUNCTION_ARGS  )

Definition at line 5884 of file timestamp.c.

5885 {
5886  return timestamptz_part_common(fcinfo, false);
5887 }

References timestamptz_part_common().

◆ timestamptz_part_common()

static Datum timestamptz_part_common ( PG_FUNCTION_ARGS  ,
bool  retnumeric 
)
static

Definition at line 5627 of file timestamp.c.

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

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

Referenced by extract_timestamptz(), and timestamptz_part().

◆ timestamptz_pl_interval()

◆ timestamptz_pl_interval_at_zone()

Datum timestamptz_pl_interval_at_zone ( PG_FUNCTION_ARGS  )

◆ timestamptz_pl_interval_internal()

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

Definition at line 3193 of file timestamp.c.

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

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

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

◆ timestamptz_recv()

Datum timestamptz_recv ( PG_FUNCTION_ARGS  )

Definition at line 814 of file timestamp.c.

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

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

◆ timestamptz_scale()

Datum timestamptz_scale ( PG_FUNCTION_ARGS  )

Definition at line 880 of file timestamp.c.

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

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

◆ timestamptz_send()

◆ timestamptz_timestamp()

Datum timestamptz_timestamp ( PG_FUNCTION_ARGS  )

◆ timestamptz_to_str()

const char* timestamptz_to_str ( TimestampTz  t)

Definition at line 1854 of file timestamp.c.

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

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

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

◆ timestamptz_to_time_t()

pg_time_t timestamptz_to_time_t ( TimestampTz  t)

Definition at line 1834 of file timestamp.c.

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

References POSTGRES_EPOCH_JDATE, SECS_PER_DAY, UNIX_EPOCH_JDATE, and USECS_PER_SEC.

Referenced by DetermineTimeZoneAbbrevOffsetTS(), and InitProcessGlobals().

◆ timestamptz_trunc()

Datum timestamptz_trunc ( PG_FUNCTION_ARGS  )

Definition at line 4971 of file timestamp.c.

4972 {
4973  text *units = PG_GETARG_TEXT_PP(0);
4975  TimestampTz result;
4976 
4979 
4981 
4982  PG_RETURN_TIMESTAMPTZ(result);
4983 }
static TimestampTz timestamptz_trunc_internal(text *units, TimestampTz timestamp, pg_tz *tzp)
Definition: timestamp.c:4827

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

◆ timestamptz_trunc_internal()

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

Definition at line 4827 of file timestamp.c.

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

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

Referenced by timestamptz_trunc(), and timestamptz_trunc_zone().

◆ timestamptz_trunc_zone()

Datum timestamptz_trunc_zone ( PG_FUNCTION_ARGS  )

Definition at line 4989 of file timestamp.c.

4990 {
4991  text *units = PG_GETARG_TEXT_PP(0);
4993  text *zone = PG_GETARG_TEXT_PP(2);
4994  TimestampTz result;
4995  pg_tz *tzp;
4996 
4997  /*
4998  * timestamptz_zone() doesn't look up the zone for infinite inputs, so we
4999  * don't do so here either.
5000  */
5003 
5004  /*
5005  * Look up the requested timezone.
5006  */
5007  tzp = lookup_timezone(zone);
5008 
5009  result = timestamptz_trunc_internal(units, timestamp, tzp);
5010 
5011  PG_RETURN_TIMESTAMPTZ(result);
5012 }

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

◆ timestamptz_zone()

Datum timestamptz_zone ( PG_FUNCTION_ARGS  )

Definition at line 6403 of file timestamp.c.

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

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

◆ timestamptztypmodin()

Datum timestamptztypmodin ( PG_FUNCTION_ARGS  )

Definition at line 859 of file timestamp.c.

860 {
862 
864 }

References anytimestamp_typmodin(), PG_GETARG_ARRAYTYPE_P, and PG_RETURN_INT32.

◆ timestamptztypmodout()

Datum timestamptztypmodout ( PG_FUNCTION_ARGS  )

Definition at line 867 of file timestamp.c.

868 {
869  int32 typmod = PG_GETARG_INT32(0);
870 
872 }

References anytimestamp_typmodout(), PG_GETARG_INT32, and PG_RETURN_CSTRING.

◆ tm2timestamp()

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

Definition at line 1998 of file timestamp.c.

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

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

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

Variable Documentation

◆ PgReloadTime

TimestampTz PgReloadTime

Definition at line 56 of file timestamp.c.

Referenced by pg_conf_load_time(), and ProcessConfigFileInternal().

◆ PgStartTime

TimestampTz PgStartTime

Definition at line 53 of file timestamp.c.

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