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)
 
Datum timestamptz_hash (PG_FUNCTION_ARGS)
 
Datum timestamptz_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 1349 of file timestamp.c.

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

1621 {
1623 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1644
#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 5160 of file timestamp.c.

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

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

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

5273 {
5274  return date2j(year, mon, mday) - isoweek2j(date2isoyear(year, mon, mday), 1) + 1;
5275 }
int isoweek2j(int year, int week)
Definition: timestamp.c:5109
int date2isoyear(int year, int mon, int mday)
Definition: timestamp.c:5215

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

3942 {
3943  /* Infinite inputs are counted separately, and do not affect "N" */
3945  {
3946  state->nInfcount++;
3947  return;
3948  }
3949 
3951  {
3952  state->pInfcount++;
3953  return;
3954  }
3955 
3956  finite_interval_pl(&state->sumX, newval, &state->sumX);
3957  state->N++;
3958 }
static void finite_interval_pl(const Interval *span1, const Interval *span2, Interval *result)
Definition: timestamp.c:3440
#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 3964 of file timestamp.c.

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

2116 {
2117  dt -= (timezone * USECS_PER_SEC);
2118  return dt;
2119 }
#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 1864 of file timestamp.c.

1865 {
1866  TimeOffset time;
1867 
1868  time = jd;
1869 
1870  *hour = time / USECS_PER_HOUR;
1871  time -= (*hour) * USECS_PER_HOUR;
1872  *min = time / USECS_PER_MINUTE;
1873  time -= (*min) * USECS_PER_MINUTE;
1874  *sec = time / USECS_PER_SEC;
1875  *fsec = time - (*sec * USECS_PER_SEC);
1876 } /* 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 1597 of file timestamp.c.

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

1587 {
1588  if (TIMESTAMP_IS_NOBEGIN(dt))
1589  strcpy(str, EARLY);
1590  else if (TIMESTAMP_IS_NOEND(dt))
1591  strcpy(str, LATE);
1592  else /* shouldn't happen */
1593  elog(ERROR, "invalid argument for EncodeSpecialTimestamp");
1594 }
#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 6158 of file timestamp.c.

6159 {
6160  return interval_part_common(fcinfo, true);
6161 }
static Datum interval_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition: timestamp.c:5945

References interval_part_common().

◆ extract_timestamp()

Datum extract_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 5610 of file timestamp.c.

5611 {
5612  return timestamp_part_common(fcinfo, true);
5613 }
static Datum timestamp_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition: timestamp.c:5346

References timestamp_part_common().

◆ extract_timestamptz()

Datum extract_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 5882 of file timestamp.c.

5883 {
5884  return timestamptz_part_common(fcinfo, true);
5885 }
static Datum timestamptz_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition: timestamp.c:5619

References timestamptz_part_common().

◆ finite_interval_mi()

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

Definition at line 3496 of file timestamp.c.

3497 {
3498  Assert(!INTERVAL_NOT_FINITE(span1));
3499  Assert(!INTERVAL_NOT_FINITE(span2));
3500 
3501  if (pg_sub_s32_overflow(span1->month, span2->month, &result->month) ||
3502  pg_sub_s32_overflow(span1->day, span2->day, &result->day) ||
3503  pg_sub_s64_overflow(span1->time, span2->time, &result->time) ||
3504  INTERVAL_NOT_FINITE(result))
3505  ereport(ERROR,
3506  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3507  errmsg("interval out of range")));
3508 }
static bool pg_sub_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:153
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 3440 of file timestamp.c.

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

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

726 {
727  float8 seconds = PG_GETARG_FLOAT8(0);
728  TimestampTz result;
729 
730  /* Deal with NaN and infinite inputs ... */
731  if (isnan(seconds))
732  ereport(ERROR,
733  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
734  errmsg("timestamp cannot be NaN")));
735 
736  if (isinf(seconds))
737  {
738  if (seconds < 0)
739  TIMESTAMP_NOBEGIN(result);
740  else
741  TIMESTAMP_NOEND(result);
742  }
743  else
744  {
745  /* Out of range? */
746  if (seconds <
748  || seconds >=
750  ereport(ERROR,
751  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
752  errmsg("timestamp out of range: \"%g\"", seconds)));
753 
754  /* Convert UNIX epoch to Postgres epoch */
756 
757  seconds = rint(seconds * USECS_PER_SEC);
758  result = (int64) seconds;
759 
760  /* Recheck in case roundoff produces something just out of range */
761  if (!IS_VALID_TIMESTAMP(result))
762  ereport(ERROR,
763  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
764  errmsg("timestamp out of range: \"%g\"",
765  PG_GETARG_FLOAT8(0))));
766  }
767 
768  PG_RETURN_TIMESTAMP(result);
769 }
#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 6515 of file timestamp.c.

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

6697 {
6698  Node *rawreq = (Node *) PG_GETARG_POINTER(0);
6699  Node *ret = NULL;
6700 
6701  if (IsA(rawreq, SupportRequestRows))
6702  {
6703  /* Try to estimate the number of rows returned */
6704  SupportRequestRows *req = (SupportRequestRows *) rawreq;
6705 
6706  if (is_funcclause(req->node)) /* be paranoid */
6707  {
6708  List *args = ((FuncExpr *) req->node)->args;
6709  Node *arg1,
6710  *arg2,
6711  *arg3;
6712 
6713  /* We can use estimated argument values here */
6715  arg2 = estimate_expression_value(req->root, lsecond(args));
6716  arg3 = estimate_expression_value(req->root, lthird(args));
6717 
6718  /*
6719  * If any argument is constant NULL, we can safely assume that
6720  * zero rows are returned. Otherwise, if they're all non-NULL
6721  * constants, we can calculate the number of rows that will be
6722  * returned.
6723  */
6724  if ((IsA(arg1, Const) && ((Const *) arg1)->constisnull) ||
6725  (IsA(arg2, Const) && ((Const *) arg2)->constisnull) ||
6726  (IsA(arg3, Const) && ((Const *) arg3)->constisnull))
6727  {
6728  req->rows = 0;
6729  ret = (Node *) req;
6730  }
6731  else if (IsA(arg1, Const) && IsA(arg2, Const) && IsA(arg3, Const))
6732  {
6733  Timestamp start,
6734  finish;
6735  Interval *step;
6736  Datum diff;
6737  double dstep;
6738  int64 dummy;
6739 
6740  start = DatumGetTimestamp(((Const *) arg1)->constvalue);
6741  finish = DatumGetTimestamp(((Const *) arg2)->constvalue);
6742  step = DatumGetIntervalP(((Const *) arg3)->constvalue);
6743 
6744  /*
6745  * Perform some prechecks which could cause timestamp_mi to
6746  * raise an ERROR. It's much better to just return some
6747  * default estimate than error out in a support function.
6748  */
6749  if (!TIMESTAMP_NOT_FINITE(start) && !TIMESTAMP_NOT_FINITE(finish) &&
6750  !pg_sub_s64_overflow(finish, start, &dummy))
6751  {
6753  TimestampGetDatum(finish),
6755 
6756 #define INTERVAL_TO_MICROSECONDS(i) ((((double) (i)->month * DAYS_PER_MONTH + (i)->day)) * USECS_PER_DAY + (i)->time)
6757 
6758  dstep = INTERVAL_TO_MICROSECONDS(step);
6759 
6760  /* This equation works for either sign of step */
6761  if (dstep != 0.0)
6762  {
6763  Interval *idiff = DatumGetIntervalP(diff);
6764  double ddiff = INTERVAL_TO_MICROSECONDS(idiff);
6765 
6766  req->rows = floor(ddiff / dstep + 1.0);
6767  ret = (Node *) req;
6768  }
6769 #undef INTERVAL_TO_MICROSECONDS
6770  }
6771  }
6772  }
6773  }
6774 
6775  PG_RETURN_POINTER(ret);
6776 }
Datum timestamp_mi(PG_FUNCTION_ARGS)
Definition: timestamp.c:2779
#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:69
#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 6681 of file timestamp.c.

6682 {
6683  return generate_series_timestamptz_internal(fcinfo);
6684 }
static Datum generate_series_timestamptz_internal(FunctionCallInfo fcinfo)
Definition: timestamp.c:6599

References generate_series_timestamptz_internal().

◆ generate_series_timestamptz_at_zone()

Datum generate_series_timestamptz_at_zone ( PG_FUNCTION_ARGS  )

Definition at line 6687 of file timestamp.c.

6688 {
6689  return generate_series_timestamptz_internal(fcinfo);
6690 }

References generate_series_timestamptz_internal().

◆ generate_series_timestamptz_internal()

static Datum generate_series_timestamptz_internal ( FunctionCallInfo  fcinfo)
static

Definition at line 6599 of file timestamp.c.

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

1645 {
1646  TimestampTz result;
1647  struct timeval tp;
1648 
1649  gettimeofday(&tp, NULL);
1650 
1651  result = (TimestampTz) tp.tv_sec -
1653  result = (result * USECS_PER_SEC) + tp.tv_usec;
1654 
1655  return result;
1656 }
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(), CleanupBackend(), 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(), WaitForLSNReplay(), 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 2149 of file timestamp.c.

2150 {
2151  struct pg_tm *t0;
2152  pg_time_t epoch = 0;
2153 
2154  t0 = pg_gmtime(&epoch);
2155 
2156  if (t0 == NULL)
2157  elog(ERROR, "could not convert epoch to timestamp: %m");
2158 
2159  tm->tm_year = t0->tm_year;
2160  tm->tm_mon = t0->tm_mon;
2161  tm->tm_mday = t0->tm_mday;
2162  tm->tm_hour = t0->tm_hour;
2163  tm->tm_min = t0->tm_min;
2164  tm->tm_sec = t0->tm_sec;
2165 
2166  tm->tm_year += 1900;
2167  tm->tm_mon++;
2168 }
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 1662 of file timestamp.c.

1663 {
1664  TimestampTz ts;
1665 
1667  if (typmod >= 0)
1668  AdjustTimestampForTypmod(&ts, typmod, NULL);
1669  return ts;
1670 }
bool AdjustTimestampForTypmod(Timestamp *time, int32 typmod, Node *escontext)
Definition: timestamp.c:367
TimestampTz GetCurrentTransactionStartTimestamp(void)
Definition: xact.c:869

References AdjustTimestampForTypmod(), and GetCurrentTransactionStartTimestamp().

Referenced by ExecEvalSQLValueFunction().

◆ GetSQLLocalTimestamp()

Timestamp GetSQLLocalTimestamp ( int32  typmod)

Definition at line 1676 of file timestamp.c.

1677 {
1678  Timestamp ts;
1679 
1681  if (typmod >= 0)
1682  AdjustTimestampForTypmod(&ts, typmod, NULL);
1683  return ts;
1684 }
static Timestamp timestamptz2timestamp(TimestampTz timestamp)
Definition: timestamp.c:6382

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

Referenced by ExecEvalSQLValueFunction().

◆ in_range_interval_interval()

Datum in_range_interval_interval ( PG_FUNCTION_ARGS  )

Definition at line 3869 of file timestamp.c.

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

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

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

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

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

2029 {
2030  TimeOffset time;
2031  TimeOffset tfrac;
2032 
2033  itm->tm_year = span.month / MONTHS_PER_YEAR;
2034  itm->tm_mon = span.month % MONTHS_PER_YEAR;
2035  itm->tm_mday = span.day;
2036  time = span.time;
2037 
2038  tfrac = time / USECS_PER_HOUR;
2039  time -= tfrac * USECS_PER_HOUR;
2040  itm->tm_hour = tfrac;
2041  tfrac = time / USECS_PER_MINUTE;
2042  time -= tfrac * USECS_PER_MINUTE;
2043  itm->tm_min = (int) tfrac;
2044  tfrac = time / USECS_PER_SEC;
2045  time -= tfrac * USECS_PER_SEC;
2046  itm->tm_sec = (int) tfrac;
2047  itm->tm_usec = (int) time;
2048 }
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 4160 of file timestamp.c.

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

3996 {
3998 
4000 
4001  /* Create the state data on the first call */
4002  if (state == NULL)
4003  state = makeIntervalAggState(fcinfo);
4004 
4005  if (!PG_ARGISNULL(1))
4007 
4009 }
static IntervalAggState * makeIntervalAggState(FunctionCallInfo fcinfo)
Definition: timestamp.c:3919
static void do_interval_accum(IntervalAggState *state, Interval *newval)
Definition: timestamp.c:3941

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

4143 {
4145 
4147 
4148  /* Should not get here with no state */
4149  if (state == NULL)
4150  elog(ERROR, "interval_avg_accum_inv called with NULL state");
4151 
4152  if (!PG_ARGISNULL(1))
4154 
4156 }
static void do_interval_discard(IntervalAggState *state, Interval *newval)
Definition: timestamp.c:3964

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

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

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

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

2571 {
2572  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2573  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2574 
2575  PG_RETURN_INT32(interval_cmp_internal(interval1, interval2));
2576 }
#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 2498 of file timestamp.c.

2499 {
2500  INT128 span1 = interval_cmp_value(interval1);
2501  INT128 span2 = interval_cmp_value(interval2);
2502 
2503  return int128_compare(span1, span2);
2504 }
static INT128 interval_cmp_value(const Interval *interval)
Definition: timestamp.c:2476
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 2476 of file timestamp.c.

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

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

2517 {
2518  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2519  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2520 
2521  PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) == 0);
2522 }

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

2137 {
2139 
2141 }

References INTERVAL_NOT_FINITE, PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

◆ interval_ge()

Datum interval_ge ( PG_FUNCTION_ARGS  )

Definition at line 2561 of file timestamp.c.

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

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

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

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

2587 {
2590  int64 span64;
2591 
2592  /*
2593  * Use only the least significant 64 bits for hashing. The upper 64 bits
2594  * seldom add any useful information, and besides we must do it like this
2595  * for compatibility with hashes calculated before use of INT128 was
2596  * introduced.
2597  */
2598  span64 = int128_to_int64(span);
2599 
2601 }
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:641
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 2604 of file timestamp.c.

2605 {
2608  int64 span64;
2609 
2610  /* Same approach as interval_hash */
2611  span64 = int128_to_int64(span);
2612 
2614  PG_GETARG_DATUM(1));
2615 }
#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 890 of file timestamp.c.

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

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

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

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

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

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

3427 {
3428  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
3429  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
3430  Interval *result;
3431 
3432  if (interval_cmp_internal(interval1, interval2) > 0)
3433  result = interval1;
3434  else
3435  result = interval2;
3436  PG_RETURN_INTERVAL_P(result);
3437 }

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_INTERVAL_P.

◆ interval_le()

Datum interval_le ( PG_FUNCTION_ARGS  )

Definition at line 2552 of file timestamp.c.

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

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

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

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

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

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

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

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

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

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

◆ interval_out()

Datum interval_out ( PG_FUNCTION_ARGS  )

Definition at line 972 of file timestamp.c.

973 {
974  Interval *span = PG_GETARG_INTERVAL_P(0);
975  char *result;
976  struct pg_itm tt,
977  *itm = &tt;
978  char buf[MAXDATELEN + 1];
979 
980  if (INTERVAL_NOT_FINITE(span))
981  EncodeSpecialInterval(span, buf);
982  else
983  {
984  interval2itm(*span, itm);
986  }
987 
988  result = pstrdup(buf);
989  PG_RETURN_CSTRING(result);
990 }
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:1597
void interval2itm(Interval span, struct pg_itm *itm)
Definition: timestamp.c:2028
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
int IntervalStyle
Definition: globals.c:126
#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 6152 of file timestamp.c.

6153 {
6154  return interval_part_common(fcinfo, false);
6155 }

References interval_part_common().

◆ interval_part_common()

static Datum interval_part_common ( PG_FUNCTION_ARGS  ,
bool  retnumeric 
)
static

Definition at line 5945 of file timestamp.c.

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

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

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

997 {
999 
1000 #ifdef NOT_USED
1001  Oid typelem = PG_GETARG_OID(1);
1002 #endif
1003  int32 typmod = PG_GETARG_INT32(2);
1004  Interval *interval;
1005 
1006  interval = (Interval *) palloc(sizeof(Interval));
1007 
1009  interval->day = pq_getmsgint(buf, sizeof(interval->day));
1010  interval->month = pq_getmsgint(buf, sizeof(interval->month));
1011 
1012  AdjustIntervalForTypmod(interval, typmod, NULL);
1013 
1015 }
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 1327 of file timestamp.c.

1328 {
1330  int32 typmod = PG_GETARG_INT32(1);
1331  Interval *result;
1332 
1333  result = palloc(sizeof(Interval));
1334  *result = *interval;
1335 
1336  AdjustIntervalForTypmod(result, typmod, NULL);
1337 
1338  PG_RETURN_INTERVAL_P(result);
1339 }

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

3412 {
3413  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
3414  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
3415  Interval *result;
3416 
3417  /* use interval_cmp_internal to be sure this agrees with comparisons */
3418  if (interval_cmp_internal(interval1, interval2) < 0)
3419  result = interval1;
3420  else
3421  result = interval2;
3422  PG_RETURN_INTERVAL_P(result);
3423 }

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_INTERVAL_P.

◆ interval_sum()

Datum interval_sum ( PG_FUNCTION_ARGS  )

Definition at line 4200 of file timestamp.c.

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

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

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

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

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

3399 {
3401  Interval *result;
3402 
3403  result = (Interval *) palloc(sizeof(Interval));
3404  interval_um_internal(interval, result);
3405 
3406  PG_RETURN_INTERVAL_P(result);
3407 }

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

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

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

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

1212 {
1213  if (typmod < 0)
1214  return 0; /* SECOND */
1215 
1216  switch (INTERVAL_RANGE(typmod))
1217  {
1218  case INTERVAL_MASK(YEAR):
1219  return 5; /* YEAR */
1220  case INTERVAL_MASK(MONTH):
1221  return 4; /* MONTH */
1222  case INTERVAL_MASK(DAY):
1223  return 3; /* DAY */
1224  case INTERVAL_MASK(HOUR):
1225  return 2; /* HOUR */
1226  case INTERVAL_MASK(MINUTE):
1227  return 1; /* MINUTE */
1228  case INTERVAL_MASK(SECOND):
1229  return 0; /* SECOND */
1231  return 4; /* MONTH */
1233  return 2; /* HOUR */
1235  return 1; /* MINUTE */
1237  return 0; /* SECOND */
1239  return 1; /* MINUTE */
1241  return 0; /* SECOND */
1243  return 0; /* SECOND */
1244  case INTERVAL_FULL_RANGE:
1245  return 0; /* SECOND */
1246  default:
1247  elog(ERROR, "invalid INTERVAL typmod: 0x%x", typmod);
1248  break;
1249  }
1250  return 0; /* can't get here, but keep compiler quiet */
1251 }

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

1126 {
1127  int32 typmod = PG_GETARG_INT32(0);
1128  char *res = (char *) palloc(64);
1129  int fields;
1130  int precision;
1131  const char *fieldstr;
1132 
1133  if (typmod < 0)
1134  {
1135  *res = '\0';
1137  }
1138 
1139  fields = INTERVAL_RANGE(typmod);
1140  precision = INTERVAL_PRECISION(typmod);
1141 
1142  switch (fields)
1143  {
1144  case INTERVAL_MASK(YEAR):
1145  fieldstr = " year";
1146  break;
1147  case INTERVAL_MASK(MONTH):
1148  fieldstr = " month";
1149  break;
1150  case INTERVAL_MASK(DAY):
1151  fieldstr = " day";
1152  break;
1153  case INTERVAL_MASK(HOUR):
1154  fieldstr = " hour";
1155  break;
1156  case INTERVAL_MASK(MINUTE):
1157  fieldstr = " minute";
1158  break;
1159  case INTERVAL_MASK(SECOND):
1160  fieldstr = " second";
1161  break;
1163  fieldstr = " year to month";
1164  break;
1166  fieldstr = " day to hour";
1167  break;
1169  fieldstr = " day to minute";
1170  break;
1172  fieldstr = " day to second";
1173  break;
1175  fieldstr = " hour to minute";
1176  break;
1178  fieldstr = " hour to second";
1179  break;
1181  fieldstr = " minute to second";
1182  break;
1183  case INTERVAL_FULL_RANGE:
1184  fieldstr = "";
1185  break;
1186  default:
1187  elog(ERROR, "invalid INTERVAL typmod: 0x%x", typmod);
1188  fieldstr = "";
1189  break;
1190  }
1191 
1192  if (precision != INTERVAL_FULL_PRECISION)
1193  snprintf(res, 64, "%s(%d)", fieldstr, precision);
1194  else
1195  snprintf(res, 64, "%s", fieldstr);
1196 
1198 }
#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 5129 of file timestamp.c.

5130 {
5131  j2date(isoweek2j(*year, woy), year, mon, mday);
5132 }
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 5109 of file timestamp.c.

5110 {
5111  int day0,
5112  day4;
5113 
5114  /* fourth day of current year */
5115  day4 = date2j(year, 1, 4);
5116 
5117  /* day0 == offset to first day of week (Monday) */
5118  day0 = j2day(day4 - 1);
5119 
5120  return ((week - 1) * 7) + (day4 - day0);
5121 }

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

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

References isoweek2j(), and j2date().

Referenced by do_to_timestamp().

◆ itm2interval()

int itm2interval ( struct pg_itm itm,
Interval span 
)

Definition at line 2058 of file timestamp.c.

2059 {
2060  int64 total_months = (int64) itm->tm_year * MONTHS_PER_YEAR + itm->tm_mon;
2061 
2062  if (total_months > INT_MAX || total_months < INT_MIN)
2063  return -1;
2064  span->month = (int32) total_months;
2065  span->day = itm->tm_mday;
2067  &span->time))
2068  return -1;
2069  /* tm_min, tm_sec are 32 bits, so intermediate products can't overflow */
2070  if (pg_add_s64_overflow(span->time, itm->tm_min * USECS_PER_MINUTE,
2071  &span->time))
2072  return -1;
2073  if (pg_add_s64_overflow(span->time, itm->tm_sec * USECS_PER_SEC,
2074  &span->time))
2075  return -1;
2076  if (pg_add_s64_overflow(span->time, itm->tm_usec,
2077  &span->time))
2078  return -1;
2079  if (INTERVAL_NOT_FINITE(span))
2080  return -1;
2081  return 0;
2082 }
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 2096 of file timestamp.c.

2097 {
2098  int64 total_months = (int64) itm_in->tm_year * MONTHS_PER_YEAR + itm_in->tm_mon;
2099 
2100  if (total_months > INT_MAX || total_months < INT_MIN)
2101  return -1;
2102  span->month = (int32) total_months;
2103  span->day = itm_in->tm_mday;
2104  span->time = itm_in->tm_usec;
2105  return 0;
2106 }

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

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

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

645 {
646  int32 year = PG_GETARG_INT32(0);
647  int32 month = PG_GETARG_INT32(1);
648  int32 mday = PG_GETARG_INT32(2);
649  int32 hour = PG_GETARG_INT32(3);
650  int32 min = PG_GETARG_INT32(4);
651  float8 sec = PG_GETARG_FLOAT8(5);
652  Timestamp result;
653 
654  result = make_timestamp_internal(year, month, mday,
655  hour, min, sec);
656 
657  PG_RETURN_TIMESTAMP(result);
658 }
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 
622  pg_add_s64_overflow(result, time, &result)))
623  ereport(ERROR,
624  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
625  errmsg("timestamp out of range: %d-%02d-%02d %d:%02d:%02g",
626  year, month, day,
627  hour, min, sec)));
628 
629  /* final range check catches just-out-of-range timestamps */
630  if (!IS_VALID_TIMESTAMP(result))
631  ereport(ERROR,
632  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
633  errmsg("timestamp out of range: %d-%02d-%02d %d:%02d:%02g",
634  year, month, day,
635  hour, min, sec)));
636 
637  return result;
638 }
int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc, struct pg_tm *tm)
Definition: datetime.c:2508
#define unlikely(x)
Definition: c.h:311
#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:1463
#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, pg_add_s64_overflow(), pg_mul_s64_overflow(), POSTGRES_EPOCH_JDATE, SECS_PER_MINUTE, tm, pg_tm::tm_mday, pg_tm::tm_mon, pg_tm::tm_year, unlikely, 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 664 of file timestamp.c.

665 {
666  int32 year = PG_GETARG_INT32(0);
667  int32 month = PG_GETARG_INT32(1);
668  int32 mday = PG_GETARG_INT32(2);
669  int32 hour = PG_GETARG_INT32(3);
670  int32 min = PG_GETARG_INT32(4);
671  float8 sec = PG_GETARG_FLOAT8(5);
672  Timestamp result;
673 
674  result = make_timestamp_internal(year, month, mday,
675  hour, min, sec);
676 
678 }
static TimestampTz timestamp2timestamptz(Timestamp timestamp)
Definition: timestamp.c:6365

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

686 {
687  int32 year = PG_GETARG_INT32(0);
688  int32 month = PG_GETARG_INT32(1);
689  int32 mday = PG_GETARG_INT32(2);
690  int32 hour = PG_GETARG_INT32(3);
691  int32 min = PG_GETARG_INT32(4);
692  float8 sec = PG_GETARG_FLOAT8(5);
694  TimestampTz result;
696  struct pg_tm tt;
697  int tz;
698  fsec_t fsec;
699 
700  timestamp = make_timestamp_internal(year, month, mday,
701  hour, min, sec);
702 
703  if (timestamp2tm(timestamp, NULL, &tt, &fsec, NULL, NULL) != 0)
704  ereport(ERROR,
705  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
706  errmsg("timestamp out of range")));
707 
708  tz = parse_sane_timezone(&tt, zone);
709 
710  result = dt2local(timestamp, -tz);
711 
712  if (!IS_VALID_TIMESTAMP(result))
713  ereport(ERROR,
714  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
715  errmsg("timestamp out of range")));
716 
717  PG_RETURN_TIMESTAMPTZ(result);
718 }
static Timestamp dt2local(Timestamp dt, int timezone)
Definition: timestamp.c:2115
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition: timestamp.c:1891
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 3919 of file timestamp.c.

3920 {
3922  MemoryContext agg_context;
3923  MemoryContext old_context;
3924 
3925  if (!AggCheckCallContext(fcinfo, &agg_context))
3926  elog(ERROR, "aggregate function called in non-aggregate context");
3927 
3928  old_context = MemoryContextSwitchTo(agg_context);
3929 
3931 
3932  MemoryContextSwitchTo(old_context);
3933 
3934  return state;
3935 }

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

3681 {
3682  /* Args are float8 and Interval *, but leave them as generic Datum */
3683  Datum factor = PG_GETARG_DATUM(0);
3684  Datum span = PG_GETARG_DATUM(1);
3685 
3686  return DirectFunctionCall2(interval_mul, span, factor);
3687 }
Datum interval_mul(PG_FUNCTION_ARGS)
Definition: timestamp.c:3560

References DirectFunctionCall2, interval_mul(), and PG_GETARG_DATUM.

◆ NonFiniteIntervalPart()

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

Definition at line 5899 of file timestamp.c.

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

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

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