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

Go to the source code of this file.

Data Structures

struct  generate_series_timestamp_fctx
 
struct  generate_series_timestamptz_fctx
 
struct  IntervalAggState
 

Macros

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

Typedefs

typedef struct IntervalAggState IntervalAggState
 

Functions

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

Variables

TimestampTz PgStartTime
 
TimestampTz PgReloadTime
 

Macro Definition Documentation

◆ IA_TOTAL_COUNT

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

Definition at line 88 of file timestamp.c.

◆ SAMESIGN

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

Definition at line 50 of file timestamp.c.

◆ TIMESTAMP_GT

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

◆ TIMESTAMP_LT

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

Typedef Documentation

◆ IntervalAggState

Function Documentation

◆ AdjustIntervalForTypmod()

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

Definition at line 1360 of file timestamp.c.

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

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

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

◆ AdjustTimestampForTypmod()

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

Definition at line 367 of file timestamp.c.

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

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

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

◆ anytimestamp_typmod_check()

int32 anytimestamp_typmod_check ( bool  istz,
int32  typmod 
)

Definition at line 124 of file timestamp.c.

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

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

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

◆ anytimestamp_typmodin()

static int32 anytimestamp_typmodin ( bool  istz,
ArrayType ta 
)
static

Definition at line 103 of file timestamp.c.

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

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:1580
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46

References psprintf(), and pstrdup().

Referenced by timestamptypmodout(), and timestamptztypmodout().

◆ clock_timestamp()

Datum clock_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 1631 of file timestamp.c.

1632 {
1634 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1655
#define PG_RETURN_TIMESTAMPTZ(x)
Definition: timestamp.h:68

References GetCurrentTimestamp(), and PG_RETURN_TIMESTAMPTZ.

◆ date2isoweek()

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

Definition at line 5156 of file timestamp.c.

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

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

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

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

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

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

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

3961 {
3962  /* Infinite inputs are counted separately, and do not affect "N" */
3964  {
3965  state->nInfcount--;
3966  return;
3967  }
3968 
3970  {
3971  state->pInfcount--;
3972  return;
3973  }
3974 
3975  /* Handle the to-be-discarded finite value. */
3976  state->N--;
3977  if (state->N > 0)
3978  finite_interval_mi(&state->sumX, newval, &state->sumX);
3979  else
3980  {
3981  /* All values discarded, reset the state */
3982  Assert(state->N == 0);
3983  memset(&state->sumX, 0, sizeof(state->sumX));
3984  }
3985 }
static void finite_interval_mi(const Interval *span1, const Interval *span2, Interval *result)
Definition: timestamp.c:3492
Assert(fmt[strlen(fmt) - 1] !='\n')

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

Referenced by interval_avg_accum_inv().

◆ dt2local()

static Timestamp dt2local ( Timestamp  dt,
int  timezone 
)
static

Definition at line 2135 of file timestamp.c.

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

References USECS_PER_SEC.

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

◆ dt2time()

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

Definition at line 1875 of file timestamp.c.

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

References USECS_PER_HOUR, USECS_PER_MINUTE, and USECS_PER_SEC.

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

◆ EncodeSpecialInterval()

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

Definition at line 1608 of file timestamp.c.

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

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

Referenced by interval_out().

◆ EncodeSpecialTimestamp()

void EncodeSpecialTimestamp ( Timestamp  dt,
char *  str 
)

Definition at line 1597 of file timestamp.c.

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

References EARLY, elog, ERROR, LATE, generate_unaccent_rules::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 6138 of file timestamp.c.

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

References interval_part_common().

◆ extract_timestamp()

Datum extract_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 5606 of file timestamp.c.

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

References timestamp_part_common().

◆ extract_timestamptz()

Datum extract_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 5878 of file timestamp.c.

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

References timestamptz_part_common().

◆ finite_interval_mi()

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

Definition at line 3492 of file timestamp.c.

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

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

Referenced by do_interval_discard(), and interval_mi().

◆ finite_interval_pl()

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

Definition at line 3436 of file timestamp.c.

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

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

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

◆ float8_timestamptz()

Datum float8_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 736 of file timestamp.c.

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

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

◆ generate_series_timestamp()

Datum generate_series_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 6495 of file timestamp.c.

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

◆ generate_series_timestamptz()

Datum generate_series_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 6661 of file timestamp.c.

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

References generate_series_timestamptz_internal().

◆ generate_series_timestamptz_at_zone()

Datum generate_series_timestamptz_at_zone ( PG_FUNCTION_ARGS  )

Definition at line 6667 of file timestamp.c.

6668 {
6669  return generate_series_timestamptz_internal(fcinfo);
6670 }

References generate_series_timestamptz_internal().

◆ generate_series_timestamptz_internal()

static Datum generate_series_timestamptz_internal ( FunctionCallInfo  fcinfo)
static

Definition at line 6579 of file timestamp.c.

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

Referenced by generate_series_timestamptz(), and generate_series_timestamptz_at_zone().

◆ GetCurrentTimestamp()

TimestampTz GetCurrentTimestamp ( void  )

Definition at line 1655 of file timestamp.c.

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

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

Referenced by ApplyLauncherMain(), asyncQueueFillWarning(), autoprewarm_main(), AutoVacLauncherMain(), BackgroundWriterMain(), bbsink_copystream_archive_contents(), bbsink_copystream_end_archive(), bbsink_copystream_new(), bbsink_throttle_begin_backup(), check_log_duration(), CheckPointGuts(), CleanupBackgroundWorker(), clock_timestamp(), CreateCheckPoint(), CreateEndOfRecoveryRecord(), CreateOverwriteContrecordRecord(), CreateRestartPoint(), 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_drandom_seed(), InitProcessGlobals(), KnownAssignedXidsCompress(), launcher_determine_sleep(), LockBufferForCleanup(), log_disconnections(), LogCheckpointEnd(), logicalrep_worker_launch(), LogicalRepApplyLoop(), maybe_start_bgworkers(), pa_send_data(), PerformWalRecovery(), pgfdw_cancel_query(), pgfdw_exec_cleanup_query(), pgfdw_finish_abort_cleanup(), pgfdw_get_cleanup_result(), pgss_shmem_startup(), pgstat_build_snapshot(), pgstat_report_activity(), pgstat_report_analyze(), pgstat_report_archiver(), pgstat_report_autovac(), pgstat_report_checksum_failures_in_db(), pgstat_report_stat(), pgstat_report_vacuum(), pgstat_reset(), pgstat_reset_after_failure(), pgstat_reset_counters(), pgstat_reset_of_kind(), pgstat_reset_slru(), PostgresSingleUserMain(), PostmasterMain(), PrepareForIncrementalBackup(), PrepareTransaction(), process_syncing_tables_for_apply(), ProcessConfigFileInternal(), ProcessPendingWrites(), ProcessRepliesIfAny(), ProcessStandbyReplyMessage(), ProcessWalSndrMessage(), ProcSleep(), rebuild_database_list(), RecordTransactionAbort(), RecordTransactionAbortPrepared(), RecordTransactionCommitPrepared(), recoveryApplyDelay(), reschedule_timeouts(), ResolveRecoveryConflictWithBufferPin(), ResolveRecoveryConflictWithLock(), ResolveRecoveryConflictWithVirtualXIDs(), send_feedback(), SetCurrentStatementStartTimestamp(), SetupApplyOrSyncWorker(), StartTransaction(), test_pattern(), throttle(), UpdateWorkerStats(), WaitExceedsMaxStandbyDelay(), WaitForWalSummarization(), WaitForWALToBecomeAvailable(), WalReceiverMain(), WalSndKeepalive(), WalSndLoop(), WalSndUpdateProgress(), WalSndWaitForWal(), WalSndWriteData(), XLogBackgroundFlush(), XLogFileRead(), XLogPrefetchResetStats(), XLogPrefetchShmemInit(), XLogRestorePoint(), XLogSendPhysical(), XLogWalRcvSendHSFeedback(), and XLogWalRcvSendReply().

◆ GetEpochTime()

void GetEpochTime ( struct pg_tm tm)

Definition at line 2169 of file timestamp.c.

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

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

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

◆ GetSQLCurrentTimestamp()

TimestampTz GetSQLCurrentTimestamp ( int32  typmod)

Definition at line 1673 of file timestamp.c.

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

References AdjustTimestampForTypmod(), and GetCurrentTransactionStartTimestamp().

Referenced by ExecEvalSQLValueFunction().

◆ GetSQLLocalTimestamp()

Timestamp GetSQLLocalTimestamp ( int32  typmod)

Definition at line 1687 of file timestamp.c.

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

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

Referenced by ExecEvalSQLValueFunction().

◆ in_range_interval_interval()

Datum in_range_interval_interval ( PG_FUNCTION_ARGS  )

Definition at line 3865 of file timestamp.c.

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

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

◆ in_range_timestamp_interval()

Datum in_range_timestamp_interval ( PG_FUNCTION_ARGS  )

Definition at line 3824 of file timestamp.c.

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

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

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

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

◆ interval2itm()

void interval2itm ( Interval  span,
struct pg_itm itm 
)

Definition at line 2048 of file timestamp.c.

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

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

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

◆ interval_avg()

Datum interval_avg ( PG_FUNCTION_ARGS  )

Definition at line 4156 of file timestamp.c.

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

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

◆ interval_avg_accum()

Datum interval_avg_accum ( PG_FUNCTION_ARGS  )

Definition at line 3991 of file timestamp.c.

3992 {
3994 
3996 
3997  /* Create the state data on the first call */
3998  if (state == NULL)
3999  state = makeIntervalAggState(fcinfo);
4000 
4001  if (!PG_ARGISNULL(1))
4003 
4005 }
static IntervalAggState * makeIntervalAggState(FunctionCallInfo fcinfo)
Definition: timestamp.c:3915
static void do_interval_accum(IntervalAggState *state, Interval *newval)
Definition: timestamp.c:3937
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361

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

◆ interval_avg_accum_inv()

Datum interval_avg_accum_inv ( PG_FUNCTION_ARGS  )

Definition at line 4138 of file timestamp.c.

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

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

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

4096 {
4097  bytea *sstate;
4098  IntervalAggState *result;
4100 
4101  if (!AggCheckCallContext(fcinfo, NULL))
4102  elog(ERROR, "aggregate function called in non-aggregate context");
4103 
4104  sstate = PG_GETARG_BYTEA_PP(0);
4105 
4106  /*
4107  * Initialize a StringInfo so that we can "receive" it using the standard
4108  * recv-function infrastructure.
4109  */
4111  VARSIZE_ANY_EXHDR(sstate));
4112 
4113  result = (IntervalAggState *) palloc0(sizeof(IntervalAggState));
4114 
4115  /* N */
4116  result->N = pq_getmsgint64(&buf);
4117 
4118  /* sumX */
4119  result->sumX.time = pq_getmsgint64(&buf);
4120  result->sumX.day = pq_getmsgint(&buf, 4);
4121  result->sumX.month = pq_getmsgint(&buf, 4);
4122 
4123  /* pInfcount */
4124  result->pInfcount = pq_getmsgint64(&buf);
4125 
4126  /* nInfcount */
4127  result->nInfcount = pq_getmsgint64(&buf);
4128 
4129  pq_getmsgend(&buf);
4130 
4131  PG_RETURN_POINTER(result);
4132 }
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
void * palloc0(Size size)
Definition: mcxt.c:1231
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4512
static char * buf
Definition: pg_test_fsync.c:73
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:418
void pq_getmsgend(StringInfo msg)
Definition: pqformat.c:638
int64 pq_getmsgint64(StringInfo msg)
Definition: pqformat.c:456
static void initReadOnlyStringInfo(StringInfo str, char *data, int len)
Definition: stringinfo.h:129
#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 4057 of file timestamp.c.

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

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

◆ interval_cmp()

Datum interval_cmp ( PG_FUNCTION_ARGS  )

Definition at line 2578 of file timestamp.c.

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

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_INT32.

Referenced by gbt_intvkey_cmp().

◆ interval_cmp_internal()

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

Definition at line 2506 of file timestamp.c.

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

References int128_compare(), and interval_cmp_value().

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

◆ interval_cmp_value()

static INT128 interval_cmp_value ( const Interval interval)
inlinestatic

Definition at line 2484 of file timestamp.c.

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

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

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

Referenced by interval_avg().

◆ interval_eq()

Datum interval_eq ( PG_FUNCTION_ARGS  )

Definition at line 2524 of file timestamp.c.

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

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by gbt_intveq().

◆ interval_finite()

Datum interval_finite ( PG_FUNCTION_ARGS  )

Definition at line 2156 of file timestamp.c.

2157 {
2159 
2161 }

References INTERVAL_NOT_FINITE, PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

◆ interval_ge()

Datum interval_ge ( PG_FUNCTION_ARGS  )

Definition at line 2569 of file timestamp.c.

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

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by gbt_intvge().

◆ interval_gt()

Datum interval_gt ( PG_FUNCTION_ARGS  )

Definition at line 2551 of file timestamp.c.

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

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by gbt_intvgt().

◆ interval_hash()

Datum interval_hash ( PG_FUNCTION_ARGS  )

Definition at line 2594 of file timestamp.c.

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

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

◆ interval_hash_extended()

Datum interval_hash_extended ( PG_FUNCTION_ARGS  )

Definition at line 2612 of file timestamp.c.

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

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

◆ interval_in()

Datum interval_in ( PG_FUNCTION_ARGS  )

Definition at line 901 of file timestamp.c.

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

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

Referenced by check_timezone(), and flatten_set_variable_args().

◆ interval_justify_days()

Datum interval_justify_days ( PG_FUNCTION_ARGS  )

Definition at line 3003 of file timestamp.c.

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

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

◆ interval_justify_hours()

Datum interval_justify_hours ( PG_FUNCTION_ARGS  )

Definition at line 2961 of file timestamp.c.

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

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

Referenced by timestamp_mi().

◆ interval_justify_interval()

Datum interval_justify_interval ( PG_FUNCTION_ARGS  )

Definition at line 2881 of file timestamp.c.

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

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

◆ interval_larger()

Datum interval_larger ( PG_FUNCTION_ARGS  )

Definition at line 3422 of file timestamp.c.

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

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_INTERVAL_P.

◆ interval_le()

Datum interval_le ( PG_FUNCTION_ARGS  )

Definition at line 2560 of file timestamp.c.

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

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by gbt_intvle().

◆ interval_lt()

Datum interval_lt ( PG_FUNCTION_ARGS  )

Definition at line 2542 of file timestamp.c.

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

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by abs_interval(), and gbt_intvlt().

◆ interval_mi()

Datum interval_mi ( PG_FUNCTION_ARGS  )

Definition at line 3507 of file timestamp.c.

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

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

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

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

Referenced by interval_lerp(), and mul_d_interval().

◆ interval_ne()

Datum interval_ne ( PG_FUNCTION_ARGS  )

Definition at line 2533 of file timestamp.c.

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

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

◆ interval_out()

Datum interval_out ( PG_FUNCTION_ARGS  )

Definition at line 983 of file timestamp.c.

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

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

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

◆ interval_part()

Datum interval_part ( PG_FUNCTION_ARGS  )

Definition at line 6132 of file timestamp.c.

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

References interval_part_common().

◆ interval_part_common()

static Datum interval_part_common ( PG_FUNCTION_ARGS  ,
bool  retnumeric 
)
static

Definition at line 5940 of file timestamp.c.

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

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

Referenced by extract_interval(), and interval_part().

◆ interval_pl()

Datum interval_pl ( PG_FUNCTION_ARGS  )

Definition at line 3451 of file timestamp.c.

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

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

Referenced by in_range_interval_interval(), and interval_lerp().

◆ interval_recv()

Datum interval_recv ( PG_FUNCTION_ARGS  )

Definition at line 1007 of file timestamp.c.

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

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

◆ interval_scale()

Datum interval_scale ( PG_FUNCTION_ARGS  )

Definition at line 1338 of file timestamp.c.

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

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

◆ interval_send()

◆ interval_sign()

static int interval_sign ( const Interval interval)
static

◆ interval_smaller()

Datum interval_smaller ( PG_FUNCTION_ARGS  )

Definition at line 3407 of file timestamp.c.

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

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_INTERVAL_P.

◆ interval_sum()

Datum interval_sum ( PG_FUNCTION_ARGS  )

Definition at line 4196 of file timestamp.c.

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

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

◆ interval_support()

Datum interval_support ( PG_FUNCTION_ARGS  )

Definition at line 1275 of file timestamp.c.

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

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

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

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

◆ interval_um()

Datum interval_um ( PG_FUNCTION_ARGS  )

Definition at line 3394 of file timestamp.c.

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

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

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

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

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

◆ intervaltypmodin()

Datum intervaltypmodin ( PG_FUNCTION_ARGS  )

Definition at line 1057 of file timestamp.c.

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

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

◆ intervaltypmodleastfield()

static int intervaltypmodleastfield ( int32  typmod)
static

Definition at line 1222 of file timestamp.c.

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

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

Referenced by interval_support().

◆ intervaltypmodout()

Datum intervaltypmodout ( PG_FUNCTION_ARGS  )

Definition at line 1136 of file timestamp.c.

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

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

◆ isoweek2date()

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

Definition at line 5125 of file timestamp.c.

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

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

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

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

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

References isoweek2j(), and j2date().

Referenced by do_to_timestamp().

◆ itm2interval()

int itm2interval ( struct pg_itm itm,
Interval span 
)

Definition at line 2078 of file timestamp.c.

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

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

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

◆ itmin2interval()

int itmin2interval ( struct pg_itm_in itm_in,
Interval span 
)

Definition at line 2116 of file timestamp.c.

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

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

Referenced by interval_in(), and pg_timezone_abbrevs().

◆ lookup_timezone()

static pg_tz* lookup_timezone ( text zone)
static

Definition at line 559 of file timestamp.c.

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

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

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

◆ make_interval()

Datum make_interval ( PG_FUNCTION_ARGS  )

Definition at line 1540 of file timestamp.c.

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

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

◆ make_timestamp()

Datum make_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 655 of file timestamp.c.

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

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

◆ make_timestamp_internal()

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

Definition at line 573 of file timestamp.c.

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

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

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

◆ make_timestamptz()

Datum make_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 675 of file timestamp.c.

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

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

◆ make_timestamptz_at_timezone()

Datum make_timestamptz_at_timezone ( PG_FUNCTION_ARGS  )

Definition at line 696 of file timestamp.c.

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

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

◆ makeIntervalAggState()

static IntervalAggState* makeIntervalAggState ( FunctionCallInfo  fcinfo)
static

Definition at line 3915 of file timestamp.c.

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

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

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

References DirectFunctionCall2, interval_mul(), and PG_GETARG_DATUM.

◆ NonFiniteIntervalPart()

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

Definition at line 5895 of file timestamp.c.

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

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

Referenced by interval_part_common().

◆ NonFiniteTimestampTzPart()

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

Definition at line 5285 of file timestamp.c.

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

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

Referenced by timestamp_part_common(), and timestamptz_part_common().

◆ now()

Definition at line 1619 of file timestamp.c.

References GetCurrentTransactionStartTimestamp(), and PG_RETURN_TIMESTAMPTZ.

Referenced by advanceConnectionState(), ApplyLauncherMain(), BackgroundWriterMain(), bbsink_copystream_archive_contents(), CalculateCopyStreamSleeptime(), CheckArchiveTimeout(), CheckpointerMain(), doLog(), doRetry(), dumpTimestamp(), enable_timeout(), enable_timeout_after(), enable_timeout_at(), enable_timeout_every(), enable_timeouts(), executeMetaCommand(), flushAndSendFeedback(), handle_sig_alarm(), HandleCopyStream(), has_startup_progress_timeout_expired(), initialize_drandom_seed(), IsCheckpointOnSchedule(), LagTrackerRead(), launch_worker(), 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(), RequestXLogStreaming(), ResolveRecoveryConflictWithLock(), ResolveRecoveryConflictWithVirtualXIDs(), schedule_alarm(), send_feedback(), sendFeedback(), ServerLoop(), set_next_rotation_time(), StreamLogicalLog(), SysLoggerMain(), threadRun(), timetz_zone(), WaitForWalSummarization(), WaitForWALToBecomeAvailable(), WalRcvComputeNextWakeup(), WalRcvRunning(), WalRcvStreaming(), WalReceiverMain(), WalSndComputeSleeptime(), WalSndUpdateProgress(), WalSndWriteData(), xid_age(), XLogBackgroundFlush(), XLogWalRcvSendHSFeedback(), and XLogWalRcvSendReply().

◆ overlaps_timestamp()

Datum overlaps_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2632 of file timestamp.c.

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

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

◆ parse_sane_timezone()

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

Definition at line 490 of file timestamp.c.

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

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

Referenced by make_timestamptz_at_timezone().

◆ pg_conf_load_time()

Datum pg_conf_load_time ( PG_FUNCTION_ARGS  )

Definition at line 1643 of file timestamp.c.

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

References PG_RETURN_TIMESTAMPTZ, and PgReloadTime.

◆ pg_postmaster_start_time()

Datum pg_postmaster_start_time ( PG_FUNCTION_ARGS  )

Definition at line 1637 of file timestamp.c.

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

References PG_RETURN_TIMESTAMPTZ, and PgStartTime.

◆ SetEpochTimestamp()

Timestamp SetEpochTimestamp ( void  )

Definition at line 2191 of file timestamp.c.

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

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

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

◆ statement_timestamp()

Datum statement_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 1625 of file timestamp.c.

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

References GetCurrentStatementStartTimestamp(), and PG_RETURN_TIMESTAMPTZ.

◆ time2t()

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

Definition at line 2129 of file timestamp.c.

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

References MINS_PER_HOUR, SECS_PER_MINUTE, and USECS_PER_SEC.

Referenced by tm2timestamp().

◆ time_t_to_timestamptz()

TimestampTz time_t_to_timestamptz ( pg_time_t  tm)

Definition at line 1812 of file timestamp.c.

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

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

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

◆ timeofday()

Datum timeofday ( PG_FUNCTION_ARGS  )

Definition at line 1701 of file timestamp.c.

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

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

◆ timestamp2timestamptz()

static TimestampTz timestamp2timestamptz ( Timestamp  timestamp)
static

Definition at line 6345 of file timestamp.c.

6346 {
6348 }
TimestampTz timestamp2timestamptz_opt_overflow(Timestamp timestamp, int *overflow)
Definition: timestamp.c:6293

References timestamp2timestamptz_opt_overflow().

Referenced by make_timestamptz(), and timestamp_timestamptz().

◆ timestamp2timestamptz_opt_overflow()

TimestampTz timestamp2timestamptz_opt_overflow ( Timestamp  timestamp,
int *  overflow 
)

Definition at line 6293 of file timestamp.c.

6294 {
6295  TimestampTz result;
6296  struct pg_tm tt,
6297  *tm = &tt;
6298  fsec_t fsec;
6299  int tz;
6300 
6301  if (overflow)
6302  *overflow = 0;
6303