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

Go to the source code of this file.

Data Structures

struct  generate_series_timestamp_fctx
 
struct  generate_series_timestamptz_fctx
 
struct  IntervalAggState
 

Macros

#define SAMESIGN(a, b)   (((a) < 0) == ((b) < 0))
 
#define IA_TOTAL_COUNT(ia)    ((ia)->N + (ia)->pInfcount + (ia)->nInfcount)
 
#define TIMESTAMP_GT(t1, t2)    DatumGetBool(DirectFunctionCall2(timestamp_gt,t1,t2))
 
#define TIMESTAMP_LT(t1, t2)    DatumGetBool(DirectFunctionCall2(timestamp_lt,t1,t2))
 
#define INTERVAL_TO_MICROSECONDS(i)   ((((double) (i)->month * DAYS_PER_MONTH + (i)->day)) * USECS_PER_DAY + (i)->time)
 

Typedefs

typedef struct IntervalAggState IntervalAggState
 

Functions

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

Variables

TimestampTz PgStartTime
 
TimestampTz PgReloadTime
 

Macro Definition Documentation

◆ IA_TOTAL_COUNT

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

Definition at line 89 of file timestamp.c.

◆ INTERVAL_TO_MICROSECONDS

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

◆ SAMESIGN

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

Definition at line 51 of file timestamp.c.

◆ TIMESTAMP_GT

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

◆ TIMESTAMP_LT

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

Typedef Documentation

◆ IntervalAggState

Function Documentation

◆ AdjustIntervalForTypmod()

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

Definition at line 1350 of file timestamp.c.

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

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

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

◆ AdjustTimestampForTypmod()

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

Definition at line 368 of file timestamp.c.

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

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

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

◆ anytimestamp_typmod_check()

int32 anytimestamp_typmod_check ( bool  istz,
int32  typmod 
)

Definition at line 125 of file timestamp.c.

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

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

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

◆ anytimestamp_typmodin()

static int32 anytimestamp_typmodin ( bool  istz,
ArrayType ta 
)
static

Definition at line 104 of file timestamp.c.

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

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

Referenced by timestamptypmodin(), and timestamptztypmodin().

◆ anytimestamp_typmodout()

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

Definition at line 147 of file timestamp.c.

148{
149 const char *tz = istz ? " with time zone" : " without time zone";
150
151 if (typmod >= 0)
152 return psprintf("(%d)%s", (int) typmod, tz);
153 else
154 return pstrdup(tz);
155}
char * pstrdup(const char *in)
Definition: mcxt.c:1759
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43

References psprintf(), and pstrdup().

Referenced by timestamptypmodout(), and timestamptztypmodout().

◆ clock_timestamp()

Datum clock_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 1621 of file timestamp.c.

1622{
1624}
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1645
#define PG_RETURN_TIMESTAMPTZ(x)
Definition: timestamp.h:68

References GetCurrentTimestamp(), and PG_RETURN_TIMESTAMPTZ.

◆ date2isoweek()

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

Definition at line 5295 of file timestamp.c.

5296{
5297 int day0,
5298 day4,
5299 dayn,
5300 week;
5301
5302 /* current day */
5303 dayn = date2j(year, mon, mday);
5304
5305 /* fourth day of current year */
5306 day4 = date2j(year, 1, 4);
5307
5308 /* day0 == offset to first day of week (Monday) */
5309 day0 = j2day(day4 - 1);
5310
5311 /*
5312 * We need the first week containing a Thursday, otherwise this day falls
5313 * into the previous year for purposes of counting weeks
5314 */
5315 if (dayn < day4 - day0)
5316 {
5317 day4 = date2j(year - 1, 1, 4);
5318
5319 /* day0 == offset to first day of week (Monday) */
5320 day0 = j2day(day4 - 1);
5321 }
5322
5323 week = (dayn - (day4 - day0)) / 7 + 1;
5324
5325 /*
5326 * Sometimes the last few days in a year will fall into the first week of
5327 * the next year, so check for this.
5328 */
5329 if (week >= 52)
5330 {
5331 day4 = date2j(year + 1, 1, 4);
5332
5333 /* day0 == offset to first day of week (Monday) */
5334 day0 = j2day(day4 - 1);
5335
5336 if (dayn >= day4 - day0)
5337 week = (dayn - (day4 - day0)) / 7 + 1;
5338 }
5339
5340 return week;
5341}
int j2day(int date)
Definition: datetime.c:354
int date2j(int year, int month, int day)
Definition: datetime.c:296

References date2j(), and j2day().

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

◆ date2isoyear()

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

Definition at line 5350 of file timestamp.c.

5351{
5352 int day0,
5353 day4,
5354 dayn,
5355 week;
5356
5357 /* current day */
5358 dayn = date2j(year, mon, mday);
5359
5360 /* fourth day of current year */
5361 day4 = date2j(year, 1, 4);
5362
5363 /* day0 == offset to first day of week (Monday) */
5364 day0 = j2day(day4 - 1);
5365
5366 /*
5367 * We need the first week containing a Thursday, otherwise this day falls
5368 * into the previous year for purposes of counting weeks
5369 */
5370 if (dayn < day4 - day0)
5371 {
5372 day4 = date2j(year - 1, 1, 4);
5373
5374 /* day0 == offset to first day of week (Monday) */
5375 day0 = j2day(day4 - 1);
5376
5377 year--;
5378 }
5379
5380 week = (dayn - (day4 - day0)) / 7 + 1;
5381
5382 /*
5383 * Sometimes the last few days in a year will fall into the first week of
5384 * the next year, so check for this.
5385 */
5386 if (week >= 52)
5387 {
5388 day4 = date2j(year + 1, 1, 4);
5389
5390 /* day0 == offset to first day of week (Monday) */
5391 day0 = j2day(day4 - 1);
5392
5393 if (dayn >= day4 - day0)
5394 year++;
5395 }
5396
5397 return year;
5398}

References date2j(), and j2day().

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

◆ date2isoyearday()

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

Definition at line 5407 of file timestamp.c.

5408{
5409 return date2j(year, mon, mday) - isoweek2j(date2isoyear(year, mon, mday), 1) + 1;
5410}
int isoweek2j(int year, int week)
Definition: timestamp.c:5244
int date2isoyear(int year, int mon, int mday)
Definition: timestamp.c:5350

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

Referenced by DCH_to_char().

◆ do_interval_accum()

static void do_interval_accum ( IntervalAggState state,
Interval newval 
)
static

Definition at line 3989 of file timestamp.c.

3990{
3991 /* Infinite inputs are counted separately, and do not affect "N" */
3993 {
3994 state->nInfcount++;
3995 return;
3996 }
3997
3999 {
4000 state->pInfcount++;
4001 return;
4002 }
4003
4004 finite_interval_pl(&state->sumX, newval, &state->sumX);
4005 state->N++;
4006}
static void finite_interval_pl(const Interval *span1, const Interval *span2, Interval *result)
Definition: timestamp.c:3488
#define INTERVAL_IS_NOBEGIN(i)
Definition: timestamp.h:182
#define INTERVAL_IS_NOEND(i)
Definition: timestamp.h:192
#define newval
Definition: regguts.h:323

References finite_interval_pl(), INTERVAL_IS_NOBEGIN, INTERVAL_IS_NOEND, and newval.

Referenced by interval_avg_accum().

◆ do_interval_discard()

static void do_interval_discard ( IntervalAggState state,
Interval newval 
)
static

Definition at line 4012 of file timestamp.c.

4013{
4014 /* Infinite inputs are counted separately, and do not affect "N" */
4016 {
4017 state->nInfcount--;
4018 return;
4019 }
4020
4022 {
4023 state->pInfcount--;
4024 return;
4025 }
4026
4027 /* Handle the to-be-discarded finite value. */
4028 state->N--;
4029 if (state->N > 0)
4030 finite_interval_mi(&state->sumX, newval, &state->sumX);
4031 else
4032 {
4033 /* All values discarded, reset the state */
4034 Assert(state->N == 0);
4035 memset(&state->sumX, 0, sizeof(state->sumX));
4036 }
4037}
static void finite_interval_mi(const Interval *span1, const Interval *span2, Interval *result)
Definition: timestamp.c:3544
Assert(PointerIsAligned(start, uint64))

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

Referenced by interval_avg_accum_inv().

◆ dt2local()

static Timestamp dt2local ( Timestamp  dt,
int  timezone 
)
static

Definition at line 2134 of file timestamp.c.

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

References USECS_PER_SEC.

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

◆ dt2time()

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

Definition at line 1883 of file timestamp.c.

1884{
1885 TimeOffset time;
1886
1887 time = jd;
1888
1889 *hour = time / USECS_PER_HOUR;
1890 time -= (*hour) * USECS_PER_HOUR;
1891 *min = time / USECS_PER_MINUTE;
1892 time -= (*min) * USECS_PER_MINUTE;
1893 *sec = time / USECS_PER_SEC;
1894 *fsec = time - (*sec * USECS_PER_SEC);
1895} /* dt2time() */
int64 TimeOffset
Definition: timestamp.h:40

References USECS_PER_HOUR, USECS_PER_MINUTE, and USECS_PER_SEC.

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

◆ EncodeSpecialInterval()

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

Definition at line 1598 of file timestamp.c.

1599{
1601 strcpy(str, EARLY);
1602 else if (INTERVAL_IS_NOEND(interval))
1603 strcpy(str, LATE);
1604 else /* shouldn't happen */
1605 elog(ERROR, "invalid argument for EncodeSpecialInterval");
1606}
const char * str
#define EARLY
Definition: datetime.h:39
#define LATE
Definition: datetime.h:40

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

Referenced by interval_out().

◆ EncodeSpecialTimestamp()

void EncodeSpecialTimestamp ( Timestamp  dt,
char *  str 
)

Definition at line 1587 of file timestamp.c.

1588{
1589 if (TIMESTAMP_IS_NOBEGIN(dt))
1590 strcpy(str, EARLY);
1591 else if (TIMESTAMP_IS_NOEND(dt))
1592 strcpy(str, LATE);
1593 else /* shouldn't happen */
1594 elog(ERROR, "invalid argument for EncodeSpecialTimestamp");
1595}
#define TIMESTAMP_IS_NOEND(j)
Definition: timestamp.h:167
#define TIMESTAMP_IS_NOBEGIN(j)
Definition: timestamp.h:162

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

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

◆ extract_interval()

Datum extract_interval ( PG_FUNCTION_ARGS  )

Definition at line 6293 of file timestamp.c.

6294{
6295 return interval_part_common(fcinfo, true);
6296}
static Datum interval_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition: timestamp.c:6080

References interval_part_common().

◆ extract_timestamp()

Datum extract_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 5745 of file timestamp.c.

5746{
5747 return timestamp_part_common(fcinfo, true);
5748}
static Datum timestamp_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition: timestamp.c:5481

References timestamp_part_common().

◆ extract_timestamptz()

Datum extract_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 6017 of file timestamp.c.

6018{
6019 return timestamptz_part_common(fcinfo, true);
6020}
static Datum timestamptz_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition: timestamp.c:5754

References timestamptz_part_common().

◆ finite_interval_mi()

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

Definition at line 3544 of file timestamp.c.

3545{
3546 Assert(!INTERVAL_NOT_FINITE(span1));
3547 Assert(!INTERVAL_NOT_FINITE(span2));
3548
3549 if (pg_sub_s32_overflow(span1->month, span2->month, &result->month) ||
3550 pg_sub_s32_overflow(span1->day, span2->day, &result->day) ||
3551 pg_sub_s64_overflow(span1->time, span2->time, &result->time) ||
3552 INTERVAL_NOT_FINITE(result))
3553 ereport(ERROR,
3554 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3555 errmsg("interval out of range")));
3556}
static bool pg_sub_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:169
int32 day
Definition: timestamp.h:51
int32 month
Definition: timestamp.h:52
TimeOffset time
Definition: timestamp.h:49

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

Referenced by do_interval_discard(), and interval_mi().

◆ finite_interval_pl()

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

Definition at line 3488 of file timestamp.c.

3489{
3490 Assert(!INTERVAL_NOT_FINITE(span1));
3491 Assert(!INTERVAL_NOT_FINITE(span2));
3492
3493 if (pg_add_s32_overflow(span1->month, span2->month, &result->month) ||
3494 pg_add_s32_overflow(span1->day, span2->day, &result->day) ||
3495 pg_add_s64_overflow(span1->time, span2->time, &result->time) ||
3496 INTERVAL_NOT_FINITE(result))
3497 ereport(ERROR,
3498 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3499 errmsg("interval out of range")));
3500}
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:151

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

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

◆ float8_timestamptz()

Datum float8_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 726 of file timestamp.c.

727{
728 float8 seconds = PG_GETARG_FLOAT8(0);
729 TimestampTz result;
730
731 /* Deal with NaN and infinite inputs ... */
732 if (isnan(seconds))
734 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
735 errmsg("timestamp cannot be NaN")));
736
737 if (isinf(seconds))
738 {
739 if (seconds < 0)
740 TIMESTAMP_NOBEGIN(result);
741 else
742 TIMESTAMP_NOEND(result);
743 }
744 else
745 {
746 /* Out of range? */
747 if (seconds <
749 || seconds >=
752 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
753 errmsg("timestamp out of range: \"%g\"", seconds)));
754
755 /* Convert UNIX epoch to Postgres epoch */
757
758 seconds = rint(seconds * USECS_PER_SEC);
759 result = (int64) seconds;
760
761 /* Recheck in case roundoff produces something just out of range */
762 if (!IS_VALID_TIMESTAMP(result))
764 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
765 errmsg("timestamp out of range: \"%g\"",
766 PG_GETARG_FLOAT8(0))));
767 }
768
769 PG_RETURN_TIMESTAMP(result);
770}
double float8
Definition: c.h:638
#define DATETIME_MIN_JULIAN
Definition: timestamp.h:251
int64 TimestampTz
Definition: timestamp.h:39
#define TIMESTAMP_NOBEGIN(j)
Definition: timestamp.h:159
#define TIMESTAMP_END_JULIAN
Definition: timestamp.h:253
#define IS_VALID_TIMESTAMP(t)
Definition: timestamp.h:267
#define UNIX_EPOCH_JDATE
Definition: timestamp.h:234
#define SECS_PER_DAY
Definition: timestamp.h:126
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:235
#define TIMESTAMP_NOEND(j)
Definition: timestamp.h:164
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:282
#define PG_RETURN_TIMESTAMP(x)
Definition: timestamp.h:67

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

◆ generate_series_timestamp()

Datum generate_series_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 6667 of file timestamp.c.

6668{
6669 FuncCallContext *funcctx;
6671 Timestamp result;
6672
6673 /* stuff done only on the first call of the function */
6674 if (SRF_IS_FIRSTCALL())
6675 {
6677 Timestamp finish = PG_GETARG_TIMESTAMP(1);
6678 Interval *step = PG_GETARG_INTERVAL_P(2);
6679 MemoryContext oldcontext;
6680
6681 /* create a function context for cross-call persistence */
6682 funcctx = SRF_FIRSTCALL_INIT();
6683
6684 /*
6685 * switch to memory context appropriate for multiple function calls
6686 */
6687 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
6688
6689 /* allocate memory for user context */
6692
6693 /*
6694 * Use fctx to keep state from call to call. Seed current with the
6695 * original start value
6696 */
6697 fctx->current = start;
6698 fctx->finish = finish;
6699 fctx->step = *step;
6700
6701 /* Determine sign of the interval */
6702 fctx->step_sign = interval_sign(&fctx->step);
6703
6704 if (fctx->step_sign == 0)
6705 ereport(ERROR,
6706 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6707 errmsg("step size cannot equal zero")));
6708
6709 if (INTERVAL_NOT_FINITE((&fctx->step)))
6710 ereport(ERROR,
6711 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6712 errmsg("step size cannot be infinite")));
6713
6714 funcctx->user_fctx = fctx;
6715 MemoryContextSwitchTo(oldcontext);
6716 }
6717
6718 /* stuff done on every call of the function */
6719 funcctx = SRF_PERCALL_SETUP();
6720
6721 /*
6722 * get the saved state and use current as the result for this iteration
6723 */
6724 fctx = funcctx->user_fctx;
6725 result = fctx->current;
6726
6727 if (fctx->step_sign > 0 ?
6728 timestamp_cmp_internal(result, fctx->finish) <= 0 :
6729 timestamp_cmp_internal(result, fctx->finish) >= 0)
6730 {
6731 /* increment current in preparation for next iteration */
6734 PointerGetDatum(&fctx->step)));
6735
6736 /* do when there is more left to send */
6737 SRF_RETURN_NEXT(funcctx, TimestampGetDatum(result));
6738 }
6739 else
6740 {
6741 /* do when there is no more left */
6742 SRF_RETURN_DONE(funcctx);
6743 }
6744}
int timestamp_cmp_internal(Timestamp dt1, Timestamp dt2)
Definition: timestamp.c:2210
Datum timestamp_pl_interval(PG_FUNCTION_ARGS)
Definition: timestamp.c:3090
static int interval_sign(const Interval *interval)
Definition: timestamp.c:2555
int64 Timestamp
Definition: timestamp.h:38
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:684
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:304
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:308
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:310
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:306
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:328
return str start
void * palloc(Size size)
Definition: mcxt.c:1365
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:332
void * user_fctx
Definition: funcapi.h:82
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:101
static Datum TimestampGetDatum(Timestamp X)
Definition: timestamp.h:46
#define PG_GETARG_TIMESTAMP(n)
Definition: timestamp.h:63
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:65
static Timestamp DatumGetTimestamp(Datum X)
Definition: timestamp.h:28

References generate_series_timestamp_fctx::current, DatumGetTimestamp(), DirectFunctionCall2, ereport, errcode(), errmsg(), ERROR, generate_series_timestamp_fctx::finish, INTERVAL_NOT_FINITE, interval_sign(), MemoryContextSwitchTo(), FuncCallContext::multi_call_memory_ctx, palloc(), PG_GETARG_INTERVAL_P, PG_GETARG_TIMESTAMP, PointerGetDatum(), SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, start, generate_series_timestamp_fctx::step, generate_series_timestamp_fctx::step_sign, timestamp_cmp_internal(), timestamp_pl_interval(), TimestampGetDatum(), and FuncCallContext::user_fctx.

◆ generate_series_timestamp_support()

Datum generate_series_timestamp_support ( PG_FUNCTION_ARGS  )

Definition at line 6848 of file timestamp.c.

6849{
6850 Node *rawreq = (Node *) PG_GETARG_POINTER(0);
6851 Node *ret = NULL;
6852
6853 if (IsA(rawreq, SupportRequestRows))
6854 {
6855 /* Try to estimate the number of rows returned */
6856 SupportRequestRows *req = (SupportRequestRows *) rawreq;
6857
6858 if (is_funcclause(req->node)) /* be paranoid */
6859 {
6860 List *args = ((FuncExpr *) req->node)->args;
6861 Node *arg1,
6862 *arg2,
6863 *arg3;
6864
6865 /* We can use estimated argument values here */
6869
6870 /*
6871 * If any argument is constant NULL, we can safely assume that
6872 * zero rows are returned. Otherwise, if they're all non-NULL
6873 * constants, we can calculate the number of rows that will be
6874 * returned.
6875 */
6876 if ((IsA(arg1, Const) && ((Const *) arg1)->constisnull) ||
6877 (IsA(arg2, Const) && ((Const *) arg2)->constisnull) ||
6878 (IsA(arg3, Const) && ((Const *) arg3)->constisnull))
6879 {
6880 req->rows = 0;
6881 ret = (Node *) req;
6882 }
6883 else if (IsA(arg1, Const) && IsA(arg2, Const) && IsA(arg3, Const))
6884 {
6886 finish;
6887 Interval *step;
6888 Datum diff;
6889 double dstep;
6890 int64 dummy;
6891
6892 start = DatumGetTimestamp(((Const *) arg1)->constvalue);
6893 finish = DatumGetTimestamp(((Const *) arg2)->constvalue);
6894 step = DatumGetIntervalP(((Const *) arg3)->constvalue);
6895
6896 /*
6897 * Perform some prechecks which could cause timestamp_mi to
6898 * raise an ERROR. It's much better to just return some
6899 * default estimate than error out in a support function.
6900 */
6902 !pg_sub_s64_overflow(finish, start, &dummy))
6903 {
6905 TimestampGetDatum(finish),
6907
6908#define INTERVAL_TO_MICROSECONDS(i) ((((double) (i)->month * DAYS_PER_MONTH + (i)->day)) * USECS_PER_DAY + (i)->time)
6909
6910 dstep = INTERVAL_TO_MICROSECONDS(step);
6911
6912 /* This equation works for either sign of step */
6913 if (dstep != 0.0)
6914 {
6915 Interval *idiff = DatumGetIntervalP(diff);
6916 double ddiff = INTERVAL_TO_MICROSECONDS(idiff);
6917
6918 req->rows = floor(ddiff / dstep + 1.0);
6919 ret = (Node *) req;
6920 }
6921#undef INTERVAL_TO_MICROSECONDS
6922 }
6923 }
6924 }
6925 }
6926
6927 PG_RETURN_POINTER(ret);
6928}
Datum timestamp_mi(PG_FUNCTION_ARGS)
Definition: timestamp.c:2827
#define INTERVAL_TO_MICROSECONDS(i)
Node * estimate_expression_value(PlannerInfo *root, Node *node)
Definition: clauses.c:2411
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
static bool is_funcclause(const void *clause)
Definition: nodeFuncs.h:69
#define IsA(nodeptr, _type_)
Definition: nodes.h:164
#define lthird(l)
Definition: pg_list.h:188
#define linitial(l)
Definition: pg_list.h:178
#define lsecond(l)
Definition: pg_list.h:183
uint64_t Datum
Definition: postgres.h:70
Definition: pg_list.h:54
Definition: nodes.h:135
PlannerInfo * root
Definition: supportnodes.h:218
static Interval * DatumGetIntervalP(Datum X)
Definition: timestamp.h:40

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

◆ generate_series_timestamptz()

Datum generate_series_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 6833 of file timestamp.c.

6834{
6836}
static Datum generate_series_timestamptz_internal(FunctionCallInfo fcinfo)
Definition: timestamp.c:6751

References generate_series_timestamptz_internal().

◆ generate_series_timestamptz_at_zone()

Datum generate_series_timestamptz_at_zone ( PG_FUNCTION_ARGS  )

Definition at line 6839 of file timestamp.c.

6840{
6842}

References generate_series_timestamptz_internal().

◆ generate_series_timestamptz_internal()

static Datum generate_series_timestamptz_internal ( FunctionCallInfo  fcinfo)
static

Definition at line 6751 of file timestamp.c.

6752{
6753 FuncCallContext *funcctx;
6755 TimestampTz result;
6756
6757 /* stuff done only on the first call of the function */
6758 if (SRF_IS_FIRSTCALL())
6759 {
6762 Interval *step = PG_GETARG_INTERVAL_P(2);
6763 text *zone = (PG_NARGS() == 4) ? PG_GETARG_TEXT_PP(3) : NULL;
6764 MemoryContext oldcontext;
6765
6766 /* create a function context for cross-call persistence */
6767 funcctx = SRF_FIRSTCALL_INIT();
6768
6769 /*
6770 * switch to memory context appropriate for multiple function calls
6771 */
6772 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
6773
6774 /* allocate memory for user context */
6777
6778 /*
6779 * Use fctx to keep state from call to call. Seed current with the
6780 * original start value
6781 */
6782 fctx->current = start;
6783 fctx->finish = finish;
6784 fctx->step = *step;
6786
6787 /* Determine sign of the interval */
6788 fctx->step_sign = interval_sign(&fctx->step);
6789
6790 if (fctx->step_sign == 0)
6791 ereport(ERROR,
6792 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6793 errmsg("step size cannot equal zero")));
6794
6795 if (INTERVAL_NOT_FINITE((&fctx->step)))
6796 ereport(ERROR,
6797 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6798 errmsg("step size cannot be infinite")));
6799
6800 funcctx->user_fctx = fctx;
6801 MemoryContextSwitchTo(oldcontext);
6802 }
6803
6804 /* stuff done on every call of the function */
6805 funcctx = SRF_PERCALL_SETUP();
6806
6807 /*
6808 * get the saved state and use current as the result for this iteration
6809 */
6810 fctx = funcctx->user_fctx;
6811 result = fctx->current;
6812
6813 if (fctx->step_sign > 0 ?
6814 timestamp_cmp_internal(result, fctx->finish) <= 0 :
6815 timestamp_cmp_internal(result, fctx->finish) >= 0)
6816 {
6817 /* increment current in preparation for next iteration */
6819 &fctx->step,
6820 fctx->attimezone);
6821
6822 /* do when there is more left to send */
6823 SRF_RETURN_NEXT(funcctx, TimestampTzGetDatum(result));
6824 }
6825 else
6826 {
6827 /* do when there is no more left */
6828 SRF_RETURN_DONE(funcctx);
6829 }
6830}
static pg_tz * lookup_timezone(text *zone)
Definition: timestamp.c:560
static TimestampTz timestamptz_pl_interval_internal(TimestampTz timestamp, Interval *span, pg_tz *attimezone)
Definition: timestamp.c:3233
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_NARGS()
Definition: fmgr.h:203
PGDLLIMPORT pg_tz * session_timezone
Definition: pgtz.c:28
Definition: c.h:695
Definition: zic.c:99
static Datum TimestampTzGetDatum(TimestampTz X)
Definition: timestamp.h:52
#define PG_GETARG_TIMESTAMPTZ(n)
Definition: timestamp.h:64

References generate_series_timestamptz_fctx::attimezone, generate_series_timestamptz_fctx::current, ereport, errcode(), errmsg(), ERROR, generate_series_timestamptz_fctx::finish, INTERVAL_NOT_FINITE, interval_sign(), lookup_timezone(), MemoryContextSwitchTo(), FuncCallContext::multi_call_memory_ctx, palloc(), PG_GETARG_INTERVAL_P, PG_GETARG_TEXT_PP, PG_GETARG_TIMESTAMPTZ, PG_NARGS, session_timezone, SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, start, generate_series_timestamptz_fctx::step, generate_series_timestamptz_fctx::step_sign, timestamp_cmp_internal(), timestamptz_pl_interval_internal(), TimestampTzGetDatum(), and FuncCallContext::user_fctx.

Referenced by generate_series_timestamptz(), and generate_series_timestamptz_at_zone().

◆ GetCurrentTimestamp()

TimestampTz GetCurrentTimestamp ( void  )

Definition at line 1645 of file timestamp.c.

1646{
1647 TimestampTz result;
1648 struct timeval tp;
1649
1650 gettimeofday(&tp, NULL);
1651
1652 result = (TimestampTz) tp.tv_sec -
1654 result = (result * USECS_PER_SEC) + tp.tv_usec;
1655
1656 return result;
1657}
int gettimeofday(struct timeval *tp, void *tzp)

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

Referenced by ApplyLauncherMain(), asyncQueueFillWarning(), autoprewarm_main(), AutoVacLauncherMain(), BackendStartup(), BackgroundWriterMain(), bbsink_copystream_archive_contents(), bbsink_copystream_end_archive(), bbsink_copystream_new(), bbsink_throttle_begin_backup(), check_log_duration(), CheckPointGuts(), CleanupBackend(), clock_timestamp(), CreateCheckPoint(), CreateEndOfRecoveryRecord(), CreateOverwriteContrecordRecord(), CreateRestartPoint(), dblink_cancel_query(), DetermineSleepTime(), disable_timeout(), disable_timeouts(), do_analyze_rel(), do_start_worker(), enable_startup_progress_timeout(), enable_timeout_after(), enable_timeout_at(), enable_timeout_every(), enable_timeouts(), entry_alloc(), entry_reset(), get_candidate_xid(), get_role_password(), GetCurrentTransactionStopTimestamp(), GetReplicationApplyDelay(), handle_sig_alarm(), has_startup_progress_timeout_expired(), heap_vacuum_rel(), initialize_prng(), InitProcessGlobals(), InvalidatePossiblyObsoleteSlot(), KnownAssignedXidsCompress(), launch_sync_worker(), launcher_determine_sleep(), libpqsrv_cancel(), LockBufferForCleanup(), log_disconnections(), LogCheckpointEnd(), logicalrep_worker_launch(), LogicalRepApplyLoop(), maybe_start_bgworkers(), pa_send_data(), PerformAuthentication(), PerformWalRecovery(), pg_sleep(), pgfdw_abort_cleanup_begin(), pgfdw_cancel_query(), pgfdw_exec_cleanup_query(), pgfdw_finish_abort_cleanup(), pgfdw_get_cleanup_result(), pgss_shmem_startup(), pgstat_build_snapshot(), pgstat_report_activity(), pgstat_report_analyze(), pgstat_report_archiver(), pgstat_report_autovac(), pgstat_report_checksum_failures_in_db(), pgstat_report_replslotsync(), pgstat_report_stat(), pgstat_report_vacuum(), pgstat_reset(), pgstat_reset_after_failure(), pgstat_reset_counters(), pgstat_reset_of_kind(), pgstat_reset_slru(), PostgresMain(), PostgresSingleUserMain(), postmaster_child_launch(), PostmasterMain(), PrepareTransaction(), ProcessConfigFileInternal(), ProcessPendingWrites(), ProcessRepliesIfAny(), ProcessStandbyPSRequestMessage(), ProcessStandbyReplyMessage(), ProcessWalSndrMessage(), ProcSleep(), rebuild_database_list(), RecordTransactionAbort(), RecordTransactionAbortPrepared(), RecordTransactionCommitPrepared(), recoveryApplyDelay(), ReplicationSlotRelease(), request_publisher_status(), reschedule_timeouts(), ResolveRecoveryConflictWithBufferPin(), ResolveRecoveryConflictWithLock(), ResolveRecoveryConflictWithVirtualXIDs(), RestoreSlotFromDisk(), send_feedback(), SetCurrentStatementStartTimestamp(), SetupApplyOrSyncWorker(), should_stop_conflict_info_retention(), StartBackgroundWorker(), StartTransaction(), test_pattern(), test_random(), test_random_operations(), throttle(), update_synced_slots_inactive_since(), UpdateWorkerStats(), wait_for_local_flush(), WaitExceedsMaxStandbyDelay(), WaitForLSN(), WaitForWalSummarization(), WaitForWALToBecomeAvailable(), WalReceiverMain(), WalSndKeepalive(), WalSndLoop(), WalSndUpdateProgress(), WalSndWaitForWal(), WalSndWriteData(), XLogBackgroundFlush(), XLogFileRead(), XLogPrefetchResetStats(), XLogPrefetchShmemInit(), XLogRestorePoint(), XLogSendPhysical(), XLogWalRcvSendHSFeedback(), and XLogWalRcvSendReply().

◆ GetEpochTime()

void GetEpochTime ( struct pg_tm tm)

Definition at line 2168 of file timestamp.c.

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

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

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

◆ GetSQLCurrentTimestamp()

TimestampTz GetSQLCurrentTimestamp ( int32  typmod)

Definition at line 1663 of file timestamp.c.

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

References AdjustTimestampForTypmod(), and GetCurrentTransactionStartTimestamp().

Referenced by ExecEvalSQLValueFunction().

◆ GetSQLLocalTimestamp()

Timestamp GetSQLLocalTimestamp ( int32  typmod)

Definition at line 1677 of file timestamp.c.

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

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

Referenced by ExecEvalSQLValueFunction().

◆ in_range_interval_interval()

Datum in_range_interval_interval ( PG_FUNCTION_ARGS  )

Definition at line 3917 of file timestamp.c.

3918{
3920 Interval *base = PG_GETARG_INTERVAL_P(1);
3921 Interval *offset = PG_GETARG_INTERVAL_P(2);
3922 bool sub = PG_GETARG_BOOL(3);
3923 bool less = PG_GETARG_BOOL(4);
3924 Interval *sum;
3925
3926 if (interval_sign(offset) < 0)
3927 ereport(ERROR,
3928 (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
3929 errmsg("invalid preceding or following size in window function")));
3930
3931 /*
3932 * Deal with cases where both base and offset are infinite, and computing
3933 * base +/- offset would cause an error. As for float and numeric types,
3934 * we assume that all values infinitely precede +infinity and infinitely
3935 * follow -infinity. See in_range_float8_float8() for reasoning.
3936 */
3937 if (INTERVAL_IS_NOEND(offset) &&
3938 (sub ? INTERVAL_IS_NOEND(base) : INTERVAL_IS_NOBEGIN(base)))
3939 PG_RETURN_BOOL(true);
3940
3941 /* We don't currently bother to avoid overflow hazards here */
3942 if (sub)
3944 IntervalPGetDatum(base),
3945 IntervalPGetDatum(offset)));
3946 else
3948 IntervalPGetDatum(base),
3949 IntervalPGetDatum(offset)));
3950
3951 if (less)
3953 else
3955}
Datum interval_mi(PG_FUNCTION_ARGS)
Definition: timestamp.c:3559
Datum interval_pl(PG_FUNCTION_ARGS)
Definition: timestamp.c:3503
static int interval_cmp_internal(const Interval *interval1, const Interval *interval2)
Definition: timestamp.c:2546
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
long val
Definition: informix.c:689
static Datum IntervalPGetDatum(const Interval *X)
Definition: timestamp.h:58

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

◆ in_range_timestamp_interval()

Datum in_range_timestamp_interval ( PG_FUNCTION_ARGS  )

Definition at line 3876 of file timestamp.c.

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

References DatumGetTimestamp(), DirectFunctionCall2, ereport, errcode(), errmsg(), ERROR, INTERVAL_IS_NOEND, interval_sign(), IntervalPGetDatum(), PG_GETARG_BOOL, PG_GETARG_INTERVAL_P, PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, TIMESTAMP_IS_NOBEGIN, TIMESTAMP_IS_NOEND, timestamp_mi_interval(), timestamp_pl_interval(), TimestampGetDatum(), and val.

Referenced by in_range_date_interval().

◆ in_range_timestamptz_interval()

Datum in_range_timestamptz_interval ( PG_FUNCTION_ARGS  )

Definition at line 3839 of file timestamp.c.

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

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

◆ interval2itm()

void interval2itm ( Interval  span,
struct pg_itm itm 
)

Definition at line 2047 of file timestamp.c.

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

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

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

◆ interval_avg()

Datum interval_avg ( PG_FUNCTION_ARGS  )

Definition at line 4208 of file timestamp.c.

4209{
4211
4213
4214 /* If there were no non-null inputs, return NULL */
4215 if (state == NULL || IA_TOTAL_COUNT(state) == 0)
4217
4218 /*
4219 * Aggregating infinities that all have the same sign produces infinity
4220 * with that sign. Aggregating infinities with different signs results in
4221 * an error.
4222 */
4223 if (state->pInfcount > 0 || state->nInfcount > 0)
4224 {
4225 Interval *result;
4226
4227 if (state->pInfcount > 0 && state->nInfcount > 0)
4228 ereport(ERROR,
4229 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4230 errmsg("interval out of range")));
4231
4232 result = (Interval *) palloc(sizeof(Interval));
4233 if (state->pInfcount > 0)
4234 INTERVAL_NOEND(result);
4235 else
4236 INTERVAL_NOBEGIN(result);
4237
4238 PG_RETURN_INTERVAL_P(result);
4239 }
4240
4242 IntervalPGetDatum(&state->sumX),
4243 Float8GetDatum((double) state->N));
4244}
#define IA_TOTAL_COUNT(ia)
Definition: timestamp.c:89
Datum interval_div(PG_FUNCTION_ARGS)
Definition: timestamp.c:3738
#define INTERVAL_NOEND(i)
Definition: timestamp.h:185
#define INTERVAL_NOBEGIN(i)
Definition: timestamp.h:175
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define PG_RETURN_NULL()
Definition: fmgr.h:345
static Datum Float8GetDatum(float8 X)
Definition: postgres.h:492
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:69

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

◆ interval_avg_accum()

Datum interval_avg_accum ( PG_FUNCTION_ARGS  )

Definition at line 4043 of file timestamp.c.

4044{
4046
4048
4049 /* Create the state data on the first call */
4050 if (state == NULL)
4051 state = makeIntervalAggState(fcinfo);
4052
4053 if (!PG_ARGISNULL(1))
4055
4057}
static void do_interval_accum(IntervalAggState *state, Interval *newval)
Definition: timestamp.c:3989
static IntervalAggState * makeIntervalAggState(FunctionCallInfo fcinfo)
Definition: timestamp.c:3967

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

◆ interval_avg_accum_inv()

Datum interval_avg_accum_inv ( PG_FUNCTION_ARGS  )

Definition at line 4190 of file timestamp.c.

4191{
4193
4195
4196 /* Should not get here with no state */
4197 if (state == NULL)
4198 elog(ERROR, "interval_avg_accum_inv called with NULL state");
4199
4200 if (!PG_ARGISNULL(1))
4202
4204}
static void do_interval_discard(IntervalAggState *state, Interval *newval)
Definition: timestamp.c:4012

References do_interval_discard(), elog, ERROR, PG_ARGISNULL, PG_GETARG_INTERVAL_P, PG_GETARG_POINTER, and PG_RETURN_POINTER.

◆ interval_avg_combine()

Datum interval_avg_combine ( PG_FUNCTION_ARGS  )

Definition at line 4066 of file timestamp.c.

4067{
4068 IntervalAggState *state1;
4069 IntervalAggState *state2;
4070
4071 state1 = PG_ARGISNULL(0) ? NULL : (IntervalAggState *) PG_GETARG_POINTER(0);
4072 state2 = PG_ARGISNULL(1) ? NULL : (IntervalAggState *) PG_GETARG_POINTER(1);
4073
4074 if (state2 == NULL)
4075 PG_RETURN_POINTER(state1);
4076
4077 if (state1 == NULL)
4078 {
4079 /* manually copy all fields from state2 to state1 */
4080 state1 = makeIntervalAggState(fcinfo);
4081
4082 state1->N = state2->N;
4083 state1->pInfcount = state2->pInfcount;
4084 state1->nInfcount = state2->nInfcount;
4085
4086 state1->sumX.day = state2->sumX.day;
4087 state1->sumX.month = state2->sumX.month;
4088 state1->sumX.time = state2->sumX.time;
4089
4090 PG_RETURN_POINTER(state1);
4091 }
4092
4093 state1->N += state2->N;
4094 state1->pInfcount += state2->pInfcount;
4095 state1->nInfcount += state2->nInfcount;
4096
4097 /* Accumulate finite interval values, if any. */
4098 if (state2->N > 0)
4099 finite_interval_pl(&state1->sumX, &state2->sumX, &state1->sumX);
4100
4101 PG_RETURN_POINTER(state1);
4102}
Interval sumX
Definition: timestamp.c:83

References Interval::day, finite_interval_pl(), makeIntervalAggState(), Interval::month, IntervalAggState::N, IntervalAggState::nInfcount, PG_ARGISNULL, PG_GETARG_POINTER, PG_RETURN_POINTER, IntervalAggState::pInfcount, IntervalAggState::sumX, and Interval::time.

◆ interval_avg_deserialize()

Datum interval_avg_deserialize ( PG_FUNCTION_ARGS  )

Definition at line 4147 of file timestamp.c.

4148{
4149 bytea *sstate;
4150 IntervalAggState *result;
4152
4153 if (!AggCheckCallContext(fcinfo, NULL))
4154 elog(ERROR, "aggregate function called in non-aggregate context");
4155
4156 sstate = PG_GETARG_BYTEA_PP(0);
4157
4158 /*
4159 * Initialize a StringInfo so that we can "receive" it using the standard
4160 * recv-function infrastructure.
4161 */
4163 VARSIZE_ANY_EXHDR(sstate));
4164
4165 result = (IntervalAggState *) palloc0(sizeof(IntervalAggState));
4166
4167 /* N */
4168 result->N = pq_getmsgint64(&buf);
4169
4170 /* sumX */
4171 result->sumX.time = pq_getmsgint64(&buf);
4172 result->sumX.day = pq_getmsgint(&buf, 4);
4173 result->sumX.month = pq_getmsgint(&buf, 4);
4174
4175 /* pInfcount */
4176 result->pInfcount = pq_getmsgint64(&buf);
4177
4178 /* nInfcount */
4179 result->nInfcount = pq_getmsgint64(&buf);
4180
4181 pq_getmsgend(&buf);
4182
4183 PG_RETURN_POINTER(result);
4184}
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
void * palloc0(Size size)
Definition: mcxt.c:1395
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4613
static char * buf
Definition: pg_test_fsync.c:72
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:415
void pq_getmsgend(StringInfo msg)
Definition: pqformat.c:635
int64 pq_getmsgint64(StringInfo msg)
Definition: pqformat.c:453
static void initReadOnlyStringInfo(StringInfo str, char *data, int len)
Definition: stringinfo.h:157
static Size VARSIZE_ANY_EXHDR(const void *PTR)
Definition: varatt.h:472
static char * VARDATA_ANY(const void *PTR)
Definition: varatt.h:486

References AggCheckCallContext(), buf, Interval::day, elog, ERROR, initReadOnlyStringInfo(), Interval::month, IntervalAggState::N, IntervalAggState::nInfcount, palloc0(), PG_GETARG_BYTEA_PP, PG_RETURN_POINTER, IntervalAggState::pInfcount, pq_getmsgend(), pq_getmsgint(), pq_getmsgint64(), IntervalAggState::sumX, Interval::time, VARDATA_ANY(), and VARSIZE_ANY_EXHDR().

◆ interval_avg_serialize()

Datum interval_avg_serialize ( PG_FUNCTION_ARGS  )

Definition at line 4109 of file timestamp.c.

4110{
4113 bytea *result;
4114
4115 /* Ensure we disallow calling when not in aggregate context */
4116 if (!AggCheckCallContext(fcinfo, NULL))
4117 elog(ERROR, "aggregate function called in non-aggregate context");
4118
4120
4122
4123 /* N */
4124 pq_sendint64(&buf, state->N);
4125
4126 /* sumX */
4127 pq_sendint64(&buf, state->sumX.time);
4128 pq_sendint32(&buf, state->sumX.day);
4129 pq_sendint32(&buf, state->sumX.month);
4130
4131 /* pInfcount */
4132 pq_sendint64(&buf, state->pInfcount);
4133
4134 /* nInfcount */
4135 pq_sendint64(&buf, state->nInfcount);
4136
4137 result = pq_endtypsend(&buf);
4138
4139 PG_RETURN_BYTEA_P(result);
4140}
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:326
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:346
static void pq_sendint32(StringInfo buf, uint32 i)
Definition: pqformat.h:144
static void pq_sendint64(StringInfo buf, uint64 i)
Definition: pqformat.h:152

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

◆ interval_cmp()

Datum interval_cmp ( PG_FUNCTION_ARGS  )

Definition at line 2618 of file timestamp.c.

2619{
2620 Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2621 Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2622
2623 PG_RETURN_INT32(interval_cmp_internal(interval1, interval2));
2624}
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_INT32.

Referenced by gbt_intv_ssup_cmp(), and gbt_intvkey_cmp().

◆ interval_cmp_internal()

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

Definition at line 2546 of file timestamp.c.

2547{
2548 INT128 span1 = interval_cmp_value(interval1);
2549 INT128 span2 = interval_cmp_value(interval2);
2550
2551 return int128_compare(span1, span2);
2552}
static INT128 interval_cmp_value(const Interval *interval)
Definition: timestamp.c:2524
static int int128_compare(INT128 x, INT128 y)
Definition: int128.h:425
Definition: int128.h:55

References int128_compare(), and interval_cmp_value().

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

◆ interval_cmp_value()

static INT128 interval_cmp_value ( const Interval interval)
inlinestatic

Definition at line 2524 of file timestamp.c.

2525{
2526 INT128 span;
2527 int64 days;
2528
2529 /*
2530 * Combine the month and day fields into an integral number of days.
2531 * Because the inputs are int32, int64 arithmetic suffices here.
2532 */
2533 days = interval->month * INT64CONST(30);
2534 days += interval->day;
2535
2536 /* Widen time field to 128 bits */
2537 span = int64_to_int128(interval->time);
2538
2539 /* Scale up days to microseconds, forming a 128-bit product */
2541
2542 return span;
2543}
const char *const days[]
Definition: datetime.c:84
#define USECS_PER_DAY
Definition: timestamp.h:131
static INT128 int64_to_int128(int64 v)
Definition: int128.h:450
static void int128_add_int64_mul_int64(INT128 *i128, int64 x, int64 y)
Definition: int128.h:203

References days, int128_add_int64_mul_int64(), int64_to_int128(), INT64CONST, interval::month, interval::time, and USECS_PER_DAY.

Referenced by interval_cmp_internal(), interval_hash(), interval_hash_extended(), and interval_sign().

◆ interval_div()

Datum interval_div ( PG_FUNCTION_ARGS  )

Definition at line 3738 of file timestamp.c.

3739{
3740 Interval *span = PG_GETARG_INTERVAL_P(0);
3741 float8 factor = PG_GETARG_FLOAT8(1);
3742 double month_remainder_days,
3743 sec_remainder,
3744 result_double;
3745 int32 orig_month = span->month,
3746 orig_day = span->day;
3747 Interval *result;
3748
3749 result = (Interval *) palloc(sizeof(Interval));
3750
3751 if (factor == 0.0)
3752 ereport(ERROR,
3753 (errcode(ERRCODE_DIVISION_BY_ZERO),
3754 errmsg("division by zero")));
3755
3756 /*
3757 * Handle NaN and infinities.
3758 *
3759 * We treat "infinity / infinity" as an error, since the interval type has
3760 * nothing equivalent to NaN. Otherwise, dividing by infinity is handled
3761 * by the regular division code, causing all fields to be set to zero.
3762 */
3763 if (isnan(factor))
3764 goto out_of_range;
3765
3766 if (INTERVAL_NOT_FINITE(span))
3767 {
3768 if (isinf(factor))
3769 goto out_of_range;
3770
3771 if (factor < 0.0)
3772 interval_um_internal(span, result);
3773 else
3774 memcpy(result, span, sizeof(Interval));
3775
3776 PG_RETURN_INTERVAL_P(result);
3777 }
3778
3779 result_double = span->month / factor;
3780 if (isnan(result_double) || !FLOAT8_FITS_IN_INT32(result_double))
3781 goto out_of_range;
3782 result->month = (int32) result_double;
3783
3784 result_double = span->day / factor;
3785 if (isnan(result_double) || !FLOAT8_FITS_IN_INT32(result_double))
3786 goto out_of_range;
3787 result->day = (int32) result_double;
3788
3789 /*
3790 * Fractional months full days into days. See comment in interval_mul().
3791 */
3792 month_remainder_days = (orig_month / factor - result->month) * DAYS_PER_MONTH;
3793 month_remainder_days = TSROUND(month_remainder_days);
3794 sec_remainder = (orig_day / factor - result->day +
3795 month_remainder_days - (int) month_remainder_days) * SECS_PER_DAY;
3796 sec_remainder = TSROUND(sec_remainder);
3797 if (fabs(sec_remainder) >= SECS_PER_DAY)
3798 {
3799 if (pg_add_s32_overflow(result->day,
3800 (int) (sec_remainder / SECS_PER_DAY),
3801 &result->day))
3802 goto out_of_range;
3803 sec_remainder -= (int) (sec_remainder / SECS_PER_DAY) * SECS_PER_DAY;
3804 }
3805
3806 /* cascade units down */
3807 if (pg_add_s32_overflow(result->day, (int32) month_remainder_days,
3808 &result->day))
3809 goto out_of_range;
3810 result_double = rint(span->time / factor + sec_remainder * USECS_PER_SEC);
3811 if (isnan(result_double) || !FLOAT8_FITS_IN_INT64(result_double))
3812 goto out_of_range;
3813 result->time = (int64) result_double;
3814
3815 if (INTERVAL_NOT_FINITE(result))
3816 goto out_of_range;
3817
3818 PG_RETURN_INTERVAL_P(result);
3819
3820out_of_range:
3821 ereport(ERROR,
3822 errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3823 errmsg("interval out of range"));
3824
3825 PG_RETURN_NULL(); /* keep compiler quiet */
3826}
static void interval_um_internal(const Interval *interval, Interval *result)
Definition: timestamp.c:3426
#define FLOAT8_FITS_IN_INT32(num)
Definition: c.h:1092
#define FLOAT8_FITS_IN_INT64(num)
Definition: c.h:1094
#define DAYS_PER_MONTH
Definition: timestamp.h:116
#define TSROUND(j)
Definition: timestamp.h:100

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

Referenced by interval_avg().

◆ interval_eq()

Datum interval_eq ( PG_FUNCTION_ARGS  )

Definition at line 2564 of file timestamp.c.

2565{
2566 Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2567 Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2568
2569 PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) == 0);
2570}

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by gbt_intveq().

◆ interval_finite()

Datum interval_finite ( PG_FUNCTION_ARGS  )

◆ interval_ge()

Datum interval_ge ( PG_FUNCTION_ARGS  )

Definition at line 2609 of file timestamp.c.

2610{
2611 Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2612 Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2613
2614 PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) >= 0);
2615}

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by gbt_intvge().

◆ interval_gt()

Datum interval_gt ( PG_FUNCTION_ARGS  )

Definition at line 2591 of file timestamp.c.

2592{
2593 Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2594 Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2595
2596 PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) > 0);
2597}

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by gbt_intvgt().

◆ interval_hash()

Datum interval_hash ( PG_FUNCTION_ARGS  )

Definition at line 2634 of file timestamp.c.

2635{
2638 int64 span64;
2639
2640 /*
2641 * Use only the least significant 64 bits for hashing. The upper 64 bits
2642 * seldom add any useful information, and besides we must do it like this
2643 * for compatibility with hashes calculated before use of INT128 was
2644 * introduced.
2645 */
2646 span64 = int128_to_int64(span);
2647
2649}
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:682
Datum hashint8(PG_FUNCTION_ARGS)
Definition: hashfunc.c:83
static int64 int128_to_int64(INT128 val)
Definition: int128.h:468
#define Int64GetDatumFast(X)
Definition: postgres.h:515

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

◆ interval_hash_extended()

Datum interval_hash_extended ( PG_FUNCTION_ARGS  )

Definition at line 2652 of file timestamp.c.

2653{
2656 int64 span64;
2657
2658 /* Same approach as interval_hash */
2659 span64 = int128_to_int64(span);
2660
2662 PG_GETARG_DATUM(1));
2663}
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
Datum hashint8extended(PG_FUNCTION_ARGS)
Definition: hashfunc.c:103

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

◆ interval_in()

Datum interval_in ( PG_FUNCTION_ARGS  )

Definition at line 891 of file timestamp.c.

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

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

Referenced by check_timezone(), and flatten_set_variable_args().

◆ interval_justify_days()

Datum interval_justify_days ( PG_FUNCTION_ARGS  )

Definition at line 3043 of file timestamp.c.

3044{
3045 Interval *span = PG_GETARG_INTERVAL_P(0);
3046 Interval *result;
3047 int32 wholemonth;
3048
3049 result = (Interval *) palloc(sizeof(Interval));
3050 result->month = span->month;
3051 result->day = span->day;
3052 result->time = span->time;
3053
3054 /* do nothing for infinite intervals */
3055 if (INTERVAL_NOT_FINITE(result))
3056 PG_RETURN_INTERVAL_P(result);
3057
3058 wholemonth = result->day / DAYS_PER_MONTH;
3059 result->day -= wholemonth * DAYS_PER_MONTH;
3060 if (pg_add_s32_overflow(result->month, wholemonth, &result->month))
3061 ereport(ERROR,
3062 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3063 errmsg("interval out of range")));
3064
3065 if (result->month > 0 && result->day < 0)
3066 {
3067 result->day += DAYS_PER_MONTH;
3068 result->month--;
3069 }
3070 else if (result->month < 0 && result->day > 0)
3071 {
3072 result->day -= DAYS_PER_MONTH;
3073 result->month++;
3074 }
3075
3076 PG_RETURN_INTERVAL_P(result);
3077}

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

◆ interval_justify_hours()

Datum interval_justify_hours ( PG_FUNCTION_ARGS  )

Definition at line 3001 of file timestamp.c.

3002{
3003 Interval *span = PG_GETARG_INTERVAL_P(0);
3004 Interval *result;
3005 TimeOffset wholeday;
3006
3007 result = (Interval *) palloc(sizeof(Interval));
3008 result->month = span->month;
3009 result->day = span->day;
3010 result->time = span->time;
3011
3012 /* do nothing for infinite intervals */
3013 if (INTERVAL_NOT_FINITE(result))
3014 PG_RETURN_INTERVAL_P(result);
3015
3016 TMODULO(result->time, wholeday, USECS_PER_DAY);
3017 if (pg_add_s32_overflow(result->day, wholeday, &result->day))
3018 ereport(ERROR,
3019 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3020 errmsg("interval out of range")));
3021
3022 if (result->day > 0 && result->time < 0)
3023 {
3024 result->time += USECS_PER_DAY;
3025 result->day--;
3026 }
3027 else if (result->day < 0 && result->time > 0)
3028 {
3029 result->time -= USECS_PER_DAY;
3030 result->day++;
3031 }
3032
3033 PG_RETURN_INTERVAL_P(result);
3034}
#define TMODULO(t, q, u)
Definition: datetime.h:248

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

Referenced by timestamp_mi().

◆ interval_justify_interval()

Datum interval_justify_interval ( PG_FUNCTION_ARGS  )

Definition at line 2921 of file timestamp.c.

2922{
2923 Interval *span = PG_GETARG_INTERVAL_P(0);
2924 Interval *result;
2925 TimeOffset wholeday;
2926 int32 wholemonth;
2927
2928 result = (Interval *) palloc(sizeof(Interval));
2929 result->month = span->month;
2930 result->day = span->day;
2931 result->time = span->time;
2932
2933 /* do nothing for infinite intervals */
2934 if (INTERVAL_NOT_FINITE(result))
2935 PG_RETURN_INTERVAL_P(result);
2936
2937 /* pre-justify days if it might prevent overflow */
2938 if ((result->day > 0 && result->time > 0) ||
2939 (result->day < 0 && result->time < 0))
2940 {
2941 wholemonth = result->day / DAYS_PER_MONTH;
2942 result->day -= wholemonth * DAYS_PER_MONTH;
2943 if (pg_add_s32_overflow(result->month, wholemonth, &result->month))
2944 ereport(ERROR,
2945 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2946 errmsg("interval out of range")));
2947 }
2948
2949 /*
2950 * Since TimeOffset is int64, abs(wholeday) can't exceed about 1.07e8. If
2951 * we pre-justified then abs(result->day) is less than DAYS_PER_MONTH, so
2952 * this addition can't overflow. If we didn't pre-justify, then day and
2953 * time are of different signs, so it still can't overflow.
2954 */
2955 TMODULO(result->time, wholeday, USECS_PER_DAY);
2956 result->day += wholeday;
2957
2958 wholemonth = result->day / DAYS_PER_MONTH;
2959 result->day -= wholemonth * DAYS_PER_MONTH;
2960 if (pg_add_s32_overflow(result->month, wholemonth, &result->month))
2961 ereport(ERROR,
2962 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2963 errmsg("interval out of range")));
2964
2965 if (result->month > 0 &&
2966 (result->day < 0 || (result->day == 0 && result->time < 0)))
2967 {
2968 result->day += DAYS_PER_MONTH;
2969 result->month--;
2970 }
2971 else if (result->month < 0 &&
2972 (result->day > 0 || (result->day == 0 && result->time > 0)))
2973 {
2974 result->day -= DAYS_PER_MONTH;
2975 result->month++;
2976 }
2977
2978 if (result->day > 0 && result->time < 0)
2979 {
2980 result->time += USECS_PER_DAY;
2981 result->day--;
2982 }
2983 else if (result->day < 0 && result->time > 0)
2984 {
2985 result->time -= USECS_PER_DAY;
2986 result->day++;
2987 }
2988
2989 PG_RETURN_INTERVAL_P(result);
2990}

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

◆ interval_larger()

Datum interval_larger ( PG_FUNCTION_ARGS  )

Definition at line 3474 of file timestamp.c.

3475{
3476 Interval *interval1 = PG_GETARG_INTERVAL_P(0);
3477 Interval *interval2 = PG_GETARG_INTERVAL_P(1);
3478 Interval *result;
3479
3480 if (interval_cmp_internal(interval1, interval2) > 0)
3481 result = interval1;
3482 else
3483 result = interval2;
3484 PG_RETURN_INTERVAL_P(result);
3485}

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_INTERVAL_P.

◆ interval_le()

Datum interval_le ( PG_FUNCTION_ARGS  )

Definition at line 2600 of file timestamp.c.

2601{
2602 Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2603 Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2604
2605 PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) <= 0);
2606}

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by gbt_intvle().

◆ interval_lt()

Datum interval_lt ( PG_FUNCTION_ARGS  )

Definition at line 2582 of file timestamp.c.

2583{
2584 Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2585 Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2586
2587 PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) < 0);
2588}

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by abs_interval(), and gbt_intvlt().

◆ interval_mi()

Datum interval_mi ( PG_FUNCTION_ARGS  )

Definition at line 3559 of file timestamp.c.

3560{
3561 Interval *span1 = PG_GETARG_INTERVAL_P(0);
3562 Interval *span2 = PG_GETARG_INTERVAL_P(1);
3563 Interval *result;
3564
3565 result = (Interval *) palloc(sizeof(Interval));
3566
3567 /*
3568 * Handle infinities.
3569 *
3570 * We treat anything that amounts to "infinity - infinity" as an error,
3571 * since the interval type has nothing equivalent to NaN.
3572 */
3573 if (INTERVAL_IS_NOBEGIN(span1))
3574 {
3575 if (INTERVAL_IS_NOBEGIN(span2))
3576 ereport(ERROR,
3577 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3578 errmsg("interval out of range")));
3579 else
3580 INTERVAL_NOBEGIN(result);
3581 }
3582 else if (INTERVAL_IS_NOEND(span1))
3583 {
3584 if (INTERVAL_IS_NOEND(span2))
3585 ereport(ERROR,
3586 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3587 errmsg("interval out of range")));
3588 else
3589 INTERVAL_NOEND(result);
3590 }
3591 else if (INTERVAL_IS_NOBEGIN(span2))
3592 INTERVAL_NOEND(result);
3593 else if (INTERVAL_IS_NOEND(span2))
3594 INTERVAL_NOBEGIN(result);
3595 else
3596 finite_interval_mi(span1, span2, result);
3597
3598 PG_RETURN_INTERVAL_P(result);
3599}

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

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

◆ interval_mul()

Datum interval_mul ( PG_FUNCTION_ARGS  )

Definition at line 3608 of file timestamp.c.

3609{
3610 Interval *span = PG_GETARG_INTERVAL_P(0);
3611 float8 factor = PG_GETARG_FLOAT8(1);
3612 double month_remainder_days,
3613 sec_remainder,
3614 result_double;
3615 int32 orig_month = span->month,
3616 orig_day = span->day;
3617 Interval *result;
3618
3619 result = (Interval *) palloc(sizeof(Interval));
3620
3621 /*
3622 * Handle NaN and infinities.
3623 *
3624 * We treat "0 * infinity" and "infinity * 0" as errors, since the
3625 * interval type has nothing equivalent to NaN.
3626 */
3627 if (isnan(factor))
3628 goto out_of_range;
3629
3630 if (INTERVAL_NOT_FINITE(span))
3631 {
3632 if (factor == 0.0)
3633 goto out_of_range;
3634
3635 if (factor < 0.0)
3636 interval_um_internal(span, result);
3637 else
3638 memcpy(result, span, sizeof(Interval));
3639
3640 PG_RETURN_INTERVAL_P(result);
3641 }
3642 if (isinf(factor))
3643 {
3644 int isign = interval_sign(span);
3645
3646 if (isign == 0)
3647 goto out_of_range;
3648
3649 if (factor * isign < 0)
3650 INTERVAL_NOBEGIN(result);
3651 else
3652 INTERVAL_NOEND(result);
3653
3654 PG_RETURN_INTERVAL_P(result);
3655 }
3656
3657 result_double = span->month * factor;
3658 if (isnan(result_double) || !FLOAT8_FITS_IN_INT32(result_double))
3659 goto out_of_range;
3660 result->month = (int32) result_double;
3661
3662 result_double = span->day * factor;
3663 if (isnan(result_double) || !FLOAT8_FITS_IN_INT32(result_double))
3664 goto out_of_range;
3665 result->day = (int32) result_double;
3666
3667 /*
3668 * The above correctly handles the whole-number part of the month and day
3669 * products, but we have to do something with any fractional part
3670 * resulting when the factor is non-integral. We cascade the fractions
3671 * down to lower units using the conversion factors DAYS_PER_MONTH and
3672 * SECS_PER_DAY. Note we do NOT cascade up, since we are not forced to do
3673 * so by the representation. The user can choose to cascade up later,
3674 * using justify_hours and/or justify_days.
3675 */
3676
3677 /*
3678 * Fractional months full days into days.
3679 *
3680 * Floating point calculation are inherently imprecise, so these
3681 * calculations are crafted to produce the most reliable result possible.
3682 * TSROUND() is needed to more accurately produce whole numbers where
3683 * appropriate.
3684 */
3685 month_remainder_days = (orig_month * factor - result->month) * DAYS_PER_MONTH;
3686 month_remainder_days = TSROUND(month_remainder_days);
3687 sec_remainder = (orig_day * factor - result->day +
3688 month_remainder_days - (int) month_remainder_days) * SECS_PER_DAY;
3689 sec_remainder = TSROUND(sec_remainder);
3690
3691 /*
3692 * Might have 24:00:00 hours due to rounding, or >24 hours because of time
3693 * cascade from months and days. It might still be >24 if the combination
3694 * of cascade and the seconds factor operation itself.
3695 */
3696 if (fabs(sec_remainder) >= SECS_PER_DAY)
3697 {
3698 if (pg_add_s32_overflow(result->day,
3699 (int) (sec_remainder / SECS_PER_DAY),
3700 &result->day))
3701 goto out_of_range;
3702 sec_remainder -= (int) (sec_remainder / SECS_PER_DAY) * SECS_PER_DAY;
3703 }
3704
3705 /* cascade units down */
3706 if (pg_add_s32_overflow(result->day, (int32) month_remainder_days,
3707 &result->day))
3708 goto out_of_range;
3709 result_double = rint(span->time * factor + sec_remainder * USECS_PER_SEC);
3710 if (isnan(result_double) || !FLOAT8_FITS_IN_INT64(result_double))
3711 goto out_of_range;
3712 result->time = (int64) result_double;
3713
3714 if (INTERVAL_NOT_FINITE(result))
3715 goto out_of_range;
3716
3717 PG_RETURN_INTERVAL_P(result);
3718
3719out_of_range:
3720 ereport(ERROR,
3721 errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3722 errmsg("interval out of range"));
3723
3724 PG_RETURN_NULL(); /* keep compiler quiet */
3725}

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

Referenced by interval_lerp(), and mul_d_interval().

◆ interval_ne()

Datum interval_ne ( PG_FUNCTION_ARGS  )

Definition at line 2573 of file timestamp.c.

2574{
2575 Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2576 Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2577
2578 PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) != 0);
2579}

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

◆ interval_out()

Datum interval_out ( PG_FUNCTION_ARGS  )

Definition at line 973 of file timestamp.c.

974{
976 char *result;
977 struct pg_itm tt,
978 *itm = &tt;
979 char buf[MAXDATELEN + 1];
980
981 if (INTERVAL_NOT_FINITE(span))
983 else
984 {
985 interval2itm(*span, itm);
987 }
988
989 result = pstrdup(buf);
990 PG_RETURN_CSTRING(result);
991}
void EncodeInterval(struct pg_itm *itm, int style, char *str)
Definition: datetime.c:4707
static void EncodeSpecialInterval(const Interval *interval, char *str)
Definition: timestamp.c:1598
void interval2itm(Interval span, struct pg_itm *itm)
Definition: timestamp.c:2047
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
int IntervalStyle
Definition: globals.c:127
#define MAXDATELEN
Definition: datetime.h:200

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

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

◆ interval_part()

Datum interval_part ( PG_FUNCTION_ARGS  )

Definition at line 6287 of file timestamp.c.

6288{
6289 return interval_part_common(fcinfo, false);
6290}

References interval_part_common().

◆ interval_part_common()

static Datum interval_part_common ( PG_FUNCTION_ARGS  ,
bool  retnumeric 
)
static

Definition at line 6080 of file timestamp.c.

6081{
6082 text *units = PG_GETARG_TEXT_PP(0);
6084 int64 intresult;
6085 int type,
6086 val;
6087 char *lowunits;
6088 struct pg_itm tt,
6089 *tm = &tt;
6090
6091 lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
6092 VARSIZE_ANY_EXHDR(units),
6093 false);
6094
6095 type = DecodeUnits(0, lowunits, &val);
6096 if (type == UNKNOWN_FIELD)
6097 type = DecodeSpecial(0, lowunits, &val);
6098
6100 {
6101 double r = NonFiniteIntervalPart(type, val, lowunits,
6103
6104 if (r != 0.0)
6105 {
6106 if (retnumeric)
6107 {
6108 if (r < 0)
6110 CStringGetDatum("-Infinity"),
6112 Int32GetDatum(-1));
6113 else if (r > 0)
6115 CStringGetDatum("Infinity"),
6117 Int32GetDatum(-1));
6118 }
6119 else
6121 }
6122 else
6124 }
6125
6126 if (type == UNITS)
6127 {
6129 switch (val)
6130 {
6131 case DTK_MICROSEC:
6132 intresult = tm->tm_sec * INT64CONST(1000000) + tm->tm_usec;
6133 break;
6134
6135 case DTK_MILLISEC:
6136 if (retnumeric)
6137 /*---
6138 * tm->tm_sec * 1000 + fsec / 1000
6139 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
6140 */
6142 else
6143 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + tm->tm_usec / 1000.0);
6144 break;
6145
6146 case DTK_SECOND:
6147 if (retnumeric)
6148 /*---
6149 * tm->tm_sec + fsec / 1'000'000
6150 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
6151 */
6153 else
6154 PG_RETURN_FLOAT8(tm->tm_sec + tm->tm_usec / 1000000.0);
6155 break;
6156
6157 case DTK_MINUTE:
6158 intresult = tm->tm_min;
6159 break;
6160
6161 case DTK_HOUR:
6162 intresult = tm->tm_hour;
6163 break;
6164
6165 case DTK_DAY:
6166 intresult = tm->tm_mday;
6167 break;
6168
6169 case DTK_WEEK:
6170 intresult = tm->tm_mday / 7;
6171 break;
6172
6173 case DTK_MONTH:
6174 intresult = tm->tm_mon;
6175 break;
6176
6177 case DTK_QUARTER:
6178
6179 /*
6180 * We want to maintain the rule that a field extracted from a
6181 * negative interval is the negative of the field's value for
6182 * the sign-reversed interval. The broken-down tm_year and
6183 * tm_mon aren't very helpful for that, so work from
6184 * interval->month.
6185 */
6186 if (interval->month >= 0)
6187 intresult = (tm->tm_mon / 3) + 1;
6188 else
6189 intresult = -(((-interval->month % MONTHS_PER_YEAR) / 3) + 1);
6190 break;
6191
6192 case DTK_YEAR:
6193 intresult = tm->tm_year;
6194 break;
6195
6196 case DTK_DECADE:
6197 /* caution: C division may have negative remainder */
6198 intresult = tm->tm_year / 10;
6199 break;
6200
6201 case DTK_CENTURY:
6202 /* caution: C division may have negative remainder */
6203 intresult = tm->tm_year / 100;
6204 break;
6205
6206 case DTK_MILLENNIUM:
6207 /* caution: C division may have negative remainder */
6208 intresult = tm->tm_year / 1000;
6209 break;
6210
6211 default:
6212 ereport(ERROR,
6213 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6214 errmsg("unit \"%s\" not supported for type %s",
6215 lowunits, format_type_be(INTERVALOID))));
6216 intresult = 0;
6217 }
6218 }
6219 else if (type == RESERV && val == DTK_EPOCH)
6220 {
6221 if (retnumeric)
6222 {
6223 Numeric result;
6224 int64 secs_from_day_month;
6225 int64 val;
6226
6227 /*
6228 * To do this calculation in integer arithmetic even though
6229 * DAYS_PER_YEAR is fractional, multiply everything by 4 and then
6230 * divide by 4 again at the end. This relies on DAYS_PER_YEAR
6231 * being a multiple of 0.25 and on SECS_PER_DAY being a multiple
6232 * of 4.
6233 */
6234 secs_from_day_month = ((int64) (4 * DAYS_PER_YEAR) * (interval->month / MONTHS_PER_YEAR) +
6236 (int64) 4 * interval->day) * (SECS_PER_DAY / 4);
6237
6238 /*---
6239 * result = secs_from_day_month + interval->time / 1'000'000
6240 * = (secs_from_day_month * 1'000'000 + interval->time) / 1'000'000
6241 */
6242
6243 /*
6244 * Try the computation inside int64; if it overflows, do it in
6245 * numeric (slower). This overflow happens around 10^9 days, so
6246 * not common in practice.
6247 */
6248 if (!pg_mul_s64_overflow(secs_from_day_month, 1000000, &val) &&
6250 result = int64_div_fast_to_numeric(val, 6);
6251 else
6252 result =
6254 int64_to_numeric(secs_from_day_month),
6255 NULL);
6256
6257 PG_RETURN_NUMERIC(result);
6258 }
6259 else
6260 {
6261 float8 result;
6262
6263 result = interval->time / 1000000.0;
6264 result += ((double) DAYS_PER_YEAR * SECS_PER_DAY) * (interval->month / MONTHS_PER_YEAR);
6265 result += ((double) DAYS_PER_MONTH * SECS_PER_DAY) * (interval->month % MONTHS_PER_YEAR);
6266 result += ((double) SECS_PER_DAY) * interval->day;
6267
6268 PG_RETURN_FLOAT8(result);
6269 }
6270 }
6271 else
6272 {
6273 ereport(ERROR,
6274 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6275 errmsg("unit \"%s\" not recognized for type %s",
6276 lowunits, format_type_be(INTERVALOID))));
6277 intresult = 0;
6278 }
6279
6280 if (retnumeric)
6282 else
6283 PG_RETURN_FLOAT8(intresult);
6284}
int DecodeUnits(int field, const char *lowtoken, int *val)
Definition: datetime.c:4169
int DecodeSpecial(int field, const char *lowtoken, int *val)
Definition: datetime.c:3246
Numeric int64_to_numeric(int64 val)
Definition: numeric.c:4260
Numeric numeric_add_safe(Numeric num1, Numeric num2, Node *escontext)
Definition: numeric.c:2882
Numeric int64_div_fast_to_numeric(int64 val1, int log10val2)
Definition: numeric.c:4281
Datum numeric_in(PG_FUNCTION_ARGS)
Definition: numeric.c:626
static float8 NonFiniteIntervalPart(int type, int unit, char *lowunits, bool isNegative)
Definition: timestamp.c:6034
#define DAYS_PER_YEAR
Definition: timestamp.h:107
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:367
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:686
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
#define DTK_EPOCH
Definition: datetime.h:152
#define UNKNOWN_FIELD
Definition: datetime.h:124
#define DTK_DECADE
Definition: datetime.h:168
#define DTK_SECOND
Definition: datetime.h:160
#define DTK_QUARTER
Definition: datetime.h:166
#define DTK_CENTURY
Definition: datetime.h:169
#define DTK_DAY
Definition: datetime.h:163
#define RESERV
Definition: datetime.h:90
#define DTK_MILLENNIUM
Definition: datetime.h:170
#define DTK_HOUR
Definition: datetime.h:162
#define DTK_WEEK
Definition: datetime.h:164
#define DTK_MICROSEC
Definition: datetime.h:172
#define DTK_YEAR
Definition: datetime.h:167
#define DTK_MILLISEC
Definition: datetime.h:171
#define DTK_MONTH
Definition: datetime.h:165
#define DTK_MINUTE
Definition: datetime.h:161
#define UNITS
Definition: datetime.h:107
static bool pg_mul_s64_overflow(int64 a, int64 b, int64 *result)
Definition: int.h:293
#define PG_RETURN_NUMERIC(x)
Definition: numeric.h:83
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:262
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:360
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:222
#define InvalidOid
Definition: postgres_ext.h:37
char * downcase_truncate_identifier(const char *ident, int len, bool warn)
Definition: scansup.c:37
const char * type

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

Referenced by extract_interval(), and interval_part().

◆ interval_pl()

Datum interval_pl ( PG_FUNCTION_ARGS  )

Definition at line 3503 of file timestamp.c.

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

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

Referenced by in_range_interval_interval(), and interval_lerp().

◆ interval_recv()

Datum interval_recv ( PG_FUNCTION_ARGS  )

Definition at line 997 of file timestamp.c.

998{
1000
1001#ifdef NOT_USED
1002 Oid typelem = PG_GETARG_OID(1);
1003#endif
1004 int32 typmod = PG_GETARG_INT32(2);
1006
1007 interval = (Interval *) palloc(sizeof(Interval));
1008
1010 interval->day = pq_getmsgint(buf, sizeof(interval->day));
1012
1013 AdjustIntervalForTypmod(interval, typmod, NULL);
1014
1016}
struct StringInfoData * StringInfo
Definition: string.h:15

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

◆ interval_scale()

Datum interval_scale ( PG_FUNCTION_ARGS  )

Definition at line 1328 of file timestamp.c.

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

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

◆ interval_send()

◆ interval_sign()

static int interval_sign ( const Interval interval)
static

◆ interval_smaller()

Datum interval_smaller ( PG_FUNCTION_ARGS  )

Definition at line 3459 of file timestamp.c.

3460{
3461 Interval *interval1 = PG_GETARG_INTERVAL_P(0);
3462 Interval *interval2 = PG_GETARG_INTERVAL_P(1);
3463 Interval *result;
3464
3465 /* use interval_cmp_internal to be sure this agrees with comparisons */
3466 if (interval_cmp_internal(interval1, interval2) < 0)
3467 result = interval1;
3468 else
3469 result = interval2;
3470 PG_RETURN_INTERVAL_P(result);
3471}

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_INTERVAL_P.

◆ interval_sum()

Datum interval_sum ( PG_FUNCTION_ARGS  )

Definition at line 4248 of file timestamp.c.

4249{
4251 Interval *result;
4252
4254
4255 /* If there were no non-null inputs, return NULL */
4256 if (state == NULL || IA_TOTAL_COUNT(state) == 0)
4258
4259 /*
4260 * Aggregating infinities that all have the same sign produces infinity
4261 * with that sign. Aggregating infinities with different signs results in
4262 * an error.
4263 */
4264 if (state->pInfcount > 0 && state->nInfcount > 0)
4265 ereport(ERROR,
4266 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4267 errmsg("interval out of range")));
4268
4269 result = (Interval *) palloc(sizeof(Interval));
4270
4271 if (state->pInfcount > 0)
4272 INTERVAL_NOEND(result);
4273 else if (state->nInfcount > 0)
4274 INTERVAL_NOBEGIN(result);
4275 else
4276 memcpy(result, &state->sumX, sizeof(Interval));
4277
4278 PG_RETURN_INTERVAL_P(result);
4279}

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

◆ interval_support()

Datum interval_support ( PG_FUNCTION_ARGS  )

Definition at line 1265 of file timestamp.c.

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

References FuncExpr::args, Assert(), DatumGetInt32(), exprTypmod(), SupportRequestSimplify::fcall, INTERVAL_FULL_PRECISION, INTERVAL_PRECISION, intervaltypmodleastfield(), IsA, linitial, list_length(), lsecond, MAX_INTERVAL_PRECISION, PG_GETARG_POINTER, PG_RETURN_POINTER, relabel_to_typmod(), and source.

◆ interval_trunc()

Datum interval_trunc ( PG_FUNCTION_ARGS  )

Definition at line 5112 of file timestamp.c.

5113{
5114 text *units = PG_GETARG_TEXT_PP(0);
5116 Interval *result;
5117 int type,
5118 val;
5119 char *lowunits;
5120 struct pg_itm tt,
5121 *tm = &tt;
5122
5123 result = (Interval *) palloc(sizeof(Interval));
5124
5125 lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
5126 VARSIZE_ANY_EXHDR(units),
5127 false);
5128
5129 type = DecodeUnits(0, lowunits, &val);
5130
5131 if (type == UNITS)
5132 {
5134 {
5135 /*
5136 * Errors thrown here for invalid units should exactly match those
5137 * below, else there will be unexpected discrepancies between
5138 * finite- and infinite-input cases.
5139 */
5140 switch (val)
5141 {
5142 case DTK_MILLENNIUM:
5143 case DTK_CENTURY:
5144 case DTK_DECADE:
5145 case DTK_YEAR:
5146 case DTK_QUARTER:
5147 case DTK_MONTH:
5148 case DTK_DAY:
5149 case DTK_HOUR:
5150 case DTK_MINUTE:
5151 case DTK_SECOND:
5152 case DTK_MILLISEC:
5153 case DTK_MICROSEC:
5154 memcpy(result, interval, sizeof(Interval));
5155 PG_RETURN_INTERVAL_P(result);
5156 break;
5157
5158 default:
5159 ereport(ERROR,
5160 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5161 errmsg("unit \"%s\" not supported for type %s",
5162 lowunits, format_type_be(INTERVALOID)),
5163 (val == DTK_WEEK) ? errdetail("Months usually have fractional weeks.") : 0));
5164 result = NULL;
5165 }
5166 }
5167
5169 switch (val)
5170 {
5171 case DTK_MILLENNIUM:
5172 /* caution: C division may have negative remainder */
5173 tm->tm_year = (tm->tm_year / 1000) * 1000;
5174 /* FALL THRU */
5175 case DTK_CENTURY:
5176 /* caution: C division may have negative remainder */
5177 tm->tm_year = (tm->tm_year / 100) * 100;
5178 /* FALL THRU */
5179 case DTK_DECADE:
5180 /* caution: C division may have negative remainder */
5181 tm->tm_year = (tm->tm_year / 10) * 10;
5182 /* FALL THRU */
5183 case DTK_YEAR:
5184 tm->tm_mon = 0;
5185 /* FALL THRU */
5186 case DTK_QUARTER:
5187 tm->tm_mon = 3 * (tm->tm_mon / 3);
5188 /* FALL THRU */
5189 case DTK_MONTH:
5190 tm->tm_mday = 0;
5191 /* FALL THRU */
5192 case DTK_DAY:
5193 tm->tm_hour = 0;
5194 /* FALL THRU */
5195 case DTK_HOUR:
5196 tm->tm_min = 0;
5197 /* FALL THRU */
5198 case DTK_MINUTE:
5199 tm->tm_sec = 0;
5200 /* FALL THRU */
5201 case DTK_SECOND:
5202 tm->tm_usec = 0;
5203 break;
5204 case DTK_MILLISEC:
5205 tm->tm_usec = (tm->tm_usec / 1000) * 1000;
5206 break;
5207 case DTK_MICROSEC:
5208 break;
5209
5210 default:
5211 ereport(ERROR,
5212 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5213 errmsg("unit \"%s\" not supported for type %s",
5214 lowunits, format_type_be(INTERVALOID)),
5215 (val == DTK_WEEK) ? errdetail("Months usually have fractional weeks.") : 0));
5216 }
5217
5218 if (itm2interval(tm, result) != 0)
5219 ereport(ERROR,
5220 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
5221 errmsg("interval out of range")));
5222 }
5223 else
5224 {
5225 ereport(ERROR,
5226 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5227 errmsg("unit \"%s\" not recognized for type %s",
5228 lowunits, format_type_be(INTERVALOID))));
5229 }
5230
5231 PG_RETURN_INTERVAL_P(result);
5232}
int itm2interval(struct pg_itm *itm, Interval *span)
Definition: timestamp.c:2077
int errdetail(const char *fmt,...)
Definition: elog.c:1216

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

◆ interval_um()

Datum interval_um ( PG_FUNCTION_ARGS  )

Definition at line 3446 of file timestamp.c.

3447{
3449 Interval *result;
3450
3451 result = (Interval *) palloc(sizeof(Interval));
3453
3454 PG_RETURN_INTERVAL_P(result);
3455}

References interval_um_internal(), palloc(), PG_GETARG_INTERVAL_P, and PG_RETURN_INTERVAL_P.

Referenced by abs_interval().

◆ interval_um_internal()

static void interval_um_internal ( const Interval interval,
Interval result 
)
static

Definition at line 3426 of file timestamp.c.

3427{
3429 INTERVAL_NOEND(result);
3430 else if (INTERVAL_IS_NOEND(interval))
3431 INTERVAL_NOBEGIN(result);
3432 else
3433 {
3434 /* Negate each field, guarding against overflow */
3435 if (pg_sub_s64_overflow(INT64CONST(0), interval->time, &result->time) ||
3436 pg_sub_s32_overflow(0, interval->day, &result->day) ||
3437 pg_sub_s32_overflow(0, interval->month, &result->month) ||
3438 INTERVAL_NOT_FINITE(result))
3439 ereport(ERROR,
3440 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3441 errmsg("interval out of range")));
3442 }
3443}

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

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

◆ intervaltypmodin()

Datum intervaltypmodin ( PG_FUNCTION_ARGS  )

Definition at line 1047 of file timestamp.c.

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

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

◆ intervaltypmodleastfield()

static int intervaltypmodleastfield ( int32  typmod)
static

Definition at line 1212 of file timestamp.c.

1213{
1214 if (typmod < 0)
1215 return 0; /* SECOND */
1216
1217 switch (INTERVAL_RANGE(typmod))
1218 {
1219 case INTERVAL_MASK(YEAR):
1220 return 5; /* YEAR */
1221 case INTERVAL_MASK(MONTH):
1222 return 4; /* MONTH */
1223 case INTERVAL_MASK(DAY):
1224 return 3; /* DAY */
1225 case INTERVAL_MASK(HOUR):
1226 return 2; /* HOUR */
1227 case INTERVAL_MASK(MINUTE):
1228 return 1; /* MINUTE */
1229 case INTERVAL_MASK(SECOND):
1230 return 0; /* SECOND */
1232 return 4; /* MONTH */
1234 return 2; /* HOUR */
1236 return 1; /* MINUTE */
1238 return 0; /* SECOND */
1240 return 1; /* MINUTE */
1242 return 0; /* SECOND */
1244 return 0; /* SECOND */
1246 return 0; /* SECOND */
1247 default:
1248 elog(ERROR, "invalid INTERVAL typmod: 0x%x", typmod);
1249 break;
1250 }
1251 return 0; /* can't get here, but keep compiler quiet */
1252}

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

Referenced by interval_support().

◆ intervaltypmodout()

Datum intervaltypmodout ( PG_FUNCTION_ARGS  )

Definition at line 1126 of file timestamp.c.

1127{
1128 int32 typmod = PG_GETARG_INT32(0);
1129 char *res = (char *) palloc(64);
1130 int fields;
1131 int precision;
1132 const char *fieldstr;
1133
1134 if (typmod < 0)
1135 {
1136 *res = '\0';
1137 PG_RETURN_CSTRING(res);
1138 }
1139
1140 fields = INTERVAL_RANGE(typmod);
1141 precision = INTERVAL_PRECISION(typmod);
1142
1143 switch (fields)
1144 {
1145 case INTERVAL_MASK(YEAR):
1146 fieldstr = " year";
1147 break;
1148 case INTERVAL_MASK(MONTH):
1149 fieldstr = " month";
1150 break;
1151 case INTERVAL_MASK(DAY):
1152 fieldstr = " day";
1153 break;
1154 case INTERVAL_MASK(HOUR):
1155 fieldstr = " hour";
1156 break;
1157 case INTERVAL_MASK(MINUTE):
1158 fieldstr = " minute";
1159 break;
1160 case INTERVAL_MASK(SECOND):
1161 fieldstr = " second";
1162 break;
1164 fieldstr = " year to month";
1165 break;
1167 fieldstr = " day to hour";
1168 break;
1170 fieldstr = " day to minute";
1171 break;
1173 fieldstr = " day to second";
1174 break;
1176 fieldstr = " hour to minute";
1177 break;
1179 fieldstr = " hour to second";
1180 break;
1182 fieldstr = " minute to second";
1183 break;
1185 fieldstr = "";
1186 break;
1187 default:
1188 elog(ERROR, "invalid INTERVAL typmod: 0x%x", typmod);
1189 fieldstr = "";
1190 break;
1191 }
1192
1193 if (precision != INTERVAL_FULL_PRECISION)
1194 snprintf(res, 64, "%s(%d)", fieldstr, precision);
1195 else
1196 snprintf(res, 64, "%s", fieldstr);
1197
1198 PG_RETURN_CSTRING(res);
1199}
#define snprintf
Definition: port.h:260

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.

◆ isoweek2date()

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

Definition at line 5264 of file timestamp.c.

5265{
5266 j2date(isoweek2j(*year, woy), year, mon, mday);
5267}
void j2date(int jd, int *year, int *month, int *day)
Definition: datetime.c:321

References isoweek2j(), and j2date().

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

◆ isoweek2j()

int isoweek2j ( int  year,
int  week 
)

Definition at line 5244 of file timestamp.c.

5245{
5246 int day0,
5247 day4;
5248
5249 /* fourth day of current year */
5250 day4 = date2j(year, 1, 4);
5251
5252 /* day0 == offset to first day of week (Monday) */
5253 day0 = j2day(day4 - 1);
5254
5255 return ((week - 1) * 7) + (day4 - day0);
5256}

References date2j(), and j2day().

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

◆ isoweekdate2date()

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

Definition at line 5277 of file timestamp.c.

5278{
5279 int jday;
5280
5281 jday = isoweek2j(*year, isoweek);
5282 /* convert Gregorian week start (Sunday=1) to ISO week start (Monday=1) */
5283 if (wday > 1)
5284 jday += wday - 2;
5285 else
5286 jday += 6;
5287 j2date(jday, year, mon, mday);
5288}

References isoweek2j(), and j2date().

Referenced by do_to_timestamp().

◆ itm2interval()

int itm2interval ( struct pg_itm itm,
Interval span 
)

Definition at line 2077 of file timestamp.c.

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

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

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

◆ itmin2interval()

int itmin2interval ( struct pg_itm_in itm_in,
Interval span 
)

Definition at line 2115 of file timestamp.c.

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

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

Referenced by interval_in(), pg_timezone_abbrevs_abbrevs(), and pg_timezone_abbrevs_zone().

◆ lookup_timezone()

static pg_tz * lookup_timezone ( text zone)
static

Definition at line 560 of file timestamp.c.

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

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

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

◆ make_interval()

Datum make_interval ( PG_FUNCTION_ARGS  )

Definition at line 1530 of file timestamp.c.

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

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

◆ make_timestamp()

Datum make_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 645 of file timestamp.c.

646{
647 int32 year = PG_GETARG_INT32(0);
648 int32 month = PG_GETARG_INT32(1);
649 int32 mday = PG_GETARG_INT32(2);
650 int32 hour = PG_GETARG_INT32(3);
651 int32 min = PG_GETARG_INT32(4);
652 float8 sec = PG_GETARG_FLOAT8(5);
653 Timestamp result;
654
655 result = make_timestamp_internal(year, month, mday,
656 hour, min, sec);
657
658 PG_RETURN_TIMESTAMP(result);
659}
static Timestamp make_timestamp_internal(int year, int month, int day, int hour, int min, double sec)
Definition: timestamp.c:574

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

◆ make_timestamp_internal()

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

Definition at line 574 of file timestamp.c.

576{
577 struct pg_tm tm;
579 TimeOffset time;
580 int dterr;
581 bool bc = false;
582 Timestamp result;
583
584 tm.tm_year = year;
585 tm.tm_mon = month;
586 tm.tm_mday = day;
587
588 /* Handle negative years as BC */
589 if (tm.tm_year < 0)
590 {
591 bc = true;
592 tm.tm_year = -tm.tm_year;
593 }
594
595 dterr = ValidateDate(DTK_DATE_M, false, false, bc, &tm);
596
597 if (dterr != 0)
599 (errcode(ERRCODE_DATETIME_FIELD_OVERFLOW),
600 errmsg("date field value out of range: %d-%02d-%02d",
601 year, month, day)));
602
605 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
606 errmsg("date out of range: %d-%02d-%02d",
607 year, month, day)));
608
610
611 /* Check for time overflow */
612 if (float_time_overflows(hour, min, sec))
614 (errcode(ERRCODE_DATETIME_FIELD_OVERFLOW),
615 errmsg("time field value out of range: %d:%02d:%02g",
616 hour, min, sec)));
617
618 /* This should match tm2time */
619 time = (((hour * MINS_PER_HOUR + min) * SECS_PER_MINUTE)
620 * USECS_PER_SEC) + (int64) rint(sec * USECS_PER_SEC);
621
623 pg_add_s64_overflow(result, time, &result)))
625 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
626 errmsg("timestamp out of range: %d-%02d-%02d %d:%02d:%02g",
627 year, month, day,
628 hour, min, sec)));
629
630 /* final range check catches just-out-of-range timestamps */
631 if (!IS_VALID_TIMESTAMP(result))
633 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
634 errmsg("timestamp out of range: %d-%02d-%02d %d:%02d:%02g",
635 year, month, day,
636 hour, min, sec)));
637
638 return result;
639}
int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc, struct pg_tm *tm)
Definition: datetime.c:2561
#define unlikely(x)
Definition: c.h:407
#define MINS_PER_HOUR
Definition: timestamp.h:129
#define IS_VALID_JULIAN(y, m, d)
Definition: timestamp.h:227
#define SECS_PER_MINUTE
Definition: timestamp.h:128
bool float_time_overflows(int hour, int min, double sec)
Definition: date.c:1547
#define DTK_DATE_M
Definition: datetime.h:191
long date
Definition: pgtypes_date.h:9

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

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

◆ make_timestamptz()

Datum make_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 665 of file timestamp.c.

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

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

◆ make_timestamptz_at_timezone()

Datum make_timestamptz_at_timezone ( PG_FUNCTION_ARGS  )

Definition at line 686 of file timestamp.c.

687{
688 int32 year = PG_GETARG_INT32(0);
689 int32 month = PG_GETARG_INT32(1);
690 int32 mday = PG_GETARG_INT32(2);
691 int32 hour = PG_GETARG_INT32(3);
692 int32 min = PG_GETARG_INT32(4);
693 float8 sec = PG_GETARG_FLOAT8(5);
695 TimestampTz result;
697 struct pg_tm tt;
698 int tz;
699 fsec_t fsec;
700
701 timestamp = make_timestamp_internal(year, month, mday,
702 hour, min, sec);
703
704 if (timestamp2tm(timestamp, NULL, &tt, &fsec, NULL, NULL) != 0)
706 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
707 errmsg("timestamp out of range")));
708
709 tz = parse_sane_timezone(&tt, zone);
710
711 result = dt2local(timestamp, -tz);
712
713 if (!IS_VALID_TIMESTAMP(result))
715 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
716 errmsg("timestamp out of range")));
717
718 PG_RETURN_TIMESTAMPTZ(result);
719}
static Timestamp dt2local(Timestamp dt, int timezone)
Definition: timestamp.c:2134
int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone)
Definition: timestamp.c:1910
static int parse_sane_timezone(struct pg_tm *tm, text *zone)
Definition: timestamp.c:491
int32 fsec_t
Definition: timestamp.h:41
int64 timestamp

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

◆ makeIntervalAggState()

static IntervalAggState * makeIntervalAggState ( FunctionCallInfo  fcinfo)
static

Definition at line 3967 of file timestamp.c.

3968{
3970 MemoryContext agg_context;
3971 MemoryContext old_context;
3972
3973 if (!AggCheckCallContext(fcinfo, &agg_context))
3974 elog(ERROR, "aggregate function called in non-aggregate context");
3975
3976 old_context = MemoryContextSwitchTo(agg_context);
3977
3979
3980 MemoryContextSwitchTo(old_context);
3981
3982 return state;
3983}

References AggCheckCallContext(), elog, ERROR, MemoryContextSwitchTo(), and palloc0().

Referenced by interval_avg_accum(), and interval_avg_combine().

◆ mul_d_interval()

Datum mul_d_interval ( PG_FUNCTION_ARGS  )

Definition at line 3728 of file timestamp.c.

3729{
3730 /* Args are float8 and Interval *, but leave them as generic Datum */
3731 Datum factor = PG_GETARG_DATUM(0);
3732 Datum span = PG_GETARG_DATUM(1);
3733
3734 return DirectFunctionCall2(interval_mul, span, factor);
3735}
Datum interval_mul(PG_FUNCTION_ARGS)
Definition: timestamp.c:3608

References DirectFunctionCall2, interval_mul(), and PG_GETARG_DATUM.

◆ NonFiniteIntervalPart()

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

Definition at line 6034 of file timestamp.c.

6035{
6036 if ((type != UNITS) && (type != RESERV))
6037 ereport(ERROR,
6038 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6039 errmsg("unit \"%s\" not recognized for type %s",
6040 lowunits, format_type_be(INTERVALOID))));
6041
6042 switch (unit)
6043 {
6044 /* Oscillating units */
6045 case DTK_MICROSEC:
6046 case DTK_MILLISEC:
6047 case DTK_SECOND:
6048 case DTK_MINUTE:
6049 case DTK_WEEK:
6050 case DTK_MONTH:
6051 case DTK_QUARTER:
6052 return 0.0;
6053
6054 /* Monotonically-increasing units */
6055 case DTK_HOUR:
6056 case DTK_DAY:
6057 case DTK_YEAR:
6058 case DTK_DECADE:
6059 case DTK_CENTURY:
6060 case DTK_MILLENNIUM:
6061 case DTK_EPOCH:
6062 if (isNegative)
6063 return -get_float8_infinity();
6064 else
6065 return get_float8_infinity();
6066
6067 default:
6068 ereport(ERROR,
6069 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6070 errmsg("unit \"%s\" not supported for type %s",
6071 lowunits, format_type_be(INTERVALOID))));
6072 return 0.0; /* keep compiler quiet */
6073 }
6074}
static float8 get_float8_infinity(void)
Definition: float.h:65

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

Referenced by interval_part_common().

◆ NonFiniteTimestampTzPart()

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

Definition at line 5424 of file timestamp.c.

5426{
5427 if ((type != UNITS) && (type != RESERV))
5428 ereport(ERROR,
5429 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5430 errmsg("unit \"%s\" not recognized for type %s",
5431 lowunits,
5432 format_type_be(isTz ? TIMESTAMPTZOID : TIMESTAMPOID))));
5433
5434 switch (unit)
5435 {
5436 /* Oscillating units */
5437 case DTK_MICROSEC:
5438 case DTK_MILLISEC:
5439 case DTK_SECOND:
5440 case DTK_MINUTE:
5441 case DTK_HOUR:
5442 case DTK_DAY:
5443 case DTK_MONTH:
5444 case DTK_QUARTER:
5445 case DTK_WEEK:
5446 case DTK_DOW:
5447 case DTK_ISODOW:
5448 case DTK_DOY:
5449 case DTK_TZ:
5450 case DTK_TZ_MINUTE:
5451 case DTK_TZ_HOUR:
5452 return 0.0;
5453
5454 /* Monotonically-increasing units */
5455 case DTK_YEAR:
5456 case DTK_DECADE:
5457 case DTK_CENTURY:
5458 case DTK_MILLENNIUM:
5459 case DTK_JULIAN:
5460 case DTK_ISOYEAR:
5461 case DTK_EPOCH:
5462 if (isNegative)
5463 return -get_float8_infinity();
5464 else
5465 return get_float8_infinity();
5466
5467 default:
5468 ereport(ERROR,
5469 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5470 errmsg("unit \"%s\" not supported for type %s",
5471 lowunits,
5472 format_type_be(isTz ? TIMESTAMPTZOID : TIMESTAMPOID))));
5473 return 0.0; /* keep compiler quiet */
5474 }
5475}
#define DTK_JULIAN
Definition: datetime.h:173
#define DTK_TZ_HOUR
Definition: datetime.h:177
#define DTK_TZ_MINUTE
Definition: datetime.h:178
#define DTK_ISODOW
Definition: datetime.h:180
#define DTK_ISOYEAR
Definition: datetime.h:179
#define DTK_DOY
Definition: datetime.h:176
#define DTK_TZ
Definition: datetime.h:146
#define DTK_DOW
Definition: datetime.h:175

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

Referenced by timestamp_part_common(), and timestamptz_part_common().

◆ now()

Definition at line 1609 of file timestamp.c.

References GetCurrentTransactionStartTimestamp(), and PG_RETURN_TIMESTAMPTZ.

Referenced by advanceConnectionState(), ApplyLauncherMain(), BackgroundWriterMain(), bbsink_copystream_archive_contents(), CalculateCopyStreamSleeptime(), CheckArchiveTimeout(), CheckpointerMain(), DetermineSlotInvalidationCause(), doLog(), doRetry(), dumpTimestamp(), enable_timeout(), enable_timeout_after(), enable_timeout_at(), enable_timeout_every(), enable_timeouts(), executeMetaCommand(), flushAndSendFeedback(), get_candidate_xid(), handle_sig_alarm(), HandleCopyStream(), has_startup_progress_timeout_expired(), initialize_prng(), InvalidatePossiblyObsoleteSlot(), IsCheckpointOnSchedule(), LagTrackerRead(), launch_sync_worker(), launch_worker(), libpqsrv_cancel(), LockBufferForCleanup(), logicalrep_worker_launch(), LogicalRepApplyLoop(), LogRecoveryConflict(), maybe_start_bgworkers(), mxid_age(), OutputFsync(), PerformRadiusTransaction(), pg_clock_gettime_ns(), pg_time_now(), pg_time_now_lazy(), pg_timezone_abbrevs_abbrevs(), pg_timezone_abbrevs_zone(), pgfdw_cancel_query(), pgfdw_finish_abort_cleanup(), pgfdw_get_cleanup_result(), pgstat_report_archiver(), pgstat_report_stat(), PQsocketPoll(), pqTraceFormatTimestamp(), printProgressReport(), printVerboseErrorMessages(), ProcessKeepaliveMsg(), ProcessStandbyReplyMessage(), processXactStats(), ProcSleep(), progress_report(), ReplicationSlotRelease(), RequestXLogStreaming(), ResolveRecoveryConflictWithLock(), ResolveRecoveryConflictWithVirtualXIDs(), RestoreSlotFromDisk(), schedule_alarm(), send_feedback(), sendFeedback(), ServerLoop(), set_next_rotation_time(), should_stop_conflict_info_retention(), StreamLogicalLog(), SysLoggerMain(), threadRun(), timetz_zone(), update_synced_slots_inactive_since(), wait_for_local_flush(), WaitForWALToBecomeAvailable(), WalRcvComputeNextWakeup(), WalRcvRunning(), WalRcvStreaming(), WalReceiverMain(), WalSndComputeSleeptime(), WalSndLoop(), WalSndUpdateProgress(), WalSndWaitForWal(), WalSndWriteData(), xid_age(), XLogBackgroundFlush(), XLogWalRcvSendHSFeedback(), and XLogWalRcvSendReply().

◆ overlaps_timestamp()

Datum overlaps_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2672 of file timestamp.c.

2673{
2674 /*
2675 * The arguments are Timestamps, but we leave them as generic Datums to
2676 * avoid unnecessary conversions between value and reference forms --- not
2677 * to mention possible dereferences of null pointers.
2678 */
2679 Datum ts1 = PG_GETARG_DATUM(0);
2680 Datum te1 = PG_GETARG_DATUM(1);
2681 Datum ts2 = PG_GETARG_DATUM(2);
2682 Datum te2 = PG_GETARG_DATUM(3);
2683 bool ts1IsNull = PG_ARGISNULL(0);
2684 bool te1IsNull = PG_ARGISNULL(1);
2685 bool ts2IsNull = PG_ARGISNULL(2);
2686 bool te2IsNull = PG_ARGISNULL(3);
2687
2688#define TIMESTAMP_GT(t1,t2) \
2689 DatumGetBool(DirectFunctionCall2(timestamp_gt,t1,t2))
2690#define TIMESTAMP_LT(t1,t2) \
2691 DatumGetBool(DirectFunctionCall2(timestamp_lt,t1,t2))
2692
2693 /*
2694 * If both endpoints of interval 1 are null, the result is null (unknown).
2695 * If just one endpoint is null, take ts1 as the non-null one. Otherwise,
2696 * take ts1 as the lesser endpoint.
2697 */
2698 if (ts1IsNull)
2699 {
2700 if (te1IsNull)
2702 /* swap null for non-null */
2703 ts1 = te1;
2704 te1IsNull = true;
2705 }
2706 else if (!te1IsNull)
2707 {
2708 if (TIMESTAMP_GT(ts1, te1))
2709 {
2710 Datum tt = ts1;
2711
2712 ts1 = te1;
2713 te1 = tt;
2714 }
2715 }
2716
2717 /* Likewise for interval 2. */
2718 if (ts2IsNull)
2719 {
2720 if (te2IsNull)
2722 /* swap null for non-null */
2723 ts2 = te2;
2724 te2IsNull = true;
2725 }
2726 else if (!te2IsNull)
2727 {
2728 if (TIMESTAMP_GT(ts2, te2))
2729 {
2730 Datum tt = ts2;
2731
2732 ts2 = te2;
2733 te2 = tt;
2734 }
2735 }
2736
2737 /*
2738 * At this point neither ts1 nor ts2 is null, so we can consider three
2739 * cases: ts1 > ts2, ts1 < ts2, ts1 = ts2
2740 */
2741 if (TIMESTAMP_GT(ts1, ts2))
2742 {
2743 /*
2744 * This case is ts1 < te2 OR te1 < te2, which may look redundant but
2745 * in the presence of nulls it's not quite completely so.
2746 */
2747 if (te2IsNull)
2749 if (TIMESTAMP_LT(ts1, te2))
2750 PG_RETURN_BOOL(true);
2751 if (te1IsNull)
2753
2754 /*
2755 * If te1 is not null then we had ts1 <= te1 above, and we just found
2756 * ts1 >= te2, hence te1 >= te2.
2757 */
2758 PG_RETURN_BOOL(false);
2759 }
2760 else if (TIMESTAMP_LT(ts1, ts2))
2761 {
2762 /* This case is ts2 < te1 OR te2 < te1 */
2763 if (te1IsNull)
2765 if (TIMESTAMP_LT(ts2, te1))
2766 PG_RETURN_BOOL(true);
2767 if (te2IsNull)
2769
2770 /*
2771 * If te2 is not null then we had ts2 <= te2 above, and we just found
2772 * ts2 >= te1, hence te2 >= te1.
2773 */
2774 PG_RETURN_BOOL(false);
2775 }
2776 else
2777 {
2778 /*
2779 * For ts1 = ts2 the spec says te1 <> te2 OR te1 = te2, which is a
2780 * rather silly way of saying "true if both are non-null, else null".
2781 */
2782 if (te1IsNull || te2IsNull)
2784 PG_RETURN_BOOL(true);
2785 }
2786
2787#undef TIMESTAMP_GT
2788#undef TIMESTAMP_LT
2789}
#define TIMESTAMP_GT(t1, t2)
#define TIMESTAMP_LT(t1, t2)

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

◆ parse_sane_timezone()

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

Definition at line 491 of file timestamp.c.

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

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

Referenced by make_timestamptz_at_timezone().

◆ pg_conf_load_time()

Datum pg_conf_load_time ( PG_FUNCTION_ARGS  )

Definition at line 1633 of file timestamp.c.

1634{
1636}
TimestampTz PgReloadTime
Definition: timestamp.c:57

References PG_RETURN_TIMESTAMPTZ, and PgReloadTime.

◆ pg_postmaster_start_time()

Datum pg_postmaster_start_time ( PG_FUNCTION_ARGS  )

Definition at line 1627 of file timestamp.c.

1628{
1630}
TimestampTz PgStartTime
Definition: timestamp.c:54

References PG_RETURN_TIMESTAMPTZ, and PgStartTime.

◆ SetEpochTimestamp()

Timestamp SetEpochTimestamp ( void  )

Definition at line 2190 of file timestamp.c.

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

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

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

◆ statement_timestamp()

Datum statement_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 1615 of file timestamp.c.

1616{
1618}
TimestampTz GetCurrentStatementStartTimestamp(void)
Definition: xact.c:880

References GetCurrentStatementStartTimestamp(), and PG_RETURN_TIMESTAMPTZ.

◆ time2t()

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

Definition at line 2128 of file timestamp.c.

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

References MINS_PER_HOUR, SECS_PER_MINUTE, and USECS_PER_SEC.

Referenced by tm2timestamp().

◆ time_t_to_timestamptz()

TimestampTz time_t_to_timestamptz ( pg_time_t  tm)

Definition at line 1820 of file timestamp.c.

1821{
1822 TimestampTz result;
1823
1824 result = (TimestampTz) tm -
1826 result *= USECS_PER_SEC;
1827
1828 return result;
1829}

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

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

◆ timeofday()

Datum timeofday ( PG_FUNCTION_ARGS  )

Definition at line 1691 of file timestamp.c.

1692{
1693 struct timeval tp;
1694 char templ[128];
1695 char buf[128];
1696 pg_time_t tt;
1697
1698 gettimeofday(&tp, NULL);
1699 tt = (pg_time_t) tp.tv_sec;
1700 pg_strftime(templ, sizeof(templ), "%a %b %d %H:%M:%S.%%06d %Y %Z",
1702 snprintf(buf, sizeof(buf), templ, tp.tv_usec);
1703
1705}
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
size_t pg_strftime(char *s, size_t maxsize, const char *format, const struct pg_tm *t)
Definition: strftime.c:128
struct pg_tm * pg_localtime(const pg_time_t *timep, const pg_tz *tz)
Definition: localtime.c:1345
Definition: lexi.c:60
text * cstring_to_text(const char *s)
Definition: varlena.c:181

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

◆ timestamp2timestamptz()

static TimestampTz timestamp2timestamptz ( Timestamp  timestamp)
static

Definition at line 6484 of file timestamp.c.

6485{
6487}
TimestampTz timestamp2timestamptz_safe(Timestamp timestamp, Node *escontext)
Definition: timestamp.c:6448

References timestamp2timestamptz_safe().

Referenced by make_timestamptz(), and timestamp_timestamptz().

◆ timestamp2timestamptz_safe()

TimestampTz timestamp2timestamptz_safe ( Timestamp  timestamp,
Node escontext 
)

Definition at line 6448 of file timestamp.c.

6449{
6450 TimestampTz result;
6451 struct pg_tm tt,
6452 *tm = &tt;
6453 fsec_t fsec;
6454 int tz;
6455
6457 return timestamp;
6458
6459 /* timestamp2tm should not fail on valid timestamps, but cope */
6460 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0)
6461 {
6463
6464 result = dt2local(timestamp, -tz);
6465
6466 if (IS_VALID_TIMESTAMP(result))
6467 return result;
6468 }
6469
6470 if (timestamp < 0)
6471 TIMESTAMP_NOBEGIN(result);
6472 else
6473 TIMESTAMP_NOEND(result);
6474
6475 ereturn(escontext, result,
6476 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6477 errmsg("timestamp out of range")));
6478}

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

Referenced by cvt_timestamp_timestamptz(), timestamp2timestamptz(), and timestamp_cmp_timestamptz_internal().

◆ timestamp2tm()

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

Definition at line 1910 of file timestamp.c.

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

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

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

◆ timestamp_age()

Datum timestamp_age ( PG_FUNCTION_ARGS  )

Definition at line 4288 of file timestamp.c.

4289{
4292 Interval *result;
4293 fsec_t fsec1,
4294 fsec2;
4295 struct pg_itm tt,
4296 *tm = &tt;
4297 struct pg_tm tt1,
4298 *tm1 = &tt1;
4299 struct pg_tm tt2,
4300 *tm2 = &tt2;
4301
4302 result = (Interval *) palloc(sizeof(Interval));
4303
4304 /*
4305 * Handle infinities.
4306 *
4307 * We treat anything that amounts to "infinity - infinity" as an error,
4308 * since the interval type has nothing equivalent to NaN.
4309 */
4310 if (TIMESTAMP_IS_NOBEGIN(dt1))
4311 {
4312 if (TIMESTAMP_IS_NOBEGIN(dt2))
4313 ereport(ERROR,
4314 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4315 errmsg("interval out of range")));
4316 else
4317 INTERVAL_NOBEGIN(result);
4318 }
4319 else if (TIMESTAMP_IS_NOEND(dt1))
4320 {
4321 if (TIMESTAMP_IS_NOEND(dt2))
4322 ereport(ERROR,
4323 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4324 errmsg("interval out of range")));
4325 else
4326 INTERVAL_NOEND(result);
4327 }
4328 else if (TIMESTAMP_IS_NOBEGIN(dt2))
4329 INTERVAL_NOEND(result);
4330 else if (TIMESTAMP_IS_NOEND(dt2))
4331 INTERVAL_NOBEGIN(result);
4332 else if (timestamp2tm(dt1, NULL, tm1, &fsec1, NULL, NULL) == 0 &&
4333 timestamp2tm(dt2, NULL, tm2, &fsec2, NULL, NULL) == 0)
4334 {
4335 /* form the symbolic difference */
4336 tm->tm_usec = fsec1 - fsec2;
4337 tm->tm_sec = tm1->tm_sec - tm2->tm_sec;
4338 tm->tm_min = tm1->tm_min - tm2->tm_min;
4339 tm->tm_hour = tm1->tm_hour - tm2->tm_hour;
4340 tm->tm_mday = tm1->tm_mday - tm2->tm_mday;
4341 tm->tm_mon = tm1->tm_mon - tm2->tm_mon;
4342 tm->tm_year = tm1->tm_year - tm2->tm_year;
4343
4344 /* flip sign if necessary... */
4345 if (dt1 < dt2)
4346 {
4347 tm->tm_usec = -tm->tm_usec;
4348 tm->tm_sec = -tm->tm_sec;
4349 tm->tm_min = -tm->tm_min;
4350 tm->tm_hour = -tm->tm_hour;
4351 tm->tm_mday = -tm->tm_mday;
4352 tm->tm_mon = -tm->tm_mon;
4353 tm->tm_year = -tm->tm_year;
4354 }
4355
4356 /* propagate any negative fields into the next higher field */
4357 while (tm->tm_usec < 0)
4358 {
4359 tm->tm_usec += USECS_PER_SEC;
4360 tm->tm_sec--;
4361 }
4362
4363 while (tm->tm_sec < 0)
4364 {
4366 tm->tm_min--;
4367 }
4368
4369 while (tm->tm_min < 0)
4370 {
4372 tm->tm_hour--;
4373 }
4374
4375 while (tm->tm_hour < 0)
4376 {
4378 tm->tm_mday--;
4379 }
4380
4381 while (tm->tm_mday < 0)
4382 {
4383 if (dt1 < dt2)
4384 {
4385 tm->tm_mday += day_tab[isleap(tm1->tm_year)][tm1->tm_mon - 1];
4386 tm->tm_mon--;
4387 }
4388 else
4389 {
4390 tm->tm_mday += day_tab[isleap(tm2->tm_year)][tm2->tm_mon - 1];
4391 tm->tm_mon--;
4392 }
4393 }
4394
4395 while (tm->tm_mon < 0)
4396 {
4398 tm->tm_year--;
4399 }
4400
4401 /* recover sign if necessary... */
4402 if (dt1 < dt2)
4403 {
4404 tm->tm_usec = -tm->tm_usec;
4405 tm->tm_sec = -tm->tm_sec;
4406 tm->tm_min = -tm->tm_min;
4407 tm->tm_hour = -tm->tm_hour;
4408 tm->tm_mday = -tm->tm_mday;
4409 tm->tm_mon = -tm->tm_mon;
4410 tm->tm_year = -tm->tm_year;
4411 }
4412
4413 if (itm2interval(tm, result) != 0)
4414 ereport(ERROR,
4415 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4416 errmsg("interval out of range")));
4417 }
4418 else
4419 ereport(ERROR,
4420 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4421 errmsg("timestamp out of range")));
4422
4423 PG_RETURN_INTERVAL_P(result);
4424}
const int day_tab[2][13]
Definition: datetime.c:75
#define HOURS_PER_DAY
Definition: timestamp.h:118
#define isleap(y)
Definition: datetime.h:271

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

◆ timestamp_at_local()

Datum timestamp_at_local ( PG_FUNCTION_ARGS  )

Definition at line 6940 of file timestamp.c.

6941{
6942 return timestamp_timestamptz(fcinfo);
6943}
Datum timestamp_timestamptz(PG_FUNCTION_ARGS)
Definition: timestamp.c:6430

References timestamp_timestamptz().

◆ timestamp_bin()

Datum timestamp_bin ( PG_FUNCTION_ARGS  )

Definition at line 4588 of file timestamp.c.

4589{
4590 Interval *stride = PG_GETARG_INTERVAL_P(0);
4592 Timestamp origin = PG_GETARG_TIMESTAMP(2);
4593 Timestamp result,
4594 stride_usecs,
4595 tm_diff,
4596 tm_modulo,
4597 tm_delta;
4598
4601
4602 if (TIMESTAMP_NOT_FINITE(origin))
4603 ereport(ERROR,
4604 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4605 errmsg("origin out of range")));
4606
4607 if (INTERVAL_NOT_FINITE(stride))
4608 ereport(ERROR,
4609 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4610 errmsg("timestamps cannot be binned into infinite intervals")));
4611
4612 if (stride->month != 0)
4613 ereport(ERROR,
4614 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4615 errmsg("timestamps cannot be binned into intervals containing months or years")));
4616
4617 if (unlikely(pg_mul_s64_overflow(stride->day, USECS_PER_DAY, &stride_usecs)) ||
4618 unlikely(pg_add_s64_overflow(stride_usecs, stride->time, &stride_usecs)))
4619 ereport(ERROR,
4620 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4621 errmsg("interval out of range")));
4622
4623 if (stride_usecs <= 0)
4624 ereport(ERROR,
4625 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4626 errmsg("stride must be greater than zero")));
4627
4628 if (unlikely(pg_sub_s64_overflow(timestamp, origin, &tm_diff)))
4629 ereport(ERROR,
4630 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4631 errmsg("interval out of range")));
4632
4633 /* These calculations cannot overflow */
4634 tm_modulo = tm_diff % stride_usecs;
4635 tm_delta = tm_diff - tm_modulo;
4636 result = origin + tm_delta;
4637
4638 /*
4639 * We want to round towards -infinity, not 0, when tm_diff is negative and
4640 * not a multiple of stride_usecs. This adjustment *can* cause overflow,
4641 * since the result might now be out of the range origin .. timestamp.
4642 */
4643 if (tm_modulo < 0)
4644 {
4645 if (unlikely(pg_sub_s64_overflow(result, stride_usecs, &result)) ||
4646 !IS_VALID_TIMESTAMP(result))
4647 ereport(ERROR,
4648 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4649 errmsg("timestamp out of range")));
4650 }
4651
4652 PG_RETURN_TIMESTAMP(result);
4653}

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

◆ timestamp_cmp()

Datum timestamp_cmp ( PG_FUNCTION_ARGS  )

Definition at line 2270 of file timestamp.c.

2271{
2274
2276}

References PG_GETARG_TIMESTAMP, PG_RETURN_INT32, and timestamp_cmp_internal().

Referenced by compareDatetime(), gbt_ts_ssup_cmp(), and gbt_tskey_cmp().

◆ timestamp_cmp_internal()

int timestamp_cmp_internal ( Timestamp  dt1,
Timestamp  dt2 
)

◆ timestamp_cmp_timestamptz()

Datum timestamp_cmp_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 2441 of file timestamp.c.

2442{
2443 Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2445
2447}
int32 timestamp_cmp_timestamptz_internal(Timestamp timestampVal, TimestampTz dt2)
Definition: timestamp.c:2363

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

◆ timestamp_cmp_timestamptz_internal()

int32 timestamp_cmp_timestamptz_internal ( Timestamp  timestampVal,
TimestampTz  dt2 
)

Definition at line 2363 of file timestamp.c.

2364{
2365 TimestampTz dt1;
2366 ErrorSaveContext escontext = {T_ErrorSaveContext};
2367
2368 dt1 = timestamp2timestamptz_safe(timestampVal, (Node *) &escontext);
2369 if (escontext.error_occurred)
2370 {
2371 if (TIMESTAMP_IS_NOEND(dt1))
2372 {
2373 /* dt1 is larger than any finite timestamp, but less than infinity */
2374 return TIMESTAMP_IS_NOEND(dt2) ? -1 : +1;
2375 }
2376 if (TIMESTAMP_IS_NOBEGIN(dt1))
2377 {
2378 /* dt1 is less than any finite timestamp, but more than -infinity */
2379 return TIMESTAMP_IS_NOBEGIN(dt2) ? +1 : -1;
2380 }
2381 }
2382
2383 return timestamptz_cmp_internal(dt1, dt2);
2384}
bool error_occurred
Definition: miscnodes.h:47
#define timestamptz_cmp_internal(dt1, dt2)
Definition: timestamp.h:143

References ErrorSaveContext::error_occurred, timestamp2timestamptz_safe(), TIMESTAMP_IS_NOBEGIN, TIMESTAMP_IS_NOEND, and timestamptz_cmp_internal.

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

◆ timestamp_decrement()

static Datum timestamp_decrement ( Relation  rel,
Datum  existing,
bool *  underflow 
)
static

Definition at line 2289 of file timestamp.c.

2290{
2291 Timestamp texisting = DatumGetTimestamp(existing);
2292
2293 if (texisting == PG_INT64_MIN)
2294 {
2295 /* return value is undefined */
2296 *underflow = true;
2297 return (Datum) 0;
2298 }
2299
2300 *underflow = false;
2301 return TimestampGetDatum(texisting - 1);
2302}
#define PG_INT64_MIN
Definition: c.h:599

References DatumGetTimestamp(), PG_INT64_MIN, and TimestampGetDatum().

Referenced by timestamp_skipsupport().

◆ timestamp_eq()

Datum timestamp_eq ( PG_FUNCTION_ARGS  )

Definition at line 2216 of file timestamp.c.

2217{
2220
2221 PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) == 0);
2222}

References PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, and timestamp_cmp_internal().

Referenced by gbt_tseq().

◆ timestamp_eq_timestamptz()

Datum timestamp_eq_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 2387 of file timestamp.c.

2388{
2389 Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2391
2392 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) == 0);
2393}

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

◆ timestamp_finite()

Datum timestamp_finite ( PG_FUNCTION_ARGS  )

◆ timestamp_ge()

Datum timestamp_ge ( PG_FUNCTION_ARGS  )

Definition at line 2261 of file timestamp.c.

2262{
2265
2266 PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) >= 0);
2267}

References PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, and timestamp_cmp_internal().

Referenced by gbt_tsge().

◆ timestamp_ge_timestamptz()

Datum timestamp_ge_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 2432 of file timestamp.c.

2433{
2434 Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2436
2437 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) >= 0);
2438}

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

◆ timestamp_gt()

Datum timestamp_gt ( PG_FUNCTION_ARGS  )

Definition at line 2243 of file timestamp.c.

2244{
2247
2249}

References PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, and timestamp_cmp_internal().

Referenced by gbt_tsgt().

◆ timestamp_gt_timestamptz()

Datum timestamp_gt_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 2414 of file timestamp.c.

2415{
2416 Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2418
2419 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) > 0);
2420}

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

◆ timestamp_hash()

Datum timestamp_hash ( PG_FUNCTION_ARGS  )

Definition at line 2335 of file timestamp.c.

2336{
2337 return hashint8(fcinfo);
2338}

References hashint8().

◆ timestamp_hash_extended()

Datum timestamp_hash_extended ( PG_FUNCTION_ARGS  )

Definition at line 2341 of file timestamp.c.

2342{
2343 return hashint8extended(fcinfo);
2344}

References hashint8extended().

◆ timestamp_in()

Datum timestamp_in ( PG_FUNCTION_ARGS  )

Definition at line 166 of file timestamp.c.

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

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

Referenced by moddatetime().

◆ timestamp_increment()

static Datum timestamp_increment ( Relation  rel,
Datum  existing,
bool *  overflow 
)
static

Definition at line 2306 of file timestamp.c.

2307{
2308 Timestamp texisting = DatumGetTimestamp(existing);
2309
2310 if (texisting == PG_INT64_MAX)
2311 {
2312 /* return value is undefined */
2313 *overflow = true;
2314 return (Datum) 0;
2315 }
2316
2317 *overflow = false;
2318 return TimestampGetDatum(texisting + 1);
2319}
#define PG_INT64_MAX
Definition: c.h:600

References DatumGetTimestamp(), PG_INT64_MAX, and TimestampGetDatum().

Referenced by timestamp_skipsupport().

◆ timestamp_izone()

Datum timestamp_izone ( PG_FUNCTION_ARGS  )

Definition at line 6373 of file timestamp.c.

6374{
6377 TimestampTz result;
6378 int tz;
6379
6382
6384 ereport(ERROR,
6385 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6386 errmsg("interval time zone \"%s\" must be finite",
6388 PointerGetDatum(zone))))));
6389
6390 if (zone->month != 0 || zone->day != 0)
6391 ereport(ERROR,
6392 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6393 errmsg("interval time zone \"%s\" must not include months or days",
6395 PointerGetDatum(zone))))));
6396
6397 tz = zone->time / USECS_PER_SEC;
6398
6399 result = dt2local(timestamp, tz);
6400
6401 if (!IS_VALID_TIMESTAMP(result))
6402 ereport(ERROR,
6403 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6404 errmsg("timestamp out of range")));
6405
6406 PG_RETURN_TIMESTAMPTZ(result);
6407} /* timestamp_izone() */
Datum interval_out(PG_FUNCTION_ARGS)
Definition: timestamp.c:973
static char * DatumGetCString(Datum X)
Definition: postgres.h:345

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

◆ timestamp_larger()

Datum timestamp_larger ( PG_FUNCTION_ARGS  )

Definition at line 2812 of file timestamp.c.

2813{
2816 Timestamp result;
2817
2818 if (timestamp_cmp_internal(dt1, dt2) > 0)
2819 result = dt1;
2820 else
2821 result = dt2;
2822 PG_RETURN_TIMESTAMP(result);
2823}

References PG_GETARG_TIMESTAMP, PG_RETURN_TIMESTAMP, and timestamp_cmp_internal().

◆ timestamp_le()

Datum timestamp_le ( PG_FUNCTION_ARGS  )

Definition at line 2252 of file timestamp.c.

2253{
2256
2257 PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) <= 0);
2258}

References PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, and timestamp_cmp_internal().

Referenced by gbt_tsle().

◆ timestamp_le_timestamptz()

Datum timestamp_le_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 2423 of file timestamp.c.

2424{
2425 Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2427
2428 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) <= 0);
2429}

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

◆ timestamp_lt()

Datum timestamp_lt ( PG_FUNCTION_ARGS  )

Definition at line 2234 of file timestamp.c.

2235{
2238
2240}

References PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, and timestamp_cmp_internal().

Referenced by gbt_tslt().

◆ timestamp_lt_timestamptz()

Datum timestamp_lt_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 2405 of file timestamp.c.

2406{
2407 Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2409
2410 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) < 0);
2411}

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

◆ timestamp_mi()

Datum timestamp_mi ( PG_FUNCTION_ARGS  )

Definition at line 2827 of file timestamp.c.

2828{
2831 Interval *result;
2832
2833 result = (Interval *) palloc(sizeof(Interval));
2834
2835 /*
2836 * Handle infinities.
2837 *
2838 * We treat anything that amounts to "infinity - infinity" as an error,
2839 * since the interval type has nothing equivalent to NaN.
2840 */
2842 {
2843 if (TIMESTAMP_IS_NOBEGIN(dt1))
2844 {
2845 if (TIMESTAMP_IS_NOBEGIN(dt2))
2846 ereport(ERROR,
2847 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2848 errmsg("interval out of range")));
2849 else
2850 INTERVAL_NOBEGIN(result);
2851 }
2852 else if (TIMESTAMP_IS_NOEND(dt1))
2853 {
2854 if (TIMESTAMP_IS_NOEND(dt2))
2855 ereport(ERROR,
2856 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2857 errmsg("interval out of range")));
2858 else
2859 INTERVAL_NOEND(result);
2860 }
2861 else if (TIMESTAMP_IS_NOBEGIN(dt2))
2862 INTERVAL_NOEND(result);
2863 else /* TIMESTAMP_IS_NOEND(dt2) */
2864 INTERVAL_NOBEGIN(result);
2865
2866 PG_RETURN_INTERVAL_P(result);
2867 }
2868
2869 if (unlikely(pg_sub_s64_overflow(dt1, dt2, &result->time)))
2870 ereport(ERROR,
2871 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2872 errmsg("interval out of range")));
2873
2874 result->month = 0;
2875 result->day = 0;
2876
2877 /*----------
2878 * This is wrong, but removing it breaks a lot of regression tests.
2879 * For example:
2880 *
2881 * test=> SET timezone = 'EST5EDT';
2882 * test=> SELECT
2883 * test-> ('2005-10-30 13:22:00-05'::timestamptz -
2884 * test(> '2005-10-29 13:22:00-04'::timestamptz);
2885 * ?column?
2886 * ----------------
2887 * 1 day 01:00:00
2888 * (1 row)
2889 *
2890 * so adding that to the first timestamp gets:
2891 *
2892 * test=> SELECT
2893 * test-> ('2005-10-29 13:22:00-04'::timestamptz +
2894 * test(> ('2005-10-30 13:22:00-05'::timestamptz -
2895 * test(> '2005-10-29 13:22:00-04'::timestamptz)) at time zone 'EST';
2896 * timezone
2897 * --------------------
2898 * 2005-10-30 14:22:00
2899 * (1 row)
2900 *----------
2901 */
2903 IntervalPGetDatum(result)));
2904
2905 PG_RETURN_INTERVAL_P(result);
2906}
Datum interval_justify_hours(PG_FUNCTION_ARGS)
Definition: timestamp.c:3001

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

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

◆ timestamp_mi_interval()

◆ timestamp_ne()

Datum timestamp_ne ( PG_FUNCTION_ARGS  )

Definition at line 2225 of file timestamp.c.

2226{
2229
2230 PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) != 0);
2231}

References PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, and timestamp_cmp_internal().

◆ timestamp_ne_timestamptz()

Datum timestamp_ne_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 2396 of file timestamp.c.

2397{
2398 Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2400
2401 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) != 0);
2402}

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

◆ timestamp_out()

Datum timestamp_out ( PG_FUNCTION_ARGS  )

Definition at line 234 of file timestamp.c.

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

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

Referenced by ExecGetJsonValueItemString().

◆ timestamp_part()

Datum timestamp_part ( PG_FUNCTION_ARGS  )

Definition at line 5739 of file timestamp.c.

5740{
5741 return timestamp_part_common(fcinfo, false);
5742}

References timestamp_part_common().

◆ timestamp_part_common()

static Datum timestamp_part_common ( PG_FUNCTION_ARGS  ,
bool  retnumeric 
)
static

Definition at line 5481 of file timestamp.c.

5482{
5483 text *units = PG_GETARG_TEXT_PP(0);
5485 int64 intresult;
5487 int type,
5488 val;
5489 char *lowunits;
5490 fsec_t fsec;
5491 struct pg_tm tt,
5492 *tm = &tt;
5493
5494 lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
5495 VARSIZE_ANY_EXHDR(units),
5496 false);
5497
5498 type = DecodeUnits(0, lowunits, &val);
5499 if (type == UNKNOWN_FIELD)
5500 type = DecodeSpecial(0, lowunits, &val);
5501
5503 {
5504 double r = NonFiniteTimestampTzPart(type, val, lowunits,
5506 false);
5507
5508 if (r != 0.0)
5509 {
5510 if (retnumeric)
5511 {
5512 if (r < 0)
5514 CStringGetDatum("-Infinity"),
5516 Int32GetDatum(-1));
5517 else if (r > 0)
5519 CStringGetDatum("Infinity"),
5521 Int32GetDatum(-1));
5522 }
5523 else
5525 }
5526 else
5528 }
5529
5530 if (type == UNITS)
5531 {
5532 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
5533 ereport(ERROR,
5534 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
5535 errmsg("timestamp out of range")));
5536
5537 switch (val)
5538 {
5539 case DTK_MICROSEC:
5540 intresult = tm->tm_sec * INT64CONST(1000000) + fsec;
5541 break;
5542
5543 case DTK_MILLISEC:
5544 if (retnumeric)
5545 /*---
5546 * tm->tm_sec * 1000 + fsec / 1000
5547 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
5548 */
5550 else
5551 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0);
5552 break;
5553
5554 case DTK_SECOND:
5555 if (retnumeric)
5556 /*---
5557 * tm->tm_sec + fsec / 1'000'000
5558 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
5559 */
5561 else
5562 PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0);
5563 break;
5564
5565 case DTK_MINUTE:
5566 intresult = tm->tm_min;
5567 break;
5568
5569 case DTK_HOUR:
5570 intresult = tm->tm_hour;
5571 break;
5572
5573 case DTK_DAY:
5574 intresult = tm->tm_mday;
5575 break;
5576
5577 case DTK_MONTH:
5578 intresult = tm->tm_mon;
5579 break;
5580
5581 case DTK_QUARTER:
5582 intresult = (tm->tm_mon - 1) / 3 + 1;
5583 break;
5584
5585 case DTK_WEEK:
5586 intresult = date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday);
5587 break;
5588
5589 case DTK_YEAR:
5590 if (tm->tm_year > 0)
5591 intresult = tm->tm_year;
5592 else
5593 /* there is no year 0, just 1 BC and 1 AD */
5594 intresult = tm->tm_year - 1;
5595 break;
5596
5597 case DTK_DECADE:
5598
5599 /*
5600 * what is a decade wrt dates? let us assume that decade 199
5601 * is 1990 thru 1999... decade 0 starts on year 1 BC, and -1
5602 * is 11 BC thru 2 BC...
5603 */
5604 if (tm->tm_year >= 0)
5605 intresult = tm->tm_year / 10;
5606 else
5607 intresult = -((8 - (tm->tm_year - 1)) / 10);
5608 break;
5609
5610 case DTK_CENTURY:
5611
5612 /* ----
5613 * centuries AD, c>0: year in [ (c-1)* 100 + 1 : c*100 ]
5614 * centuries BC, c<0: year in [ c*100 : (c+1) * 100 - 1]
5615 * there is no number 0 century.
5616 * ----
5617 */
5618 if (tm->tm_year > 0)
5619 intresult = (tm->tm_year + 99) / 100;
5620 else
5621 /* caution: C division may have negative remainder */
5622 intresult = -((99 - (tm->tm_year - 1)) / 100);
5623 break;
5624
5625 case DTK_MILLENNIUM:
5626 /* see comments above. */
5627 if (tm->tm_year > 0)
5628 intresult = (tm->tm_year + 999) / 1000;
5629 else
5630 intresult = -((999 - (tm->tm_year - 1)) / 1000);
5631 break;
5632
5633 case DTK_JULIAN:
5634 if (retnumeric)
5638 NULL),
5639 NULL));
5640 else
5643 tm->tm_sec + (fsec / 1000000.0)) / (double) SECS_PER_DAY);
5644 break;
5645
5646 case DTK_ISOYEAR:
5647 intresult = date2isoyear(tm->tm_year, tm->tm_mon, tm->tm_mday);
5648 /* Adjust BC years */
5649 if (intresult <= 0)
5650 intresult -= 1;
5651 break;
5652
5653 case DTK_DOW:
5654 case DTK_ISODOW:
5655 intresult = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday));
5656 if (val == DTK_ISODOW && intresult == 0)
5657 intresult = 7;
5658 break;
5659
5660 case DTK_DOY:
5661 intresult = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)
5662 - date2j(tm->tm_year, 1, 1) + 1);
5663 break;
5664
5665 case DTK_TZ:
5666 case DTK_TZ_MINUTE:
5667 case DTK_TZ_HOUR:
5668 default:
5669 ereport(ERROR,
5670 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5671 errmsg("unit \"%s\" not supported for type %s",
5672 lowunits, format_type_be(TIMESTAMPOID))));
5673 intresult = 0;
5674 }
5675 }
5676 else if (type == RESERV)
5677 {
5678 switch (val)
5679 {
5680 case DTK_EPOCH:
5682 /* (timestamp - epoch) / 1000000 */
5683 if (retnumeric)
5684 {
5685 Numeric result;
5686
5687 if (timestamp < (PG_INT64_MAX + epoch))
5689 else
5690 {
5693 NULL),
5694 int64_to_numeric(1000000),
5695 NULL);
5697 NumericGetDatum(result),
5698 Int32GetDatum(6)));
5699 }
5700 PG_RETURN_NUMERIC(result);
5701 }
5702 else
5703 {
5704 float8 result;
5705
5706 /* try to avoid precision loss in subtraction */
5707 if (timestamp < (PG_INT64_MAX + epoch))
5708 result = (timestamp - epoch) / 1000000.0;
5709 else
5710 result = ((float8) timestamp - epoch) / 1000000.0;
5711 PG_RETURN_FLOAT8(result);
5712 }
5713 break;
5714
5715 default:
5716 ereport(ERROR,
5717 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5718 errmsg("unit \"%s\" not supported for type %s",
5719 lowunits, format_type_be(TIMESTAMPOID))));
5720 intresult = 0;
5721 }
5722 }
5723 else
5724 {
5725 ereport(ERROR,
5726 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5727 errmsg("unit \"%s\" not recognized for type %s",
5728 lowunits, format_type_be(TIMESTAMPOID))));
5729 intresult = 0;
5730 }
5731
5732 if (retnumeric)
5734 else
5735 PG_RETURN_FLOAT8(intresult);
5736}
Datum numeric_round(PG_FUNCTION_ARGS)
Definition: numeric.c:1526
Numeric numeric_div_safe(Numeric num1, Numeric num2, Node *escontext)
Definition: numeric.c:3153
Numeric numeric_sub_safe(Numeric num1, Numeric num2, Node *escontext)
Definition: numeric.c:2958
static float8 NonFiniteTimestampTzPart(int type, int unit, char *lowunits, bool isNegative, bool isTz)
Definition: timestamp.c:5424
int date2isoweek(int year, int mon, int mday)
Definition: timestamp.c:5295
static Numeric DatumGetNumeric(Datum X)
Definition: numeric.h:64
static Datum NumericGetDatum(Numeric X)
Definition: numeric.h:76

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

Referenced by extract_timestamp(), and timestamp_part().

◆ timestamp_pl_interval()

Datum timestamp_pl_interval ( PG_FUNCTION_ARGS  )

Definition at line 3090 of file timestamp.c.

3091{
3093 Interval *span = PG_GETARG_INTERVAL_P(1);
3094 Timestamp result;
3095
3096 /*
3097 * Handle infinities.
3098 *
3099 * We treat anything that amounts to "infinity - infinity" as an error,
3100 * since the timestamp type has nothing equivalent to NaN.
3101 */
3102 if (INTERVAL_IS_NOBEGIN(span))
3103 {
3105 ereport(ERROR,
3106 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3107 errmsg("timestamp out of range")));
3108 else
3109 TIMESTAMP_NOBEGIN(result);
3110 }
3111 else if (INTERVAL_IS_NOEND(span))
3112 {
3114 ereport(ERROR,
3115 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3116 errmsg("timestamp out of range")));
3117 else
3118 TIMESTAMP_NOEND(result);
3119 }
3121 result = timestamp;
3122 else
3123 {
3124 if (span->month != 0)
3125 {
3126 struct pg_tm tt,
3127 *tm = &tt;
3128 fsec_t fsec;
3129
3130 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
3131 ereport(ERROR,
3132 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3133 errmsg("timestamp out of range")));
3134
3135 if (pg_add_s32_overflow(tm->tm_mon, span->month, &tm->tm_mon))
3136 ereport(ERROR,
3137 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3138 errmsg("timestamp out of range")));
3139 if (tm->tm_mon > MONTHS_PER_YEAR)
3140 {
3141 tm->tm_year += (tm->tm_mon - 1) / MONTHS_PER_YEAR;
3142 tm->tm_mon = ((tm->tm_mon - 1) % MONTHS_PER_YEAR) + 1;
3143 }
3144 else if (tm->tm_mon < 1)
3145 {
3146 tm->tm_year += tm->tm_mon / MONTHS_PER_YEAR - 1;
3148 }
3149
3150 /* adjust for end of month boundary problems... */
3151 if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
3152 tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]);
3153
3154 if (tm2timestamp(tm, fsec, NULL, &timestamp) != 0)
3155 ereport(ERROR,
3156 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3157 errmsg("timestamp out of range")));
3158 }
3159
3160 if (span->day != 0)
3161 {
3162 struct pg_tm tt,
3163 *tm = &tt;
3164 fsec_t fsec;
3165 int julian;
3166
3167 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
3168 ereport(ERROR,
3169 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3170 errmsg("timestamp out of range")));
3171
3172 /*
3173 * Add days by converting to and from Julian. We need an overflow
3174 * check here since j2date expects a non-negative integer input.
3175 */
3176 julian = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday);
3177 if (pg_add_s32_overflow(julian, span->day, &julian) ||
3178 julian < 0)
3179 ereport(ERROR,
3180 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3181 errmsg("timestamp out of range")));
3182 j2date(julian, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
3183
3184 if (tm2timestamp(tm, fsec, NULL, &timestamp) != 0)
3185 ereport(ERROR,
3186 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3187 errmsg("timestamp out of range")));
3188 }
3189
3191 ereport(ERROR,
3192 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3193 errmsg("timestamp out of range")));
3194
3196 ereport(ERROR,
3197 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3198 errmsg("timestamp out of range")));
3199
3200 result = timestamp;
3201 }
3202
3203 PG_RETURN_TIMESTAMP(result);
3204}

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

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

◆ timestamp_recv()

Datum timestamp_recv ( PG_FUNCTION_ARGS  )

Definition at line 260 of file timestamp.c.

261{
263
264#ifdef NOT_USED
265 Oid typelem = PG_GETARG_OID(1);
266#endif
267 int32 typmod = PG_GETARG_INT32(2);
269 struct pg_tm tt,
270 *tm = &tt;
271 fsec_t fsec;
272
274
275 /* range check: see if timestamp_out would like it */
277 /* ok */ ;
278 else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0 ||
281 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
282 errmsg("timestamp out of range")));
283
284 AdjustTimestampForTypmod(&timestamp, typmod, NULL);
285
287}

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

◆ timestamp_scale()

Datum timestamp_scale ( PG_FUNCTION_ARGS  )

Definition at line 347 of file timestamp.c.

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

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

◆ timestamp_send()

◆ timestamp_skipsupport()

Datum timestamp_skipsupport ( PG_FUNCTION_ARGS  )

Definition at line 2322 of file timestamp.c.

2323{
2325
2330
2332}
static Datum timestamp_increment(Relation rel, Datum existing, bool *overflow)
Definition: timestamp.c:2306
static Datum timestamp_decrement(Relation rel, Datum existing, bool *underflow)
Definition: timestamp.c:2289
#define PG_RETURN_VOID()
Definition: fmgr.h:349
struct SkipSupportData * SkipSupport
Definition: skipsupport.h:50
SkipSupportIncDec decrement
Definition: skipsupport.h:91
SkipSupportIncDec increment
Definition: skipsupport.h:92

References SkipSupportData::decrement, SkipSupportData::high_elem, SkipSupportData::increment, SkipSupportData::low_elem, PG_GETARG_POINTER, PG_INT64_MAX, PG_INT64_MIN, PG_RETURN_VOID, timestamp_decrement(), timestamp_increment(), and TimestampGetDatum().

◆ timestamp_smaller()

Datum timestamp_smaller ( PG_FUNCTION_ARGS  )

Definition at line 2797 of file timestamp.c.

2798{
2801 Timestamp result;
2802
2803 /* use timestamp_cmp_internal to be sure this agrees with comparisons */
2804 if (timestamp_cmp_internal(dt1, dt2) < 0)
2805 result = dt1;
2806 else
2807 result = dt2;
2808 PG_RETURN_TIMESTAMP(result);
2809}

References PG_GETARG_TIMESTAMP, PG_RETURN_TIMESTAMP, and timestamp_cmp_internal().

◆ timestamp_sortsupport()

Datum timestamp_sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 2279 of file timestamp.c.

2280{
2282
2285}
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
int(* comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:106
int ssup_datum_signed_cmp(Datum x, Datum y, SortSupport ssup)
Definition: tuplesort.c:3144

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

◆ timestamp_support()

Datum timestamp_support ( PG_FUNCTION_ARGS  )

Definition at line 327 of file timestamp.c.

328{
329 Node *rawreq = (Node *) PG_GETARG_POINTER(0);
330 Node *ret = NULL;
331
332 if (IsA(rawreq, SupportRequestSimplify))
333 {
335
337 }
338
340}
Node * TemporalSimplify(int32 max_precis, Node *node)
Definition: datetime.c:4962

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

◆ timestamp_timestamptz()

◆ timestamp_trunc()

Datum timestamp_trunc ( PG_FUNCTION_ARGS  )

Definition at line 4659 of file timestamp.c.

4660{
4661 text *units = PG_GETARG_TEXT_PP(0);
4663 Timestamp result;
4664 int type,
4665 val;
4666 char *lowunits;
4667 fsec_t fsec;
4668 struct pg_tm tt,
4669 *tm = &tt;
4670
4671 lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
4672 VARSIZE_ANY_EXHDR(units),
4673 false);
4674
4675 type = DecodeUnits(0, lowunits, &val);
4676
4677 if (type == UNITS)
4678 {
4680 {
4681 /*
4682 * Errors thrown here for invalid units should exactly match those
4683 * below, else there will be unexpected discrepancies between
4684 * finite- and infinite-input cases.
4685 */
4686 switch (val)
4687 {
4688 case DTK_WEEK:
4689 case DTK_MILLENNIUM:
4690 case DTK_CENTURY:
4691 case DTK_DECADE:
4692 case DTK_YEAR:
4693 case DTK_QUARTER:
4694 case DTK_MONTH:
4695 case DTK_DAY:
4696 case DTK_HOUR:
4697 case DTK_MINUTE:
4698 case DTK_SECOND:
4699 case DTK_MILLISEC:
4700 case DTK_MICROSEC:
4702 break;
4703 default:
4704 ereport(ERROR,
4705 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4706 errmsg("unit \"%s\" not supported for type %s",
4707 lowunits, format_type_be(TIMESTAMPOID))));
4708 result = 0;
4709 }
4710 }
4711
4712 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
4713 ereport(ERROR,
4714 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4715 errmsg("timestamp out of range")));
4716
4717 switch (val)
4718 {
4719 case DTK_WEEK:
4720 {
4721 int woy;
4722
4724
4725 /*
4726 * If it is week 52/53 and the month is January, then the
4727 * week must belong to the previous year. Also, some
4728 * December dates belong to the next year.
4729 */
4730 if (woy >= 52 && tm->tm_mon == 1)
4731 --tm->tm_year;
4732 if (woy <= 1 && tm->tm_mon == MONTHS_PER_YEAR)
4733 ++tm->tm_year;
4734 isoweek2date(woy, &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
4735 tm->tm_hour = 0;
4736 tm->tm_min = 0;
4737 tm->tm_sec = 0;
4738 fsec = 0;
4739 break;
4740 }
4741 case DTK_MILLENNIUM:
4742 /* see comments in timestamptz_trunc */
4743 if (tm->tm_year > 0)
4744 tm->tm_year = ((tm->tm_year + 999) / 1000) * 1000 - 999;
4745 else
4746 tm->tm_year = -((999 - (tm->tm_year - 1)) / 1000) * 1000 + 1;
4747 /* FALL THRU */
4748 case DTK_CENTURY:
4749 /* see comments in timestamptz_trunc */
4750 if (tm->tm_year > 0)
4751 tm->tm_year = ((tm->tm_year + 99) / 100) * 100 - 99;
4752 else
4753 tm->tm_year = -((99 - (tm->tm_year - 1)) / 100) * 100 + 1;
4754 /* FALL THRU */
4755 case DTK_DECADE:
4756 /* see comments in timestamptz_trunc */
4757 if (val != DTK_MILLENNIUM && val != DTK_CENTURY)
4758 {
4759 if (tm->tm_year > 0)
4760 tm->tm_year = (tm->tm_year / 10) * 10;
4761 else
4762 tm->tm_year = -((8 - (tm->tm_year - 1)) / 10) * 10;
4763 }
4764 /* FALL THRU */
4765 case DTK_YEAR:
4766 tm->tm_mon = 1;
4767 /* FALL THRU */
4768 case DTK_QUARTER:
4769 tm->tm_mon = (3 * ((tm->tm_mon - 1) / 3)) + 1;
4770 /* FALL THRU */
4771 case DTK_MONTH:
4772 tm->tm_mday = 1;
4773 /* FALL THRU */
4774 case DTK_DAY:
4775 tm->tm_hour = 0;
4776 /* FALL THRU */
4777 case DTK_HOUR:
4778 tm->tm_min = 0;
4779 /* FALL THRU */
4780 case DTK_MINUTE:
4781 tm->tm_sec = 0;
4782 /* FALL THRU */
4783 case DTK_SECOND:
4784 fsec = 0;
4785 break;
4786
4787 case DTK_MILLISEC:
4788 fsec = (fsec / 1000) * 1000;
4789 break;
4790
4791 case DTK_MICROSEC:
4792 break;
4793
4794 default:
4795 ereport(ERROR,
4796 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4797 errmsg("unit \"%s\" not supported for type %s",
4798 lowunits, format_type_be(TIMESTAMPOID))));
4799 result = 0;
4800 }
4801
4802 if (tm2timestamp(tm, fsec, NULL, &result) != 0)
4803 ereport(ERROR,
4804 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4805 errmsg("timestamp out of range")));
4806 }
4807 else
4808 {
4809 ereport(ERROR,
4810 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4811 errmsg("unit \"%s\" not recognized for type %s",
4812 lowunits, format_type_be(TIMESTAMPOID))));
4813 result = 0;
4814 }
4815
4816 PG_RETURN_TIMESTAMP(result);
4817}
void isoweek2date(int woy, int *year, int *mon, int *mday)
Definition: timestamp.c:5264

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

◆ timestamp_zone()

Datum timestamp_zone ( PG_FUNCTION_ARGS  )

Definition at line 6308 of file timestamp.c.

6309{
6312 TimestampTz result;
6313 int tz;
6314 char tzname[TZ_STRLEN_MAX + 1];
6315 int type,
6316 val;
6317 pg_tz *tzp;
6318 struct pg_tm tm;
6319 fsec_t fsec;
6320
6323
6324 /*
6325 * Look up the requested timezone.
6326 */
6327 text_to_cstring_buffer(zone, tzname, sizeof(tzname));
6328
6329 type = DecodeTimezoneName(tzname, &val, &tzp);
6330
6332 {
6333 /* fixed-offset abbreviation */
6334 tz = val;
6335 result = dt2local(timestamp, tz);
6336 }
6337 else if (type == TZNAME_DYNTZ)
6338 {
6339 /* dynamic-offset abbreviation, resolve using specified time */
6340 if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, tzp) != 0)
6341 ereport(ERROR,
6342 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6343 errmsg("timestamp out of range")));
6344 tz = -DetermineTimeZoneAbbrevOffset(&tm, tzname, tzp);
6345 result = dt2local(timestamp, tz);
6346 }
6347 else
6348 {
6349 /* full zone name, rotate to that zone */
6350 if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, tzp) != 0)
6351 ereport(ERROR,
6352 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6353 errmsg("timestamp out of range")));
6354 tz = DetermineTimeZoneOffset(&tm, tzp);
6355 if (tm2timestamp(&tm, fsec, &tz, &result) != 0)
6356 ereport(ERROR,
6357 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6358 errmsg("timestamp out of range")));
6359 }
6360
6361 if (!IS_VALID_TIMESTAMP(result))
6362 ereport(ERROR,
6363 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6364 errmsg("timestamp out of range")));
6365
6366 PG_RETURN_TIMESTAMPTZ(result);
6367}

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

◆ TimestampDifference()

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

Definition at line 1721 of file timestamp.c.

1723{
1724 TimestampTz diff = stop_time - start_time;
1725
1726 if (diff <= 0)
1727 {
1728 *secs = 0;
1729 *microsecs = 0;
1730 }
1731 else
1732 {
1733 *secs = (long) (diff / USECS_PER_SEC);
1734 *microsecs = (int) (diff % USECS_PER_SEC);
1735 }
1736}
static time_t start_time
Definition: pg_ctl.c:96

References start_time, and USECS_PER_SEC.

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

◆ TimestampDifferenceExceeds()

◆ TimestampDifferenceExceedsSeconds()

bool TimestampDifferenceExceedsSeconds ( TimestampTz  start_time,
TimestampTz  stop_time,
int  threshold_sec 
)

Definition at line 1795 of file timestamp.c.

1798{
1799 long secs;
1800 int usecs;
1801
1802 /* Calculate the difference in seconds */
1803 TimestampDifference(start_time, stop_time, &secs, &usecs);
1804
1805 return (secs >= threshold_sec);
1806}
void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)
Definition: timestamp.c:1721

References start_time, and TimestampDifference().

Referenced by DetermineSlotInvalidationCause().

◆ TimestampDifferenceMilliseconds()

long TimestampDifferenceMilliseconds ( TimestampTz  start_time,
TimestampTz  stop_time 
)

Definition at line 1757 of file timestamp.c.

1758{
1759 TimestampTz diff;
1760
1761 /* Deal with zero or negative elapsed time quickly. */
1762 if (start_time >= stop_time)
1763 return 0;
1764 /* To not fail with timestamp infinities, we must detect overflow. */
1765 if (pg_sub_s64_overflow(stop_time, start_time, &diff))
1766 return (long) INT_MAX;
1767 if (diff >= (INT_MAX * INT64CONST(1000) - 999))
1768 return (long) INT_MAX;
1769 else
1770 return (long) ((diff + 999) / 1000);
1771}

References INT64CONST, pg_sub_s64_overflow(), and start_time.

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

◆ TimestampTimestampTzRequiresRewrite()

bool TimestampTimestampTzRequiresRewrite ( void  )

Definition at line 6417 of file timestamp.c.

6418{
6419 long offset;
6420
6421 if (pg_get_timezone_offset(session_timezone, &offset) && offset == 0)
6422 return false;
6423 return true;
6424}
bool pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff)
Definition: localtime.c:1966

References pg_get_timezone_offset(), and session_timezone.

Referenced by ATColumnChangeRequiresRewrite().

◆ timestamptypmodin()

Datum timestamptypmodin ( PG_FUNCTION_ARGS  )

Definition at line 304 of file timestamp.c.

305{
307
309}
static int32 anytimestamp_typmodin(bool istz, ArrayType *ta)
Definition: timestamp.c:104

References anytimestamp_typmodin(), PG_GETARG_ARRAYTYPE_P, and PG_RETURN_INT32.

◆ timestamptypmodout()

Datum timestamptypmodout ( PG_FUNCTION_ARGS  )

Definition at line 312 of file timestamp.c.

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

References anytimestamp_typmodout(), PG_GETARG_INT32, and PG_RETURN_CSTRING.

◆ timestamptz2timestamp()

static Timestamp timestamptz2timestamp ( TimestampTz  timestamp)
static

Definition at line 6504 of file timestamp.c.

6505{
6507}
Timestamp timestamptz2timestamp_safe(TimestampTz timestamp, Node *escontext)
Definition: timestamp.c:6520

References timestamptz2timestamp_safe().

Referenced by GetSQLLocalTimestamp(), and timestamptz_timestamp().

◆ timestamptz2timestamp_safe()

Timestamp timestamptz2timestamp_safe ( TimestampTz  timestamp,
Node escontext 
)

Definition at line 6520 of file timestamp.c.

6521{
6522 Timestamp result;
6523 struct pg_tm tt,
6524 *tm = &tt;
6525 fsec_t fsec;
6526 int tz;
6527
6529 result = timestamp;
6530 else
6531 {
6532 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
6533 {
6534 if (timestamp < 0)
6535 TIMESTAMP_NOBEGIN(result);
6536 else
6537 TIMESTAMP_NOEND(result);
6538
6539 ereturn(escontext, result,
6540 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6541 errmsg("timestamp out of range")));
6542 }
6543 if (tm2timestamp(tm, fsec, NULL, &result) != 0)
6544 {
6545 if (timestamp < 0)
6546 TIMESTAMP_NOBEGIN(result);
6547 else
6548 TIMESTAMP_NOEND(result);
6549
6550 ereturn(escontext, result,
6551 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6552 errmsg("timestamp out of range")));
6553 }
6554 }
6555 return result;
6556}

References ereturn, errcode(), errmsg(), timestamp2tm(), TIMESTAMP_NOBEGIN, TIMESTAMP_NOEND, TIMESTAMP_NOT_FINITE, tm, and tm2timestamp().

Referenced by cvt_timestamptz_timestamp(), and timestamptz2timestamp().

◆ timestamptz_age()

Datum timestamptz_age ( PG_FUNCTION_ARGS  )

Definition at line 4434 of file timestamp.c.

4435{
4438 Interval *result;
4439 fsec_t fsec1,
4440 fsec2;
4441 struct pg_itm tt,
4442 *tm = &tt;
4443 struct pg_tm tt1,
4444 *tm1 = &tt1;
4445 struct pg_tm tt2,
4446 *tm2 = &tt2;
4447 int tz1;
4448 int tz2;
4449
4450 result = (Interval *) palloc(sizeof(Interval));
4451
4452 /*
4453 * Handle infinities.
4454 *
4455 * We treat anything that amounts to "infinity - infinity" as an error,
4456 * since the interval type has nothing equivalent to NaN.
4457 */
4458 if (TIMESTAMP_IS_NOBEGIN(dt1))
4459 {
4460 if (TIMESTAMP_IS_NOBEGIN(dt2))
4461 ereport(ERROR,
4462 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4463 errmsg("interval out of range")));
4464 else
4465 INTERVAL_NOBEGIN(result);
4466 }
4467 else if (TIMESTAMP_IS_NOEND(dt1))
4468 {
4469 if (TIMESTAMP_IS_NOEND(dt2))
4470 ereport(ERROR,
4471 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4472 errmsg("interval out of range")));
4473 else
4474 INTERVAL_NOEND(result);
4475 }
4476 else if (TIMESTAMP_IS_NOBEGIN(dt2))
4477 INTERVAL_NOEND(result);
4478 else if (TIMESTAMP_IS_NOEND(dt2))
4479 INTERVAL_NOBEGIN(result);
4480 else if (timestamp2tm(dt1, &tz1, tm1, &fsec1, NULL, NULL) == 0 &&
4481 timestamp2tm(dt2, &tz2, tm2, &fsec2, NULL, NULL) == 0)
4482 {
4483 /* form the symbolic difference */
4484 tm->tm_usec = fsec1 - fsec2;
4485 tm->tm_sec = tm1->tm_sec - tm2->tm_sec;
4486 tm->tm_min = tm1->tm_min - tm2->tm_min;
4487 tm->tm_hour = tm1->tm_hour - tm2->tm_hour;
4488 tm->tm_mday = tm1->tm_mday - tm2->tm_mday;
4489 tm->tm_mon = tm1->tm_mon - tm2->tm_mon;
4490 tm->tm_year = tm1->tm_year - tm2->tm_year;
4491
4492 /* flip sign if necessary... */
4493 if (dt1 < dt2)
4494 {
4495 tm->tm_usec = -tm->tm_usec;
4496 tm->tm_sec = -tm->tm_sec;
4497 tm->tm_min = -tm->tm_min;
4498 tm->tm_hour = -tm->tm_hour;
4499 tm->tm_mday = -tm->tm_mday;
4500 tm->tm_mon = -tm->tm_mon;
4501 tm->tm_year = -tm->tm_year;
4502 }
4503
4504 /* propagate any negative fields into the next higher field */
4505 while (tm->tm_usec < 0)
4506 {
4507 tm->tm_usec += USECS_PER_SEC;
4508 tm->tm_sec--;
4509 }
4510
4511 while (tm->tm_sec < 0)
4512 {
4514 tm->tm_min--;
4515 }
4516
4517 while (tm->tm_min < 0)
4518 {
4520 tm->tm_hour--;
4521 }
4522
4523 while (tm->tm_hour < 0)
4524 {
4526 tm->tm_mday--;
4527 }
4528
4529 while (tm->tm_mday < 0)
4530 {
4531 if (dt1 < dt2)
4532 {
4533 tm->tm_mday += day_tab[isleap(tm1->tm_year)][tm1->tm_mon - 1];
4534 tm->tm_mon--;
4535 }
4536 else
4537 {
4538 tm->tm_mday += day_tab[isleap(tm2->tm_year)][tm2->tm_mon - 1];
4539 tm->tm_mon--;
4540 }
4541 }
4542
4543 while (tm->tm_mon < 0)
4544 {
4546 tm->tm_year--;
4547 }
4548
4549 /*
4550 * Note: we deliberately ignore any difference between tz1 and tz2.
4551 */
4552
4553 /* recover sign if necessary... */
4554 if (dt1 < dt2)
4555 {
4556 tm->tm_usec = -tm->tm_usec;
4557 tm->tm_sec = -tm->tm_sec;
4558 tm->tm_min = -tm->tm_min;
4559 tm->tm_hour = -tm->tm_hour;
4560 tm->tm_mday = -tm->tm_mday;
4561 tm->tm_mon = -tm->tm_mon;
4562 tm->tm_year = -tm->tm_year;
4563 }
4564
4565 if (itm2interval(tm, result) != 0)
4566 ereport(ERROR,
4567 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4568 errmsg("interval out of range")));
4569 }
4570 else
4571 ereport(ERROR,
4572 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4573 errmsg("timestamp out of range")));
4574
4575 PG_RETURN_INTERVAL_P(result);
4576}

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

◆ timestamptz_at_local()

Datum timestamptz_at_local ( PG_FUNCTION_ARGS  )

Definition at line 6946 of file timestamp.c.

6947{
6948 return timestamptz_timestamp(fcinfo);
6949}
Datum timestamptz_timestamp(PG_FUNCTION_ARGS)
Definition: timestamp.c:6493

References timestamptz_timestamp().

◆ timestamptz_bin()

Datum timestamptz_bin ( PG_FUNCTION_ARGS  )

Definition at line 4823 of file timestamp.c.

4824{
4825 Interval *stride = PG_GETARG_INTERVAL_P(0);
4828 TimestampTz result,
4829 stride_usecs,
4830 tm_diff,
4831 tm_modulo,
4832 tm_delta;
4833
4836
4837 if (TIMESTAMP_NOT_FINITE(origin))
4838 ereport(ERROR,
4839 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4840 errmsg("origin out of range")));
4841
4842 if (INTERVAL_NOT_FINITE(stride))
4843 ereport(ERROR,
4844 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4845 errmsg("timestamps cannot be binned into infinite intervals")));
4846
4847 if (stride->month != 0)
4848 ereport(ERROR,
4849 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4850 errmsg("timestamps cannot be binned into intervals containing months or years")));
4851
4852 if (unlikely(pg_mul_s64_overflow(stride->day, USECS_PER_DAY, &stride_usecs)) ||
4853 unlikely(pg_add_s64_overflow(stride_usecs, stride->time, &stride_usecs)))
4854 ereport(ERROR,
4855 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4856 errmsg("interval out of range")));
4857
4858 if (stride_usecs <= 0)
4859 ereport(ERROR,
4860 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4861 errmsg("stride must be greater than zero")));
4862
4863 if (unlikely(pg_sub_s64_overflow(timestamp, origin, &tm_diff)))
4864 ereport(ERROR,
4865 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4866 errmsg("interval out of range")));
4867
4868 /* These calculations cannot overflow */
4869 tm_modulo = tm_diff % stride_usecs;
4870 tm_delta = tm_diff - tm_modulo;
4871 result = origin + tm_delta;
4872
4873 /*
4874 * We want to round towards -infinity, not 0, when tm_diff is negative and
4875 * not a multiple of stride_usecs. This adjustment *can* cause overflow,
4876 * since the result might now be out of the range origin .. timestamp.
4877 */
4878 if (tm_modulo < 0)
4879 {
4880 if (unlikely(pg_sub_s64_overflow(result, stride_usecs, &result)) ||
4881 !IS_VALID_TIMESTAMP(result))
4882 ereport(ERROR,
4883 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4884 errmsg("timestamp out of range")));
4885 }
4886
4887 PG_RETURN_TIMESTAMPTZ(result);
4888}

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

◆ timestamptz_cmp_timestamp()

Datum timestamptz_cmp_timestamp ( PG_FUNCTION_ARGS  )

◆ timestamptz_eq_timestamp()

Datum timestamptz_eq_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2450 of file timestamp.c.

2451{
2453 Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
2454
2455 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) == 0);
2456}

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

◆ timestamptz_ge_timestamp()

Datum timestamptz_ge_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2495 of file timestamp.c.

2496{
2498 Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
2499
2500 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) <= 0);
2501}

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

◆ timestamptz_gt_timestamp()

Datum timestamptz_gt_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2477 of file timestamp.c.

2478{
2480 Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
2481
2482 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) < 0);
2483}

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

◆ timestamptz_hash()

Datum timestamptz_hash ( PG_FUNCTION_ARGS  )

Definition at line 2347 of file timestamp.c.

2348{
2349 return hashint8(fcinfo);
2350}

References hashint8().

◆ timestamptz_hash_extended()

Datum timestamptz_hash_extended ( PG_FUNCTION_ARGS  )

Definition at line 2353 of file timestamp.c.

2354{
2355 return hashint8extended(fcinfo);
2356}

References hashint8extended().

◆ timestamptz_in()

Datum timestamptz_in ( PG_FUNCTION_ARGS  )

Definition at line 418 of file timestamp.c.

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

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

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

◆ timestamptz_izone()

Datum timestamptz_izone ( PG_FUNCTION_ARGS  )

Definition at line 6627 of file timestamp.c.

6628{
6631 Timestamp result;
6632 int tz;
6633
6636
6638 ereport(ERROR,
6639 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6640 errmsg("interval time zone \"%s\" must be finite",
6642 PointerGetDatum(zone))))));
6643
6644 if (zone->month != 0 || zone->day != 0)
6645 ereport(ERROR,
6646 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6647 errmsg("interval time zone \"%s\" must not include months or days",
6649 PointerGetDatum(zone))))));
6650
6651 tz = -(zone->time / USECS_PER_SEC);
6652
6653 result = dt2local(timestamp, tz);
6654
6655 if (!IS_VALID_TIMESTAMP(result))
6656 ereport(ERROR,
6657 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6658 errmsg("timestamp out of range")));
6659
6660 PG_RETURN_TIMESTAMP(result);
6661}

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

◆ timestamptz_le_timestamp()

Datum timestamptz_le_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2486 of file timestamp.c.

2487{
2489 Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
2490
2491 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) >= 0);
2492}

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

◆ timestamptz_lt_timestamp()

Datum timestamptz_lt_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2468 of file timestamp.c.

2469{
2471 Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
2472
2473 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) > 0);
2474}

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

◆ timestamptz_mi_interval()

◆ timestamptz_mi_interval_at_zone()

◆ timestamptz_mi_interval_internal()

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

Definition at line 3365 of file timestamp.c.

3368{
3369 Interval tspan;
3370
3371 interval_um_internal(span, &tspan);
3372
3373 return timestamptz_pl_interval_internal(timestamp, &tspan, attimezone);
3374}

References interval_um_internal(), and timestamptz_pl_interval_internal().

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

◆ timestamptz_ne_timestamp()

Datum timestamptz_ne_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2459 of file timestamp.c.

2460{
2462 Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
2463
2464 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) != 0);
2465}

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

◆ timestamptz_out()

Datum timestamptz_out ( PG_FUNCTION_ARGS  )

Definition at line 776 of file timestamp.c.

777{
779 char *result;
780 int tz;
781 struct pg_tm tt,
782 *tm = &tt;
783 fsec_t fsec;
784 const char *tzn;
785 char buf[MAXDATELEN + 1];
786
787 if (TIMESTAMP_NOT_FINITE(dt))
789 else if (timestamp2tm(dt, &tz, tm, &fsec, &tzn, NULL) == 0)
790 EncodeDateTime(tm, fsec, true, tz, tzn, DateStyle, buf);
791 else
793 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
794 errmsg("timestamp out of range")));
795
796 result = pstrdup(buf);
797 PG_RETURN_CSTRING(result);
798}

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

Referenced by ExecGetJsonValueItemString().

◆ timestamptz_part()

Datum timestamptz_part ( PG_FUNCTION_ARGS  )

Definition at line 6011 of file timestamp.c.

6012{
6013 return timestamptz_part_common(fcinfo, false);
6014}

References timestamptz_part_common().

◆ timestamptz_part_common()

static Datum timestamptz_part_common ( PG_FUNCTION_ARGS  ,
bool  retnumeric 
)
static

Definition at line 5754 of file timestamp.c.

5755{
5756 text *units = PG_GETARG_TEXT_PP(0);
5758 int64 intresult;
5760 int tz;
5761 int type,
5762 val;
5763 char *lowunits;
5764 fsec_t fsec;
5765 struct pg_tm tt,
5766 *tm = &tt;
5767
5768 lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
5769 VARSIZE_ANY_EXHDR(units),
5770 false);
5771
5772 type = DecodeUnits(0, lowunits, &val);
5773 if (type == UNKNOWN_FIELD)
5774 type = DecodeSpecial(0, lowunits, &val);
5775
5777 {
5778 double r = NonFiniteTimestampTzPart(type, val, lowunits,
5780 true);
5781
5782 if (r != 0.0)
5783 {
5784 if (retnumeric)
5785 {
5786 if (r < 0)
5788 CStringGetDatum("-Infinity"),
5790 Int32GetDatum(-1));
5791 else if (r > 0)
5793 CStringGetDatum("Infinity"),
5795 Int32GetDatum(-1));
5796 }
5797 else
5799 }
5800 else
5802 }
5803
5804 if (type == UNITS)
5805 {
5806 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
5807 ereport(ERROR,
5808 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
5809 errmsg("timestamp out of range")));
5810
5811 switch (val)
5812 {
5813 case DTK_TZ:
5814 intresult = -tz;
5815 break;
5816
5817 case DTK_TZ_MINUTE:
5818 intresult = (-tz / SECS_PER_MINUTE) % MINS_PER_HOUR;
5819 break;
5820
5821 case DTK_TZ_HOUR:
5822 intresult = -tz / SECS_PER_HOUR;
5823 break;
5824
5825 case DTK_MICROSEC:
5826 intresult = tm->tm_sec * INT64CONST(1000000) + fsec;
5827 break;
5828
5829 case DTK_MILLISEC:
5830 if (retnumeric)
5831 /*---
5832 * tm->tm_sec * 1000 + fsec / 1000
5833 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
5834 */
5836 else
5837 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0);
5838 break;
5839
5840 case DTK_SECOND:
5841 if (retnumeric)
5842 /*---
5843 * tm->tm_sec + fsec / 1'000'000
5844 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
5845 */
5847 else
5848 PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0);
5849 break;
5850
5851 case DTK_MINUTE:
5852 intresult = tm->tm_min;
5853 break;
5854
5855 case DTK_HOUR:
5856 intresult = tm->tm_hour;
5857 break;
5858
5859 case DTK_DAY:
5860 intresult = tm->tm_mday;
5861 break;
5862
5863 case DTK_MONTH:
5864 intresult = tm->tm_mon;
5865 break;
5866
5867 case DTK_QUARTER:
5868 intresult = (tm->tm_mon - 1) / 3 + 1;
5869 break;
5870
5871 case DTK_WEEK:
5872 intresult = date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday);
5873 break;
5874
5875 case DTK_YEAR:
5876 if (tm->tm_year > 0)
5877 intresult = tm->tm_year;
5878 else
5879 /* there is no year 0, just 1 BC and 1 AD */
5880 intresult = tm->tm_year - 1;
5881 break;
5882
5883 case DTK_DECADE:
5884 /* see comments in timestamp_part */
5885 if (tm->tm_year > 0)
5886 intresult = tm->tm_year / 10;
5887 else
5888 intresult = -((8 - (tm->tm_year - 1)) / 10);
5889 break;
5890
5891 case DTK_CENTURY:
5892 /* see comments in timestamp_part */
5893 if (tm->tm_year > 0)
5894 intresult = (tm->tm_year + 99) / 100;
5895 else
5896 intresult = -((99 - (tm->tm_year - 1)) / 100);
5897 break;
5898
5899 case DTK_MILLENNIUM:
5900 /* see comments in timestamp_part */
5901 if (tm->tm_year > 0)
5902 intresult = (tm->tm_year + 999) / 1000;
5903 else
5904 intresult = -((999 - (tm->tm_year - 1)) / 1000);
5905 break;
5906
5907 case DTK_JULIAN:
5908 if (retnumeric)
5912 NULL),
5913 NULL));
5914 else
5917 tm->tm_sec + (fsec / 1000000.0)) / (double) SECS_PER_DAY);
5918 break;
5919
5920 case DTK_ISOYEAR:
5921 intresult = date2isoyear(tm->tm_year, tm->tm_mon, tm->tm_mday);
5922 /* Adjust BC years */
5923 if (intresult <= 0)
5924 intresult -= 1;
5925 break;
5926
5927 case DTK_DOW:
5928 case DTK_ISODOW:
5929 intresult = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday));
5930 if (val == DTK_ISODOW && intresult == 0)
5931 intresult = 7;
5932 break;
5933
5934 case DTK_DOY:
5935 intresult = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)
5936 - date2j(tm->tm_year, 1, 1) + 1);
5937 break;
5938
5939 default:
5940 ereport(ERROR,
5941 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5942 errmsg("unit \"%s\" not supported for type %s",
5943 lowunits, format_type_be(TIMESTAMPTZOID))));
5944 intresult = 0;
5945 }
5946 }
5947 else if (type == RESERV)
5948 {
5949 switch (val)
5950 {
5951 case DTK_EPOCH:
5953 /* (timestamp - epoch) / 1000000 */
5954 if (retnumeric)
5955 {
5956 Numeric result;
5957
5958 if (timestamp < (PG_INT64_MAX + epoch))
5960 else
5961 {
5964 NULL),
5965 int64_to_numeric(1000000),
5966 NULL);
5968 NumericGetDatum(result),
5969 Int32GetDatum(6)));
5970 }
5971 PG_RETURN_NUMERIC(result);
5972 }
5973 else
5974 {
5975 float8 result;
5976
5977 /* try to avoid precision loss in subtraction */
5978 if (timestamp < (PG_INT64_MAX + epoch))
5979 result = (timestamp - epoch) / 1000000.0;
5980 else
5981 result = ((float8) timestamp - epoch) / 1000000.0;
5982 PG_RETURN_FLOAT8(result);
5983 }
5984 break;
5985
5986 default:
5987 ereport(ERROR,
5988 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5989 errmsg("unit \"%s\" not supported for type %s",
5990 lowunits, format_type_be(TIMESTAMPTZOID))));
5991 intresult = 0;
5992 }
5993 }
5994 else
5995 {
5996 ereport(ERROR,
5997 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5998 errmsg("unit \"%s\" not recognized for type %s",
5999 lowunits, format_type_be(TIMESTAMPTZOID))));
6000
6001 intresult = 0;
6002 }
6003
6004 if (retnumeric)
6006 else
6007 PG_RETURN_FLOAT8(intresult);
6008}
#define SECS_PER_HOUR
Definition: timestamp.h:127

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

Referenced by extract_timestamptz(), and timestamptz_part().

◆ timestamptz_pl_interval()

◆ timestamptz_pl_interval_at_zone()

◆ timestamptz_pl_interval_internal()

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

Definition at line 3233 of file timestamp.c.

3236{
3237 TimestampTz result;
3238 int tz;
3239
3240 /*
3241 * Handle infinities.
3242 *
3243 * We treat anything that amounts to "infinity - infinity" as an error,
3244 * since the timestamptz type has nothing equivalent to NaN.
3245 */
3246 if (INTERVAL_IS_NOBEGIN(span))
3247 {
3249 ereport(ERROR,
3250 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3251 errmsg("timestamp out of range")));
3252 else
3253 TIMESTAMP_NOBEGIN(result);
3254 }
3255 else if (INTERVAL_IS_NOEND(span))
3256 {
3258 ereport(ERROR,
3259 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3260 errmsg("timestamp out of range")));
3261 else
3262 TIMESTAMP_NOEND(result);
3263 }
3265 result = timestamp;
3266 else
3267 {
3268 /* Use session timezone if caller asks for default */
3269 if (attimezone == NULL)
3270 attimezone = session_timezone;
3271
3272 if (span->month != 0)
3273 {
3274 struct pg_tm tt,
3275 *tm = &tt;
3276 fsec_t fsec;
3277
3278 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, attimezone) != 0)
3279 ereport(ERROR,
3280 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3281 errmsg("timestamp out of range")));
3282
3283 if (pg_add_s32_overflow(tm->tm_mon, span->month, &tm->tm_mon))
3284 ereport(ERROR,
3285 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3286 errmsg("timestamp out of range")));
3287 if (tm->tm_mon > MONTHS_PER_YEAR)
3288 {
3289 tm->tm_year += (tm->tm_mon - 1) / MONTHS_PER_YEAR;
3290 tm->tm_mon = ((tm->tm_mon - 1) % MONTHS_PER_YEAR) + 1;
3291 }
3292 else if (tm->tm_mon < 1)
3293 {
3294 tm->tm_year += tm->tm_mon / MONTHS_PER_YEAR - 1;
3296 }
3297
3298 /* adjust for end of month boundary problems... */
3299 if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
3300 tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]);
3301
3302 tz = DetermineTimeZoneOffset(tm, attimezone);
3303
3304 if (tm2timestamp(tm, fsec, &tz, &timestamp) != 0)
3305 ereport(ERROR,
3306 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3307 errmsg("timestamp out of range")));
3308 }
3309
3310 if (span->day != 0)
3311 {
3312 struct pg_tm tt,
3313 *tm = &tt;
3314 fsec_t fsec;
3315 int julian;
3316
3317 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, attimezone) != 0)
3318 ereport(ERROR,
3319 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3320 errmsg("timestamp out of range")));
3321
3322 /*
3323 * Add days by converting to and from Julian. We need an overflow
3324 * check here since j2date expects a non-negative integer input.
3325 * In practice though, it will give correct answers for small
3326 * negative Julian dates; we should allow -1 to avoid
3327 * timezone-dependent failures, as discussed in timestamp.h.
3328 */
3329 julian = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday);
3330 if (pg_add_s32_overflow(julian, span->day, &julian) ||
3331 julian < -1)
3332 ereport(ERROR,
3333 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3334 errmsg("timestamp out of range")));
3335 j2date(julian, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
3336
3337 tz = DetermineTimeZoneOffset(tm, attimezone);
3338
3339 if (tm2timestamp(tm, fsec, &tz, &timestamp) != 0)
3340 ereport(ERROR,
3341 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3342 errmsg("timestamp out of range")));
3343 }
3344
3346 ereport(ERROR,
3347 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3348 errmsg("timestamp out of range")));
3349
3351 ereport(ERROR,
3352 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3353 errmsg("timestamp out of range")));
3354
3355 result = timestamp;
3356 }
3357
3358 return result;
3359}

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

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

◆ timestamptz_recv()

Datum timestamptz_recv ( PG_FUNCTION_ARGS  )

Definition at line 804 of file timestamp.c.

805{
807
808#ifdef NOT_USED
809 Oid typelem = PG_GETARG_OID(1);
810#endif
811 int32 typmod = PG_GETARG_INT32(2);
813 int tz;
814 struct pg_tm tt,
815 *tm = &tt;
816 fsec_t fsec;
817
819
820 /* range check: see if timestamptz_out would like it */
822 /* ok */ ;
823 else if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0 ||
826 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
827 errmsg("timestamp out of range")));
828
829 AdjustTimestampForTypmod(&timestamp, typmod, NULL);
830
832}

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

◆ timestamptz_scale()

Datum timestamptz_scale ( PG_FUNCTION_ARGS  )

Definition at line 870 of file timestamp.c.

871{
873 int32 typmod = PG_GETARG_INT32(1);
874 TimestampTz result;
875
876 result = timestamp;
877
878 AdjustTimestampForTypmod(&result, typmod, NULL);
879
880 PG_RETURN_TIMESTAMPTZ(result);
881}

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

◆ timestamptz_send()

◆ timestamptz_timestamp()

◆ timestamptz_to_str()

const char * timestamptz_to_str ( TimestampTz  t)

Definition at line 1862 of file timestamp.c.

1863{
1864 static char buf[MAXDATELEN + 1];
1865 int tz;
1866 struct pg_tm tt,
1867 *tm = &tt;
1868 fsec_t fsec;
1869 const char *tzn;
1870
1871 if (TIMESTAMP_NOT_FINITE(t))
1873 else if (timestamp2tm(t, &tz, tm, &fsec, &tzn, NULL) == 0)
1874 EncodeDateTime(tm, fsec, true, tz, tzn, USE_ISO_DATES, buf);
1875 else
1876 strlcpy(buf, "(timestamp out of range)", sizeof(buf));
1877
1878 return buf;
1879}
#define USE_ISO_DATES
Definition: miscadmin.h:237
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45

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

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

◆ timestamptz_to_time_t()

pg_time_t timestamptz_to_time_t ( TimestampTz  t)

Definition at line 1842 of file timestamp.c.

1843{
1844 pg_time_t result;
1845
1846 result = (pg_time_t) (t / USECS_PER_SEC +
1848
1849 return result;
1850}

References POSTGRES_EPOCH_JDATE, SECS_PER_DAY, UNIX_EPOCH_JDATE, and USECS_PER_SEC.

Referenced by DetermineTimeZoneAbbrevOffsetTS(), InitProcessGlobals(), and pg_timezone_abbrevs_zone().

◆ timestamptz_trunc()

Datum timestamptz_trunc ( PG_FUNCTION_ARGS  )

Definition at line 5075 of file timestamp.c.

5076{
5077 text *units = PG_GETARG_TEXT_PP(0);
5079 TimestampTz result;
5080
5082
5083 PG_RETURN_TIMESTAMPTZ(result);
5084}
static TimestampTz timestamptz_trunc_internal(text *units, TimestampTz timestamp, pg_tz *tzp)
Definition: timestamp.c:4897

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

◆ timestamptz_trunc_internal()

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

Definition at line 4897 of file timestamp.c.

4898{
4899 TimestampTz result;
4900 int tz;
4901 int type,
4902 val;
4903 bool redotz = false;
4904 char *lowunits;
4905 fsec_t fsec;
4906 struct pg_tm tt,
4907 *tm = &tt;
4908
4909 lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
4910 VARSIZE_ANY_EXHDR(units),
4911 false);
4912
4913 type = DecodeUnits(0, lowunits, &val);
4914
4915 if (type == UNITS)
4916 {
4918 {
4919 /*
4920 * Errors thrown here for invalid units should exactly match those
4921 * below, else there will be unexpected discrepancies between
4922 * finite- and infinite-input cases.
4923 */
4924 switch (val)
4925 {
4926 case DTK_WEEK:
4927 case DTK_MILLENNIUM:
4928 case DTK_CENTURY:
4929 case DTK_DECADE:
4930 case DTK_YEAR:
4931 case DTK_QUARTER:
4932 case DTK_MONTH:
4933 case DTK_DAY:
4934 case DTK_HOUR:
4935 case DTK_MINUTE:
4936 case DTK_SECOND:
4937 case DTK_MILLISEC:
4938 case DTK_MICROSEC:
4939 return timestamp;
4940 break;
4941
4942 default:
4943 ereport(ERROR,
4944 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4945 errmsg("unit \"%s\" not supported for type %s",
4946 lowunits, format_type_be(TIMESTAMPTZOID))));
4947 result = 0;
4948 }
4949 }
4950
4951 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, tzp) != 0)
4952 ereport(ERROR,
4953 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4954 errmsg("timestamp out of range")));
4955
4956 switch (val)
4957 {
4958 case DTK_WEEK:
4959 {
4960 int woy;
4961
4963
4964 /*
4965 * If it is week 52/53 and the month is January, then the
4966 * week must belong to the previous year. Also, some
4967 * December dates belong to the next year.
4968 */
4969 if (woy >= 52 && tm->tm_mon == 1)
4970 --tm->tm_year;
4971 if (woy <= 1 && tm->tm_mon == MONTHS_PER_YEAR)
4972 ++tm->tm_year;
4973 isoweek2date(woy, &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
4974 tm->tm_hour = 0;
4975 tm->tm_min = 0;
4976 tm->tm_sec = 0;
4977 fsec = 0;
4978 redotz = true;
4979 break;
4980 }
4981 /* one may consider DTK_THOUSAND and DTK_HUNDRED... */
4982 case DTK_MILLENNIUM:
4983
4984 /*
4985 * truncating to the millennium? what is this supposed to
4986 * mean? let us put the first year of the millennium... i.e.
4987 * -1000, 1, 1001, 2001...
4988 */
4989 if (tm->tm_year > 0)
4990 tm->tm_year = ((tm->tm_year + 999) / 1000) * 1000 - 999;
4991 else
4992 tm->tm_year = -((999 - (tm->tm_year - 1)) / 1000) * 1000 + 1;
4993 /* FALL THRU */
4994 case DTK_CENTURY:
4995 /* truncating to the century? as above: -100, 1, 101... */
4996 if (tm->tm_year > 0)
4997 tm->tm_year = ((tm->tm_year + 99) / 100) * 100 - 99;
4998 else
4999 tm->tm_year = -((99 - (tm->tm_year - 1)) / 100) * 100 + 1;
5000 /* FALL THRU */
5001 case DTK_DECADE:
5002
5003 /*
5004 * truncating to the decade? first year of the decade. must
5005 * not be applied if year was truncated before!
5006 */
5007 if (val != DTK_MILLENNIUM && val != DTK_CENTURY)
5008 {
5009 if (tm->tm_year > 0)
5010 tm->tm_year = (tm->tm_year / 10) * 10;
5011 else
5012 tm->tm_year = -((8 - (tm->tm_year - 1)) / 10) * 10;
5013 }
5014 /* FALL THRU */
5015 case DTK_YEAR:
5016 tm->tm_mon = 1;
5017 /* FALL THRU */
5018 case DTK_QUARTER:
5019 tm->tm_mon = (3 * ((tm->tm_mon - 1) / 3)) + 1;
5020 /* FALL THRU */
5021 case DTK_MONTH:
5022 tm->tm_mday = 1;
5023 /* FALL THRU */
5024 case DTK_DAY:
5025 tm->tm_hour = 0;
5026 redotz = true; /* for all cases >= DAY */
5027 /* FALL THRU */
5028 case DTK_HOUR:
5029 tm->tm_min = 0;
5030 /* FALL THRU */
5031 case DTK_MINUTE:
5032 tm->tm_sec = 0;
5033 /* FALL THRU */
5034 case DTK_SECOND:
5035 fsec = 0;
5036 break;
5037 case DTK_MILLISEC:
5038 fsec = (fsec / 1000) * 1000;
5039 break;
5040 case DTK_MICROSEC:
5041 break;
5042
5043 default:
5044 ereport(ERROR,
5045 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5046 errmsg("unit \"%s\" not supported for type %s",
5047 lowunits, format_type_be(TIMESTAMPTZOID))));
5048 result = 0;
5049 }
5050
5051 if (redotz)
5052 tz = DetermineTimeZoneOffset(tm, tzp);
5053
5054 if (tm2timestamp(tm, fsec, &tz, &result) != 0)
5055 ereport(ERROR,
5056 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
5057 errmsg("timestamp out of range")));
5058 }
5059 else
5060 {
5061 ereport(ERROR,
5062 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5063 errmsg("unit \"%s\" not recognized for type %s",
5064 lowunits, format_type_be(TIMESTAMPTZOID))));
5065 result = 0;
5066 }
5067
5068 return result;
5069}

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

Referenced by timestamptz_trunc(), and timestamptz_trunc_zone().

◆ timestamptz_trunc_zone()

Datum timestamptz_trunc_zone ( PG_FUNCTION_ARGS  )

Definition at line 5090 of file timestamp.c.

5091{
5092 text *units = PG_GETARG_TEXT_PP(0);
5095 TimestampTz result;
5096 pg_tz *tzp;
5097
5098 /*
5099 * Look up the requested timezone.
5100 */
5101 tzp = lookup_timezone(zone);
5102
5103 result = timestamptz_trunc_internal(units, timestamp, tzp);
5104
5105 PG_RETURN_TIMESTAMPTZ(result);
5106}

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

◆ timestamptz_zone()

Datum timestamptz_zone ( PG_FUNCTION_ARGS  )

Definition at line 6563 of file timestamp.c.

6564{
6567 Timestamp result;
6568 int tz;
6569 char tzname[TZ_STRLEN_MAX + 1];
6570 int type,
6571 val;
6572 pg_tz *tzp;
6573
6576
6577 /*
6578 * Look up the requested timezone.
6579 */
6580 text_to_cstring_buffer(zone, tzname, sizeof(tzname));
6581
6582 type = DecodeTimezoneName(tzname, &val, &tzp);
6583
6585 {
6586 /* fixed-offset abbreviation */
6587 tz = -val;
6588 result = dt2local(timestamp, tz);
6589 }
6590 else if (type == TZNAME_DYNTZ)
6591 {
6592 /* dynamic-offset abbreviation, resolve using specified time */
6593 int isdst;
6594
6595 tz = DetermineTimeZoneAbbrevOffsetTS(timestamp, tzname, tzp, &isdst);
6596 result = dt2local(timestamp, tz);
6597 }
6598 else
6599 {
6600 /* full zone name, rotate from that zone */
6601 struct pg_tm tm;
6602 fsec_t fsec;
6603
6604 if (timestamp2tm(timestamp, &tz, &tm, &fsec, NULL, tzp) != 0)
6605 ereport(ERROR,
6606 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6607 errmsg("timestamp out of range")));
6608 if (tm2timestamp(&tm, fsec, NULL, &result) != 0)
6609 ereport(ERROR,
6610 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6611 errmsg("timestamp out of range")));
6612 }
6613
6614 if (!IS_VALID_TIMESTAMP(result))
6615 ereport(ERROR,
6616 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6617 errmsg("timestamp out of range")));
6618
6619 PG_RETURN_TIMESTAMP(result);
6620}
int DetermineTimeZoneAbbrevOffsetTS(TimestampTz ts, const char *abbr, pg_tz *tzp, int *isdst)
Definition: datetime.c:1803

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

◆ timestamptztypmodin()

Datum timestamptztypmodin ( PG_FUNCTION_ARGS  )

Definition at line 849 of file timestamp.c.

850{
852
854}

References anytimestamp_typmodin(), PG_GETARG_ARRAYTYPE_P, and PG_RETURN_INT32.

◆ timestamptztypmodout()

Datum timestamptztypmodout ( PG_FUNCTION_ARGS  )

Definition at line 857 of file timestamp.c.

858{
859 int32 typmod = PG_GETARG_INT32(0);
860
862}

References anytimestamp_typmodout(), PG_GETARG_INT32, and PG_RETURN_CSTRING.

◆ tm2timestamp()

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

Definition at line 2006 of file timestamp.c.

2007{
2009 TimeOffset time;
2010
2011 /* Prevent overflow in Julian-day routines */
2013 {
2014 *result = 0; /* keep compiler quiet */
2015 return -1;
2016 }
2017
2019 time = time2t(tm->tm_hour, tm->tm_min, tm->tm_sec, fsec);
2020
2022 pg_add_s64_overflow(*result, time, result)))
2023 {
2024 *result = 0; /* keep compiler quiet */
2025 return -1;
2026 }
2027 if (tzp != NULL)
2028 *result = dt2local(*result, -(*tzp));
2029
2030 /* final range check catches just-out-of-range timestamps */
2031 if (!IS_VALID_TIMESTAMP(*result))
2032 {
2033 *result = 0; /* keep compiler quiet */
2034 return -1;
2035 }
2036
2037 return 0;
2038}
static TimeOffset time2t(const int hour, const int min, const int sec, const fsec_t fsec)
Definition: timestamp.c:2128

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

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

Variable Documentation

◆ PgReloadTime

TimestampTz PgReloadTime

Definition at line 57 of file timestamp.c.

Referenced by pg_conf_load_time(), and ProcessConfigFileInternal().

◆ PgStartTime

TimestampTz PgStartTime

Definition at line 54 of file timestamp.c.

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