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

Macros

#define SAMESIGN(a, b)   (((a) < 0) == ((b) < 0))
 
#define TIMESTAMP_GT(t1, t2)   DatumGetBool(DirectFunctionCall2(timestamp_gt,t1,t2))
 
#define TIMESTAMP_LT(t1, t2)   DatumGetBool(DirectFunctionCall2(timestamp_lt,t1,t2))
 

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 void AdjustIntervalForTypmod (Interval *interval, int32 typmod)
 
static TimestampTz timestamp2timestamptz (Timestamp timestamp)
 
static Timestamp timestamptz2timestamp (TimestampTz timestamp)
 
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 AdjustTimestampForTypmodError (Timestamp *time, int32 typmod, bool *error)
 
void AdjustTimestampForTypmod (Timestamp *time, int32 typmod)
 
Datum timestamptz_in (PG_FUNCTION_ARGS)
 
static int parse_sane_timezone (struct pg_tm *tm, 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)
 
int interval2tm (Interval span, struct pg_tm *tm, fsec_t *fsec)
 
int tm2interval (struct pg_tm *tm, fsec_t fsec, 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 (Interval *interval1, Interval *interval2)
 
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)
 
Datum timestamptz_pl_interval (PG_FUNCTION_ARGS)
 
Datum timestamptz_mi_interval (PG_FUNCTION_ARGS)
 
Datum interval_um (PG_FUNCTION_ARGS)
 
Datum interval_smaller (PG_FUNCTION_ARGS)
 
Datum interval_larger (PG_FUNCTION_ARGS)
 
Datum interval_pl (PG_FUNCTION_ARGS)
 
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)
 
Datum interval_accum (PG_FUNCTION_ARGS)
 
Datum interval_combine (PG_FUNCTION_ARGS)
 
Datum interval_accum_inv (PG_FUNCTION_ARGS)
 
Datum interval_avg (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 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)
 
Datum generate_series_timestamptz (PG_FUNCTION_ARGS)
 

Variables

TimestampTz PgStartTime
 
TimestampTz PgReloadTime
 

Macro Definition Documentation

◆ SAMESIGN

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

Definition at line 49 of file timestamp.c.

Referenced by interval2tm(), interval_mi(), interval_pl(), and interval_um().

◆ TIMESTAMP_GT

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

Referenced by overlaps_timestamp().

◆ TIMESTAMP_LT

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

Referenced by overlaps_timestamp().

Function Documentation

◆ AdjustIntervalForTypmod()

static void AdjustIntervalForTypmod ( Interval interval,
int32  typmod 
)
static

Definition at line 1330 of file timestamp.c.

References Interval::day, DAY, elog, ereport, errcode(), errmsg(), ERROR, HOUR, INTERVAL_FULL_PRECISION, INTERVAL_FULL_RANGE, INTERVAL_MASK, INTERVAL_PRECISION, INTERVAL_RANGE, MAX_INTERVAL_PRECISION, MINUTE, Interval::month, MONTH, MONTHS_PER_YEAR, range(), SECOND, Interval::time, USECS_PER_HOUR, USECS_PER_MINUTE, and YEAR.

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

1331 {
1332  static const int64 IntervalScales[MAX_INTERVAL_PRECISION + 1] = {
1333  INT64CONST(1000000),
1334  INT64CONST(100000),
1335  INT64CONST(10000),
1336  INT64CONST(1000),
1337  INT64CONST(100),
1338  INT64CONST(10),
1339  INT64CONST(1)
1340  };
1341 
1342  static const int64 IntervalOffsets[MAX_INTERVAL_PRECISION + 1] = {
1343  INT64CONST(500000),
1344  INT64CONST(50000),
1345  INT64CONST(5000),
1346  INT64CONST(500),
1347  INT64CONST(50),
1348  INT64CONST(5),
1349  INT64CONST(0)
1350  };
1351 
1352  /*
1353  * Unspecified range and precision? Then not necessary to adjust. Setting
1354  * typmod to -1 is the convention for all data types.
1355  */
1356  if (typmod >= 0)
1357  {
1358  int range = INTERVAL_RANGE(typmod);
1359  int precision = INTERVAL_PRECISION(typmod);
1360 
1361  /*
1362  * Our interpretation of intervals with a limited set of fields is
1363  * that fields to the right of the last one specified are zeroed out,
1364  * but those to the left of it remain valid. Thus for example there
1365  * is no operational difference between INTERVAL YEAR TO MONTH and
1366  * INTERVAL MONTH. In some cases we could meaningfully enforce that
1367  * higher-order fields are zero; for example INTERVAL DAY could reject
1368  * nonzero "month" field. However that seems a bit pointless when we
1369  * can't do it consistently. (We cannot enforce a range limit on the
1370  * highest expected field, since we do not have any equivalent of
1371  * SQL's <interval leading field precision>.) If we ever decide to
1372  * revisit this, interval_support will likely require adjusting.
1373  *
1374  * Note: before PG 8.4 we interpreted a limited set of fields as
1375  * actually causing a "modulo" operation on a given value, potentially
1376  * losing high-order as well as low-order information. But there is
1377  * no support for such behavior in the standard, and it seems fairly
1378  * undesirable on data consistency grounds anyway. Now we only
1379  * perform truncation or rounding of low-order fields.
1380  */
1381  if (range == INTERVAL_FULL_RANGE)
1382  {
1383  /* Do nothing... */
1384  }
1385  else if (range == INTERVAL_MASK(YEAR))
1386  {
1387  interval->month = (interval->month / MONTHS_PER_YEAR) * MONTHS_PER_YEAR;
1388  interval->day = 0;
1389  interval->time = 0;
1390  }
1391  else if (range == INTERVAL_MASK(MONTH))
1392  {
1393  interval->day = 0;
1394  interval->time = 0;
1395  }
1396  /* YEAR TO MONTH */
1397  else if (range == (INTERVAL_MASK(YEAR) | INTERVAL_MASK(MONTH)))
1398  {
1399  interval->day = 0;
1400  interval->time = 0;
1401  }
1402  else if (range == INTERVAL_MASK(DAY))
1403  {
1404  interval->time = 0;
1405  }
1406  else if (range == INTERVAL_MASK(HOUR))
1407  {
1408  interval->time = (interval->time / USECS_PER_HOUR) *
1410  }
1411  else if (range == INTERVAL_MASK(MINUTE))
1412  {
1413  interval->time = (interval->time / USECS_PER_MINUTE) *
1415  }
1416  else if (range == INTERVAL_MASK(SECOND))
1417  {
1418  /* fractional-second rounding will be dealt with below */
1419  }
1420  /* DAY TO HOUR */
1421  else if (range == (INTERVAL_MASK(DAY) |
1422  INTERVAL_MASK(HOUR)))
1423  {
1424  interval->time = (interval->time / USECS_PER_HOUR) *
1426  }
1427  /* DAY TO MINUTE */
1428  else if (range == (INTERVAL_MASK(DAY) |
1429  INTERVAL_MASK(HOUR) |
1431  {
1432  interval->time = (interval->time / USECS_PER_MINUTE) *
1434  }
1435  /* DAY TO SECOND */
1436  else if (range == (INTERVAL_MASK(DAY) |
1437  INTERVAL_MASK(HOUR) |
1440  {
1441  /* fractional-second rounding will be dealt with below */
1442  }
1443  /* HOUR TO MINUTE */
1444  else if (range == (INTERVAL_MASK(HOUR) |
1446  {
1447  interval->time = (interval->time / USECS_PER_MINUTE) *
1449  }
1450  /* HOUR TO SECOND */
1451  else if (range == (INTERVAL_MASK(HOUR) |
1454  {
1455  /* fractional-second rounding will be dealt with below */
1456  }
1457  /* MINUTE TO SECOND */
1458  else if (range == (INTERVAL_MASK(MINUTE) |
1460  {
1461  /* fractional-second rounding will be dealt with below */
1462  }
1463  else
1464  elog(ERROR, "unrecognized interval typmod: %d", typmod);
1465 
1466  /* Need to adjust sub-second precision? */
1467  if (precision != INTERVAL_FULL_PRECISION)
1468  {
1469  if (precision < 0 || precision > MAX_INTERVAL_PRECISION)
1470  ereport(ERROR,
1471  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1472  errmsg("interval(%d) precision must be between %d and %d",
1473  precision, 0, MAX_INTERVAL_PRECISION)));
1474 
1475  if (interval->time >= INT64CONST(0))
1476  {
1477  interval->time = ((interval->time +
1478  IntervalOffsets[precision]) /
1479  IntervalScales[precision]) *
1480  IntervalScales[precision];
1481  }
1482  else
1483  {
1484  interval->time = -(((-interval->time +
1485  IntervalOffsets[precision]) /
1486  IntervalScales[precision]) *
1487  IntervalScales[precision]);
1488  }
1489  }
1490  }
1491 }
#define DAY
Definition: datetime.h:94
#define YEAR
Definition: datetime.h:93
#define USECS_PER_MINUTE
Definition: timestamp.h:93
int errcode(int sqlerrcode)
Definition: elog.c:698
#define SECOND
Definition: datetime.h:103
#define INTERVAL_FULL_RANGE
Definition: timestamp.h:48
int32 day
Definition: timestamp.h:47
#define MONTHS_PER_YEAR
Definition: timestamp.h:69
#define ERROR
Definition: elog.h:46
#define MAX_INTERVAL_PRECISION
Definition: timestamp.h:54
#define INTERVAL_FULL_PRECISION
Definition: timestamp.h:50
#define USECS_PER_HOUR
Definition: timestamp.h:92
TimeOffset time
Definition: timestamp.h:45
#define MINUTE
Definition: datetime.h:102
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
#define MONTH
Definition: datetime.h:92
int32 month
Definition: timestamp.h:48
#define INTERVAL_PRECISION(t)
Definition: timestamp.h:53
#define INTERVAL_RANGE(t)
Definition: timestamp.h:54
#define ereport(elevel,...)
Definition: elog.h:157
#define INTERVAL_MASK(b)
Definition: timestamp.h:45
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
#define HOUR
Definition: datetime.h:101

◆ AdjustTimestampForTypmod()

void AdjustTimestampForTypmod ( Timestamp time,
int32  typmod 
)

Definition at line 394 of file timestamp.c.

References AdjustTimestampForTypmodError().

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

395 {
396  (void) AdjustTimestampForTypmodError(time, typmod, NULL);
397 }
bool AdjustTimestampForTypmodError(Timestamp *time, int32 typmod, bool *error)
Definition: timestamp.c:339

◆ AdjustTimestampForTypmodError()

bool AdjustTimestampForTypmodError ( Timestamp time,
int32  typmod,
bool error 
)

Definition at line 339 of file timestamp.c.

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

Referenced by AdjustTimestampForTypmod().

340 {
341  static const int64 TimestampScales[MAX_TIMESTAMP_PRECISION + 1] = {
342  INT64CONST(1000000),
343  INT64CONST(100000),
344  INT64CONST(10000),
345  INT64CONST(1000),
346  INT64CONST(100),
347  INT64CONST(10),
348  INT64CONST(1)
349  };
350 
351  static const int64 TimestampOffsets[MAX_TIMESTAMP_PRECISION + 1] = {
352  INT64CONST(500000),
353  INT64CONST(50000),
354  INT64CONST(5000),
355  INT64CONST(500),
356  INT64CONST(50),
357  INT64CONST(5),
358  INT64CONST(0)
359  };
360 
361  if (!TIMESTAMP_NOT_FINITE(*time)
362  && (typmod != -1) && (typmod != MAX_TIMESTAMP_PRECISION))
363  {
364  if (typmod < 0 || typmod > MAX_TIMESTAMP_PRECISION)
365  {
366  if (error)
367  {
368  *error = true;
369  return false;
370  }
371 
372  ereport(ERROR,
373  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
374  errmsg("timestamp(%d) precision must be between %d and %d",
375  typmod, 0, MAX_TIMESTAMP_PRECISION)));
376  }
377 
378  if (*time >= INT64CONST(0))
379  {
380  *time = ((*time + TimestampOffsets[typmod]) / TimestampScales[typmod]) *
381  TimestampScales[typmod];
382  }
383  else
384  {
385  *time = -((((-*time) + TimestampOffsets[typmod]) / TimestampScales[typmod])
386  * TimestampScales[typmod]);
387  }
388  }
389 
390  return true;
391 }
static void error(void)
Definition: sql-dyntest.c:147
int errcode(int sqlerrcode)
Definition: elog.c:698
#define TIMESTAMP_NOT_FINITE(j)
Definition: timestamp.h:122
#define ERROR
Definition: elog.h:46
#define MAX_TIMESTAMP_PRECISION
Definition: timestamp.h:53
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ anytimestamp_typmod_check()

int32 anytimestamp_typmod_check ( bool  istz,
int32  typmod 
)

Definition at line 104 of file timestamp.c.

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

Referenced by anytimestamp_typmodin(), and transformSQLValueFunction().

105 {
106  if (typmod < 0)
107  ereport(ERROR,
108  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
109  errmsg("TIMESTAMP(%d)%s precision must not be negative",
110  typmod, (istz ? " WITH TIME ZONE" : ""))));
111  if (typmod > MAX_TIMESTAMP_PRECISION)
112  {
114  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
115  errmsg("TIMESTAMP(%d)%s precision reduced to maximum allowed, %d",
116  typmod, (istz ? " WITH TIME ZONE" : ""),
118  typmod = MAX_TIMESTAMP_PRECISION;
119  }
120 
121  return typmod;
122 }
int errcode(int sqlerrcode)
Definition: elog.c:698
#define ERROR
Definition: elog.h:46
#define MAX_TIMESTAMP_PRECISION
Definition: timestamp.h:53
#define WARNING
Definition: elog.h:40
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ anytimestamp_typmodin()

static int32 anytimestamp_typmodin ( bool  istz,
ArrayType ta 
)
static

Definition at line 83 of file timestamp.c.

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

Referenced by timestamptypmodin(), and timestamptztypmodin().

84 {
85  int32 *tl;
86  int n;
87 
88  tl = ArrayGetIntegerTypmods(ta, &n);
89 
90  /*
91  * we're not too tense about good error message here because grammar
92  * shouldn't allow wrong number of modifiers for TIMESTAMP
93  */
94  if (n != 1)
95  ereport(ERROR,
96  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
97  errmsg("invalid type modifier")));
98 
99  return anytimestamp_typmod_check(istz, tl[0]);
100 }
int32 * ArrayGetIntegerTypmods(ArrayType *arr, int *n)
Definition: arrayutils.c:231
int errcode(int sqlerrcode)
Definition: elog.c:698
signed int int32
Definition: c.h:429
#define ERROR
Definition: elog.h:46
#define ereport(elevel,...)
Definition: elog.h:157
int32 anytimestamp_typmod_check(bool istz, int32 typmod)
Definition: timestamp.c:104
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ anytimestamp_typmodout()

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

Definition at line 126 of file timestamp.c.

References psprintf().

Referenced by timestamptypmodout(), and timestamptztypmodout().

127 {
128  const char *tz = istz ? " with time zone" : " without time zone";
129 
130  if (typmod >= 0)
131  return psprintf("(%d)%s", (int) typmod, tz);
132  else
133  return psprintf("%s", tz);
134 }
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46

◆ clock_timestamp()

Datum clock_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 1556 of file timestamp.c.

References GetCurrentTimestamp(), and PG_RETURN_TIMESTAMPTZ.

1557 {
1559 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1580
#define PG_RETURN_TIMESTAMPTZ(x)
Definition: timestamp.h:40

◆ date2isoweek()

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

Definition at line 4429 of file timestamp.c.

References date2j(), and j2day().

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

4430 {
4431  float8 result;
4432  int day0,
4433  day4,
4434  dayn;
4435 
4436  /* current day */
4437  dayn = date2j(year, mon, mday);
4438 
4439  /* fourth day of current year */
4440  day4 = date2j(year, 1, 4);
4441 
4442  /* day0 == offset to first day of week (Monday) */
4443  day0 = j2day(day4 - 1);
4444 
4445  /*
4446  * We need the first week containing a Thursday, otherwise this day falls
4447  * into the previous year for purposes of counting weeks
4448  */
4449  if (dayn < day4 - day0)
4450  {
4451  day4 = date2j(year - 1, 1, 4);
4452 
4453  /* day0 == offset to first day of week (Monday) */
4454  day0 = j2day(day4 - 1);
4455  }
4456 
4457  result = (dayn - (day4 - day0)) / 7 + 1;
4458 
4459  /*
4460  * Sometimes the last few days in a year will fall into the first week of
4461  * the next year, so check for this.
4462  */
4463  if (result >= 52)
4464  {
4465  day4 = date2j(year + 1, 1, 4);
4466 
4467  /* day0 == offset to first day of week (Monday) */
4468  day0 = j2day(day4 - 1);
4469 
4470  if (dayn >= day4 - day0)
4471  result = (dayn - (day4 - day0)) / 7 + 1;
4472  }
4473 
4474  return (int) result;
4475 }
double float8
Definition: c.h:565
int j2day(int date)
Definition: datetime.c:327
int date2j(int y, int m, int d)
Definition: datetime.c:269

◆ date2isoyear()

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

Definition at line 4484 of file timestamp.c.

References date2j(), and j2day().

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

4485 {
4486  float8 result;
4487  int day0,
4488  day4,
4489  dayn;
4490 
4491  /* current day */
4492  dayn = date2j(year, mon, mday);
4493 
4494  /* fourth day of current year */
4495  day4 = date2j(year, 1, 4);
4496 
4497  /* day0 == offset to first day of week (Monday) */
4498  day0 = j2day(day4 - 1);
4499 
4500  /*
4501  * We need the first week containing a Thursday, otherwise this day falls
4502  * into the previous year for purposes of counting weeks
4503  */
4504  if (dayn < day4 - day0)
4505  {
4506  day4 = date2j(year - 1, 1, 4);
4507 
4508  /* day0 == offset to first day of week (Monday) */
4509  day0 = j2day(day4 - 1);
4510 
4511  year--;
4512  }
4513 
4514  result = (dayn - (day4 - day0)) / 7 + 1;
4515 
4516  /*
4517  * Sometimes the last few days in a year will fall into the first week of
4518  * the next year, so check for this.
4519  */
4520  if (result >= 52)
4521  {
4522  day4 = date2j(year + 1, 1, 4);
4523 
4524  /* day0 == offset to first day of week (Monday) */
4525  day0 = j2day(day4 - 1);
4526 
4527  if (dayn >= day4 - day0)
4528  year++;
4529  }
4530 
4531  return year;
4532 }
double float8
Definition: c.h:565
int j2day(int date)
Definition: datetime.c:327
int date2j(int y, int m, int d)
Definition: datetime.c:269

◆ date2isoyearday()

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

Definition at line 4541 of file timestamp.c.

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

Referenced by DCH_to_char().

4542 {
4543  return date2j(year, mon, mday) - isoweek2j(date2isoyear(year, mon, mday), 1) + 1;
4544 }
int date2isoyear(int year, int mon, int mday)
Definition: timestamp.c:4484
int isoweek2j(int year, int week)
Definition: timestamp.c:4378
int date2j(int y, int m, int d)
Definition: datetime.c:269

◆ dt2local()

static Timestamp dt2local ( Timestamp  dt,
int  timezone 
)
static

Definition at line 2016 of file timestamp.c.

References USECS_PER_SEC.

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

2017 {
2018  dt -= (tz * USECS_PER_SEC);
2019  return dt;
2020 }
#define USECS_PER_SEC
Definition: timestamp.h:94

◆ dt2time()

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

Definition at line 1795 of file timestamp.c.

References USECS_PER_HOUR, USECS_PER_MINUTE, and USECS_PER_SEC.

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

1796 {
1797  TimeOffset time;
1798 
1799  time = jd;
1800 
1801  *hour = time / USECS_PER_HOUR;
1802  time -= (*hour) * USECS_PER_HOUR;
1803  *min = time / USECS_PER_MINUTE;
1804  time -= (*min) * USECS_PER_MINUTE;
1805  *sec = time / USECS_PER_SEC;
1806  *fsec = time - (*sec * USECS_PER_SEC);
1807 } /* dt2time() */
#define USECS_PER_SEC
Definition: timestamp.h:94
#define USECS_PER_MINUTE
Definition: timestamp.h:93
#define USECS_PER_HOUR
Definition: timestamp.h:92
int64 TimeOffset
Definition: timestamp.h:40

◆ EncodeSpecialTimestamp()

void EncodeSpecialTimestamp ( Timestamp  dt,
char *  str 
)

Definition at line 1533 of file timestamp.c.

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

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

1534 {
1535  if (TIMESTAMP_IS_NOBEGIN(dt))
1536  strcpy(str, EARLY);
1537  else if (TIMESTAMP_IS_NOEND(dt))
1538  strcpy(str, LATE);
1539  else /* shouldn't happen */
1540  elog(ERROR, "invalid argument for EncodeSpecialTimestamp");
1541 }
#define LATE
Definition: datetime.h:41
#define ERROR
Definition: elog.h:46
#define TIMESTAMP_IS_NOEND(j)
Definition: timestamp.h:120
#define TIMESTAMP_IS_NOBEGIN(j)
Definition: timestamp.h:115
#define elog(elevel,...)
Definition: elog.h:232
#define EARLY
Definition: datetime.h:40

◆ extract_interval()

Datum extract_interval ( PG_FUNCTION_ARGS  )

Definition at line 5347 of file timestamp.c.

References interval_part_common().

5348 {
5349  return interval_part_common(fcinfo, true);
5350 }
static Datum interval_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition: timestamp.c:5174

◆ extract_timestamp()

Datum extract_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 4891 of file timestamp.c.

References timestamp_part_common().

4892 {
4893  return timestamp_part_common(fcinfo, true);
4894 }
static Datum timestamp_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition: timestamp.c:4627

◆ extract_timestamptz()

Datum extract_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 5164 of file timestamp.c.

References timestamptz_part_common().

5165 {
5166  return timestamptz_part_common(fcinfo, true);
5167 }
static Datum timestamptz_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition: timestamp.c:4900

◆ float8_timestamptz()

Datum float8_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 717 of file timestamp.c.

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.

718 {
719  float8 seconds = PG_GETARG_FLOAT8(0);
720  TimestampTz result;
721 
722  /* Deal with NaN and infinite inputs ... */
723  if (isnan(seconds))
724  ereport(ERROR,
725  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
726  errmsg("timestamp cannot be NaN")));
727 
728  if (isinf(seconds))
729  {
730  if (seconds < 0)
731  TIMESTAMP_NOBEGIN(result);
732  else
733  TIMESTAMP_NOEND(result);
734  }
735  else
736  {
737  /* Out of range? */
738  if (seconds <
740  || seconds >=
742  ereport(ERROR,
743  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
744  errmsg("timestamp out of range: \"%g\"", seconds)));
745 
746  /* Convert UNIX epoch to Postgres epoch */
748 
749  seconds = rint(seconds * USECS_PER_SEC);
750  result = (int64) seconds;
751 
752  /* Recheck in case roundoff produces something just out of range */
753  if (!IS_VALID_TIMESTAMP(result))
754  ereport(ERROR,
755  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
756  errmsg("timestamp out of range: \"%g\"",
757  PG_GETARG_FLOAT8(0))));
758  }
759 
760  PG_RETURN_TIMESTAMP(result);
761 }
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:282
#define TIMESTAMP_NOEND(j)
Definition: timestamp.h:117
#define TIMESTAMP_END_JULIAN
Definition: timestamp.h:181
#define USECS_PER_SEC
Definition: timestamp.h:94
int64 TimestampTz
Definition: timestamp.h:39
int errcode(int sqlerrcode)
Definition: elog.c:698
#define ERROR
Definition: elog.h:46
double float8
Definition: c.h:565
#define SECS_PER_DAY
Definition: timestamp.h:86
#define TIMESTAMP_NOBEGIN(j)
Definition: timestamp.h:112
#define ereport(elevel,...)
Definition: elog.h:157
#define IS_VALID_TIMESTAMP(t)
Definition: timestamp.h:195
#define PG_RETURN_TIMESTAMP(x)
Definition: timestamp.h:39
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define UNIX_EPOCH_JDATE
Definition: timestamp.h:162
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:163
#define DATETIME_MIN_JULIAN
Definition: timestamp.h:179

◆ generate_series_timestamp()

Datum generate_series_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 5736 of file timestamp.c.

References generate_series_timestamp_fctx::current, DatumGetTimestamp, DirectFunctionCall2, ereport, errcode(), errmsg(), ERROR, generate_series_timestamp_fctx::finish, interval_cmp_internal(), MemoryContextSwitchTo(), MemSet, 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.

5737 {
5738  FuncCallContext *funcctx;
5740  Timestamp result;
5741 
5742  /* stuff done only on the first call of the function */
5743  if (SRF_IS_FIRSTCALL())
5744  {
5745  Timestamp start = PG_GETARG_TIMESTAMP(0);
5746  Timestamp finish = PG_GETARG_TIMESTAMP(1);
5747  Interval *step = PG_GETARG_INTERVAL_P(2);
5748  MemoryContext oldcontext;
5749  Interval interval_zero;
5750 
5751  /* create a function context for cross-call persistence */
5752  funcctx = SRF_FIRSTCALL_INIT();
5753 
5754  /*
5755  * switch to memory context appropriate for multiple function calls
5756  */
5757  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
5758 
5759  /* allocate memory for user context */
5762 
5763  /*
5764  * Use fctx to keep state from call to call. Seed current with the
5765  * original start value
5766  */
5767  fctx->current = start;
5768  fctx->finish = finish;
5769  fctx->step = *step;
5770 
5771  /* Determine sign of the interval */
5772  MemSet(&interval_zero, 0, sizeof(Interval));
5773  fctx->step_sign = interval_cmp_internal(&fctx->step, &interval_zero);
5774 
5775  if (fctx->step_sign == 0)
5776  ereport(ERROR,
5777  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5778  errmsg("step size cannot equal zero")));
5779 
5780  funcctx->user_fctx = fctx;
5781  MemoryContextSwitchTo(oldcontext);
5782  }
5783 
5784  /* stuff done on every call of the function */
5785  funcctx = SRF_PERCALL_SETUP();
5786 
5787  /*
5788  * get the saved state and use current as the result for this iteration
5789  */
5790  fctx = funcctx->user_fctx;
5791  result = fctx->current;
5792 
5793  if (fctx->step_sign > 0 ?
5794  timestamp_cmp_internal(result, fctx->finish) <= 0 :
5795  timestamp_cmp_internal(result, fctx->finish) >= 0)
5796  {
5797  /* increment current in preparation for next iteration */
5799  TimestampGetDatum(fctx->current),
5800  PointerGetDatum(&fctx->step)));
5801 
5802  /* do when there is more left to send */
5803  SRF_RETURN_NEXT(funcctx, TimestampGetDatum(result));
5804  }
5805  else
5806  {
5807  /* do when there is no more left */
5808  SRF_RETURN_DONE(funcctx);
5809  }
5810 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
int timestamp_cmp_internal(Timestamp dt1, Timestamp dt2)
Definition: timestamp.c:2090
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:293
#define PointerGetDatum(X)
Definition: postgres.h:600
#define PG_GETARG_TIMESTAMP(n)
Definition: timestamp.h:35
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
int errcode(int sqlerrcode)
Definition: elog.c:698
#define MemSet(start, val, len)
Definition: c.h:1008
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:297
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:299
Datum timestamp_pl_interval(PG_FUNCTION_ARGS)
Definition: timestamp.c:2838
#define ERROR
Definition: elog.h:46
#define TimestampGetDatum(X)
Definition: timestamp.h:31
int64 Timestamp
Definition: timestamp.h:38
#define ereport(elevel,...)
Definition: elog.h:157
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:101
static int interval_cmp_internal(Interval *interval1, Interval *interval2)
Definition: timestamp.c:2374
void * user_fctx
Definition: funcapi.h:82
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:628
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:317
#define DatumGetTimestamp(X)
Definition: timestamp.h:27
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:295

◆ generate_series_timestamptz()

Datum generate_series_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 5816 of file timestamp.c.

References generate_series_timestamptz_fctx::current, DatumGetTimestampTz, DirectFunctionCall2, ereport, errcode(), errmsg(), ERROR, generate_series_timestamptz_fctx::finish, interval_cmp_internal(), MemoryContextSwitchTo(), MemSet, FuncCallContext::multi_call_memory_ctx, palloc(), PG_GETARG_INTERVAL_P, PG_GETARG_TIMESTAMPTZ, PointerGetDatum, 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(), TimestampTzGetDatum, and FuncCallContext::user_fctx.

5817 {
5818  FuncCallContext *funcctx;
5820  TimestampTz result;
5821 
5822  /* stuff done only on the first call of the function */
5823  if (SRF_IS_FIRSTCALL())
5824  {
5826  TimestampTz finish = PG_GETARG_TIMESTAMPTZ(1);
5827  Interval *step = PG_GETARG_INTERVAL_P(2);
5828  MemoryContext oldcontext;
5829  Interval interval_zero;
5830 
5831  /* create a function context for cross-call persistence */
5832  funcctx = SRF_FIRSTCALL_INIT();
5833 
5834  /*
5835  * switch to memory context appropriate for multiple function calls
5836  */
5837  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
5838 
5839  /* allocate memory for user context */
5842 
5843  /*
5844  * Use fctx to keep state from call to call. Seed current with the
5845  * original start value
5846  */
5847  fctx->current = start;
5848  fctx->finish = finish;
5849  fctx->step = *step;
5850 
5851  /* Determine sign of the interval */
5852  MemSet(&interval_zero, 0, sizeof(Interval));
5853  fctx->step_sign = interval_cmp_internal(&fctx->step, &interval_zero);
5854 
5855  if (fctx->step_sign == 0)
5856  ereport(ERROR,
5857  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5858  errmsg("step size cannot equal zero")));
5859 
5860  funcctx->user_fctx = fctx;
5861  MemoryContextSwitchTo(oldcontext);
5862  }
5863 
5864  /* stuff done on every call of the function */
5865  funcctx = SRF_PERCALL_SETUP();
5866 
5867  /*
5868  * get the saved state and use current as the result for this iteration
5869  */
5870  fctx = funcctx->user_fctx;
5871  result = fctx->current;
5872 
5873  if (fctx->step_sign > 0 ?
5874  timestamp_cmp_internal(result, fctx->finish) <= 0 :
5875  timestamp_cmp_internal(result, fctx->finish) >= 0)
5876  {
5877  /* increment current in preparation for next iteration */
5880  PointerGetDatum(&fctx->step)));
5881 
5882  /* do when there is more left to send */
5883  SRF_RETURN_NEXT(funcctx, TimestampTzGetDatum(result));
5884  }
5885  else
5886  {
5887  /* do when there is no more left */
5888  SRF_RETURN_DONE(funcctx);
5889  }
5890 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
int timestamp_cmp_internal(Timestamp dt1, Timestamp dt2)
Definition: timestamp.c:2090
int64 TimestampTz
Definition: timestamp.h:39
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:293
#define PointerGetDatum(X)
Definition: postgres.h:600
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
int errcode(int sqlerrcode)
Definition: elog.c:698
#define MemSet(start, val, len)
Definition: c.h:1008
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:297
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:299
#define ERROR
Definition: elog.h:46
#define TimestampTzGetDatum(X)
Definition: timestamp.h:32
#define DatumGetTimestampTz(X)
Definition: timestamp.h:28
#define ereport(elevel,...)
Definition: elog.h:157
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:101
Datum timestamptz_pl_interval(PG_FUNCTION_ARGS)
Definition: timestamp.c:2943
static int interval_cmp_internal(Interval *interval1, Interval *interval2)
Definition: timestamp.c:2374
void * user_fctx
Definition: funcapi.h:82
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define PG_GETARG_TIMESTAMPTZ(n)
Definition: timestamp.h:36
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:628
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:317
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:295

◆ GetCurrentTimestamp()

TimestampTz GetCurrentTimestamp ( void  )

Definition at line 1580 of file timestamp.c.

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

Referenced by ApplyLauncherMain(), ApplyWorkerMain(), asyncQueueFillWarning(), autoprewarm_main(), autovac_refresh_stats(), AutoVacLauncherMain(), backend_read_statsfile(), BackgroundWriterMain(), begin_startup_progress_phase(), 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(), drandom(), enable_timeout_after(), enable_timeout_at(), enable_timeout_every(), enable_timeouts(), entry_reset(), get_role_password(), GetCurrentTransactionStopTimestamp(), GetReplicationApplyDelay(), GetSnapshotCurrentTimestamp(), handle_sig_alarm(), has_startup_progress_timeout_expired(), heap_vacuum_rel(), InitProcessGlobals(), launcher_determine_sleep(), LockBufferForCleanup(), log_disconnections(), LogCheckpointEnd(), logicalrep_worker_launch(), LogicalRepApplyLoop(), maybe_start_bgworkers(), perform_base_backup(), pgfdw_cancel_query(), pgfdw_exec_cleanup_query(), pgfdw_get_cleanup_result(), pgss_shmem_startup(), pgstat_read_statsfiles(), pgstat_recv_inquiry(), pgstat_recv_resetreplslotcounter(), pgstat_recv_resetsharedcounter(), pgstat_recv_resetsinglecounter(), pgstat_recv_resetslrucounter(), pgstat_report_activity(), pgstat_report_analyze(), pgstat_report_autovac(), pgstat_report_checksum_failures_in_db(), pgstat_report_vacuum(), pgstat_send_archiver(), pgstat_send_wal(), pgstat_write_statsfiles(), PostgresSingleUserMain(), PostmasterMain(), PrepareTransaction(), process_syncing_tables_for_apply(), ProcessRepliesIfAny(), ProcessStandbyReplyMessage(), ProcessWalSndrMessage(), ProcSleep(), rebuild_database_list(), RecordTransactionAbort(), RecordTransactionAbortPrepared(), RecordTransactionCommitPrepared(), recoveryApplyDelay(), reschedule_timeouts(), reset_dbentry_counters(), ResolveRecoveryConflictWithBufferPin(), ResolveRecoveryConflictWithLock(), ResolveRecoveryConflictWithVirtualXIDs(), send_feedback(), SetCurrentStatementStartTimestamp(), SetCurrentTransactionStopTimestamp(), StartTransaction(), StartupXLOG(), test_pattern(), throttle(), UpdateWorkerStats(), WaitExceedsMaxStandbyDelay(), WaitForWALToBecomeAvailable(), WalReceiverMain(), WalSndKeepalive(), WalSndLoop(), WalSndUpdateProgress(), WalSndWaitForWal(), WalSndWriteData(), XLogBackgroundFlush(), XLogFileRead(), XLogRestorePoint(), XLogSendPhysical(), XLogWalRcvSendHSFeedback(), and XLogWalRcvSendReply().

1581 {
1582  TimestampTz result;
1583  struct timeval tp;
1584 
1585  gettimeofday(&tp, NULL);
1586 
1587  result = (TimestampTz) tp.tv_sec -
1589  result = (result * USECS_PER_SEC) + tp.tv_usec;
1590 
1591  return result;
1592 }
int gettimeofday(struct timeval *tp, struct timezone *tzp)
Definition: gettimeofday.c:104
#define USECS_PER_SEC
Definition: timestamp.h:94
int64 TimestampTz
Definition: timestamp.h:39
#define SECS_PER_DAY
Definition: timestamp.h:86
#define UNIX_EPOCH_JDATE
Definition: timestamp.h:162
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:163

◆ GetEpochTime()

void GetEpochTime ( struct pg_tm tm)

Definition at line 2048 of file timestamp.c.

References elog, epoch, ERROR, pg_gmtime(), 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().

2049 {
2050  struct pg_tm *t0;
2051  pg_time_t epoch = 0;
2052 
2053  t0 = pg_gmtime(&epoch);
2054 
2055  if (t0 == NULL)
2056  elog(ERROR, "could not convert epoch to timestamp: %m");
2057 
2058  tm->tm_year = t0->tm_year;
2059  tm->tm_mon = t0->tm_mon;
2060  tm->tm_mday = t0->tm_mday;
2061  tm->tm_hour = t0->tm_hour;
2062  tm->tm_min = t0->tm_min;
2063  tm->tm_sec = t0->tm_sec;
2064 
2065  tm->tm_year += 1900;
2066  tm->tm_mon++;
2067 }
int64 pg_time_t
Definition: pgtime.h:23
struct pg_tm * pg_gmtime(const pg_time_t *timep)
Definition: localtime.c:1387
int tm_hour
Definition: pgtime.h:36
Definition: pgtime.h:32
#define ERROR
Definition: elog.h:46
int tm_mday
Definition: pgtime.h:37
int tm_mon
Definition: pgtime.h:38
int tm_year
Definition: pgtime.h:39
#define elog(elevel,...)
Definition: elog.h:232
static const unsigned __int64 epoch
Definition: gettimeofday.c:34
int tm_sec
Definition: pgtime.h:34
int tm_min
Definition: pgtime.h:35

◆ GetSQLCurrentTimestamp()

TimestampTz GetSQLCurrentTimestamp ( int32  typmod)

Definition at line 1598 of file timestamp.c.

References AdjustTimestampForTypmod(), and GetCurrentTransactionStartTimestamp().

Referenced by ExecEvalSQLValueFunction().

1599 {
1600  TimestampTz ts;
1601 
1603  if (typmod >= 0)
1604  AdjustTimestampForTypmod(&ts, typmod);
1605  return ts;
1606 }
int64 TimestampTz
Definition: timestamp.h:39
void AdjustTimestampForTypmod(Timestamp *time, int32 typmod)
Definition: timestamp.c:394
TimestampTz GetCurrentTransactionStartTimestamp(void)
Definition: xact.c:799

◆ GetSQLLocalTimestamp()

Timestamp GetSQLLocalTimestamp ( int32  typmod)

Definition at line 1612 of file timestamp.c.

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

Referenced by ExecEvalSQLValueFunction().

1613 {
1614  Timestamp ts;
1615 
1617  if (typmod >= 0)
1618  AdjustTimestampForTypmod(&ts, typmod);
1619  return ts;
1620 }
void AdjustTimestampForTypmod(Timestamp *time, int32 typmod)
Definition: timestamp.c:394
static Timestamp timestamptz2timestamp(TimestampTz timestamp)
Definition: timestamp.c:5587
int64 Timestamp
Definition: timestamp.h:38
TimestampTz GetCurrentTransactionStartTimestamp(void)
Definition: xact.c:799

◆ in_range_interval_interval()

Datum in_range_interval_interval ( PG_FUNCTION_ARGS  )

Definition at line 3377 of file timestamp.c.

References DatumGetIntervalP, DirectFunctionCall2, ereport, errcode(), errmsg(), ERROR, int128_compare(), int64_to_int128(), interval_cmp_internal(), interval_cmp_value(), interval_mi(), interval_pl(), IntervalPGetDatum, PG_GETARG_BOOL, PG_GETARG_INTERVAL_P, PG_RETURN_BOOL, and val.

3378 {
3380  Interval *base = PG_GETARG_INTERVAL_P(1);
3381  Interval *offset = PG_GETARG_INTERVAL_P(2);
3382  bool sub = PG_GETARG_BOOL(3);
3383  bool less = PG_GETARG_BOOL(4);
3384  Interval *sum;
3385 
3386  if (int128_compare(interval_cmp_value(offset), int64_to_int128(0)) < 0)
3387  ereport(ERROR,
3388  (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
3389  errmsg("invalid preceding or following size in window function")));
3390 
3391  /* We don't currently bother to avoid overflow hazards here */
3392  if (sub)
3394  IntervalPGetDatum(base),
3395  IntervalPGetDatum(offset)));
3396  else
3398  IntervalPGetDatum(base),
3399  IntervalPGetDatum(offset)));
3400 
3401  if (less)
3402  PG_RETURN_BOOL(interval_cmp_internal(val, sum) <= 0);
3403  else
3404  PG_RETURN_BOOL(interval_cmp_internal(val, sum) >= 0);
3405 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define DatumGetIntervalP(X)
Definition: timestamp.h:29
static int int128_compare(INT128 x, INT128 y)
Definition: int128.h:238
int errcode(int sqlerrcode)
Definition: elog.c:698
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
Datum interval_mi(PG_FUNCTION_ARGS)
Definition: timestamp.c:3136
Datum interval_pl(PG_FUNCTION_ARGS)
Definition: timestamp.c:3102
#define ERROR
Definition: elog.h:46
#define IntervalPGetDatum(X)
Definition: timestamp.h:33
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
static INT128 int64_to_int128(int64 v)
Definition: int128.h:255
#define ereport(elevel,...)
Definition: elog.h:157
static int interval_cmp_internal(Interval *interval1, Interval *interval2)
Definition: timestamp.c:2374
int errmsg(const char *fmt,...)
Definition: elog.c:909
long val
Definition: informix.c:664
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:628
static INT128 interval_cmp_value(const Interval *interval)
Definition: timestamp.c:2352

◆ in_range_timestamp_interval()

Datum in_range_timestamp_interval ( PG_FUNCTION_ARGS  )

Definition at line 3346 of file timestamp.c.

References DatumGetTimestamp, DirectFunctionCall2, ereport, errcode(), errmsg(), ERROR, int128_compare(), int64_to_int128(), interval_cmp_value(), IntervalPGetDatum, PG_GETARG_BOOL, PG_GETARG_INTERVAL_P, PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, timestamp_mi_interval(), timestamp_pl_interval(), TimestampGetDatum, and val.

Referenced by in_range_date_interval().

3347 {
3349  Timestamp base = PG_GETARG_TIMESTAMP(1);
3350  Interval *offset = PG_GETARG_INTERVAL_P(2);
3351  bool sub = PG_GETARG_BOOL(3);
3352  bool less = PG_GETARG_BOOL(4);
3353  Timestamp sum;
3354 
3355  if (int128_compare(interval_cmp_value(offset), int64_to_int128(0)) < 0)
3356  ereport(ERROR,
3357  (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
3358  errmsg("invalid preceding or following size in window function")));
3359 
3360  /* We don't currently bother to avoid overflow hazards here */
3361  if (sub)
3363  TimestampGetDatum(base),
3364  IntervalPGetDatum(offset)));
3365  else
3367  TimestampGetDatum(base),
3368  IntervalPGetDatum(offset)));
3369 
3370  if (less)
3371  PG_RETURN_BOOL(val <= sum);
3372  else
3373  PG_RETURN_BOOL(val >= sum);
3374 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define PG_GETARG_TIMESTAMP(n)
Definition: timestamp.h:35
static int int128_compare(INT128 x, INT128 y)
Definition: int128.h:238
int errcode(int sqlerrcode)
Definition: elog.c:698
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
Datum timestamp_mi_interval(PG_FUNCTION_ARGS)
Definition: timestamp.c:2917
Datum timestamp_pl_interval(PG_FUNCTION_ARGS)
Definition: timestamp.c:2838
#define ERROR
Definition: elog.h:46
#define IntervalPGetDatum(X)
Definition: timestamp.h:33
#define TimestampGetDatum(X)
Definition: timestamp.h:31
int64 Timestamp
Definition: timestamp.h:38
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
static INT128 int64_to_int128(int64 v)
Definition: int128.h:255
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
long val
Definition: informix.c:664
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:628
static INT128 interval_cmp_value(const Interval *interval)
Definition: timestamp.c:2352
#define DatumGetTimestamp(X)
Definition: timestamp.h:27

◆ in_range_timestamptz_interval()

Datum in_range_timestamptz_interval ( PG_FUNCTION_ARGS  )

Definition at line 3315 of file timestamp.c.

References DatumGetTimestampTz, DirectFunctionCall2, ereport, errcode(), errmsg(), ERROR, int128_compare(), int64_to_int128(), interval_cmp_value(), IntervalPGetDatum, PG_GETARG_BOOL, PG_GETARG_INTERVAL_P, PG_GETARG_TIMESTAMPTZ, PG_RETURN_BOOL, timestamptz_mi_interval(), timestamptz_pl_interval(), TimestampTzGetDatum, and val.

3316 {
3319  Interval *offset = PG_GETARG_INTERVAL_P(2);
3320  bool sub = PG_GETARG_BOOL(3);
3321  bool less = PG_GETARG_BOOL(4);
3322  TimestampTz sum;
3323 
3324  if (int128_compare(interval_cmp_value(offset), int64_to_int128(0)) < 0)
3325  ereport(ERROR,
3326  (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
3327  errmsg("invalid preceding or following size in window function")));
3328 
3329  /* We don't currently bother to avoid overflow hazards here */
3330  if (sub)
3332  TimestampTzGetDatum(base),
3333  IntervalPGetDatum(offset)));
3334  else
3336  TimestampTzGetDatum(base),
3337  IntervalPGetDatum(offset)));
3338 
3339  if (less)
3340  PG_RETURN_BOOL(val <= sum);
3341  else
3342  PG_RETURN_BOOL(val >= sum);
3343 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
int64 TimestampTz
Definition: timestamp.h:39
static int int128_compare(INT128 x, INT128 y)
Definition: int128.h:238
int errcode(int sqlerrcode)
Definition: elog.c:698
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
#define ERROR
Definition: elog.h:46
#define IntervalPGetDatum(X)
Definition: timestamp.h:33
#define TimestampTzGetDatum(X)
Definition: timestamp.h:32
#define DatumGetTimestampTz(X)
Definition: timestamp.h:28
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
static INT128 int64_to_int128(int64 v)
Definition: int128.h:255
#define ereport(elevel,...)
Definition: elog.h:157
Datum timestamptz_mi_interval(PG_FUNCTION_ARGS)
Definition: timestamp.c:3027
Datum timestamptz_pl_interval(PG_FUNCTION_ARGS)
Definition: timestamp.c:2943
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define PG_GETARG_TIMESTAMPTZ(n)
Definition: timestamp.h:36
long val
Definition: informix.c:664
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:628
static INT128 interval_cmp_value(const Interval *interval)
Definition: timestamp.c:2352

◆ interval2tm()

int interval2tm ( Interval  span,
struct pg_tm tm,
fsec_t fsec 
)

Definition at line 1966 of file timestamp.c.

References Interval::day, ereport, errcode(), errmsg(), ERROR, Interval::month, MONTHS_PER_YEAR, SAMESIGN, Interval::time, pg_tm::tm_hour, pg_tm::tm_mday, pg_tm::tm_min, pg_tm::tm_mon, pg_tm::tm_sec, pg_tm::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().

1967 {
1968  TimeOffset time;
1969  TimeOffset tfrac;
1970 
1971  tm->tm_year = span.month / MONTHS_PER_YEAR;
1972  tm->tm_mon = span.month % MONTHS_PER_YEAR;
1973  tm->tm_mday = span.day;
1974  time = span.time;
1975 
1976  tfrac = time / USECS_PER_HOUR;
1977  time -= tfrac * USECS_PER_HOUR;
1978  tm->tm_hour = tfrac;
1979  if (!SAMESIGN(tm->tm_hour, tfrac))
1980  ereport(ERROR,
1981  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1982  errmsg("interval out of range")));
1983  tfrac = time / USECS_PER_MINUTE;
1984  time -= tfrac * USECS_PER_MINUTE;
1985  tm->tm_min = tfrac;
1986  tfrac = time / USECS_PER_SEC;
1987  *fsec = time - (tfrac * USECS_PER_SEC);
1988  tm->tm_sec = tfrac;
1989 
1990  return 0;
1991 }
#define USECS_PER_SEC
Definition: timestamp.h:94
int tm_hour
Definition: pgtime.h:36
#define USECS_PER_MINUTE
Definition: timestamp.h:93
int errcode(int sqlerrcode)
Definition: elog.c:698
int32 day
Definition: timestamp.h:47
#define MONTHS_PER_YEAR
Definition: timestamp.h:69
#define ERROR
Definition: elog.h:46
int tm_mday
Definition: pgtime.h:37
int tm_mon
Definition: pgtime.h:38
#define USECS_PER_HOUR
Definition: timestamp.h:92
TimeOffset time
Definition: timestamp.h:45
#define SAMESIGN(a, b)
Definition: timestamp.c:49
int32 month
Definition: timestamp.h:48
int64 TimeOffset
Definition: timestamp.h:40
#define ereport(elevel,...)
Definition: elog.h:157
int tm_year
Definition: pgtime.h:39
int errmsg(const char *fmt,...)
Definition: elog.c:909
int tm_sec
Definition: pgtime.h:34
int tm_min
Definition: pgtime.h:35

◆ interval_accum()

Datum interval_accum ( PG_FUNCTION_ARGS  )

Definition at line 3419 of file timestamp.c.

References construct_array(), DatumGetIntervalP, deconstruct_array(), DirectFunctionCall2, elog, ERROR, interval_pl(), IntervalPGetDatum, newval, PG_GETARG_ARRAYTYPE_P, PG_GETARG_INTERVAL_P, PG_RETURN_ARRAYTYPE_P, and Interval::time.

3420 {
3421  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3423  Datum *transdatums;
3424  int ndatums;
3425  Interval sumX,
3426  N;
3427  Interval *newsum;
3428  ArrayType *result;
3429 
3430  deconstruct_array(transarray,
3431  INTERVALOID, sizeof(Interval), false, TYPALIGN_DOUBLE,
3432  &transdatums, NULL, &ndatums);
3433  if (ndatums != 2)
3434  elog(ERROR, "expected 2-element interval array");
3435 
3436  sumX = *(DatumGetIntervalP(transdatums[0]));
3437  N = *(DatumGetIntervalP(transdatums[1]));
3438 
3440  IntervalPGetDatum(&sumX),
3441  IntervalPGetDatum(newval)));
3442  N.time += 1;
3443 
3444  transdatums[0] = IntervalPGetDatum(newsum);
3445  transdatums[1] = IntervalPGetDatum(&N);
3446 
3447  result = construct_array(transdatums, 2,
3448  INTERVALOID, sizeof(Interval), false, TYPALIGN_DOUBLE);
3449 
3450  PG_RETURN_ARRAYTYPE_P(result);
3451 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define DatumGetIntervalP(X)
Definition: timestamp.h:29
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3319
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:256
Datum interval_pl(PG_FUNCTION_ARGS)
Definition: timestamp.c:3102
#define ERROR
Definition: elog.h:46
#define IntervalPGetDatum(X)
Definition: timestamp.h:33
TimeOffset time
Definition: timestamp.h:45
#define PG_RETURN_ARRAYTYPE_P(x)
Definition: array.h:258
uintptr_t Datum
Definition: postgres.h:411
#define newval
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3491
#define elog(elevel,...)
Definition: elog.h:232
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:628

◆ interval_accum_inv()

Datum interval_accum_inv ( PG_FUNCTION_ARGS  )

Definition at line 3503 of file timestamp.c.

References construct_array(), DatumGetIntervalP, deconstruct_array(), DirectFunctionCall2, elog, ERROR, interval_mi(), IntervalPGetDatum, newval, PG_GETARG_ARRAYTYPE_P, PG_GETARG_INTERVAL_P, PG_RETURN_ARRAYTYPE_P, and Interval::time.

3504 {
3505  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3507  Datum *transdatums;
3508  int ndatums;
3509  Interval sumX,
3510  N;
3511  Interval *newsum;
3512  ArrayType *result;
3513 
3514  deconstruct_array(transarray,
3515  INTERVALOID, sizeof(Interval), false, TYPALIGN_DOUBLE,
3516  &transdatums, NULL, &ndatums);
3517  if (ndatums != 2)
3518  elog(ERROR, "expected 2-element interval array");
3519 
3520  sumX = *(DatumGetIntervalP(transdatums[0]));
3521  N = *(DatumGetIntervalP(transdatums[1]));
3522 
3524  IntervalPGetDatum(&sumX),
3525  IntervalPGetDatum(newval)));
3526  N.time -= 1;
3527 
3528  transdatums[0] = IntervalPGetDatum(newsum);
3529  transdatums[1] = IntervalPGetDatum(&N);
3530 
3531  result = construct_array(transdatums, 2,
3532  INTERVALOID, sizeof(Interval), false, TYPALIGN_DOUBLE);
3533 
3534  PG_RETURN_ARRAYTYPE_P(result);
3535 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define DatumGetIntervalP(X)
Definition: timestamp.h:29
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3319
Datum interval_mi(PG_FUNCTION_ARGS)
Definition: timestamp.c:3136
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:256
#define ERROR
Definition: elog.h:46
#define IntervalPGetDatum(X)
Definition: timestamp.h:33
TimeOffset time
Definition: timestamp.h:45
#define PG_RETURN_ARRAYTYPE_P(x)
Definition: array.h:258
uintptr_t Datum
Definition: postgres.h:411
#define newval
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3491
#define elog(elevel,...)
Definition: elog.h:232
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:628

◆ interval_avg()

Datum interval_avg ( PG_FUNCTION_ARGS  )

Definition at line 3538 of file timestamp.c.

References DatumGetIntervalP, deconstruct_array(), DirectFunctionCall2, elog, ERROR, Float8GetDatum(), interval_div(), IntervalPGetDatum, PG_GETARG_ARRAYTYPE_P, PG_RETURN_NULL, and Interval::time.

3539 {
3540  ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
3541  Datum *transdatums;
3542  int ndatums;
3543  Interval sumX,
3544  N;
3545 
3546  deconstruct_array(transarray,
3547  INTERVALOID, sizeof(Interval), false, TYPALIGN_DOUBLE,
3548  &transdatums, NULL, &ndatums);
3549  if (ndatums != 2)
3550  elog(ERROR, "expected 2-element interval array");
3551 
3552  sumX = *(DatumGetIntervalP(transdatums[0]));
3553  N = *(DatumGetIntervalP(transdatums[1]));
3554 
3555  /* SQL defines AVG of no values to be NULL */
3556  if (N.time == 0)
3557  PG_RETURN_NULL();
3558 
3560  IntervalPGetDatum(&sumX),
3561  Float8GetDatum((double) N.time));
3562 }
#define DatumGetIntervalP(X)
Definition: timestamp.h:29
Datum Float8GetDatum(float8 X)
Definition: fmgr.c:1706
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:256
#define ERROR
Definition: elog.h:46
#define IntervalPGetDatum(X)
Definition: timestamp.h:33
TimeOffset time
Definition: timestamp.h:45
uintptr_t Datum
Definition: postgres.h:411
Datum interval_div(PG_FUNCTION_ARGS)
Definition: timestamp.c:3263
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3491
#define elog(elevel,...)
Definition: elog.h:232
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:628
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ interval_cmp()

Datum interval_cmp ( PG_FUNCTION_ARGS  )

Definition at line 2437 of file timestamp.c.

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_INT32.

Referenced by gbt_intvkey_cmp(), and leftmostvalue_interval().

2438 {
2439  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2440  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2441 
2442  PG_RETURN_INT32(interval_cmp_internal(interval1, interval2));
2443 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
static int interval_cmp_internal(Interval *interval1, Interval *interval2)
Definition: timestamp.c:2374

◆ interval_cmp_internal()

static int interval_cmp_internal ( Interval interval1,
Interval interval2 
)
static

Definition at line 2374 of file timestamp.c.

References int128_compare(), and interval_cmp_value().

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

2375 {
2376  INT128 span1 = interval_cmp_value(interval1);
2377  INT128 span2 = interval_cmp_value(interval2);
2378 
2379  return int128_compare(span1, span2);
2380 }
static int int128_compare(INT128 x, INT128 y)
Definition: int128.h:238
Definition: int128.h:107
static INT128 interval_cmp_value(const Interval *interval)
Definition: timestamp.c:2352

◆ interval_cmp_value()

static INT128 interval_cmp_value ( const Interval interval)
inlinestatic

Definition at line 2352 of file timestamp.c.

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

Referenced by in_range_interval_interval(), in_range_timestamp_interval(), in_range_timestamptz_interval(), interval_cmp_internal(), interval_hash(), and interval_hash_extended().

2353 {
2354  INT128 span;
2355  int64 days;
2356 
2357  /*
2358  * Combine the month and day fields into an integral number of days.
2359  * Because the inputs are int32, int64 arithmetic suffices here.
2360  */
2361  days = interval->month * INT64CONST(30);
2362  days += interval->day;
2363 
2364  /* Widen time field to 128 bits */
2365  span = int64_to_int128(interval->time);
2366 
2367  /* Scale up days to microseconds, forming a 128-bit product */
2369 
2370  return span;
2371 }
int32 day
Definition: timestamp.h:47
TimeOffset time
Definition: timestamp.h:45
const char *const days[]
Definition: datetime.c:68
#define USECS_PER_DAY
Definition: timestamp.h:91
int32 month
Definition: timestamp.h:48
static INT128 int64_to_int128(int64 v)
Definition: int128.h:255
Definition: int128.h:107
static void int128_add_int64_mul_int64(INT128 *i128, int64 x, int64 y)
Definition: int128.h:177

◆ interval_combine()

Datum interval_combine ( PG_FUNCTION_ARGS  )

Definition at line 3454 of file timestamp.c.

References construct_array(), DatumGetIntervalP, deconstruct_array(), DirectFunctionCall2, elog, ERROR, interval_pl(), IntervalPGetDatum, PG_GETARG_ARRAYTYPE_P, PG_RETURN_ARRAYTYPE_P, and Interval::time.

3455 {
3456  ArrayType *transarray1 = PG_GETARG_ARRAYTYPE_P(0);
3457  ArrayType *transarray2 = PG_GETARG_ARRAYTYPE_P(1);
3458  Datum *transdatums1;
3459  Datum *transdatums2;
3460  int ndatums1;
3461  int ndatums2;
3462  Interval sum1,
3463  N1;
3464  Interval sum2,
3465  N2;
3466 
3467  Interval *newsum;
3468  ArrayType *result;
3469 
3470  deconstruct_array(transarray1,
3471  INTERVALOID, sizeof(Interval), false, TYPALIGN_DOUBLE,
3472  &transdatums1, NULL, &ndatums1);
3473  if (ndatums1 != 2)
3474  elog(ERROR, "expected 2-element interval array");
3475 
3476  sum1 = *(DatumGetIntervalP(transdatums1[0]));
3477  N1 = *(DatumGetIntervalP(transdatums1[1]));
3478 
3479  deconstruct_array(transarray2,
3480  INTERVALOID, sizeof(Interval), false, TYPALIGN_DOUBLE,
3481  &transdatums2, NULL, &ndatums2);
3482  if (ndatums2 != 2)
3483  elog(ERROR, "expected 2-element interval array");
3484 
3485  sum2 = *(DatumGetIntervalP(transdatums2[0]));
3486  N2 = *(DatumGetIntervalP(transdatums2[1]));
3487 
3489  IntervalPGetDatum(&sum1),
3490  IntervalPGetDatum(&sum2)));
3491  N1.time += N2.time;
3492 
3493  transdatums1[0] = IntervalPGetDatum(newsum);
3494  transdatums1[1] = IntervalPGetDatum(&N1);
3495 
3496  result = construct_array(transdatums1, 2,
3497  INTERVALOID, sizeof(Interval), false, TYPALIGN_DOUBLE);
3498 
3499  PG_RETURN_ARRAYTYPE_P(result);
3500 }
#define DatumGetIntervalP(X)
Definition: timestamp.h:29
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Definition: arrayfuncs.c:3319
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:256
Datum interval_pl(PG_FUNCTION_ARGS)
Definition: timestamp.c:3102
#define ERROR
Definition: elog.h:46
#define IntervalPGetDatum(X)
Definition: timestamp.h:33
TimeOffset time
Definition: timestamp.h:45
#define PG_RETURN_ARRAYTYPE_P(x)
Definition: array.h:258
uintptr_t Datum
Definition: postgres.h:411
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3491
#define elog(elevel,...)
Definition: elog.h:232
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:628

◆ interval_div()

Datum interval_div ( PG_FUNCTION_ARGS  )

Definition at line 3263 of file timestamp.c.

References Abs, Interval::day, DAYS_PER_MONTH, ereport, errcode(), errmsg(), ERROR, Interval::month, palloc(), PG_GETARG_FLOAT8, PG_GETARG_INTERVAL_P, PG_RETURN_INTERVAL_P, SECS_PER_DAY, Interval::time, TSROUND, and USECS_PER_SEC.

Referenced by interval_avg().

3264 {
3265  Interval *span = PG_GETARG_INTERVAL_P(0);
3266  float8 factor = PG_GETARG_FLOAT8(1);
3267  double month_remainder_days,
3268  sec_remainder;
3269  int32 orig_month = span->month,
3270  orig_day = span->day;
3271  Interval *result;
3272 
3273  result = (Interval *) palloc(sizeof(Interval));
3274 
3275  if (factor == 0.0)
3276  ereport(ERROR,
3277  (errcode(ERRCODE_DIVISION_BY_ZERO),
3278  errmsg("division by zero")));
3279 
3280  result->month = (int32) (span->month / factor);
3281  result->day = (int32) (span->day / factor);
3282 
3283  /*
3284  * Fractional months full days into days. See comment in interval_mul().
3285  */
3286  month_remainder_days = (orig_month / factor - result->month) * DAYS_PER_MONTH;
3287  month_remainder_days = TSROUND(month_remainder_days);
3288  sec_remainder = (orig_day / factor - result->day +
3289  month_remainder_days - (int) month_remainder_days) * SECS_PER_DAY;
3290  sec_remainder = TSROUND(sec_remainder);
3291  if (Abs(sec_remainder) >= SECS_PER_DAY)
3292  {
3293  result->day += (int) (sec_remainder / SECS_PER_DAY);
3294  sec_remainder -= (int) (sec_remainder / SECS_PER_DAY) * SECS_PER_DAY;
3295  }
3296 
3297  /* cascade units down */
3298  result->day += (int32) month_remainder_days;
3299  result->time = rint(span->time / factor + sec_remainder * USECS_PER_SEC);
3300 
3301  PG_RETURN_INTERVAL_P(result);
3302 }
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:282
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:41
#define USECS_PER_SEC
Definition: timestamp.h:94
int errcode(int sqlerrcode)
Definition: elog.c:698
signed int int32
Definition: c.h:429
int32 day
Definition: timestamp.h:47
#define Abs(x)
Definition: c.h:992
#define ERROR
Definition: elog.h:46
double float8
Definition: c.h:565
#define SECS_PER_DAY
Definition: timestamp.h:86
TimeOffset time
Definition: timestamp.h:45
int32 month
Definition: timestamp.h:48
#define DAYS_PER_MONTH
Definition: timestamp.h:77
#define ereport(elevel,...)
Definition: elog.h:157
#define TSROUND(j)
Definition: timestamp.h:61
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ interval_eq()

Datum interval_eq ( PG_FUNCTION_ARGS  )

Definition at line 2383 of file timestamp.c.

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by gbt_intveq().

2384 {
2385  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2386  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2387 
2388  PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) == 0);
2389 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
static int interval_cmp_internal(Interval *interval1, Interval *interval2)
Definition: timestamp.c:2374

◆ interval_finite()

Datum interval_finite ( PG_FUNCTION_ARGS  )

Definition at line 2037 of file timestamp.c.

References PG_RETURN_BOOL.

2038 {
2039  PG_RETURN_BOOL(true);
2040 }
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359

◆ interval_ge()

Datum interval_ge ( PG_FUNCTION_ARGS  )

Definition at line 2428 of file timestamp.c.

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by gbt_intvge().

2429 {
2430  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2431  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2432 
2433  PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) >= 0);
2434 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
static int interval_cmp_internal(Interval *interval1, Interval *interval2)
Definition: timestamp.c:2374

◆ interval_gt()

Datum interval_gt ( PG_FUNCTION_ARGS  )

Definition at line 2410 of file timestamp.c.

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by gbt_intvgt().

2411 {
2412  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2413  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2414 
2415  PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) > 0);
2416 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
static int interval_cmp_internal(Interval *interval1, Interval *interval2)
Definition: timestamp.c:2374

◆ interval_hash()

Datum interval_hash ( PG_FUNCTION_ARGS  )

Definition at line 2453 of file timestamp.c.

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

2454 {
2456  INT128 span = interval_cmp_value(interval);
2457  int64 span64;
2458 
2459  /*
2460  * Use only the least significant 64 bits for hashing. The upper 64 bits
2461  * seldom add any useful information, and besides we must do it like this
2462  * for compatibility with hashes calculated before use of INT128 was
2463  * introduced.
2464  */
2465  span64 = int128_to_int64(span);
2466 
2468 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
Datum hashint8(PG_FUNCTION_ARGS)
Definition: hashfunc.c:84
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:626
#define Int64GetDatumFast(X)
Definition: postgres.h:804
Definition: int128.h:107
static int64 int128_to_int64(INT128 val)
Definition: int128.h:269
static INT128 interval_cmp_value(const Interval *interval)
Definition: timestamp.c:2352

◆ interval_hash_extended()

Datum interval_hash_extended ( PG_FUNCTION_ARGS  )

Definition at line 2471 of file timestamp.c.

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

2472 {
2474  INT128 span = interval_cmp_value(interval);
2475  int64 span64;
2476 
2477  /* Same approach as interval_hash */
2478  span64 = int128_to_int64(span);
2479 
2481  PG_GETARG_DATUM(1));
2482 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
Datum hashint8extended(PG_FUNCTION_ARGS)
Definition: hashfunc.c:104
#define Int64GetDatumFast(X)
Definition: postgres.h:804
Definition: int128.h:107
static int64 int128_to_int64(INT128 val)
Definition: int128.h:269
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:628
static INT128 interval_cmp_value(const Interval *interval)
Definition: timestamp.c:2352

◆ interval_in()

Datum interval_in ( PG_FUNCTION_ARGS  )

Definition at line 882 of file timestamp.c.

References AdjustIntervalForTypmod(), DateTimeParseError(), DecodeInterval(), DecodeISO8601Interval(), DTERR_BAD_FORMAT, DTERR_FIELD_OVERFLOW, DTERR_INTERVAL_OVERFLOW, DTK_DELTA, elog, ereport, errcode(), errmsg(), ERROR, INTERVAL_FULL_RANGE, INTERVAL_RANGE, MAXDATEFIELDS, palloc(), ParseDateTime(), PG_GETARG_CSTRING, PG_GETARG_INT32, PG_GETARG_OID, PG_RETURN_INTERVAL_P, range(), generate_unaccent_rules::str, tm, tm2interval(), 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 check_timezone(), and flatten_set_variable_args().

883 {
884  char *str = PG_GETARG_CSTRING(0);
885 
886 #ifdef NOT_USED
887  Oid typelem = PG_GETARG_OID(1);
888 #endif
889  int32 typmod = PG_GETARG_INT32(2);
890  Interval *result;
891  fsec_t fsec;
892  struct pg_tm tt,
893  *tm = &tt;
894  int dtype;
895  int nf;
896  int range;
897  int dterr;
898  char *field[MAXDATEFIELDS];
899  int ftype[MAXDATEFIELDS];
900  char workbuf[256];
901 
902  tm->tm_year = 0;
903  tm->tm_mon = 0;
904  tm->tm_mday = 0;
905  tm->tm_hour = 0;
906  tm->tm_min = 0;
907  tm->tm_sec = 0;
908  fsec = 0;
909 
910  if (typmod >= 0)
911  range = INTERVAL_RANGE(typmod);
912  else
913  range = INTERVAL_FULL_RANGE;
914 
915  dterr = ParseDateTime(str, workbuf, sizeof(workbuf), field,
916  ftype, MAXDATEFIELDS, &nf);
917  if (dterr == 0)
918  dterr = DecodeInterval(field, ftype, nf, range,
919  &dtype, tm, &fsec);
920 
921  /* if those functions think it's a bad format, try ISO8601 style */
922  if (dterr == DTERR_BAD_FORMAT)
923  dterr = DecodeISO8601Interval(str,
924  &dtype, tm, &fsec);
925 
926  if (dterr != 0)
927  {
928  if (dterr == DTERR_FIELD_OVERFLOW)
929  dterr = DTERR_INTERVAL_OVERFLOW;
930  DateTimeParseError(dterr, str, "interval");
931  }
932 
933  result = (Interval *) palloc(sizeof(Interval));
934 
935  switch (dtype)
936  {
937  case DTK_DELTA:
938  if (tm2interval(tm, fsec, result) != 0)
939  ereport(ERROR,
940  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
941  errmsg("interval out of range")));
942  break;
943 
944  default:
945  elog(ERROR, "unexpected dtype %d while parsing interval \"%s\"",
946  dtype, str);
947  }
948 
949  AdjustIntervalForTypmod(result, typmod);
950 
951  PG_RETURN_INTERVAL_P(result);
952 }
#define DTERR_BAD_FORMAT
Definition: datetime.h:280
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
void DateTimeParseError(int dterr, const char *str, const char *datatype)
Definition: datetime.c:3764
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:41
#define DTK_DELTA
Definition: datetime.h:160
int tm_hour
Definition: pgtime.h:36
int errcode(int sqlerrcode)
Definition: elog.c:698
Definition: pgtime.h:32
unsigned int Oid
Definition: postgres_ext.h:31
#define INTERVAL_FULL_RANGE
Definition: timestamp.h:48
signed int int32
Definition: c.h:429
static struct pg_tm tm
Definition: localtime.c:102
#define ERROR
Definition: elog.h:46
#define DTERR_FIELD_OVERFLOW
Definition: datetime.h:281
#define DTERR_INTERVAL_OVERFLOW
Definition: datetime.h:283
static void AdjustIntervalForTypmod(Interval *interval, int32 typmod)
Definition: timestamp.c:1330
int tm_mday
Definition: pgtime.h:37
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
int tm_mon
Definition: pgtime.h:38
int32 fsec_t
Definition: timestamp.h:41
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
int DecodeISO8601Interval(char *str, int *dtype, struct pg_tm *tm, fsec_t *fsec)
Definition: datetime.c:3518
#define INTERVAL_RANGE(t)
Definition: timestamp.h:54
#define ereport(elevel,...)
Definition: elog.h:157
#define MAXDATEFIELDS
Definition: datetime.h:203
int tm_year
Definition: pgtime.h:39
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
int DecodeInterval(char **field, int *ftype, int nf, int range, int *dtype, struct pg_tm *tm, fsec_t *fsec)
Definition: datetime.c:3096
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
int tm_sec
Definition: pgtime.h:34
int ParseDateTime(const char *timestr, char *workbuf, size_t buflen, char **field, int *ftype, int maxfields, int *numfields)
Definition: datetime.c:582
int tm_min
Definition: pgtime.h:35
int tm2interval(struct pg_tm *tm, fsec_t fsec, Interval *span)
Definition: timestamp.c:1994

◆ interval_justify_days()

Datum interval_justify_days ( PG_FUNCTION_ARGS  )

Definition at line 2798 of file timestamp.c.

References Interval::day, DAYS_PER_MONTH, Interval::month, palloc(), PG_GETARG_INTERVAL_P, PG_RETURN_INTERVAL_P, and Interval::time.

2799 {
2800  Interval *span = PG_GETARG_INTERVAL_P(0);
2801  Interval *result;
2802  int32 wholemonth;
2803 
2804  result = (Interval *) palloc(sizeof(Interval));
2805  result->month = span->month;
2806  result->day = span->day;
2807  result->time = span->time;
2808 
2809  wholemonth = result->day / DAYS_PER_MONTH;
2810  result->day -= wholemonth * DAYS_PER_MONTH;
2811  result->month += wholemonth;
2812 
2813  if (result->month > 0 && result->day < 0)
2814  {
2815  result->day += DAYS_PER_MONTH;
2816  result->month--;
2817  }
2818  else if (result->month < 0 && result->day > 0)
2819  {
2820  result->day -= DAYS_PER_MONTH;
2821  result->month++;
2822  }
2823 
2824  PG_RETURN_INTERVAL_P(result);
2825 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:41
signed int int32
Definition: c.h:429
int32 day
Definition: timestamp.h:47
TimeOffset time
Definition: timestamp.h:45
int32 month
Definition: timestamp.h:48
#define DAYS_PER_MONTH
Definition: timestamp.h:77
void * palloc(Size size)
Definition: mcxt.c:1062

◆ interval_justify_hours()

Datum interval_justify_hours ( PG_FUNCTION_ARGS  )

Definition at line 2763 of file timestamp.c.

References Interval::day, Interval::month, palloc(), PG_GETARG_INTERVAL_P, PG_RETURN_INTERVAL_P, Interval::time, TMODULO, and USECS_PER_DAY.

Referenced by timestamp_mi().

2764 {
2765  Interval *span = PG_GETARG_INTERVAL_P(0);
2766  Interval *result;
2767  TimeOffset wholeday;
2768 
2769  result = (Interval *) palloc(sizeof(Interval));
2770  result->month = span->month;
2771  result->day = span->day;
2772  result->time = span->time;
2773 
2774  TMODULO(result->time, wholeday, USECS_PER_DAY);
2775  result->day += wholeday; /* could overflow... */
2776 
2777  if (result->day > 0 && result->time < 0)
2778  {
2779  result->time += USECS_PER_DAY;
2780  result->day--;
2781  }
2782  else if (result->day < 0 && result->time > 0)
2783  {
2784  result->time -= USECS_PER_DAY;
2785  result->day++;
2786  }
2787 
2788  PG_RETURN_INTERVAL_P(result);
2789 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:41
int32 day
Definition: timestamp.h:47
TimeOffset time
Definition: timestamp.h:45
#define USECS_PER_DAY
Definition: timestamp.h:91
int32 month
Definition: timestamp.h:48
int64 TimeOffset
Definition: timestamp.h:40
void * palloc(Size size)
Definition: mcxt.c:1062
#define TMODULO(t, q, u)
Definition: datetime.h:249

◆ interval_justify_interval()

Datum interval_justify_interval ( PG_FUNCTION_ARGS  )

Definition at line 2708 of file timestamp.c.

References Interval::day, DAYS_PER_MONTH, Interval::month, palloc(), PG_GETARG_INTERVAL_P, PG_RETURN_INTERVAL_P, Interval::time, TMODULO, and USECS_PER_DAY.

2709 {
2710  Interval *span = PG_GETARG_INTERVAL_P(0);
2711  Interval *result;
2712  TimeOffset wholeday;
2713  int32 wholemonth;
2714 
2715  result = (Interval *) palloc(sizeof(Interval));
2716  result->month = span->month;
2717  result->day = span->day;
2718  result->time = span->time;
2719 
2720  TMODULO(result->time, wholeday, USECS_PER_DAY);
2721  result->day += wholeday; /* could overflow... */
2722 
2723  wholemonth = result->day / DAYS_PER_MONTH;
2724  result->day -= wholemonth * DAYS_PER_MONTH;
2725  result->month += wholemonth;
2726 
2727  if (result->month > 0 &&
2728  (result->day < 0 || (result->day == 0 && result->time < 0)))
2729  {
2730  result->day += DAYS_PER_MONTH;
2731  result->month--;
2732  }
2733  else if (result->month < 0 &&
2734  (result->day > 0 || (result->day == 0 && result->time > 0)))
2735  {
2736  result->day -= DAYS_PER_MONTH;
2737  result->month++;
2738  }
2739 
2740  if (result->day > 0 && result->time < 0)
2741  {
2742  result->time += USECS_PER_DAY;
2743  result->day--;
2744  }
2745  else if (result->day < 0 && result->time > 0)
2746  {
2747  result->time -= USECS_PER_DAY;
2748  result->day++;
2749  }
2750 
2751  PG_RETURN_INTERVAL_P(result);
2752 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:41
signed int int32
Definition: c.h:429
int32 day
Definition: timestamp.h:47
TimeOffset time
Definition: timestamp.h:45
#define USECS_PER_DAY
Definition: timestamp.h:91
int32 month
Definition: timestamp.h:48
int64 TimeOffset
Definition: timestamp.h:40
#define DAYS_PER_MONTH
Definition: timestamp.h:77
void * palloc(Size size)
Definition: mcxt.c:1062
#define TMODULO(t, q, u)
Definition: datetime.h:249

◆ interval_larger()

Datum interval_larger ( PG_FUNCTION_ARGS  )

Definition at line 3088 of file timestamp.c.

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_INTERVAL_P.

3089 {
3090  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
3091  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
3092  Interval *result;
3093 
3094  if (interval_cmp_internal(interval1, interval2) > 0)
3095  result = interval1;
3096  else
3097  result = interval2;
3098  PG_RETURN_INTERVAL_P(result);
3099 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:41
static int interval_cmp_internal(Interval *interval1, Interval *interval2)
Definition: timestamp.c:2374

◆ interval_le()

Datum interval_le ( PG_FUNCTION_ARGS  )

Definition at line 2419 of file timestamp.c.

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by gbt_intvle().

2420 {
2421  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2422  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2423 
2424  PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) <= 0);
2425 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
static int interval_cmp_internal(Interval *interval1, Interval *interval2)
Definition: timestamp.c:2374

◆ interval_lt()

Datum interval_lt ( PG_FUNCTION_ARGS  )

Definition at line 2401 of file timestamp.c.

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by abs_interval(), and gbt_intvlt().

2402 {
2403  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2404  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2405 
2406  PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) < 0);
2407 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
static int interval_cmp_internal(Interval *interval1, Interval *interval2)
Definition: timestamp.c:2374

◆ interval_mi()

Datum interval_mi ( PG_FUNCTION_ARGS  )

Definition at line 3136 of file timestamp.c.

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

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

3137 {
3138  Interval *span1 = PG_GETARG_INTERVAL_P(0);
3139  Interval *span2 = PG_GETARG_INTERVAL_P(1);
3140  Interval *result;
3141 
3142  result = (Interval *) palloc(sizeof(Interval));
3143 
3144  result->month = span1->month - span2->month;
3145  /* overflow check copied from int4mi */
3146  if (!SAMESIGN(span1->month, span2->month) &&
3147  !SAMESIGN(result->month, span1->month))
3148  ereport(ERROR,
3149  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3150  errmsg("interval out of range")));
3151 
3152  result->day = span1->day - span2->day;
3153  if (!SAMESIGN(span1->day, span2->day) &&
3154  !SAMESIGN(result->day, span1->day))
3155  ereport(ERROR,
3156  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3157  errmsg("interval out of range")));
3158 
3159  result->time = span1->time - span2->time;
3160  if (!SAMESIGN(span1->time, span2->time) &&
3161  !SAMESIGN(result->time, span1->time))
3162  ereport(ERROR,
3163  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3164  errmsg("interval out of range")));
3165 
3166  PG_RETURN_INTERVAL_P(result);
3167 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:41
int errcode(int sqlerrcode)
Definition: elog.c:698
int32 day
Definition: timestamp.h:47
#define ERROR
Definition: elog.h:46
TimeOffset time
Definition: timestamp.h:45
#define SAMESIGN(a, b)
Definition: timestamp.c:49
int32 month
Definition: timestamp.h:48
#define ereport(elevel,...)
Definition: elog.h:157
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ interval_mul()

Datum interval_mul ( PG_FUNCTION_ARGS  )

Definition at line 3176 of file timestamp.c.

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

Referenced by interval_lerp(), and mul_d_interval().

3177 {
3178  Interval *span = PG_GETARG_INTERVAL_P(0);
3179  float8 factor = PG_GETARG_FLOAT8(1);
3180  double month_remainder_days,
3181  sec_remainder,
3182  result_double;
3183  int32 orig_month = span->month,
3184  orig_day = span->day;
3185  Interval *result;
3186 
3187  result = (Interval *) palloc(sizeof(Interval));
3188 
3189  result_double = span->month * factor;
3190  if (isnan(result_double) ||
3191  result_double > INT_MAX || result_double < INT_MIN)
3192  ereport(ERROR,
3193  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3194  errmsg("interval out of range")));
3195  result->month = (int32) result_double;
3196 
3197  result_double = span->day * factor;
3198  if (isnan(result_double) ||
3199  result_double > INT_MAX || result_double < INT_MIN)
3200  ereport(ERROR,
3201  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3202  errmsg("interval out of range")));
3203  result->day = (int32) result_double;
3204 
3205  /*
3206  * The above correctly handles the whole-number part of the month and day
3207  * products, but we have to do something with any fractional part
3208  * resulting when the factor is non-integral. We cascade the fractions
3209  * down to lower units using the conversion factors DAYS_PER_MONTH and
3210  * SECS_PER_DAY. Note we do NOT cascade up, since we are not forced to do
3211  * so by the representation. The user can choose to cascade up later,
3212  * using justify_hours and/or justify_days.
3213  */
3214 
3215  /*
3216  * Fractional months full days into days.
3217  *
3218  * Floating point calculation are inherently imprecise, so these
3219  * calculations are crafted to produce the most reliable result possible.
3220  * TSROUND() is needed to more accurately produce whole numbers where
3221  * appropriate.
3222  */
3223  month_remainder_days = (orig_month * factor - result->month) * DAYS_PER_MONTH;
3224  month_remainder_days = TSROUND(month_remainder_days);
3225  sec_remainder = (orig_day * factor - result->day +
3226  month_remainder_days - (int) month_remainder_days) * SECS_PER_DAY;
3227  sec_remainder = TSROUND(sec_remainder);
3228 
3229  /*
3230  * Might have 24:00:00 hours due to rounding, or >24 hours because of time
3231  * cascade from months and days. It might still be >24 if the combination
3232  * of cascade and the seconds factor operation itself.
3233  */
3234  if (Abs(sec_remainder) >= SECS_PER_DAY)
3235  {
3236  result->day += (int) (sec_remainder / SECS_PER_DAY);
3237  sec_remainder -= (int) (sec_remainder / SECS_PER_DAY) * SECS_PER_DAY;
3238  }
3239 
3240  /* cascade units down */
3241  result->day += (int32) month_remainder_days;
3242  result_double = rint(span->time * factor + sec_remainder * USECS_PER_SEC);
3243  if (isnan(result_double) || !FLOAT8_FITS_IN_INT64(result_double))
3244  ereport(ERROR,
3245  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3246  errmsg("interval out of range")));
3247  result->time = (int64) result_double;
3248 
3249  PG_RETURN_INTERVAL_P(result);
3250 }
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:282
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:41
#define USECS_PER_SEC
Definition: timestamp.h:94
int errcode(int sqlerrcode)
Definition: elog.c:698
signed int int32
Definition: c.h:429
int32 day
Definition: timestamp.h:47
#define Abs(x)
Definition: c.h:992
#define ERROR
Definition: elog.h:46
double float8
Definition: c.h:565
#define SECS_PER_DAY
Definition: timestamp.h:86
#define FLOAT8_FITS_IN_INT64(num)
Definition: c.h:1107
TimeOffset time
Definition: timestamp.h:45
int32 month
Definition: timestamp.h:48
#define DAYS_PER_MONTH
Definition: timestamp.h:77
#define ereport(elevel,...)
Definition: elog.h:157
#define TSROUND(j)
Definition: timestamp.h:61
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ interval_ne()

Datum interval_ne ( PG_FUNCTION_ARGS  )

Definition at line 2392 of file timestamp.c.

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

2393 {
2394  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2395  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2396 
2397  PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) != 0);
2398 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
static int interval_cmp_internal(Interval *interval1, Interval *interval2)
Definition: timestamp.c:2374

◆ interval_out()

Datum interval_out ( PG_FUNCTION_ARGS  )

Definition at line 958 of file timestamp.c.

References buf, elog, EncodeInterval(), ERROR, interval2tm(), IntervalStyle, MAXDATELEN, PG_GETARG_INTERVAL_P, PG_RETURN_CSTRING, pstrdup(), and tm.

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

959 {
960  Interval *span = PG_GETARG_INTERVAL_P(0);
961  char *result;
962  struct pg_tm tt,
963  *tm = &tt;
964  fsec_t fsec;
965  char buf[MAXDATELEN + 1];
966 
967  if (interval2tm(*span, tm, &fsec) != 0)
968  elog(ERROR, "could not convert interval to tm");
969 
970  EncodeInterval(tm, fsec, IntervalStyle, buf);
971 
972  result = pstrdup(buf);
973  PG_RETURN_CSTRING(result);
974 }
#define MAXDATELEN
Definition: datetime.h:201
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
char * pstrdup(const char *in)
Definition: mcxt.c:1299
int IntervalStyle
Definition: globals.c:120
Definition: pgtime.h:32
static struct pg_tm tm
Definition: localtime.c:102
#define ERROR
Definition: elog.h:46
int interval2tm(Interval span, struct pg_tm *tm, fsec_t *fsec)
Definition: timestamp.c:1966
static char * buf
Definition: pg_test_fsync.c:68
int32 fsec_t
Definition: timestamp.h:41
void EncodeInterval(struct pg_tm *tm, fsec_t fsec, int style, char *str)
Definition: datetime.c:4241
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
#define elog(elevel,...)
Definition: elog.h:232

◆ interval_part()

Datum interval_part ( PG_FUNCTION_ARGS  )

Definition at line 5341 of file timestamp.c.

References interval_part_common().

5342 {
5343  return interval_part_common(fcinfo, false);
5344 }
static Datum interval_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition: timestamp.c:5174

◆ interval_part_common()

static Datum interval_part_common ( PG_FUNCTION_ARGS  ,
bool  retnumeric 
)
static

Definition at line 5174 of file timestamp.c.

References Interval::day, DAYS_PER_MONTH, DAYS_PER_YEAR, DecodeSpecial(), DecodeUnits(), 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, elog, ereport, errcode(), errmsg(), ERROR, int64_div_fast_to_numeric(), int64_to_numeric(), interval2tm(), Interval::month, MONTHS_PER_YEAR, numeric_add_opt_error(), pg_add_s64_overflow(), PG_GETARG_INTERVAL_P, PG_GETARG_TEXT_PP, pg_mul_s64_overflow(), PG_RETURN_FLOAT8, 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, generate_unaccent_rules::type, UNITS, UNKNOWN_FIELD, val, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by extract_interval(), and interval_part().

5175 {
5176  text *units = PG_GETARG_TEXT_PP(0);
5178  int64 intresult;
5179  int type,
5180  val;
5181  char *lowunits;
5182  fsec_t fsec;
5183  struct pg_tm tt,
5184  *tm = &tt;
5185 
5186  lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
5187  VARSIZE_ANY_EXHDR(units),
5188  false);
5189 
5190  type = DecodeUnits(0, lowunits, &val);
5191  if (type == UNKNOWN_FIELD)
5192  type = DecodeSpecial(0, lowunits, &val);
5193 
5194  if (type == UNITS)
5195  {
5196  if (interval2tm(*interval, tm, &fsec) == 0)
5197  {
5198  switch (val)
5199  {
5200  case DTK_MICROSEC:
5201  intresult = tm->tm_sec * INT64CONST(1000000) + fsec;
5202  break;
5203 
5204  case DTK_MILLISEC:
5205  if (retnumeric)
5206  /*---
5207  * tm->tm_sec * 1000 + fsec / 1000
5208  * = (tm->tm_sec * 1'000'000 + fsec) / 1000
5209  */
5210  PG_RETURN_NUMERIC(int64_div_fast_to_numeric(tm->tm_sec * INT64CONST(1000000) + fsec, 3));
5211  else
5212  PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0);
5213  break;
5214 
5215  case DTK_SECOND:
5216  if (retnumeric)
5217  /*---
5218  * tm->tm_sec + fsec / 1'000'000
5219  * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
5220  */
5221  PG_RETURN_NUMERIC(int64_div_fast_to_numeric(tm->tm_sec * INT64CONST(1000000) + fsec, 6));
5222  else
5223  PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0);
5224  break;
5225 
5226  case DTK_MINUTE:
5227  intresult = tm->tm_min;
5228  break;
5229 
5230  case DTK_HOUR:
5231  intresult = tm->tm_hour;
5232  break;
5233 
5234  case DTK_DAY:
5235  intresult = tm->tm_mday;
5236  break;
5237 
5238  case DTK_MONTH:
5239  intresult = tm->tm_mon;
5240  break;
5241 
5242  case DTK_QUARTER:
5243  intresult = (tm->tm_mon / 3) + 1;
5244  break;
5245 
5246  case DTK_YEAR:
5247  intresult = tm->tm_year;
5248  break;
5249 
5250  case DTK_DECADE:
5251  /* caution: C division may have negative remainder */
5252  intresult = tm->tm_year / 10;
5253  break;
5254 
5255  case DTK_CENTURY:
5256  /* caution: C division may have negative remainder */
5257  intresult = tm->tm_year / 100;
5258  break;
5259 
5260  case DTK_MILLENNIUM:
5261  /* caution: C division may have negative remainder */
5262  intresult = tm->tm_year / 1000;
5263  break;
5264 
5265  default:
5266  ereport(ERROR,
5267  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5268  errmsg("interval units \"%s\" not supported",
5269  lowunits)));
5270  intresult = 0;
5271  }
5272  }
5273  else
5274  {
5275  elog(ERROR, "could not convert interval to tm");
5276  intresult = 0;
5277  }
5278  }
5279  else if (type == RESERV && val == DTK_EPOCH)
5280  {
5281  if (retnumeric)
5282  {
5283  Numeric result;
5284  int64 secs_from_day_month;
5285  int64 val;
5286 
5287  /* this always fits into int64 */
5288  secs_from_day_month = ((int64) DAYS_PER_YEAR * (interval->month / MONTHS_PER_YEAR) +
5289  (int64) DAYS_PER_MONTH * (interval->month % MONTHS_PER_YEAR) +
5290  interval->day) * SECS_PER_DAY;
5291 
5292  /*---
5293  * result = secs_from_day_month + interval->time / 1'000'000
5294  * = (secs_from_day_month * 1'000'000 + interval->time) / 1'000'000
5295  */
5296 
5297  /*
5298  * Try the computation inside int64; if it overflows, do it in
5299  * numeric (slower). This overflow happens around 10^9 days, so
5300  * not common in practice.
5301  */
5302  if (!pg_mul_s64_overflow(secs_from_day_month, 1000000, &val) &&
5303  !pg_add_s64_overflow(val, interval->time, &val))
5304  result = int64_div_fast_to_numeric(val, 6);
5305  else
5306  result =
5308  int64_to_numeric(secs_from_day_month),
5309  NULL);
5310 
5311  PG_RETURN_NUMERIC(result);
5312  }
5313  else
5314  {
5315  float8 result;
5316 
5317  result = interval->time / 1000000.0;
5318  result += ((double) DAYS_PER_YEAR * SECS_PER_DAY) * (interval->month / MONTHS_PER_YEAR);
5319  result += ((double) DAYS_PER_MONTH * SECS_PER_DAY) * (interval->month % MONTHS_PER_YEAR);
5320  result += ((double) SECS_PER_DAY) * interval->day;
5321 
5322  PG_RETURN_FLOAT8(result);
5323  }
5324  }
5325  else
5326  {
5327  ereport(ERROR,
5328  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5329  errmsg("interval units \"%s\" not recognized",
5330  lowunits)));
5331  intresult = 0;
5332  }
5333 
5334  if (retnumeric)
5335  PG_RETURN_NUMERIC(int64_to_numeric(intresult));
5336  else
5337  PG_RETURN_FLOAT8(intresult);
5338 }
#define PG_RETURN_NUMERIC(x)
Definition: numeric.h:64
#define DTK_CENTURY
Definition: datetime.h:170
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define UNITS
Definition: datetime.h:108
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define DTK_YEAR
Definition: datetime.h:168
Numeric numeric_add_opt_error(Numeric num1, Numeric num2, bool *have_error)
Definition: numeric.c:2783
int tm_hour
Definition: pgtime.h:36
char * downcase_truncate_identifier(const char *ident, int len, bool warn)
Definition: scansup.c:37
#define DTK_QUARTER
Definition: datetime.h:167
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:367
#define DTK_MILLENNIUM
Definition: datetime.h:171
int errcode(int sqlerrcode)
Definition: elog.c:698
#define UNKNOWN_FIELD
Definition: datetime.h:125
int DecodeUnits(int field, char *lowtoken, int *val)
Definition: datetime.c:3727
Definition: pgtime.h:32
int32 day
Definition: timestamp.h:47
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
static struct pg_tm tm
Definition: localtime.c:102
#define DTK_MONTH
Definition: datetime.h:166
#define DTK_MILLISEC
Definition: datetime.h:172
#define MONTHS_PER_YEAR
Definition: timestamp.h:69
#define DTK_DECADE
Definition: datetime.h:169
#define DAYS_PER_YEAR
Definition: timestamp.h:68
#define DTK_HOUR
Definition: datetime.h:163
#define ERROR
Definition: elog.h:46
double float8
Definition: c.h:565
#define SECS_PER_DAY
Definition: timestamp.h:86
#define DTK_SECOND
Definition: datetime.h:161
int interval2tm(Interval span, struct pg_tm *tm, fsec_t *fsec)
Definition: timestamp.c:1966
int tm_mday
Definition: pgtime.h:37
int tm_mon
Definition: pgtime.h:38
Numeric int64_to_numeric(int64 val)
Definition: numeric.c:4136
TimeOffset time
Definition: timestamp.h:45
int32 fsec_t
Definition: timestamp.h:41
#define DTK_MINUTE
Definition: datetime.h:162
int32 month
Definition: timestamp.h:48
#define DTK_MICROSEC
Definition: datetime.h:173
#define DAYS_PER_MONTH
Definition: timestamp.h:77
static bool pg_add_s64_overflow(int64 a, int64 b, int64 *result)
Definition: int.h:161
#define ereport(elevel,...)
Definition: elog.h:157
static bool pg_mul_s64_overflow(int64 a, int64 b, int64 *result)
Definition: int.h:215
#define DTK_DAY
Definition: datetime.h:164
#define RESERV
Definition: datetime.h:91
int DecodeSpecial(int field, char *lowtoken, int *val)
Definition: datetime.c:3040
#define DTK_EPOCH
Definition: datetime.h:153
int tm_year
Definition: pgtime.h:39
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
Definition: c.h:621
int tm_sec
Definition: pgtime.h:34
Numeric int64_div_fast_to_numeric(int64 val1, int log10val2)
Definition: numeric.c:4157
int tm_min
Definition: pgtime.h:35
long val
Definition: informix.c:664

◆ interval_pl()

Datum interval_pl ( PG_FUNCTION_ARGS  )

Definition at line 3102 of file timestamp.c.

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

Referenced by in_range_interval_interval(), interval_accum(), interval_combine(), and interval_lerp().

3103 {
3104  Interval *span1 = PG_GETARG_INTERVAL_P(0);
3105  Interval *span2 = PG_GETARG_INTERVAL_P(1);
3106  Interval *result;
3107 
3108  result = (Interval *) palloc(sizeof(Interval));
3109 
3110  result->month = span1->month + span2->month;
3111  /* overflow check copied from int4pl */
3112  if (SAMESIGN(span1->month, span2->month) &&
3113  !SAMESIGN(result->month, span1->month))
3114  ereport(ERROR,
3115  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3116  errmsg("interval out of range")));
3117 
3118  result->day = span1->day + span2->day;
3119  if (SAMESIGN(span1->day, span2->day) &&
3120  !SAMESIGN(result->day, span1->day))
3121  ereport(ERROR,
3122  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3123  errmsg("interval out of range")));
3124 
3125  result->time = span1->time + span2->time;
3126  if (SAMESIGN(span1->time, span2->time) &&
3127  !SAMESIGN(result->time, span1->time))
3128  ereport(ERROR,
3129  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3130  errmsg("interval out of range")));
3131 
3132  PG_RETURN_INTERVAL_P(result);
3133 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:41
int errcode(int sqlerrcode)
Definition: elog.c:698
int32 day
Definition: timestamp.h:47
#define ERROR
Definition: elog.h:46
TimeOffset time
Definition: timestamp.h:45
#define SAMESIGN(a, b)
Definition: timestamp.c:49
int32 month
Definition: timestamp.h:48
#define ereport(elevel,...)
Definition: elog.h:157
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ interval_recv()

Datum interval_recv ( PG_FUNCTION_ARGS  )

Definition at line 980 of file timestamp.c.

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

981 {
983 
984 #ifdef NOT_USED
985  Oid typelem = PG_GETARG_OID(1);
986 #endif
987  int32 typmod = PG_GETARG_INT32(2);
989 
990  interval = (Interval *) palloc(sizeof(Interval));
991 
992  interval->time = pq_getmsgint64(buf);
993  interval->day = pq_getmsgint(buf, sizeof(interval->day));
994  interval->month = pq_getmsgint(buf, sizeof(interval->month));
995 
996  AdjustIntervalForTypmod(interval, typmod);
997 
998  PG_RETURN_INTERVAL_P(interval);
999 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:41
StringInfoData * StringInfo
Definition: stringinfo.h:44
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:429
int32 day
Definition: timestamp.h:47
static void AdjustIntervalForTypmod(Interval *interval, int32 typmod)
Definition: timestamp.c:1330
static char * buf
Definition: pg_test_fsync.c:68
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
TimeOffset time
Definition: timestamp.h:45
int32 month
Definition: timestamp.h:48
void * palloc(Size size)
Definition: mcxt.c:1062
int64 pq_getmsgint64(StringInfo msg)
Definition: pqformat.c:455
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:417

◆ interval_scale()

Datum interval_scale ( PG_FUNCTION_ARGS  )

Definition at line 1311 of file timestamp.c.

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

1312 {
1314  int32 typmod = PG_GETARG_INT32(1);
1315  Interval *result;
1316 
1317  result = palloc(sizeof(Interval));
1318  *result = *interval;
1319 
1320  AdjustIntervalForTypmod(result, typmod);
1321 
1322  PG_RETURN_INTERVAL_P(result);
1323 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:41
signed int int32
Definition: c.h:429
static void AdjustIntervalForTypmod(Interval *interval, int32 typmod)
Definition: timestamp.c:1330
void * palloc(Size size)
Definition: mcxt.c:1062

◆ interval_send()

Datum interval_send ( PG_FUNCTION_ARGS  )

Definition at line 1005 of file timestamp.c.

References buf, Interval::day, Interval::month, PG_GETARG_INTERVAL_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendint32(), pq_sendint64(), and Interval::time.

1006 {
1009 
1010  pq_begintypsend(&buf);
1011  pq_sendint64(&buf, interval->time);
1012  pq_sendint32(&buf, interval->day);
1013  pq_sendint32(&buf, interval->month);
1015 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:328
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
static void pq_sendint64(StringInfo buf, uint64 i)
Definition: pqformat.h:153
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:348
int32 day
Definition: timestamp.h:47
static void pq_sendint32(StringInfo buf, uint32 i)
Definition: pqformat.h:145
static char * buf
Definition: pg_test_fsync.c:68
TimeOffset time
Definition: timestamp.h:45
int32 month
Definition: timestamp.h:48

◆ interval_smaller()

Datum interval_smaller ( PG_FUNCTION_ARGS  )

Definition at line 3073 of file timestamp.c.

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_INTERVAL_P.

3074 {
3075  Interval *interval1 = PG_GETARG_INTERVAL_P(0);
3076  Interval *interval2 = PG_GETARG_INTERVAL_P(1);
3077  Interval *result;
3078 
3079  /* use interval_cmp_internal to be sure this agrees with comparisons */
3080  if (interval_cmp_internal(interval1, interval2) < 0)
3081  result = interval1;
3082  else
3083  result = interval2;
3084  PG_RETURN_INTERVAL_P(result);
3085 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:41
static int interval_cmp_internal(Interval *interval1, Interval *interval2)
Definition: timestamp.c:2374

◆ interval_support()

Datum interval_support ( PG_FUNCTION_ARGS  )

Definition at line 1248 of file timestamp.c.

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.

1249 {
1250  Node *rawreq = (Node *) PG_GETARG_POINTER(0);
1251  Node *ret = NULL;
1252 
1253  if (IsA(rawreq, SupportRequestSimplify))
1254  {
1256  FuncExpr *expr = req->fcall;
1257  Node *typmod;
1258 
1259  Assert(list_length(expr->args) >= 2);
1260 
1261  typmod = (Node *) lsecond(expr->args);
1262 
1263  if (IsA(typmod, Const) && !((Const *) typmod)->constisnull)
1264  {
1265  Node *source = (Node *) linitial(expr->args);
1266  int32 new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
1267  bool noop;
1268 
1269  if (new_typmod < 0)
1270  noop = true;
1271  else
1272  {
1273  int32 old_typmod = exprTypmod(source);
1274  int old_least_field;
1275  int new_least_field;
1276  int old_precis;
1277  int new_precis;
1278 
1279  old_least_field = intervaltypmodleastfield(old_typmod);
1280  new_least_field = intervaltypmodleastfield(new_typmod);
1281  if (old_typmod < 0)
1282  old_precis = INTERVAL_FULL_PRECISION;
1283  else
1284  old_precis = INTERVAL_PRECISION(old_typmod);
1285  new_precis = INTERVAL_PRECISION(new_typmod);
1286 
1287  /*
1288  * Cast is a no-op if least field stays the same or decreases
1289  * while precision stays the same or increases. But
1290  * precision, which is to say, sub-second precision, only
1291  * affects ranges that include SECOND.
1292  */
1293  noop = (new_least_field <= old_least_field) &&
1294  (old_least_field > 0 /* SECOND */ ||
1295  new_precis >= MAX_INTERVAL_PRECISION ||
1296  new_precis >= old_precis);
1297  }
1298  if (noop)
1299  ret = relabel_to_typmod(source, new_typmod);
1300  }
1301  }
1302 
1303  PG_RETURN_POINTER(ret);
1304 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define IsA(nodeptr, _type_)
Definition: nodes.h:588
List * args
Definition: primnodes.h:503
#define DatumGetInt32(X)
Definition: postgres.h:516
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:267
Definition: nodes.h:537
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define lsecond(l)
Definition: pg_list.h:179
signed int int32
Definition: c.h:429
#define linitial(l)
Definition: pg_list.h:174
#define MAX_INTERVAL_PRECISION
Definition: timestamp.h:54
#define INTERVAL_FULL_PRECISION
Definition: timestamp.h:50
#define INTERVAL_PRECISION(t)
Definition: timestamp.h:53
#define Assert(condition)
Definition: c.h:804
static rewind_source * source
Definition: pg_rewind.c:79
static int list_length(const List *l)
Definition: pg_list.h:149
static int intervaltypmodleastfield(int32 typmod)
Definition: timestamp.c:1195
Node * relabel_to_typmod(Node *expr, int32 typmod)
Definition: nodeFuncs.c:635

◆ interval_trunc()

Datum interval_trunc ( PG_FUNCTION_ARGS  )

Definition at line 4274 of file timestamp.c.

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, elog, ereport, errcode(), errmsg(), ERROR, interval2tm(), palloc(), PG_GETARG_INTERVAL_P, PG_GETARG_TEXT_PP, PG_RETURN_INTERVAL_P, tm, tm2interval(), pg_tm::tm_hour, pg_tm::tm_mday, pg_tm::tm_min, pg_tm::tm_mon, pg_tm::tm_sec, pg_tm::tm_year, generate_unaccent_rules::type, UNITS, val, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

4275 {
4276  text *units = PG_GETARG_TEXT_PP(0);
4278  Interval *result;
4279  int type,
4280  val;
4281  char *lowunits;
4282  fsec_t fsec;
4283  struct pg_tm tt,
4284  *tm = &tt;
4285 
4286  result = (Interval *) palloc(sizeof(Interval));
4287 
4288  lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
4289  VARSIZE_ANY_EXHDR(units),
4290  false);
4291 
4292  type = DecodeUnits(0, lowunits, &val);
4293 
4294  if (type == UNITS)
4295  {
4296  if (interval2tm(*interval, tm, &fsec) == 0)
4297  {
4298  switch (val)
4299  {
4300  case DTK_MILLENNIUM:
4301  /* caution: C division may have negative remainder */
4302  tm->tm_year = (tm->tm_year / 1000) * 1000;
4303  /* FALL THRU */
4304  case DTK_CENTURY:
4305  /* caution: C division may have negative remainder */
4306  tm->tm_year = (tm->tm_year / 100) * 100;
4307  /* FALL THRU */
4308  case DTK_DECADE:
4309  /* caution: C division may have negative remainder */
4310  tm->tm_year = (tm->tm_year / 10) * 10;
4311  /* FALL THRU */
4312  case DTK_YEAR:
4313  tm->tm_mon = 0;
4314  /* FALL THRU */
4315  case DTK_QUARTER:
4316  tm->tm_mon = 3 * (tm->tm_mon / 3);
4317  /* FALL THRU */
4318  case DTK_MONTH:
4319  tm->tm_mday = 0;
4320  /* FALL THRU */
4321  case DTK_DAY:
4322  tm->tm_hour = 0;
4323  /* FALL THRU */
4324  case DTK_HOUR:
4325  tm->tm_min = 0;
4326  /* FALL THRU */
4327  case DTK_MINUTE:
4328  tm->tm_sec = 0;
4329  /* FALL THRU */
4330  case DTK_SECOND:
4331  fsec = 0;
4332  break;
4333  case DTK_MILLISEC:
4334  fsec = (fsec / 1000) * 1000;
4335  break;
4336  case DTK_MICROSEC:
4337  break;
4338 
4339  default:
4340  if (val == DTK_WEEK)
4341  ereport(ERROR,
4342  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4343  errmsg("interval units \"%s\" not supported "
4344  "because months usually have fractional weeks",
4345  lowunits)));
4346  else
4347  ereport(ERROR,
4348  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4349  errmsg("interval units \"%s\" not supported",
4350  lowunits)));
4351  }
4352 
4353  if (tm2interval(tm, fsec, result) != 0)
4354  ereport(ERROR,
4355  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4356  errmsg("interval out of range")));
4357  }
4358  else
4359  elog(ERROR, "could not convert interval to tm");
4360  }
4361  else
4362  {
4363  ereport(ERROR,
4364  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4365  errmsg("interval units \"%s\" not recognized",
4366  lowunits)));
4367  }
4368 
4369  PG_RETURN_INTERVAL_P(result);
4370 }
#define DTK_CENTURY
Definition: datetime.h:170
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define UNITS
Definition: datetime.h:108
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:41
#define DTK_WEEK
Definition: datetime.h:165
#define DTK_YEAR
Definition: datetime.h:168
int tm_hour
Definition: pgtime.h:36
char * downcase_truncate_identifier(const char *ident, int len, bool warn)
Definition: scansup.c:37
#define DTK_QUARTER
Definition: datetime.h:167
#define DTK_MILLENNIUM
Definition: datetime.h:171
int errcode(int sqlerrcode)
Definition: elog.c:698
int DecodeUnits(int field, char *lowtoken, int *val)
Definition: datetime.c:3727
Definition: pgtime.h:32
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
static struct pg_tm tm
Definition: localtime.c:102
#define DTK_MONTH
Definition: datetime.h:166
#define DTK_MILLISEC
Definition: datetime.h:172
#define DTK_DECADE
Definition: datetime.h:169
#define DTK_HOUR
Definition: datetime.h:163
#define ERROR
Definition: elog.h:46
#define DTK_SECOND
Definition: datetime.h:161
int interval2tm(Interval span, struct pg_tm *tm, fsec_t *fsec)
Definition: timestamp.c:1966
int tm_mday
Definition: pgtime.h:37
int tm_mon
Definition: pgtime.h:38
int32 fsec_t
Definition: timestamp.h:41
#define DTK_MINUTE
Definition: datetime.h:162
#define DTK_MICROSEC
Definition: datetime.h:173
#define ereport(elevel,...)
Definition: elog.h:157
#define DTK_DAY
Definition: datetime.h:164
int tm_year
Definition: pgtime.h:39
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
Definition: c.h:621
int tm_sec
Definition: pgtime.h:34
int tm_min
Definition: pgtime.h:35
long val
Definition: informix.c:664
int tm2interval(struct pg_tm *tm, fsec_t fsec, Interval *span)
Definition: timestamp.c:1994

◆ interval_um()

Datum interval_um ( PG_FUNCTION_ARGS  )

Definition at line 3044 of file timestamp.c.

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

Referenced by abs_interval().

3045 {
3047  Interval *result;
3048 
3049  result = (Interval *) palloc(sizeof(Interval));
3050 
3051  result->time = -interval->time;
3052  /* overflow check copied from int4um */
3053  if (interval->time != 0 && SAMESIGN(result->time, interval->time))
3054  ereport(ERROR,
3055  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3056  errmsg("interval out of range")));
3057  result->day = -interval->day;
3058  if (interval->day != 0 && SAMESIGN(result->day, interval->day))
3059  ereport(ERROR,
3060  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3061  errmsg("interval out of range")));
3062  result->month = -interval->month;
3063  if (interval->month != 0 && SAMESIGN(result->month, interval->month))
3064  ereport(ERROR,
3065  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3066  errmsg("interval out of range")));
3067 
3068  PG_RETURN_INTERVAL_P(result);
3069 }
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:37
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:41
int errcode(int sqlerrcode)
Definition: elog.c:698
int32 day
Definition: timestamp.h:47
#define ERROR
Definition: elog.h:46
TimeOffset time
Definition: timestamp.h:45
#define SAMESIGN(a, b)
Definition: timestamp.c:49
int32 month
Definition: timestamp.h:48
#define ereport(elevel,...)
Definition: elog.h:157
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ intervaltypmodin()

Datum intervaltypmodin ( PG_FUNCTION_ARGS  )

Definition at line 1030 of file timestamp.c.

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.

1031 {
1033  int32 *tl;
1034  int n;
1035  int32 typmod;
1036 
1037  tl = ArrayGetIntegerTypmods(ta, &n);
1038 
1039  /*
1040  * tl[0] - interval range (fields bitmask) tl[1] - precision (optional)
1041  *
1042  * Note we must validate tl[0] even though it's normally guaranteed
1043  * correct by the grammar --- consider SELECT 'foo'::"interval"(1000).
1044  */
1045  if (n > 0)
1046  {
1047  switch (tl[0])
1048  {
1049  case INTERVAL_MASK(YEAR):
1050  case INTERVAL_MASK(MONTH):
1051  case INTERVAL_MASK(DAY):
1052  case INTERVAL_MASK(HOUR):
1053  case INTERVAL_MASK(MINUTE):
1054  case INTERVAL_MASK(SECOND):
1062  case INTERVAL_FULL_RANGE:
1063  /* all OK */
1064  break;
1065  default:
1066  ereport(ERROR,
1067  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1068  errmsg("invalid INTERVAL type modifier")));
1069  }
1070  }
1071 
1072  if (n == 1)
1073  {
1074  if (tl[0] != INTERVAL_FULL_RANGE)
1075  typmod = INTERVAL_TYPMOD(INTERVAL_FULL_PRECISION, tl[0]);
1076  else
1077  typmod = -1;
1078  }
1079  else if (n == 2)
1080  {
1081  if (tl[1] < 0)
1082  ereport(ERROR,
1083  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1084  errmsg("INTERVAL(%d) precision must not be negative",
1085  tl[1])));
1086  if (tl[1] > MAX_INTERVAL_PRECISION)
1087  {
1088  ereport(WARNING,
1089  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1090  errmsg("INTERVAL(%d) precision reduced to maximum allowed, %d",
1091  tl[1], MAX_INTERVAL_PRECISION)));
1092  typmod = INTERVAL_TYPMOD(MAX_INTERVAL_PRECISION, tl[0]);
1093  }
1094  else
1095  typmod = INTERVAL_TYPMOD(tl[1], tl[0]);
1096  }
1097  else
1098  {
1099  ereport(ERROR,
1100  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1101  errmsg("invalid INTERVAL type modifier")));
1102  typmod = 0; /* keep compiler quiet */
1103  }
1104 
1105  PG_RETURN_INT32(typmod);
1106 }
#define DAY
Definition: datetime.h:94
#define YEAR
Definition: datetime.h:93
int32 * ArrayGetIntegerTypmods(ArrayType *arr, int *n)
Definition: arrayutils.c:231
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
int errcode(int sqlerrcode)
Definition: elog.c:698
#define SECOND
Definition: datetime.h:103
#define INTERVAL_FULL_RANGE
Definition: timestamp.h:48
signed int int32
Definition: c.h:429
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:256
#define ERROR
Definition: elog.h:46
#define MAX_INTERVAL_PRECISION
Definition: timestamp.h:54
#define INTERVAL_FULL_PRECISION
Definition: timestamp.h:50
#define INTERVAL_TYPMOD(p, r)
Definition: timestamp.h:52
#define MINUTE
Definition: datetime.h:102
#define MONTH
Definition: datetime.h:92
#define WARNING
Definition: elog.h:40
#define ereport(elevel,...)
Definition: elog.h:157
#define INTERVAL_MASK(b)
Definition: timestamp.h:45
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define HOUR
Definition: datetime.h:101

◆ intervaltypmodleastfield()

static int intervaltypmodleastfield ( int32  typmod)
static

Definition at line 1195 of file timestamp.c.

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

Referenced by interval_support().

1196 {
1197  if (typmod < 0)
1198  return 0; /* SECOND */
1199 
1200  switch (INTERVAL_RANGE(typmod))
1201  {
1202  case INTERVAL_MASK(YEAR):
1203  return 5; /* YEAR */
1204  case INTERVAL_MASK(MONTH):
1205  return 4; /* MONTH */
1206  case INTERVAL_MASK(DAY):
1207  return 3; /* DAY */
1208  case INTERVAL_MASK(HOUR):
1209  return 2; /* HOUR */
1210  case INTERVAL_MASK(MINUTE):
1211  return 1; /* MINUTE */
1212  case INTERVAL_MASK(SECOND):
1213  return 0; /* SECOND */
1215  return 4; /* MONTH */
1217  return 2; /* HOUR */
1219  return 1; /* MINUTE */
1221  return 0; /* SECOND */
1223  return 1; /* MINUTE */
1225  return 0; /* SECOND */
1227  return 0; /* SECOND */
1228  case INTERVAL_FULL_RANGE:
1229  return 0; /* SECOND */
1230  default:
1231  elog(ERROR, "invalid INTERVAL typmod: 0x%x", typmod);
1232  break;
1233  }
1234  return 0; /* can't get here, but keep compiler quiet */
1235 }
#define DAY
Definition: datetime.h:94
#define YEAR
Definition: datetime.h:93
#define SECOND
Definition: datetime.h:103
#define INTERVAL_FULL_RANGE
Definition: timestamp.h:48
#define ERROR
Definition: elog.h:46
#define MINUTE
Definition: datetime.h:102
#define MONTH
Definition: datetime.h:92
#define INTERVAL_RANGE(t)
Definition: timestamp.h:54
#define INTERVAL_MASK(b)
Definition: timestamp.h:45
#define elog(elevel,...)
Definition: elog.h:232
#define HOUR
Definition: datetime.h:101

◆ intervaltypmodout()

Datum intervaltypmodout ( PG_FUNCTION_ARGS  )

Definition at line 1109 of file timestamp.c.

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, SECOND, snprintf, and YEAR.

1110 {
1111  int32 typmod = PG_GETARG_INT32(0);
1112  char *res = (char *) palloc(64);
1113  int fields;
1114  int precision;
1115  const char *fieldstr;
1116 
1117  if (typmod < 0)
1118  {
1119  *res = '\0';
1120  PG_RETURN_CSTRING(res);
1121  }
1122 
1123  fields = INTERVAL_RANGE(typmod);
1124  precision = INTERVAL_PRECISION(typmod);
1125 
1126  switch (fields)
1127  {
1128  case INTERVAL_MASK(YEAR):
1129  fieldstr = " year";
1130  break;
1131  case INTERVAL_MASK(MONTH):
1132  fieldstr = " month";
1133  break;
1134  case INTERVAL_MASK(DAY):
1135  fieldstr = " day";
1136  break;
1137  case INTERVAL_MASK(HOUR):
1138  fieldstr = " hour";
1139  break;
1140  case INTERVAL_MASK(MINUTE):
1141  fieldstr = " minute";
1142  break;
1143  case INTERVAL_MASK(SECOND):
1144  fieldstr = " second";
1145  break;
1147  fieldstr = " year to month";
1148  break;
1150  fieldstr = " day to hour";
1151  break;
1153  fieldstr = " day to minute";
1154  break;
1156  fieldstr = " day to second";
1157  break;
1159  fieldstr = " hour to minute";
1160  break;
1162  fieldstr = " hour to second";
1163  break;
1165  fieldstr = " minute to second";
1166  break;
1167  case INTERVAL_FULL_RANGE:
1168  fieldstr = "";
1169  break;
1170  default:
1171  elog(ERROR, "invalid INTERVAL typmod: 0x%x", typmod);
1172  fieldstr = "";
1173  break;
1174  }
1175 
1176  if (precision != INTERVAL_FULL_PRECISION)
1177  snprintf(res, 64, "%s(%d)", fieldstr, precision);
1178  else
1179  snprintf(res, 64, "%s", fieldstr);
1180 
1181  PG_RETURN_CSTRING(res);
1182 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define DAY
Definition: datetime.h:94
#define YEAR
Definition: datetime.h:93
#define SECOND
Definition: datetime.h:103
#define INTERVAL_FULL_RANGE
Definition: timestamp.h:48
signed int int32
Definition: c.h:429
#define ERROR
Definition: elog.h:46
#define INTERVAL_FULL_PRECISION
Definition: timestamp.h:50
#define MINUTE
Definition: datetime.h:102
#define MONTH
Definition: datetime.h:92
#define INTERVAL_PRECISION(t)
Definition: timestamp.h:53
#define INTERVAL_RANGE(t)
Definition: timestamp.h:54
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
#define INTERVAL_MASK(b)
Definition: timestamp.h:45
void * palloc(Size size)
Definition: mcxt.c:1062
#define elog(elevel,...)
Definition: elog.h:232
#define HOUR
Definition: datetime.h:101
#define snprintf
Definition: port.h:217

◆ isoweek2date()

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

Definition at line 4398 of file timestamp.c.

References isoweek2j(), and j2date().

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

4399 {
4400  j2date(isoweek2j(*year, woy), year, mon, mday);
4401 }
void j2date(int jd, int *year, int *month, int *day)
Definition: datetime.c:294
int isoweek2j(int year, int week)
Definition: timestamp.c:4378

◆ isoweek2j()

int isoweek2j ( int  year,
int  week 
)

Definition at line 4378 of file timestamp.c.

References date2j(), and j2day().

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

4379 {
4380  int day0,
4381  day4;
4382 
4383  /* fourth day of current year */
4384  day4 = date2j(year, 1, 4);
4385 
4386  /* day0 == offset to first day of week (Monday) */
4387  day0 = j2day(day4 - 1);
4388 
4389  return ((week - 1) * 7) + (day4 - day0);
4390 }
int j2day(int date)
Definition: datetime.c:327
int date2j(int y, int m, int d)
Definition: datetime.c:269

◆ isoweekdate2date()

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

Definition at line 4411 of file timestamp.c.

References isoweek2j(), and j2date().

Referenced by do_to_timestamp().

4412 {
4413  int jday;
4414 
4415  jday = isoweek2j(*year, isoweek);
4416  /* convert Gregorian week start (Sunday=1) to ISO week start (Monday=1) */
4417  if (wday > 1)
4418  jday += wday - 2;
4419  else
4420  jday += 6;
4421  j2date(jday, year, mon, mday);
4422 }
void j2date(int jd, int *year, int *month, int *day)
Definition: datetime.c:294
int isoweek2j(int year, int week)
Definition: timestamp.c:4378

◆ make_interval()

Datum make_interval ( PG_FUNCTION_ARGS  )

Definition at line 1497 of file timestamp.c.

References Interval::day, days, ereport, errcode(), errmsg(), ERROR, Interval::month, months, MONTHS_PER_YEAR, palloc(), PG_GETARG_FLOAT8, PG_GETARG_INT32, PG_RETURN_INTERVAL_P, SECS_PER_HOUR, SECS_PER_MINUTE, Interval::time, and USECS_PER_SEC.

1498 {
1499  int32 years = PG_GETARG_INT32(0);
1501  int32 weeks = PG_GETARG_INT32(2);
1502  int32 days = PG_GETARG_INT32(3);
1503  int32 hours = PG_GETARG_INT32(4);
1504  int32 mins = PG_GETARG_INT32(5);
1505  double secs = PG_GETARG_FLOAT8(6);
1506  Interval *result;
1507 
1508  /*
1509  * Reject out-of-range inputs. We really ought to check the integer
1510  * inputs as well, but it's not entirely clear what limits to apply.
1511  */
1512  if (isinf(secs) || isnan(secs))
1513  ereport(ERROR,
1514  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1515  errmsg("interval out of range")));
1516 
1517  result = (Interval *) palloc(sizeof(Interval));
1518  result->month = years * MONTHS_PER_YEAR + months;
1519  result->day = weeks * 7 + days;
1520 
1521  secs = rint(secs * USECS_PER_SEC);
1522  result->time = hours * ((int64) SECS_PER_HOUR * USECS_PER_SEC) +
1523  mins * ((int64) SECS_PER_MINUTE * USECS_PER_SEC) +
1524  (int64) secs;
1525 
1526  PG_RETURN_INTERVAL_P(result);
1527 }
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:282
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:41
#define USECS_PER_SEC
Definition: timestamp.h:94
int errcode(int sqlerrcode)
Definition: elog.c:698
signed int int32
Definition: c.h:429
int32 day
Definition: timestamp.h:47
#define MONTHS_PER_YEAR
Definition: timestamp.h:69
const char *const months[]
Definition: datetime.c:65
#define ERROR
Definition: elog.h:46
#define SECS_PER_MINUTE
Definition: timestamp.h:88
TimeOffset time
Definition: timestamp.h:45
const char *const days[]
Definition: datetime.c:68
#define SECS_PER_HOUR
Definition: timestamp.h:87
int32 month
Definition: timestamp.h:48
#define ereport(elevel,...)
Definition: elog.h:157
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ make_timestamp()

Datum make_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 636 of file timestamp.c.

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

637 {
638  int32 year = PG_GETARG_INT32(0);
639  int32 month = PG_GETARG_INT32(1);
640  int32 mday = PG_GETARG_INT32(2);
641  int32 hour = PG_GETARG_INT32(3);
642  int32 min = PG_GETARG_INT32(4);
643  float8 sec = PG_GETARG_FLOAT8(5);
644  Timestamp result;
645 
646  result = make_timestamp_internal(year, month, mday,
647  hour, min, sec);
648 
649  PG_RETURN_TIMESTAMP(result);
650 }
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:282
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
static Timestamp make_timestamp_internal(int year, int month, int day, int hour, int min, double sec)
Definition: timestamp.c:554
signed int int32
Definition: c.h:429
double float8
Definition: c.h:565
int64 Timestamp
Definition: timestamp.h:38
#define PG_RETURN_TIMESTAMP(x)
Definition: timestamp.h:39

◆ make_timestamp_internal()

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

Definition at line 554 of file timestamp.c.

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, 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().

556 {
557  struct pg_tm tm;
559  TimeOffset time;
560  int dterr;
561  bool bc = false;
562  Timestamp result;
563 
564  tm.tm_year = year;
565  tm.tm_mon = month;
566  tm.tm_mday = day;
567 
568  /* Handle negative years as BC */
569  if (tm.tm_year < 0)
570  {
571  bc = true;
572  tm.tm_year = -tm.tm_year;
573  }
574 
575  dterr = ValidateDate(DTK_DATE_M, false, false, bc, &tm);
576 
577  if (dterr != 0)
578  ereport(ERROR,
579  (errcode(ERRCODE_DATETIME_FIELD_OVERFLOW),
580  errmsg("date field value out of range: %d-%02d-%02d",
581  year, month, day)));
582 
584  ereport(ERROR,
585  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
586  errmsg("date out of range: %d-%02d-%02d",
587  year, month, day)));
588 
590 
591  /* Check for time overflow */
592  if (float_time_overflows(hour, min, sec))
593  ereport(ERROR,
594  (errcode(ERRCODE_DATETIME_FIELD_OVERFLOW),
595  errmsg("time field value out of range: %d:%02d:%02g",
596  hour, min, sec)));
597 
598  /* This should match tm2time */
599  time = (((hour * MINS_PER_HOUR + min) * SECS_PER_MINUTE)
600  * USECS_PER_SEC) + (int64) rint(sec * USECS_PER_SEC);
601 
602  result = date * USECS_PER_DAY + time;
603  /* check for major overflow */
604  if ((result - time) / USECS_PER_DAY != date)
605  ereport(ERROR,
606  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
607  errmsg("timestamp out of range: %d-%02d-%02d %d:%02d:%02g",
608  year, month, day,
609  hour, min, sec)));
610 
611  /* check for just-barely overflow (okay except time-of-day wraps) */
612  /* caution: we want to allow 1999-12-31 24:00:00 */
613  if ((result < 0 && date > 0) ||
614  (result > 0 && date < -1))
615  ereport(ERROR,
616  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
617  errmsg("timestamp out of range: %d-%02d-%02d %d:%02d:%02g",
618  year, month, day,
619  hour, min, sec)));
620 
621  /* final range check catches just-out-of-range timestamps */
622  if (!IS_VALID_TIMESTAMP(result))
623  ereport(ERROR,
624  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
625  errmsg("timestamp out of range: %d-%02d-%02d %d:%02d:%02g",
626  year, month, day,
627  hour, min, sec)));
628 
629  return result;
630 }
#define USECS_PER_SEC
Definition: timestamp.h:94
int errcode(int sqlerrcode)
Definition: elog.c:698
long date
Definition: pgtypes_date.h:9
Definition: pgtime.h:32
#define DTK_DATE_M
Definition: datetime.h:192
#define MINS_PER_HOUR
Definition: timestamp.h:89
static struct pg_tm tm
Definition: localtime.c:102
#define ERROR
Definition: elog.h:46
int tm_mday
Definition: pgtime.h:37
int tm_mon
Definition: pgtime.h:38
#define SECS_PER_MINUTE
Definition: timestamp.h:88
#define IS_VALID_JULIAN(y, m, d)
Definition: timestamp.h:155
#define USECS_PER_DAY
Definition: timestamp.h:91
int64 Timestamp
Definition: timestamp.h:38
int64 TimeOffset
Definition: timestamp.h:40
int date2j(int y, int m, int d)
Definition: datetime.c:269
#define ereport(elevel,...)
Definition: elog.h:157
bool float_time_overflows(int hour, int min, double sec)
Definition: date.c:1450
#define IS_VALID_TIMESTAMP(t)
Definition: timestamp.h:195
int tm_year
Definition: pgtime.h:39
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:163
int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc, struct pg_tm *tm)
Definition: datetime.c:2480

◆ make_timestamptz()

Datum make_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 656 of file timestamp.c.

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

657 {
658  int32 year = PG_GETARG_INT32(0);
659  int32 month = PG_GETARG_INT32(1);
660  int32 mday = PG_GETARG_INT32(2);
661  int32 hour = PG_GETARG_INT32(3);
662  int32 min = PG_GETARG_INT32(4);
663  float8 sec = PG_GETARG_FLOAT8(5);
664  Timestamp result;
665 
666  result = make_timestamp_internal(year, month, mday,
667  hour, min, sec);
668 
670 }
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:282
static TimestampTz timestamp2timestamptz(Timestamp timestamp)
Definition: timestamp.c:5570
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
static Timestamp make_timestamp_internal(int year, int month, int day, int hour, int min, double sec)
Definition: timestamp.c:554
#define PG_RETURN_TIMESTAMPTZ(x)
Definition: timestamp.h:40
signed int int32
Definition: c.h:429
double float8
Definition: c.h:565
int64 Timestamp
Definition: timestamp.h:38

◆ make_timestamptz_at_timezone()

Datum make_timestamptz_at_timezone ( PG_FUNCTION_ARGS  )

Definition at line 677 of file timestamp.c.

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().

678 {
679  int32 year = PG_GETARG_INT32(0);
680  int32 month = PG_GETARG_INT32(1);
681  int32 mday = PG_GETARG_INT32(2);
682  int32 hour = PG_GETARG_INT32(3);
683  int32 min = PG_GETARG_INT32(4);
684  float8 sec = PG_GETARG_FLOAT8(5);
686  TimestampTz result;
688  struct pg_tm tt;
689  int tz;
690  fsec_t fsec;
691 
692  timestamp = make_timestamp_internal(year, month, mday,
693  hour, min, sec);
694 
695  if (timestamp2tm(timestamp, NULL, &tt, &fsec, NULL, NULL) != 0)
696  ereport(ERROR,
697  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
698  errmsg("timestamp out of range")));
699 
700  tz = parse_sane_timezone(&tt, zone);
701 
702  result = dt2local(timestamp, -tz);
703 
704  if (!IS_VALID_TIMESTAMP(result))
705  ereport(ERROR,
706  (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
707  errmsg("timestamp out of range")));
708 
709  PG_RETURN_TIMESTAMPTZ(result);
710 }
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:282
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
int64 timestamp
int64 TimestampTz
Definition: timestamp.h:39
static Timestamp make_timestamp_internal(int year, int month, int day, int hour, int min, double sec)
Definition: timestamp.c:554
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition: timestamp.c:1822
int errcode(int sqlerrcode)
Definition: elog.c:698
Definition: pgtime.h:32
#define PG_RETURN_TIMESTAMPTZ(x)
Definition: timestamp.h:40
signed int int32
Definition: c.h:429
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define ERROR
Definition: elog.h:46
double float8
Definition: c.h:565
int32 fsec_t
Definition: timestamp.h:41
int64 Timestamp
Definition: timestamp.h:38
#define ereport(elevel,...)
Definition: elog.h:157
#define IS_VALID_TIMESTAMP(t)
Definition: timestamp.h:195
Definition: zic.c:93
int errmsg(const char *fmt,...)
Definition: elog.c:909
Definition: c.h:621
static Timestamp dt2local(Timestamp dt, int timezone)
Definition: timestamp.c:2016
static int parse_sane_timezone(struct pg_tm *tm, text *zone)
Definition: timestamp.c:470

◆ mul_d_interval()

Datum mul_d_interval ( PG_FUNCTION_ARGS  )

Definition at line 3253 of file timestamp.c.

References DirectFunctionCall2, interval_mul(), and PG_GETARG_DATUM.

3254 {
3255  /* Args are float8 and Interval *, but leave them as generic Datum */
3256  Datum factor = PG_GETARG_DATUM(0);
3257  Datum span = PG_GETARG_DATUM(1);
3258 
3259  return DirectFunctionCall2(interval_mul, span, factor);
3260 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
uintptr_t Datum
Definition: postgres.h:411
Datum interval_mul(PG_FUNCTION_ARGS)
Definition: timestamp.c:3176
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:628

◆ NonFiniteTimestampTzPart()

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

Definition at line 4558 of file timestamp.c.

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, get_float8_infinity(), RESERV, and UNITS.

Referenced by timestamp_part_common(), and timestamptz_part_common().

4560 {
4561  if ((type != UNITS) && (type != RESERV))
4562  {
4563  if (isTz)
4564  ereport(ERROR,
4565  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4566  errmsg("timestamp with time zone units \"%s\" not recognized",
4567  lowunits)));
4568  else
4569  ereport(ERROR,
4570  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4571  errmsg("timestamp units \"%s\" not recognized",
4572  lowunits)));
4573  }
4574 
4575  switch (unit)
4576  {
4577  /* Oscillating units */
4578  case DTK_MICROSEC:
4579  case DTK_MILLISEC:
4580  case DTK_SECOND:
4581  case DTK_MINUTE:
4582  case DTK_HOUR:
4583  case DTK_DAY:
4584  case DTK_MONTH:
4585  case DTK_QUARTER:
4586  case DTK_WEEK:
4587  case DTK_DOW:
4588  case DTK_ISODOW:
4589  case DTK_DOY:
4590  case DTK_TZ:
4591  case DTK_TZ_MINUTE:
4592  case DTK_TZ_HOUR:
4593  return 0.0;
4594 
4595  /* Monotonically-increasing units */
4596  case DTK_YEAR:
4597  case DTK_DECADE:
4598  case DTK_CENTURY:
4599  case DTK_MILLENNIUM:
4600  case DTK_JULIAN:
4601  case DTK_ISOYEAR:
4602  case DTK_EPOCH:
4603  if (isNegative)
4604  return -get_float8_infinity();
4605  else
4606  return get_float8_infinity();
4607 
4608  default:
4609  if (isTz)
4610  ereport(ERROR,
4611  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4612  errmsg("timestamp with time zone units \"%s\" not supported",
4613  lowunits)));
4614  else
4615  ereport(ERROR,
4616  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4617  errmsg("timestamp units \"%s\" not supported",
4618  lowunits)));
4619  return 0.0; /* keep compiler quiet */
4620  }
4621 }
#define DTK_TZ_HOUR
Definition: datetime.h:178
#define DTK_CENTURY
Definition: datetime.h:170
#define UNITS
Definition: datetime.h:108
static float8 get_float8_infinity(void)
Definition: float.h:93
#define DTK_JULIAN
Definition: datetime.h:174
#define DTK_WEEK
Definition: datetime.h:165
#define DTK_YEAR
Definition: datetime.h:168
#define DTK_QUARTER
Definition: datetime.h:167
#define DTK_MILLENNIUM
Definition: datetime.h:171
int errcode(int sqlerrcode)
Definition: elog.c:698
#define DTK_ISODOW
Definition: datetime.h:181
#define DTK_MONTH
Definition: datetime.h:166
#define DTK_MILLISEC
Definition: datetime.h:172
#define DTK_DECADE
Definition: datetime.h:169
#define DTK_TZ
Definition: datetime.h:147
#define DTK_HOUR
Definition: datetime.h:163
#define ERROR
Definition: elog.h:46
#define DTK_SECOND
Definition: datetime.h:161
#define DTK_ISOYEAR
Definition: datetime.h:180
#define DTK_TZ_MINUTE
Definition: datetime.h:179
#define DTK_MINUTE
Definition: datetime.h:162
#define DTK_DOW
Definition: datetime.h:176
#define DTK_MICROSEC
Definition: datetime.h:173
#define ereport(elevel,...)
Definition: elog.h:157
#define DTK_DOY
Definition: datetime.h:177
#define DTK_DAY
Definition: datetime.h:164
#define RESERV
Definition: datetime.h:91
#define DTK_EPOCH
Definition: datetime.h:153
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ now()

Definition at line 1544 of file timestamp.c.

References GetCurrentTransactionStartTimestamp(), and PG_RETURN_TIMESTAMPTZ.

Referenced by advanceConnectionState(), ApplyLauncherMain(), BackgroundWriterMain(), CheckArchiveTimeout(), CheckpointerMain(), doLog(), drandom(), dumpTimestamp(), enable_timeout(), enable_timeout_after(), enable_timeout_at(), enable_timeout_every(), enable_timeouts(), GetSnapshotCurrentTimestamp(), handle_sig_alarm(), HandleCopyStream(), has_startup_progress_timeout_expired(), LockBufferForCleanup(), logicalrep_worker_launch(), LogicalRepApplyLoop(), maybe_start_bgworkers(), mxid_age(), OutputFsync(), pg_time_now(), pg_timezone_abbrevs(), pgfdw_get_cleanup_result(), pgstat_report_stat(), pgstat_send_tabstat(), pgstat_send_wal(), pqSocketPoll(), pqTraceFormatTimestamp(), printProgressReport(), process_syncing_tables_for_apply(), ProcessKeepaliveMsg(), ProcessStandbyReplyMessage(), ProcSleep(), progress_report(), RequestXLogStreaming(), ResolveRecoveryConflictWithLock(), ResolveRecoveryConflictWithVirtualXIDs(), send_feedback(), ServerLoop(), set_next_rotation_time(), StreamLogicalLog(), SysLoggerMain(), threadRun(), timetz_zone(), WaitForWALToBecomeAvailable(), WalRcvRunning(), WalRcvStreaming(), WalReceiverMain(), WalSndUpdateProgress(), WalSndWriteData(), xid_age(), XLogBackgroundFlush(), XLogWalRcvSendHSFeedback(), and XLogWalRcvSendReply().

1545 {
1547 }
#define PG_RETURN_TIMESTAMPTZ(x)
Definition: timestamp.h:40
TimestampTz GetCurrentTransactionStartTimestamp(void)
Definition: xact.c:799

◆ overlaps_timestamp()

Datum overlaps_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2491 of file timestamp.c.

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

2492 {
2493  /*
2494  * The arguments are Timestamps, but we leave them as generic Datums to
2495  * avoid unnecessary conversions between value and reference forms --- not
2496  * to mention possible dereferences of null pointers.
2497  */
2498  Datum ts1 = PG_GETARG_DATUM(0);
2499  Datum te1 = PG_GETARG_DATUM(1);
2500  Datum ts2 = PG_GETARG_DATUM(2);
2501  Datum te2 = PG_GETARG_DATUM(3);
2502  bool ts1IsNull = PG_ARGISNULL(0);
2503  bool te1IsNull = PG_ARGISNULL(1);
2504  bool ts2IsNull = PG_ARGISNULL(2);
2505  bool te2IsNull = PG_ARGISNULL(3);
2506 
2507 #define TIMESTAMP_GT(t1,t2) \
2508  DatumGetBool(DirectFunctionCall2(timestamp_gt,t1,t2))
2509 #define TIMESTAMP_LT(t1,t2) \
2510  DatumGetBool(DirectFunctionCall2(timestamp_lt,t1,t2))
2511 
2512  /*
2513  * If both endpoints of interval 1 are null, the result is null (unknown).
2514  * If just one endpoint is null, take ts1 as the non-null one. Otherwise,
2515  * take ts1 as the lesser endpoint.
2516  */
2517  if (ts1IsNull)
2518  {
2519  if (te1IsNull)
2520  PG_RETURN_NULL();
2521  /* swap null for non-null */
2522  ts1 = te1;
2523  te1IsNull = true;
2524  }
2525  else if (!te1IsNull)
2526  {
2527  if (TIMESTAMP_GT(ts1, te1))
2528  {
2529  Datum tt = ts1;
2530 
2531  ts1 = te1;
2532  te1 = tt;
2533  }
2534  }
2535 
2536  /* Likewise for interval 2. */
2537  if (ts2IsNull)
2538  {
2539  if (te2IsNull)
2540  PG_RETURN_NULL();
2541  /* swap null for non-null */
2542  ts2 = te2;
2543  te2IsNull = true;
2544  }
2545  else if (!te2IsNull)
2546  {
2547  if (TIMESTAMP_GT(ts2, te2))
2548  {
2549  Datum tt = ts2;
2550 
2551  ts2 = te2;
2552  te2 = tt;
2553  }
2554  }
2555 
2556  /*
2557  * At this point neither ts1 nor ts2 is null, so we can consider three
2558  * cases: ts1 > ts2, ts1 < ts2, ts1 = ts2
2559  */
2560  if (TIMESTAMP_GT(ts1, ts2))
2561  {
2562  /*
2563  * This case is ts1 < te2 OR te1 < te2, which may look redundant but
2564  * in the presence of nulls it's not quite completely so.
2565  */
2566  if (te2IsNull)
2567  PG_RETURN_NULL();
2568  if (TIMESTAMP_LT(ts1, te2))
2569  PG_RETURN_BOOL(true);
2570  if (te1IsNull)
2571  PG_RETURN_NULL();
2572 
2573  /*
2574  * If te1 is not null then we had ts1 <= te1 above, and we just found
2575  * ts1 >= te2, hence te1 >= te2.
2576  */
2577  PG_RETURN_BOOL(false);
2578  }
2579  else if (TIMESTAMP_LT(ts1, ts2))
2580  {
2581  /* This case is ts2 < te1 OR te2 < te1 */
2582  if (te1IsNull)
2583  PG_RETURN_NULL();
2584  if (TIMESTAMP_LT(ts2, te1))
2585  PG_RETURN_BOOL(true);
2586  if (te2IsNull)
2587  PG_RETURN_NULL();
2588 
2589  /*
2590  * If te2 is not null then we had ts2 <= te2 above, and we just found
2591  * ts2 >= te1, hence te2 >= te1.
2592  */
2593  PG_RETURN_BOOL(false);
2594  }
2595  else
2596  {
2597  /*
2598  * For ts1 = ts2 the spec says te1 <> te2 OR te1 = te2, which is a
2599  * rather silly way of saying "true if both are non-null, else null".
2600  */
2601  if (te1IsNull || te2IsNull)
2602  PG_RETURN_NULL();
2603  PG_RETURN_BOOL(true);
2604  }
2605 
2606 #undef TIMESTAMP_GT
2607 #undef TIMESTAMP_LT
2608 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define TIMESTAMP_LT(t1, t2)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
uintptr_t Datum
Definition: postgres.h:411
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define TIMESTAMP_GT(t1, t2)
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ parse_sane_timezone()

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

Definition at line 470 of file timestamp.c.

References DecodeTimezone(), DecodeTimezoneAbbrev(), DetermineTimeZoneAbbrevOffset(), DetermineTimeZoneOffset(), downcase_truncate_identifier(), DTERR_BAD_FORMAT, DTERR_TZDISP_OVERFLOW, DTZ, DYNTZ, ereport, errcode(), errhint(), errmsg(), ERROR, pg_tzset(), text_to_cstring_buffer(), generate_unaccent_rules::type, TZ, TZ_STRLEN_MAX, and val.

Referenced by make_timestamptz_at_timezone().

471 {
472  char tzname[TZ_STRLEN_MAX + 1];
473  int rt;
474  int tz;
475 
476  text_to_cstring_buffer(zone, tzname, sizeof(tzname));
477 
478  /*
479  * Look up the requested timezone. First we try to interpret it as a
480  * numeric timezone specification; if DecodeTimezone decides it doesn't
481  * like the format, we look in the timezone abbreviation table (to handle
482  * cases like "EST"), and if that also fails, we look in the timezone
483  * database (to handle cases like "America/New_York"). (This matches the
484  * order in which timestamp input checks the cases; it's important because
485  * the timezone database unwisely uses a few zone names that are identical
486  * to offset abbreviations.)
487  *
488  * Note pg_tzset happily parses numeric input that DecodeTimezone would
489  * reject. To avoid having it accept input that would otherwise be seen
490  * as invalid, it's enough to disallow having a digit in the first
491  * position of our input string.
492  */
493  if (isdigit((unsigned char) *tzname))
494  ereport(ERROR,
495  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
496  errmsg("invalid input syntax for type %s: \"%s\"",
497  "numeric time zone", tzname),
498  errhint("Numeric time zones must have \"-\" or \"+\" as first character.")));
499 
500  rt = DecodeTimezone(tzname, &tz);
501  if (rt != 0)
502  {
503  char *lowzone;
504  int type,
505  val;
506  pg_tz *tzp;
507 
508  if (rt == DTERR_TZDISP_OVERFLOW)
509  ereport(ERROR,
510  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
511  errmsg("numeric time zone \"%s\" out of range", tzname)));
512  else if (rt != DTERR_BAD_FORMAT)
513  ereport(ERROR,
514  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
515  errmsg("time zone \"%s\" not recognized", tzname)));
516 
517  /* DecodeTimezoneAbbrev requires lowercase input */
518  lowzone = downcase_truncate_identifier(tzname,
519  strlen(tzname),
520  false);
521  type = DecodeTimezoneAbbrev(0, lowzone, &val, &tzp);
522 
523  if (type == TZ || type == DTZ)
524  {
525  /* fixed-offset abbreviation */
526  tz = -val;
527  }
528  else if (type == DYNTZ)
529  {
530  /* dynamic-offset abbreviation, resolve using specified time */
531  tz = DetermineTimeZoneAbbrevOffset(tm, tzname, tzp);
532  }
533  else
534  {
535  /* try it as a full zone name */
536  tzp = pg_tzset(tzname);
537  if (tzp)
538  tz = DetermineTimeZoneOffset(tm, tzp);
539  else
540  ereport(ERROR,
541  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
542  errmsg("time zone \"%s\" not recognized", tzname)));
543  }
544  }
545 
546  return tz;
547 }
#define DTERR_BAD_FORMAT
Definition: datetime.h:280
int errhint(const char *fmt,...)
Definition: elog.c:1156
char * downcase_truncate_identifier(const char *ident, int len, bool warn)
Definition: scansup.c:37
int errcode(int sqlerrcode)
Definition: elog.c:698
#define TZ
Definition: datetime.h:96
void text_to_cstring_buffer(const text *src, char *dst, size_t dst_len)
Definition: varlena.c:253
pg_tz * pg_tzset(const char *tzname)
Definition: pgtz.c:234
#define TZ_STRLEN_MAX
Definition: pgtime.h:51
#define ERROR
Definition: elog.h:46
int DecodeTimezoneAbbrev(int field, char *lowtoken, int *offset, pg_tz **tz)
Definition: datetime.c:2985
int DecodeTimezone(char *str, int *tzp)
Definition: