PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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)
 
static int timestamp_fastcmp (Datum x, Datum y, SortSupport ssup)
 
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_opt_overflow (Timestamp timestamp, int *overflow)
 
Datum timestamptz_timestamp (PG_FUNCTION_ARGS)
 
Datum timestamptz_zone (PG_FUNCTION_ARGS)
 
Datum timestamptz_izone (PG_FUNCTION_ARGS)
 
Datum generate_series_timestamp (PG_FUNCTION_ARGS)
 
static Datum generate_series_timestamptz_internal (FunctionCallInfo fcinfo)
 
Datum generate_series_timestamptz (PG_FUNCTION_ARGS)
 
Datum generate_series_timestamptz_at_zone (PG_FUNCTION_ARGS)
 
Datum generate_series_timestamp_support (PG_FUNCTION_ARGS)
 
Datum timestamp_at_local (PG_FUNCTION_ARGS)
 
Datum timestamptz_at_local (PG_FUNCTION_ARGS)
 

Variables

TimestampTz PgStartTime
 
TimestampTz PgReloadTime
 

Macro Definition Documentation

◆ IA_TOTAL_COUNT

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

Definition at line 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:516
int64_t int64
Definition: c.h:499
#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:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ereturn(context, dummy_value,...)
Definition: elog.h:277
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define MONTH
Definition: datetime.h:91
#define HOUR
Definition: datetime.h:100
#define DAY
Definition: datetime.h:93
#define YEAR
Definition: datetime.h:92
#define SECOND
Definition: datetime.h:102
#define MINUTE
Definition: datetime.h:101
static bool pg_sub_s64_overflow(int64 a, int64 b, int64 *result)
Definition: int.h: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:149

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

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

◆ anytimestamp_typmodin()

static int32 anytimestamp_typmodin ( bool  istz,
ArrayType ta 
)
static

Definition at line 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:498

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:2325
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 5313 of file timestamp.c.

5314{
5315 float8 result;
5316 int day0,
5317 day4,
5318 dayn;
5319
5320 /* current day */
5321 dayn = date2j(year, mon, mday);
5322
5323 /* fourth day of current year */
5324 day4 = date2j(year, 1, 4);
5325
5326 /* day0 == offset to first day of week (Monday) */
5327 day0 = j2day(day4 - 1);
5328
5329 /*
5330 * We need the first week containing a Thursday, otherwise this day falls
5331 * into the previous year for purposes of counting weeks
5332 */
5333 if (dayn < day4 - day0)
5334 {
5335 day4 = date2j(year - 1, 1, 4);
5336
5337 /* day0 == offset to first day of week (Monday) */
5338 day0 = j2day(day4 - 1);
5339 }
5340
5341 result = (dayn - (day4 - day0)) / 7 + 1;
5342
5343 /*
5344 * Sometimes the last few days in a year will fall into the first week of
5345 * the next year, so check for this.
5346 */
5347 if (result >= 52)
5348 {
5349 day4 = date2j(year + 1, 1, 4);
5350
5351 /* day0 == offset to first day of week (Monday) */
5352 day0 = j2day(day4 - 1);
5353
5354 if (dayn >= day4 - day0)
5355 result = (dayn - (day4 - day0)) / 7 + 1;
5356 }
5357
5358 return (int) result;
5359}
int j2day(int date)
Definition: datetime.c:354
int date2j(int year, int month, int day)
Definition: datetime.c:296
double float8
Definition: c.h:601

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

5369{
5370 float8 result;
5371 int day0,
5372 day4,
5373 dayn;
5374
5375 /* current day */
5376 dayn = date2j(year, mon, mday);
5377
5378 /* fourth day of current year */
5379 day4 = date2j(year, 1, 4);
5380
5381 /* day0 == offset to first day of week (Monday) */
5382 day0 = j2day(day4 - 1);
5383
5384 /*
5385 * We need the first week containing a Thursday, otherwise this day falls
5386 * into the previous year for purposes of counting weeks
5387 */
5388 if (dayn < day4 - day0)
5389 {
5390 day4 = date2j(year - 1, 1, 4);
5391
5392 /* day0 == offset to first day of week (Monday) */
5393 day0 = j2day(day4 - 1);
5394
5395 year--;
5396 }
5397
5398 result = (dayn - (day4 - day0)) / 7 + 1;
5399
5400 /*
5401 * Sometimes the last few days in a year will fall into the first week of
5402 * the next year, so check for this.
5403 */
5404 if (result >= 52)
5405 {
5406 day4 = date2j(year + 1, 1, 4);
5407
5408 /* day0 == offset to first day of week (Monday) */
5409 day0 = j2day(day4 - 1);
5410
5411 if (dayn >= day4 - day0)
5412 year++;
5413 }
5414
5415 return year;
5416}

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

5426{
5427 return date2j(year, mon, mday) - isoweek2j(date2isoyear(year, mon, mday), 1) + 1;
5428}
int isoweek2j(int year, int week)
Definition: timestamp.c:5262
int date2isoyear(int year, int mon, int mday)
Definition: timestamp.c:5368

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

4008{
4009 /* Infinite inputs are counted separately, and do not affect "N" */
4011 {
4012 state->nInfcount++;
4013 return;
4014 }
4015
4017 {
4018 state->pInfcount++;
4019 return;
4020 }
4021
4022 finite_interval_pl(&state->sumX, newval, &state->sumX);
4023 state->N++;
4024}
static void finite_interval_pl(const Interval *span1, const Interval *span2, Interval *result)
Definition: timestamp.c:3506
#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 4030 of file timestamp.c.

4031{
4032 /* Infinite inputs are counted separately, and do not affect "N" */
4034 {
4035 state->nInfcount--;
4036 return;
4037 }
4038
4040 {
4041 state->pInfcount--;
4042 return;
4043 }
4044
4045 /* Handle the to-be-discarded finite value. */
4046 state->N--;
4047 if (state->N > 0)
4048 finite_interval_mi(&state->sumX, newval, &state->sumX);
4049 else
4050 {
4051 /* All values discarded, reset the state */
4052 Assert(state->N == 0);
4053 memset(&state->sumX, 0, sizeof(state->sumX));
4054 }
4055}
static void finite_interval_mi(const Interval *span1, const Interval *span2, Interval *result)
Definition: timestamp.c:3562
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_opt_overflow(), timestamp_izone(), timestamp_zone(), timestamptz_izone(), timestamptz_zone(), and tm2timestamp().

◆ dt2time()

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

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

6312{
6313 return interval_part_common(fcinfo, true);
6314}
static Datum interval_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition: timestamp.c:6098

References interval_part_common().

◆ extract_timestamp()

Datum extract_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 5763 of file timestamp.c.

5764{
5765 return timestamp_part_common(fcinfo, true);
5766}
static Datum timestamp_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition: timestamp.c:5499

References timestamp_part_common().

◆ extract_timestamptz()

Datum extract_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 6035 of file timestamp.c.

6036{
6037 return timestamptz_part_common(fcinfo, true);
6038}
static Datum timestamptz_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition: timestamp.c:5772

References timestamptz_part_common().

◆ finite_interval_mi()

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

Definition at line 3562 of file timestamp.c.

3563{
3564 Assert(!INTERVAL_NOT_FINITE(span1));
3565 Assert(!INTERVAL_NOT_FINITE(span2));
3566
3567 if (pg_sub_s32_overflow(span1->month, span2->month, &result->month) ||
3568 pg_sub_s32_overflow(span1->day, span2->day, &result->day) ||
3569 pg_sub_s64_overflow(span1->time, span2->time, &result->time) ||
3570 INTERVAL_NOT_FINITE(result))
3571 ereport(ERROR,
3572 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3573 errmsg("interval out of range")));
3574}
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 3506 of file timestamp.c.

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

6669{
6670 FuncCallContext *funcctx;
6672 Timestamp result;
6673
6674 /* stuff done only on the first call of the function */
6675 if (SRF_IS_FIRSTCALL())
6676 {
6678 Timestamp finish = PG_GETARG_TIMESTAMP(1);
6679 Interval *step = PG_GETARG_INTERVAL_P(2);
6680 MemoryContext oldcontext;
6681
6682 /* create a function context for cross-call persistence */
6683 funcctx = SRF_FIRSTCALL_INIT();
6684
6685 /*
6686 * switch to memory context appropriate for multiple function calls
6687 */
6688 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
6689
6690 /* allocate memory for user context */
6693
6694 /*
6695 * Use fctx to keep state from call to call. Seed current with the
6696 * original start value
6697 */
6698 fctx->current = start;
6699 fctx->finish = finish;
6700 fctx->step = *step;
6701
6702 /* Determine sign of the interval */
6703 fctx->step_sign = interval_sign(&fctx->step);
6704
6705 if (fctx->step_sign == 0)
6706 ereport(ERROR,
6707 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6708 errmsg("step size cannot equal zero")));
6709
6710 if (INTERVAL_NOT_FINITE((&fctx->step)))
6711 ereport(ERROR,
6712 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6713 errmsg("step size cannot be infinite")));
6714
6715 funcctx->user_fctx = fctx;
6716 MemoryContextSwitchTo(oldcontext);
6717 }
6718
6719 /* stuff done on every call of the function */
6720 funcctx = SRF_PERCALL_SETUP();
6721
6722 /*
6723 * get the saved state and use current as the result for this iteration
6724 */
6725 fctx = funcctx->user_fctx;
6726 result = fctx->current;
6727
6728 if (fctx->step_sign > 0 ?
6729 timestamp_cmp_internal(result, fctx->finish) <= 0 :
6730 timestamp_cmp_internal(result, fctx->finish) >= 0)
6731 {
6732 /* increment current in preparation for next iteration */
6735 PointerGetDatum(&fctx->step)));
6736
6737 /* do when there is more left to send */
6738 SRF_RETURN_NEXT(funcctx, TimestampGetDatum(result));
6739 }
6740 else
6741 {
6742 /* do when there is no more left */
6743 SRF_RETURN_DONE(funcctx);
6744 }
6745}
int timestamp_cmp_internal(Timestamp dt1, Timestamp dt2)
Definition: timestamp.c:2210
Datum timestamp_pl_interval(PG_FUNCTION_ARGS)
Definition: timestamp.c:3108
static int interval_sign(const Interval *interval)
Definition: timestamp.c:2573
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:1943
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:327
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 6849 of file timestamp.c.

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

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

◆ generate_series_timestamptz()

Datum generate_series_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 6834 of file timestamp.c.

6835{
6837}
static Datum generate_series_timestamptz_internal(FunctionCallInfo fcinfo)
Definition: timestamp.c:6752

References generate_series_timestamptz_internal().

◆ generate_series_timestamptz_at_zone()

Datum generate_series_timestamptz_at_zone ( PG_FUNCTION_ARGS  )

Definition at line 6840 of file timestamp.c.

6841{
6843}

References generate_series_timestamptz_internal().

◆ generate_series_timestamptz_internal()

static Datum generate_series_timestamptz_internal ( FunctionCallInfo  fcinfo)
static

Definition at line 6752 of file timestamp.c.

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

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

Referenced by generate_series_timestamptz(), and generate_series_timestamptz_at_zone().

◆ GetCurrentTimestamp()

TimestampTz GetCurrentTimestamp ( void  )

Definition at line 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(), end_memorycontext_reporting(), entry_alloc(), entry_reset(), get_role_password(), GetCurrentTransactionStopTimestamp(), GetReplicationApplyDelay(), handle_sig_alarm(), has_startup_progress_timeout_expired(), heap_vacuum_rel(), initialize_prng(), InitProcessGlobals(), InvalidatePossiblyObsoleteSlot(), KnownAssignedXidsCompress(), launcher_determine_sleep(), libpqsrv_cancel(), LockBufferForCleanup(), log_disconnections(), LogCheckpointEnd(), logicalrep_worker_launch(), LogicalRepApplyLoop(), maybe_start_bgworkers(), pa_send_data(), PerformAuthentication(), PerformWalRecovery(), pg_get_process_memory_contexts(), pgfdw_abort_cleanup_begin(), pgfdw_cancel_query(), pgfdw_exec_cleanup_query(), pgfdw_finish_abort_cleanup(), pgfdw_get_cleanup_result(), pgss_shmem_startup(), pgstat_build_snapshot(), pgstat_report_activity(), pgstat_report_analyze(), pgstat_report_archiver(), pgstat_report_autovac(), pgstat_report_checksum_failures_in_db(), pgstat_report_stat(), pgstat_report_vacuum(), pgstat_reset(), pgstat_reset_after_failure(), pgstat_reset_counters(), pgstat_reset_of_kind(), pgstat_reset_slru(), PostgresMain(), PostgresSingleUserMain(), postmaster_child_launch(), PostmasterMain(), PrepareTransaction(), process_syncing_tables_for_apply(), ProcessConfigFileInternal(), ProcessPendingWrites(), ProcessRepliesIfAny(), ProcessStandbyReplyMessage(), ProcessWalSndrMessage(), ProcSleep(), rebuild_database_list(), RecordTransactionAbort(), RecordTransactionAbortPrepared(), RecordTransactionCommitPrepared(), recoveryApplyDelay(), ReplicationSlotRelease(), reschedule_timeouts(), ResolveRecoveryConflictWithBufferPin(), ResolveRecoveryConflictWithLock(), ResolveRecoveryConflictWithVirtualXIDs(), RestoreSlotFromDisk(), send_feedback(), SetCurrentStatementStartTimestamp(), SetupApplyOrSyncWorker(), StartBackgroundWorker(), StartTransaction(), test_pattern(), test_random(), throttle(), update_synced_slots_inactive_since(), UpdateWorkerStats(), WaitExceedsMaxStandbyDelay(), WaitForWalSummarization(), WaitForWALToBecomeAvailable(), WalReceiverMain(), WalSndKeepalive(), WalSndLoop(), WalSndUpdateProgress(), WalSndWaitForWal(), WalSndWriteData(), XLogBackgroundFlush(), XLogFileRead(), XLogPrefetchResetStats(), XLogPrefetchShmemInit(), XLogRestorePoint(), XLogSendPhysical(), XLogWalRcvSendHSFeedback(), and XLogWalRcvSendReply().

◆ GetEpochTime()

void GetEpochTime ( struct pg_tm tm)

Definition at line 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:1389
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:870

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

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

Referenced by ExecEvalSQLValueFunction().

◆ in_range_interval_interval()

Datum in_range_interval_interval ( PG_FUNCTION_ARGS  )

Definition at line 3935 of file timestamp.c.

3936{
3938 Interval *base = PG_GETARG_INTERVAL_P(1);
3939 Interval *offset = PG_GETARG_INTERVAL_P(2);
3940 bool sub = PG_GETARG_BOOL(3);
3941 bool less = PG_GETARG_BOOL(4);
3942 Interval *sum;
3943
3944 if (interval_sign(offset) < 0)
3945 ereport(ERROR,
3946 (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
3947 errmsg("invalid preceding or following size in window function")));
3948
3949 /*
3950 * Deal with cases where both base and offset are infinite, and computing
3951 * base +/- offset would cause an error. As for float and numeric types,
3952 * we assume that all values infinitely precede +infinity and infinitely
3953 * follow -infinity. See in_range_float8_float8() for reasoning.
3954 */
3955 if (INTERVAL_IS_NOEND(offset) &&
3956 (sub ? INTERVAL_IS_NOEND(base) : INTERVAL_IS_NOBEGIN(base)))
3957 PG_RETURN_BOOL(true);
3958
3959 /* We don't currently bother to avoid overflow hazards here */
3960 if (sub)
3962 IntervalPGetDatum(base),
3963 IntervalPGetDatum(offset)));
3964 else
3966 IntervalPGetDatum(base),
3967 IntervalPGetDatum(offset)));
3968
3969 if (less)
3971 else
3973}
Datum interval_mi(PG_FUNCTION_ARGS)
Definition: timestamp.c:3577
Datum interval_pl(PG_FUNCTION_ARGS)
Definition: timestamp.c:3521
static int interval_cmp_internal(const Interval *interval1, const Interval *interval2)
Definition: timestamp.c:2564
#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 3894 of file timestamp.c.

3895{
3898 Interval *offset = PG_GETARG_INTERVAL_P(2);
3899 bool sub = PG_GETARG_BOOL(3);
3900 bool less = PG_GETARG_BOOL(4);
3901 Timestamp sum;
3902
3903 if (interval_sign(offset) < 0)
3904 ereport(ERROR,
3905 (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
3906 errmsg("invalid preceding or following size in window function")));
3907
3908 /*
3909 * Deal with cases where both base and offset are infinite, and computing
3910 * base +/- offset would cause an error. As for float and numeric types,
3911 * we assume that all values infinitely precede +infinity and infinitely
3912 * follow -infinity. See in_range_float8_float8() for reasoning.
3913 */
3914 if (INTERVAL_IS_NOEND(offset) &&
3915 (sub ? TIMESTAMP_IS_NOEND(base) : TIMESTAMP_IS_NOBEGIN(base)))
3916 PG_RETURN_BOOL(true);
3917
3918 /* We don't currently bother to avoid overflow hazards here */
3919 if (sub)
3921 TimestampGetDatum(base),
3922 IntervalPGetDatum(offset)));
3923 else
3925 TimestampGetDatum(base),
3926 IntervalPGetDatum(offset)));
3927
3928 if (less)
3929 PG_RETURN_BOOL(val <= sum);
3930 else
3931 PG_RETURN_BOOL(val >= sum);
3932}
Datum timestamp_mi_interval(PG_FUNCTION_ARGS)
Definition: timestamp.c:3225

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

3858{
3861 Interval *offset = PG_GETARG_INTERVAL_P(2);
3862 bool sub = PG_GETARG_BOOL(3);
3863 bool less = PG_GETARG_BOOL(4);
3864 TimestampTz sum;
3865
3866 if (interval_sign(offset) < 0)
3867 ereport(ERROR,
3868 (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE),
3869 errmsg("invalid preceding or following size in window function")));
3870
3871 /*
3872 * Deal with cases where both base and offset are infinite, and computing
3873 * base +/- offset would cause an error. As for float and numeric types,
3874 * we assume that all values infinitely precede +infinity and infinitely
3875 * follow -infinity. See in_range_float8_float8() for reasoning.
3876 */
3877 if (INTERVAL_IS_NOEND(offset) &&
3878 (sub ? TIMESTAMP_IS_NOEND(base) : TIMESTAMP_IS_NOBEGIN(base)))
3879 PG_RETURN_BOOL(true);
3880
3881 /* We don't currently bother to avoid overflow hazards here */
3882 if (sub)
3883 sum = timestamptz_mi_interval_internal(base, offset, NULL);
3884 else
3885 sum = timestamptz_pl_interval_internal(base, offset, NULL);
3886
3887 if (less)
3888 PG_RETURN_BOOL(val <= sum);
3889 else
3890 PG_RETURN_BOOL(val >= sum);
3891}
static TimestampTz timestamptz_mi_interval_internal(TimestampTz timestamp, Interval *span, pg_tz *attimezone)
Definition: timestamp.c:3383

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

4227{
4229
4231
4232 /* If there were no non-null inputs, return NULL */
4233 if (state == NULL || IA_TOTAL_COUNT(state) == 0)
4235
4236 /*
4237 * Aggregating infinities that all have the same sign produces infinity
4238 * with that sign. Aggregating infinities with different signs results in
4239 * an error.
4240 */
4241 if (state->pInfcount > 0 || state->nInfcount > 0)
4242 {
4243 Interval *result;
4244
4245 if (state->pInfcount > 0 && state->nInfcount > 0)
4246 ereport(ERROR,
4247 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4248 errmsg("interval out of range")));
4249
4250 result = (Interval *) palloc(sizeof(Interval));
4251 if (state->pInfcount > 0)
4252 INTERVAL_NOEND(result);
4253 else
4254 INTERVAL_NOBEGIN(result);
4255
4256 PG_RETURN_INTERVAL_P(result);
4257 }
4258
4260 IntervalPGetDatum(&state->sumX),
4261 Float8GetDatum((double) state->N));
4262}
#define IA_TOTAL_COUNT(ia)
Definition: timestamp.c:89
Datum interval_div(PG_FUNCTION_ARGS)
Definition: timestamp.c:3756
#define INTERVAL_NOEND(i)
Definition: timestamp.h:185
#define INTERVAL_NOBEGIN(i)
Definition: timestamp.h:175
Datum Float8GetDatum(float8 X)
Definition: fmgr.c:1816
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_RETURN_INTERVAL_P(x)
Definition: timestamp.h:69

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

◆ interval_avg_accum()

Datum interval_avg_accum ( PG_FUNCTION_ARGS  )

Definition at line 4061 of file timestamp.c.

4062{
4064
4066
4067 /* Create the state data on the first call */
4068 if (state == NULL)
4069 state = makeIntervalAggState(fcinfo);
4070
4071 if (!PG_ARGISNULL(1))
4073
4075}
static void do_interval_accum(IntervalAggState *state, Interval *newval)
Definition: timestamp.c:4007
static IntervalAggState * makeIntervalAggState(FunctionCallInfo fcinfo)
Definition: timestamp.c:3985

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

4209{
4211
4213
4214 /* Should not get here with no state */
4215 if (state == NULL)
4216 elog(ERROR, "interval_avg_accum_inv called with NULL state");
4217
4218 if (!PG_ARGISNULL(1))
4220
4222}
static void do_interval_discard(IntervalAggState *state, Interval *newval)
Definition: timestamp.c:4030

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

4085{
4086 IntervalAggState *state1;
4087 IntervalAggState *state2;
4088
4089 state1 = PG_ARGISNULL(0) ? NULL : (IntervalAggState *) PG_GETARG_POINTER(0);
4090 state2 = PG_ARGISNULL(1) ? NULL : (IntervalAggState *) PG_GETARG_POINTER(1);
4091
4092 if (state2 == NULL)
4093 PG_RETURN_POINTER(state1);
4094
4095 if (state1 == NULL)
4096 {
4097 /* manually copy all fields from state2 to state1 */
4098 state1 = makeIntervalAggState(fcinfo);
4099
4100 state1->N = state2->N;
4101 state1->pInfcount = state2->pInfcount;
4102 state1->nInfcount = state2->nInfcount;
4103
4104 state1->sumX.day = state2->sumX.day;
4105 state1->sumX.month = state2->sumX.month;
4106 state1->sumX.time = state2->sumX.time;
4107
4108 PG_RETURN_POINTER(state1);
4109 }
4110
4111 state1->N += state2->N;
4112 state1->pInfcount += state2->pInfcount;
4113 state1->nInfcount += state2->nInfcount;
4114
4115 /* Accumulate finite interval values, if any. */
4116 if (state2->N > 0)
4117 finite_interval_pl(&state1->sumX, &state2->sumX, &state1->sumX);
4118
4119 PG_RETURN_POINTER(state1);
4120}
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 4165 of file timestamp.c.

4166{
4167 bytea *sstate;
4168 IntervalAggState *result;
4170
4171 if (!AggCheckCallContext(fcinfo, NULL))
4172 elog(ERROR, "aggregate function called in non-aggregate context");
4173
4174 sstate = PG_GETARG_BYTEA_PP(0);
4175
4176 /*
4177 * Initialize a StringInfo so that we can "receive" it using the standard
4178 * recv-function infrastructure.
4179 */
4181 VARSIZE_ANY_EXHDR(sstate));
4182
4183 result = (IntervalAggState *) palloc0(sizeof(IntervalAggState));
4184
4185 /* N */
4186 result->N = pq_getmsgint64(&buf);
4187
4188 /* sumX */
4189 result->sumX.time = pq_getmsgint64(&buf);
4190 result->sumX.day = pq_getmsgint(&buf, 4);
4191 result->sumX.month = pq_getmsgint(&buf, 4);
4192
4193 /* pInfcount */
4194 result->pInfcount = pq_getmsgint64(&buf);
4195
4196 /* nInfcount */
4197 result->nInfcount = pq_getmsgint64(&buf);
4198
4199 pq_getmsgend(&buf);
4200
4201 PG_RETURN_POINTER(result);
4202}
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
void * palloc0(Size size)
Definition: mcxt.c:1973
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4614
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
#define VARDATA_ANY(PTR)
Definition: varatt.h:324
#define VARSIZE_ANY_EXHDR(PTR)
Definition: varatt.h:317

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

◆ interval_avg_serialize()

Datum interval_avg_serialize ( PG_FUNCTION_ARGS  )

Definition at line 4127 of file timestamp.c.

4128{
4131 bytea *result;
4132
4133 /* Ensure we disallow calling when not in aggregate context */
4134 if (!AggCheckCallContext(fcinfo, NULL))
4135 elog(ERROR, "aggregate function called in non-aggregate context");
4136
4138
4140
4141 /* N */
4142 pq_sendint64(&buf, state->N);
4143
4144 /* sumX */
4145 pq_sendint64(&buf, state->sumX.time);
4146 pq_sendint32(&buf, state->sumX.day);
4147 pq_sendint32(&buf, state->sumX.month);
4148
4149 /* pInfcount */
4150 pq_sendint64(&buf, state->pInfcount);
4151
4152 /* nInfcount */
4153 pq_sendint64(&buf, state->nInfcount);
4154
4155 result = pq_endtypsend(&buf);
4156
4157 PG_RETURN_BYTEA_P(result);
4158}
#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 2636 of file timestamp.c.

2637{
2638 Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2639 Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2640
2641 PG_RETURN_INT32(interval_cmp_internal(interval1, interval2));
2642}
#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 2564 of file timestamp.c.

2565{
2566 INT128 span1 = interval_cmp_value(interval1);
2567 INT128 span2 = interval_cmp_value(interval2);
2568
2569 return int128_compare(span1, span2);
2570}
static INT128 interval_cmp_value(const Interval *interval)
Definition: timestamp.c:2542
static int int128_compare(INT128 x, INT128 y)
Definition: int128.h:238
Definition: int128.h:108

References int128_compare(), and interval_cmp_value().

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

◆ interval_cmp_value()

static INT128 interval_cmp_value ( const Interval interval)
inlinestatic

Definition at line 2542 of file timestamp.c.

2543{
2544 INT128 span;
2545 int64 days;
2546
2547 /*
2548 * Combine the month and day fields into an integral number of days.
2549 * Because the inputs are int32, int64 arithmetic suffices here.
2550 */
2551 days = interval->month * INT64CONST(30);
2552 days += interval->day;
2553
2554 /* Widen time field to 128 bits */
2555 span = int64_to_int128(interval->time);
2556
2557 /* Scale up days to microseconds, forming a 128-bit product */
2559
2560 return span;
2561}
const char *const days[]
Definition: datetime.c:84
#define USECS_PER_DAY
Definition: timestamp.h:131
static INT128 int64_to_int128(int64 v)
Definition: int128.h:255
static void int128_add_int64_mul_int64(INT128 *i128, int64 x, int64 y)
Definition: int128.h:177

References days, int128_add_int64_mul_int64(), int64_to_int128(), 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 3756 of file timestamp.c.

3757{
3758 Interval *span = PG_GETARG_INTERVAL_P(0);
3759 float8 factor = PG_GETARG_FLOAT8(1);
3760 double month_remainder_days,
3761 sec_remainder,
3762 result_double;
3763 int32 orig_month = span->month,
3764 orig_day = span->day;
3765 Interval *result;
3766
3767 result = (Interval *) palloc(sizeof(Interval));
3768
3769 if (factor == 0.0)
3770 ereport(ERROR,
3771 (errcode(ERRCODE_DIVISION_BY_ZERO),
3772 errmsg("division by zero")));
3773
3774 /*
3775 * Handle NaN and infinities.
3776 *
3777 * We treat "infinity / infinity" as an error, since the interval type has
3778 * nothing equivalent to NaN. Otherwise, dividing by infinity is handled
3779 * by the regular division code, causing all fields to be set to zero.
3780 */
3781 if (isnan(factor))
3782 goto out_of_range;
3783
3784 if (INTERVAL_NOT_FINITE(span))
3785 {
3786 if (isinf(factor))
3787 goto out_of_range;
3788
3789 if (factor < 0.0)
3790 interval_um_internal(span, result);
3791 else
3792 memcpy(result, span, sizeof(Interval));
3793
3794 PG_RETURN_INTERVAL_P(result);
3795 }
3796
3797 result_double = span->month / factor;
3798 if (isnan(result_double) || !FLOAT8_FITS_IN_INT32(result_double))
3799 goto out_of_range;
3800 result->month = (int32) result_double;
3801
3802 result_double = span->day / factor;
3803 if (isnan(result_double) || !FLOAT8_FITS_IN_INT32(result_double))
3804 goto out_of_range;
3805 result->day = (int32) result_double;
3806
3807 /*
3808 * Fractional months full days into days. See comment in interval_mul().
3809 */
3810 month_remainder_days = (orig_month / factor - result->month) * DAYS_PER_MONTH;
3811 month_remainder_days = TSROUND(month_remainder_days);
3812 sec_remainder = (orig_day / factor - result->day +
3813 month_remainder_days - (int) month_remainder_days) * SECS_PER_DAY;
3814 sec_remainder = TSROUND(sec_remainder);
3815 if (fabs(sec_remainder) >= SECS_PER_DAY)
3816 {
3817 if (pg_add_s32_overflow(result->day,
3818 (int) (sec_remainder / SECS_PER_DAY),
3819 &result->day))
3820 goto out_of_range;
3821 sec_remainder -= (int) (sec_remainder / SECS_PER_DAY) * SECS_PER_DAY;
3822 }
3823
3824 /* cascade units down */
3825 if (pg_add_s32_overflow(result->day, (int32) month_remainder_days,
3826 &result->day))
3827 goto out_of_range;
3828 result_double = rint(span->time / factor + sec_remainder * USECS_PER_SEC);
3829 if (isnan(result_double) || !FLOAT8_FITS_IN_INT64(result_double))
3830 goto out_of_range;
3831 result->time = (int64) result_double;
3832
3833 if (INTERVAL_NOT_FINITE(result))
3834 goto out_of_range;
3835
3836 PG_RETURN_INTERVAL_P(result);
3837
3838out_of_range:
3839 ereport(ERROR,
3840 errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3841 errmsg("interval out of range"));
3842
3843 PG_RETURN_NULL(); /* keep compiler quiet */
3844}
static void interval_um_internal(const Interval *interval, Interval *result)
Definition: timestamp.c:3444
#define FLOAT8_FITS_IN_INT32(num)
Definition: c.h:1061
#define FLOAT8_FITS_IN_INT64(num)
Definition: c.h:1063
#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 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 gbt_intveq().

◆ interval_finite()

Datum interval_finite ( PG_FUNCTION_ARGS  )

◆ interval_ge()

Datum interval_ge ( PG_FUNCTION_ARGS  )

Definition at line 2627 of file timestamp.c.

2628{
2629 Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2630 Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2631
2632 PG_RETURN_BOOL(interval_cmp_internal(interval1, interval2) >= 0);
2633}

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

◆ interval_hash()

Datum interval_hash ( PG_FUNCTION_ARGS  )

Definition at line 2652 of file timestamp.c.

2653{
2656 int64 span64;
2657
2658 /*
2659 * Use only the least significant 64 bits for hashing. The upper 64 bits
2660 * seldom add any useful information, and besides we must do it like this
2661 * for compatibility with hashes calculated before use of INT128 was
2662 * introduced.
2663 */
2664 span64 = int128_to_int64(span);
2665
2667}
#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:269
#define Int64GetDatumFast(X)
Definition: postgres.h:559

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

2671{
2674 int64 span64;
2675
2676 /* Same approach as interval_hash */
2677 span64 = int128_to_int64(span);
2678
2680 PG_GETARG_DATUM(1));
2681}
#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:764
void DateTimeParseError(int dterr, DateTimeErrorExtra *extra, const char *str, const char *datatype, Node *escontext)
Definition: datetime.c:4208
int DecodeInterval(char **field, int *ftype, int nf, int range, int *dtype, struct pg_itm_in *itm_in)
Definition: datetime.c:3480
int DecodeISO8601Interval(char *str, int *dtype, struct pg_itm_in *itm_in)
Definition: datetime.c:3945
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:30
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 3061 of file timestamp.c.

3062{
3063 Interval *span = PG_GETARG_INTERVAL_P(0);
3064 Interval *result;
3065 int32 wholemonth;
3066
3067 result = (Interval *) palloc(sizeof(Interval));
3068 result->month = span->month;
3069 result->day = span->day;
3070 result->time = span->time;
3071
3072 /* do nothing for infinite intervals */
3073 if (INTERVAL_NOT_FINITE(result))
3074 PG_RETURN_INTERVAL_P(result);
3075
3076 wholemonth = result->day / DAYS_PER_MONTH;
3077 result->day -= wholemonth * DAYS_PER_MONTH;
3078 if (pg_add_s32_overflow(result->month, wholemonth, &result->month))
3079 ereport(ERROR,
3080 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3081 errmsg("interval out of range")));
3082
3083 if (result->month > 0 && result->day < 0)
3084 {
3085 result->day += DAYS_PER_MONTH;
3086 result->month--;
3087 }
3088 else if (result->month < 0 && result->day > 0)
3089 {
3090 result->day -= DAYS_PER_MONTH;
3091 result->month++;
3092 }
3093
3094 PG_RETURN_INTERVAL_P(result);
3095}

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

3020{
3021 Interval *span = PG_GETARG_INTERVAL_P(0);
3022 Interval *result;
3023 TimeOffset wholeday;
3024
3025 result = (Interval *) palloc(sizeof(Interval));
3026 result->month = span->month;
3027 result->day = span->day;
3028 result->time = span->time;
3029
3030 /* do nothing for infinite intervals */
3031 if (INTERVAL_NOT_FINITE(result))
3032 PG_RETURN_INTERVAL_P(result);
3033
3034 TMODULO(result->time, wholeday, USECS_PER_DAY);
3035 if (pg_add_s32_overflow(result->day, wholeday, &result->day))
3036 ereport(ERROR,
3037 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3038 errmsg("interval out of range")));
3039
3040 if (result->day > 0 && result->time < 0)
3041 {
3042 result->time += USECS_PER_DAY;
3043 result->day--;
3044 }
3045 else if (result->day < 0 && result->time > 0)
3046 {
3047 result->time -= USECS_PER_DAY;
3048 result->day++;
3049 }
3050
3051 PG_RETURN_INTERVAL_P(result);
3052}
#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 2939 of file timestamp.c.

2940{
2941 Interval *span = PG_GETARG_INTERVAL_P(0);
2942 Interval *result;
2943 TimeOffset wholeday;
2944 int32 wholemonth;
2945
2946 result = (Interval *) palloc(sizeof(Interval));
2947 result->month = span->month;
2948 result->day = span->day;
2949 result->time = span->time;
2950
2951 /* do nothing for infinite intervals */
2952 if (INTERVAL_NOT_FINITE(result))
2953 PG_RETURN_INTERVAL_P(result);
2954
2955 /* pre-justify days if it might prevent overflow */
2956 if ((result->day > 0 && result->time > 0) ||
2957 (result->day < 0 && result->time < 0))
2958 {
2959 wholemonth = result->day / DAYS_PER_MONTH;
2960 result->day -= wholemonth * DAYS_PER_MONTH;
2961 if (pg_add_s32_overflow(result->month, wholemonth, &result->month))
2962 ereport(ERROR,
2963 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2964 errmsg("interval out of range")));
2965 }
2966
2967 /*
2968 * Since TimeOffset is int64, abs(wholeday) can't exceed about 1.07e8. If
2969 * we pre-justified then abs(result->day) is less than DAYS_PER_MONTH, so
2970 * this addition can't overflow. If we didn't pre-justify, then day and
2971 * time are of different signs, so it still can't overflow.
2972 */
2973 TMODULO(result->time, wholeday, USECS_PER_DAY);
2974 result->day += wholeday;
2975
2976 wholemonth = result->day / DAYS_PER_MONTH;
2977 result->day -= wholemonth * DAYS_PER_MONTH;
2978 if (pg_add_s32_overflow(result->month, wholemonth, &result->month))
2979 ereport(ERROR,
2980 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2981 errmsg("interval out of range")));
2982
2983 if (result->month > 0 &&
2984 (result->day < 0 || (result->day == 0 && result->time < 0)))
2985 {
2986 result->day += DAYS_PER_MONTH;
2987 result->month--;
2988 }
2989 else if (result->month < 0 &&
2990 (result->day > 0 || (result->day == 0 && result->time > 0)))
2991 {
2992 result->day -= DAYS_PER_MONTH;
2993 result->month++;
2994 }
2995
2996 if (result->day > 0 && result->time < 0)
2997 {
2998 result->time += USECS_PER_DAY;
2999 result->day--;
3000 }
3001 else if (result->day < 0 && result->time > 0)
3002 {
3003 result->time -= USECS_PER_DAY;
3004 result->day++;
3005 }
3006
3007 PG_RETURN_INTERVAL_P(result);
3008}

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

3493{
3494 Interval *interval1 = PG_GETARG_INTERVAL_P(0);
3495 Interval *interval2 = PG_GETARG_INTERVAL_P(1);
3496 Interval *result;
3497
3498 if (interval_cmp_internal(interval1, interval2) > 0)
3499 result = interval1;
3500 else
3501 result = interval2;
3502 PG_RETURN_INTERVAL_P(result);
3503}

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_INTERVAL_P.

◆ interval_le()

Datum interval_le ( 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_BOOL(interval_cmp_internal(interval1, interval2) <= 0);
2624}

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

◆ interval_mi()

Datum interval_mi ( PG_FUNCTION_ARGS  )

Definition at line 3577 of file timestamp.c.

3578{
3579 Interval *span1 = PG_GETARG_INTERVAL_P(0);
3580 Interval *span2 = PG_GETARG_INTERVAL_P(1);
3581 Interval *result;
3582
3583 result = (Interval *) palloc(sizeof(Interval));
3584
3585 /*
3586 * Handle infinities.
3587 *
3588 * We treat anything that amounts to "infinity - infinity" as an error,
3589 * since the interval type has nothing equivalent to NaN.
3590 */
3591 if (INTERVAL_IS_NOBEGIN(span1))
3592 {
3593 if (INTERVAL_IS_NOBEGIN(span2))
3594 ereport(ERROR,
3595 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3596 errmsg("interval out of range")));
3597 else
3598 INTERVAL_NOBEGIN(result);
3599 }
3600 else if (INTERVAL_IS_NOEND(span1))
3601 {
3602 if (INTERVAL_IS_NOEND(span2))
3603 ereport(ERROR,
3604 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3605 errmsg("interval out of range")));
3606 else
3607 INTERVAL_NOEND(result);
3608 }
3609 else if (INTERVAL_IS_NOBEGIN(span2))
3610 INTERVAL_NOEND(result);
3611 else if (INTERVAL_IS_NOEND(span2))
3612 INTERVAL_NOBEGIN(result);
3613 else
3614 finite_interval_mi(span1, span2, result);
3615
3616 PG_RETURN_INTERVAL_P(result);
3617}

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

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

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

◆ 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:4701
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:128
#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 6305 of file timestamp.c.

6306{
6307 return interval_part_common(fcinfo, false);
6308}

References interval_part_common().

◆ interval_part_common()

static Datum interval_part_common ( PG_FUNCTION_ARGS  ,
bool  retnumeric 
)
static

Definition at line 6098 of file timestamp.c.

6099{
6100 text *units = PG_GETARG_TEXT_PP(0);
6102 int64 intresult;
6103 int type,
6104 val;
6105 char *lowunits;
6106 struct pg_itm tt,
6107 *tm = &tt;
6108
6109 lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
6110 VARSIZE_ANY_EXHDR(units),
6111 false);
6112
6113 type = DecodeUnits(0, lowunits, &val);
6114 if (type == UNKNOWN_FIELD)
6115 type = DecodeSpecial(0, lowunits, &val);
6116
6118 {
6119 double r = NonFiniteIntervalPart(type, val, lowunits,
6121
6122 if (r != 0.0)
6123 {
6124 if (retnumeric)
6125 {
6126 if (r < 0)
6128 CStringGetDatum("-Infinity"),
6130 Int32GetDatum(-1));
6131 else if (r > 0)
6133 CStringGetDatum("Infinity"),
6135 Int32GetDatum(-1));
6136 }
6137 else
6139 }
6140 else
6142 }
6143
6144 if (type == UNITS)
6145 {
6147 switch (val)
6148 {
6149 case DTK_MICROSEC:
6150 intresult = tm->tm_sec * INT64CONST(1000000) + tm->tm_usec;
6151 break;
6152
6153 case DTK_MILLISEC:
6154 if (retnumeric)
6155 /*---
6156 * tm->tm_sec * 1000 + fsec / 1000
6157 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
6158 */
6160 else
6161 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + tm->tm_usec / 1000.0);
6162 break;
6163
6164 case DTK_SECOND:
6165 if (retnumeric)
6166 /*---
6167 * tm->tm_sec + fsec / 1'000'000
6168 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
6169 */
6171 else
6172 PG_RETURN_FLOAT8(tm->tm_sec + tm->tm_usec / 1000000.0);
6173 break;
6174
6175 case DTK_MINUTE:
6176 intresult = tm->tm_min;
6177 break;
6178
6179 case DTK_HOUR:
6180 intresult = tm->tm_hour;
6181 break;
6182
6183 case DTK_DAY:
6184 intresult = tm->tm_mday;
6185 break;
6186
6187 case DTK_WEEK:
6188 intresult = tm->tm_mday / 7;
6189 break;
6190
6191 case DTK_MONTH:
6192 intresult = tm->tm_mon;
6193 break;
6194
6195 case DTK_QUARTER:
6196
6197 /*
6198 * We want to maintain the rule that a field extracted from a
6199 * negative interval is the negative of the field's value for
6200 * the sign-reversed interval. The broken-down tm_year and
6201 * tm_mon aren't very helpful for that, so work from
6202 * interval->month.
6203 */
6204 if (interval->month >= 0)
6205 intresult = (tm->tm_mon / 3) + 1;
6206 else
6207 intresult = -(((-interval->month % MONTHS_PER_YEAR) / 3) + 1);
6208 break;
6209
6210 case DTK_YEAR:
6211 intresult = tm->tm_year;
6212 break;
6213
6214 case DTK_DECADE:
6215 /* caution: C division may have negative remainder */
6216 intresult = tm->tm_year / 10;
6217 break;
6218
6219 case DTK_CENTURY:
6220 /* caution: C division may have negative remainder */
6221 intresult = tm->tm_year / 100;
6222 break;
6223
6224 case DTK_MILLENNIUM:
6225 /* caution: C division may have negative remainder */
6226 intresult = tm->tm_year / 1000;
6227 break;
6228
6229 default:
6230 ereport(ERROR,
6231 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6232 errmsg("unit \"%s\" not supported for type %s",
6233 lowunits, format_type_be(INTERVALOID))));
6234 intresult = 0;
6235 }
6236 }
6237 else if (type == RESERV && val == DTK_EPOCH)
6238 {
6239 if (retnumeric)
6240 {
6241 Numeric result;
6242 int64 secs_from_day_month;
6243 int64 val;
6244
6245 /*
6246 * To do this calculation in integer arithmetic even though
6247 * DAYS_PER_YEAR is fractional, multiply everything by 4 and then
6248 * divide by 4 again at the end. This relies on DAYS_PER_YEAR
6249 * being a multiple of 0.25 and on SECS_PER_DAY being a multiple
6250 * of 4.
6251 */
6252 secs_from_day_month = ((int64) (4 * DAYS_PER_YEAR) * (interval->month / MONTHS_PER_YEAR) +
6254 (int64) 4 * interval->day) * (SECS_PER_DAY / 4);
6255
6256 /*---
6257 * result = secs_from_day_month + interval->time / 1'000'000
6258 * = (secs_from_day_month * 1'000'000 + interval->time) / 1'000'000
6259 */
6260
6261 /*
6262 * Try the computation inside int64; if it overflows, do it in
6263 * numeric (slower). This overflow happens around 10^9 days, so
6264 * not common in practice.
6265 */
6266 if (!pg_mul_s64_overflow(secs_from_day_month, 1000000, &val) &&
6268 result = int64_div_fast_to_numeric(val, 6);
6269 else
6270 result =
6272 int64_to_numeric(secs_from_day_month),
6273 NULL);
6274
6275 PG_RETURN_NUMERIC(result);
6276 }
6277 else
6278 {
6279 float8 result;
6280
6281 result = interval->time / 1000000.0;
6282 result += ((double) DAYS_PER_YEAR * SECS_PER_DAY) * (interval->month / MONTHS_PER_YEAR);
6283 result += ((double) DAYS_PER_MONTH * SECS_PER_DAY) * (interval->month % MONTHS_PER_YEAR);
6284 result += ((double) SECS_PER_DAY) * interval->day;
6285
6286 PG_RETURN_FLOAT8(result);
6287 }
6288 }
6289 else
6290 {
6291 ereport(ERROR,
6292 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6293 errmsg("unit \"%s\" not recognized for type %s",
6294 lowunits, format_type_be(INTERVALOID))));
6295 intresult = 0;
6296 }
6297
6298 if (retnumeric)
6300 else
6301 PG_RETURN_FLOAT8(intresult);
6302}
int DecodeUnits(int field, const char *lowtoken, int *val)
Definition: datetime.c:4163
int DecodeSpecial(int field, const char *lowtoken, int *val)
Definition: datetime.c:3240
Numeric int64_to_numeric(int64 val)
Definition: numeric.c:4401
Numeric int64_div_fast_to_numeric(int64 val1, int log10val2)
Definition: numeric.c:4422
Datum numeric_in(PG_FUNCTION_ARGS)
Definition: numeric.c:637
Numeric numeric_add_opt_error(Numeric num1, Numeric num2, bool *have_error)
Definition: numeric.c:2985
static float8 NonFiniteIntervalPart(int type, int unit, char *lowunits, bool isNegative)
Definition: timestamp.c:6052
#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:80
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:355
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:217
#define InvalidOid
Definition: postgres_ext.h:35
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_opt_error(), numeric_in(), ObjectIdGetDatum(), pg_add_s64_overflow(), PG_GETARG_INTERVAL_P, PG_GETARG_TEXT_PP, pg_mul_s64_overflow(), PG_RETURN_FLOAT8, PG_RETURN_NULL, PG_RETURN_NUMERIC, RESERV, SECS_PER_DAY, interval::time, tm, pg_tm::tm_hour, pg_tm::tm_mday, pg_tm::tm_min, pg_tm::tm_mon, pg_tm::tm_sec, pg_tm::tm_year, type, UNITS, UNKNOWN_FIELD, val, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by extract_interval(), and interval_part().

◆ interval_pl()

Datum interval_pl ( PG_FUNCTION_ARGS  )

Definition at line 3521 of file timestamp.c.

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

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}
StringInfoData * StringInfo
Definition: stringinfo.h:54

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

◆ interval_scale()

Datum interval_scale ( PG_FUNCTION_ARGS  )

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

3478{
3479 Interval *interval1 = PG_GETARG_INTERVAL_P(0);
3480 Interval *interval2 = PG_GETARG_INTERVAL_P(1);
3481 Interval *result;
3482
3483 /* use interval_cmp_internal to be sure this agrees with comparisons */
3484 if (interval_cmp_internal(interval1, interval2) < 0)
3485 result = interval1;
3486 else
3487 result = interval2;
3488 PG_RETURN_INTERVAL_P(result);
3489}

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_INTERVAL_P.

◆ interval_sum()

Datum interval_sum ( PG_FUNCTION_ARGS  )

Definition at line 4266 of file timestamp.c.

4267{
4269 Interval *result;
4270
4272
4273 /* If there were no non-null inputs, return NULL */
4274 if (state == NULL || IA_TOTAL_COUNT(state) == 0)
4276
4277 /*
4278 * Aggregating infinities that all have the same sign produces infinity
4279 * with that sign. Aggregating infinities with different signs results in
4280 * an error.
4281 */
4282 if (state->pInfcount > 0 && state->nInfcount > 0)
4283 ereport(ERROR,
4284 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4285 errmsg("interval out of range")));
4286
4287 result = (Interval *) palloc(sizeof(Interval));
4288
4289 if (state->pInfcount > 0)
4290 INTERVAL_NOEND(result);
4291 else if (state->nInfcount > 0)
4292 INTERVAL_NOBEGIN(result);
4293 else
4294 memcpy(result, &state->sumX, sizeof(Interval));
4295
4296 PG_RETURN_INTERVAL_P(result);
4297}

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:207
List * args
Definition: primnodes.h:785

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

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

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

3465{
3467 Interval *result;
3468
3469 result = (Interval *) palloc(sizeof(Interval));
3471
3472 PG_RETURN_INTERVAL_P(result);
3473}

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

3445{
3447 INTERVAL_NOEND(result);
3448 else if (INTERVAL_IS_NOEND(interval))
3449 INTERVAL_NOBEGIN(result);
3450 else
3451 {
3452 /* Negate each field, guarding against overflow */
3453 if (pg_sub_s64_overflow(INT64CONST(0), interval->time, &result->time) ||
3454 pg_sub_s32_overflow(0, interval->day, &result->day) ||
3455 pg_sub_s32_overflow(0, interval->month, &result->month) ||
3456 INTERVAL_NOT_FINITE(result))
3457 ereport(ERROR,
3458 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3459 errmsg("interval out of range")));
3460 }
3461}

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

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

5283{
5284 j2date(isoweek2j(*year, woy), year, mon, mday);
5285}
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 5262 of file timestamp.c.

5263{
5264 int day0,
5265 day4;
5266
5267 /* fourth day of current year */
5268 day4 = date2j(year, 1, 4);
5269
5270 /* day0 == offset to first day of week (Monday) */
5271 day0 = j2day(day4 - 1);
5272
5273 return ((week - 1) * 7) + (day4 - day0);
5274}

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

5296{
5297 int jday;
5298
5299 jday = isoweek2j(*year, isoweek);
5300 /* convert Gregorian week start (Sunday=1) to ISO week start (Monday=1) */
5301 if (wday > 1)
5302 jday += wday - 2;
5303 else
5304 jday += 6;
5305 j2date(jday, year, mon, mday);
5306}

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:3337
#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:256

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:208
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:2552
#define unlikely(x)
Definition: c.h:347
#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:1516
#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:6518

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

3986{
3988 MemoryContext agg_context;
3989 MemoryContext old_context;
3990
3991 if (!AggCheckCallContext(fcinfo, &agg_context))
3992 elog(ERROR, "aggregate function called in non-aggregate context");
3993
3994 old_context = MemoryContextSwitchTo(agg_context);
3995
3997
3998 MemoryContextSwitchTo(old_context);
3999
4000 return state;
4001}

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

3747{
3748 /* Args are float8 and Interval *, but leave them as generic Datum */
3749 Datum factor = PG_GETARG_DATUM(0);
3750 Datum span = PG_GETARG_DATUM(1);
3751
3752 return DirectFunctionCall2(interval_mul, span, factor);
3753}
Datum interval_mul(PG_FUNCTION_ARGS)
Definition: timestamp.c:3626

References DirectFunctionCall2, interval_mul(), and PG_GETARG_DATUM.

◆ NonFiniteIntervalPart()

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

Definition at line 6052 of file timestamp.c.

6053{
6054 if ((type != UNITS) && (type != RESERV))
6055 ereport(ERROR,
6056 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6057 errmsg("unit \"%s\" not recognized for type %s",
6058 lowunits, format_type_be(INTERVALOID))));
6059
6060 switch (unit)
6061 {
6062 /* Oscillating units */
6063 case DTK_MICROSEC:
6064 case DTK_MILLISEC:
6065 case DTK_SECOND:
6066 case DTK_MINUTE:
6067 case DTK_WEEK:
6068 case DTK_MONTH:
6069 case DTK_QUARTER:
6070 return 0.0;
6071
6072 /* Monotonically-increasing units */
6073 case DTK_HOUR:
6074 case DTK_DAY:
6075 case DTK_YEAR:
6076 case DTK_DECADE:
6077 case DTK_CENTURY:
6078 case DTK_MILLENNIUM:
6079 case DTK_EPOCH:
6080 if (isNegative)
6081 return -get_float8_infinity();
6082 else
6083 return get_float8_infinity();
6084
6085 default:
6086 ereport(ERROR,
6087 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6088 errmsg("unit \"%s\" not supported for type %s",
6089 lowunits, format_type_be(INTERVALOID))));
6090 return 0.0; /* keep compiler quiet */
6091 }
6092}
static float8 get_float8_infinity(void)
Definition: float.h:94

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

Referenced by interval_part_common().

◆ NonFiniteTimestampTzPart()

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

Definition at line 5442 of file timestamp.c.

5444{
5445 if ((type != UNITS) && (type != RESERV))
5446 ereport(ERROR,
5447 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5448 errmsg("unit \"%s\" not recognized for type %s",
5449 lowunits,
5450 format_type_be(isTz ? TIMESTAMPTZOID : TIMESTAMPOID))));
5451
5452 switch (unit)
5453 {
5454 /* Oscillating units */
5455 case DTK_MICROSEC:
5456 case DTK_MILLISEC:
5457 case DTK_SECOND:
5458 case DTK_MINUTE:
5459 case DTK_HOUR:
5460 case DTK_DAY:
5461 case DTK_MONTH:
5462 case DTK_QUARTER:
5463 case DTK_WEEK:
5464 case DTK_DOW:
5465 case DTK_ISODOW:
5466 case DTK_DOY:
5467 case DTK_TZ:
5468 case DTK_TZ_MINUTE:
5469 case DTK_TZ_HOUR:
5470 return 0.0;
5471
5472 /* Monotonically-increasing units */
5473 case DTK_YEAR:
5474 case DTK_DECADE:
5475 case DTK_CENTURY:
5476 case DTK_MILLENNIUM:
5477 case DTK_JULIAN:
5478 case DTK_ISOYEAR:
5479 case DTK_EPOCH:
5480 if (isNegative)
5481 return -get_float8_infinity();
5482 else
5483 return get_float8_infinity();
5484
5485 default:
5486 ereport(ERROR,
5487 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5488 errmsg("unit \"%s\" not supported for type %s",
5489 lowunits,
5490 format_type_be(isTz ? TIMESTAMPTZOID : TIMESTAMPOID))));
5491 return 0.0; /* keep compiler quiet */
5492 }
5493}
#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(), handle_sig_alarm(), HandleCopyStream(), has_startup_progress_timeout_expired(), initialize_prng(), InvalidatePossiblyObsoleteSlot(), IsCheckpointOnSchedule(), LagTrackerRead(), launch_worker(), libpqsrv_cancel(), LockBufferForCleanup(), logicalrep_worker_launch(), LogicalRepApplyLoop(), LogRecoveryConflict(), maybe_start_bgworkers(), mxid_age(), OutputFsync(), PerformRadiusTransaction(), pg_clock_gettime_ns(), pg_time_now(), pg_time_now_lazy(), pg_timezone_abbrevs_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(), process_syncing_tables_for_apply(), ProcessKeepaliveMsg(), ProcessStandbyReplyMessage(), processXactStats(), ProcSleep(), progress_report(), ReplicationSlotRelease(), RequestXLogStreaming(), ResolveRecoveryConflictWithLock(), ResolveRecoveryConflictWithVirtualXIDs(), RestoreSlotFromDisk(), schedule_alarm(), send_feedback(), sendFeedback(), ServerLoop(), set_next_rotation_time(), StreamLogicalLog(), SysLoggerMain(), threadRun(), timetz_zone(), update_synced_slots_inactive_since(), WaitForWALToBecomeAvailable(), WalRcvComputeNextWakeup(), WalRcvRunning(), WalRcvStreaming(), WalReceiverMain(), WalSndComputeSleeptime(), WalSndLoop(), WalSndUpdateProgress(), WalSndWaitForWal(), WalSndWriteData(), xid_age(), XLogBackgroundFlush(), XLogWalRcvSendHSFeedback(), and XLogWalRcvSendReply().

◆ overlaps_timestamp()

Datum overlaps_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2690 of file timestamp.c.

2691{
2692 /*
2693 * The arguments are Timestamps, but we leave them as generic Datums to
2694 * avoid unnecessary conversions between value and reference forms --- not
2695 * to mention possible dereferences of null pointers.
2696 */
2697 Datum ts1 = PG_GETARG_DATUM(0);
2698 Datum te1 = PG_GETARG_DATUM(1);
2699 Datum ts2 = PG_GETARG_DATUM(2);
2700 Datum te2 = PG_GETARG_DATUM(3);
2701 bool ts1IsNull = PG_ARGISNULL(0);
2702 bool te1IsNull = PG_ARGISNULL(1);
2703 bool ts2IsNull = PG_ARGISNULL(2);
2704 bool te2IsNull = PG_ARGISNULL(3);
2705
2706#define TIMESTAMP_GT(t1,t2) \
2707 DatumGetBool(DirectFunctionCall2(timestamp_gt,t1,t2))
2708#define TIMESTAMP_LT(t1,t2) \
2709 DatumGetBool(DirectFunctionCall2(timestamp_lt,t1,t2))
2710
2711 /*
2712 * If both endpoints of interval 1 are null, the result is null (unknown).
2713 * If just one endpoint is null, take ts1 as the non-null one. Otherwise,
2714 * take ts1 as the lesser endpoint.
2715 */
2716 if (ts1IsNull)
2717 {
2718 if (te1IsNull)
2720 /* swap null for non-null */
2721 ts1 = te1;
2722 te1IsNull = true;
2723 }
2724 else if (!te1IsNull)
2725 {
2726 if (TIMESTAMP_GT(ts1, te1))
2727 {
2728 Datum tt = ts1;
2729
2730 ts1 = te1;
2731 te1 = tt;
2732 }
2733 }
2734
2735 /* Likewise for interval 2. */
2736 if (ts2IsNull)
2737 {
2738 if (te2IsNull)
2740 /* swap null for non-null */
2741 ts2 = te2;
2742 te2IsNull = true;
2743 }
2744 else if (!te2IsNull)
2745 {
2746 if (TIMESTAMP_GT(ts2, te2))
2747 {
2748 Datum tt = ts2;
2749
2750 ts2 = te2;
2751 te2 = tt;
2752 }
2753 }
2754
2755 /*
2756 * At this point neither ts1 nor ts2 is null, so we can consider three
2757 * cases: ts1 > ts2, ts1 < ts2, ts1 = ts2
2758 */
2759 if (TIMESTAMP_GT(ts1, ts2))
2760 {
2761 /*
2762 * This case is ts1 < te2 OR te1 < te2, which may look redundant but
2763 * in the presence of nulls it's not quite completely so.
2764 */
2765 if (te2IsNull)
2767 if (TIMESTAMP_LT(ts1, te2))
2768 PG_RETURN_BOOL(true);
2769 if (te1IsNull)
2771
2772 /*
2773 * If te1 is not null then we had ts1 <= te1 above, and we just found
2774 * ts1 >= te2, hence te1 >= te2.
2775 */
2776 PG_RETURN_BOOL(false);
2777 }
2778 else if (TIMESTAMP_LT(ts1, ts2))
2779 {
2780 /* This case is ts2 < te1 OR te2 < te1 */
2781 if (te1IsNull)
2783 if (TIMESTAMP_LT(ts2, te1))
2784 PG_RETURN_BOOL(true);
2785 if (te2IsNull)
2787
2788 /*
2789 * If te2 is not null then we had ts2 <= te2 above, and we just found
2790 * ts2 >= te1, hence te2 >= te1.
2791 */
2792 PG_RETURN_BOOL(false);
2793 }
2794 else
2795 {
2796 /*
2797 * For ts1 = ts2 the spec says te1 <> te2 OR te1 = te2, which is a
2798 * rather silly way of saying "true if both are non-null, else null".
2799 */
2800 if (te1IsNull || te2IsNull)
2802 PG_RETURN_BOOL(true);
2803 }
2804
2805#undef TIMESTAMP_GT
2806#undef TIMESTAMP_LT
2807}
#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:1595
int DecodeTimezone(const char *str, int *tzp)
Definition: datetime.c:3051
int DecodeTimezoneName(const char *tzname, int *offset, pg_tz **tz)
Definition: datetime.c:3282
int DetermineTimeZoneAbbrevOffset(struct pg_tm *tm, const char *abbr, pg_tz *tzp)
Definition: datetime.c:1756
int errhint(const char *fmt,...)
Definition: elog.c:1318
#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:879

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:1344
Definition: lexi.c:60
text * cstring_to_text(const char *s)
Definition: varlena.c:192

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

6519{
6521}
TimestampTz timestamp2timestamptz_opt_overflow(Timestamp timestamp, int *overflow)
Definition: timestamp.c:6466

References timestamp2timestamptz_opt_overflow().

Referenced by make_timestamptz(), and timestamp_timestamptz().

◆ timestamp2timestamptz_opt_overflow()

TimestampTz timestamp2timestamptz_opt_overflow ( Timestamp  timestamp,
int *  overflow 
)

Definition at line 6466 of file timestamp.c.

6467{
6468 TimestampTz result;
6469 struct pg_tm tt,
6470 *tm = &tt;
6471 fsec_t fsec;
6472 int tz;
6473
6474 if (overflow)
6475 *overflow = 0;
6476
6478 return timestamp;
6479
6480 /* We don't expect this to fail, but check it pro forma */
6481 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0)
6482 {
6484
6485 result = dt2local(timestamp, -tz);
6486
6487 if (IS_VALID_TIMESTAMP(result))
6488 {
6489 return result;
6490 }
6491 else if (overflow)
6492 {
6493 if (result < MIN_TIMESTAMP)
6494 {
6495 *overflow = -1;
6496 TIMESTAMP_NOBEGIN(result);
6497 }
6498 else
6499 {
6500 *overflow = 1;
6501 TIMESTAMP_NOEND(result);
6502 }
6503 return result;
6504 }
6505 }
6506
6507 ereport(ERROR,
6508 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6509 errmsg("timestamp out of range")));
6510
6511 return 0;
6512}
#define MIN_TIMESTAMP
Definition: timestamp.h:256

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

Referenced by timestamp2timestamptz(), and timestamp_cmp_timestamptz_internal().

◆ timestamp2tm()

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

Definition at line 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(), timestamp2timestamptz_opt_overflow(), timestamp_age(), timestamp_date(), timestamp_out(), timestamp_part_common(), timestamp_pl_interval(), timestamp_recv(), timestamp_time(), timestamp_to_char(), timestamp_trunc(), timestamp_zone(), timestamptz2timestamp(), timestamptz_age(), timestamptz_date(), timestamptz_out(), timestamptz_part_common(), timestamptz_pl_interval_internal(), timestamptz_recv(), timestamptz_time(), timestamptz_timetz(), timestamptz_to_char(), timestamptz_to_str(), timestamptz_trunc_internal(), timestamptz_zone(), and timetz_zone().

◆ timestamp_age()

Datum timestamp_age ( PG_FUNCTION_ARGS  )

Definition at line 4306 of file timestamp.c.

4307{
4310 Interval *result;
4311 fsec_t fsec1,
4312 fsec2;
4313 struct pg_itm tt,
4314 *tm = &tt;
4315 struct pg_tm tt1,
4316 *tm1 = &tt1;
4317 struct pg_tm tt2,
4318 *tm2 = &tt2;
4319
4320 result = (Interval *) palloc(sizeof(Interval));
4321
4322 /*
4323 * Handle infinities.
4324 *
4325 * We treat anything that amounts to "infinity - infinity" as an error,
4326 * since the interval type has nothing equivalent to NaN.
4327 */
4328 if (TIMESTAMP_IS_NOBEGIN(dt1))
4329 {
4330 if (TIMESTAMP_IS_NOBEGIN(dt2))
4331 ereport(ERROR,
4332 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4333 errmsg("interval out of range")));
4334 else
4335 INTERVAL_NOBEGIN(result);
4336 }
4337 else if (TIMESTAMP_IS_NOEND(dt1))
4338 {
4339 if (TIMESTAMP_IS_NOEND(dt2))
4340 ereport(ERROR,
4341 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4342 errmsg("interval out of range")));
4343 else
4344 INTERVAL_NOEND(result);
4345 }
4346 else if (TIMESTAMP_IS_NOBEGIN(dt2))
4347 INTERVAL_NOEND(result);
4348 else if (TIMESTAMP_IS_NOEND(dt2))
4349 INTERVAL_NOBEGIN(result);
4350 else if (timestamp2tm(dt1, NULL, tm1, &fsec1, NULL, NULL) == 0 &&
4351 timestamp2tm(dt2, NULL, tm2, &fsec2, NULL, NULL) == 0)
4352 {
4353 /* form the symbolic difference */
4354 tm->tm_usec = fsec1 - fsec2;
4355 tm->tm_sec = tm1->tm_sec - tm2->tm_sec;
4356 tm->tm_min = tm1->tm_min - tm2->tm_min;
4357 tm->tm_hour = tm1->tm_hour - tm2->tm_hour;
4358 tm->tm_mday = tm1->tm_mday - tm2->tm_mday;
4359 tm->tm_mon = tm1->tm_mon - tm2->tm_mon;
4360 tm->tm_year = tm1->tm_year - tm2->tm_year;
4361
4362 /* flip sign if necessary... */
4363 if (dt1 < dt2)
4364 {
4365 tm->tm_usec = -tm->tm_usec;
4366 tm->tm_sec = -tm->tm_sec;
4367 tm->tm_min = -tm->tm_min;
4368 tm->tm_hour = -tm->tm_hour;
4369 tm->tm_mday = -tm->tm_mday;
4370 tm->tm_mon = -tm->tm_mon;
4371 tm->tm_year = -tm->tm_year;
4372 }
4373
4374 /* propagate any negative fields into the next higher field */
4375 while (tm->tm_usec < 0)
4376 {
4377 tm->tm_usec += USECS_PER_SEC;
4378 tm->tm_sec--;
4379 }
4380
4381 while (tm->tm_sec < 0)
4382 {
4384 tm->tm_min--;
4385 }
4386
4387 while (tm->tm_min < 0)
4388 {
4390 tm->tm_hour--;
4391 }
4392
4393 while (tm->tm_hour < 0)
4394 {
4396 tm->tm_mday--;
4397 }
4398
4399 while (tm->tm_mday < 0)
4400 {
4401 if (dt1 < dt2)
4402 {
4403 tm->tm_mday += day_tab[isleap(tm1->tm_year)][tm1->tm_mon - 1];
4404 tm->tm_mon--;
4405 }
4406 else
4407 {
4408 tm->tm_mday += day_tab[isleap(tm2->tm_year)][tm2->tm_mon - 1];
4409 tm->tm_mon--;
4410 }
4411 }
4412
4413 while (tm->tm_mon < 0)
4414 {
4416 tm->tm_year--;
4417 }
4418
4419 /* recover sign if necessary... */
4420 if (dt1 < dt2)
4421 {
4422 tm->tm_usec = -tm->tm_usec;
4423 tm->tm_sec = -tm->tm_sec;
4424 tm->tm_min = -tm->tm_min;
4425 tm->tm_hour = -tm->tm_hour;
4426 tm->tm_mday = -tm->tm_mday;
4427 tm->tm_mon = -tm->tm_mon;
4428 tm->tm_year = -tm->tm_year;
4429 }
4430
4431 if (itm2interval(tm, result) != 0)
4432 ereport(ERROR,
4433 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4434 errmsg("interval out of range")));
4435 }
4436 else
4437 ereport(ERROR,
4438 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4439 errmsg("timestamp out of range")));
4440
4441 PG_RETURN_INTERVAL_P(result);
4442}
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 6941 of file timestamp.c.

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

References timestamp_timestamptz().

◆ timestamp_bin()

Datum timestamp_bin ( PG_FUNCTION_ARGS  )

Definition at line 4606 of file timestamp.c.

4607{
4608 Interval *stride = PG_GETARG_INTERVAL_P(0);
4610 Timestamp origin = PG_GETARG_TIMESTAMP(2);
4611 Timestamp result,
4612 stride_usecs,
4613 tm_diff,
4614 tm_modulo,
4615 tm_delta;
4616
4619
4620 if (TIMESTAMP_NOT_FINITE(origin))
4621 ereport(ERROR,
4622 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4623 errmsg("origin out of range")));
4624
4625 if (INTERVAL_NOT_FINITE(stride))
4626 ereport(ERROR,
4627 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4628 errmsg("timestamps cannot be binned into infinite intervals")));
4629
4630 if (stride->month != 0)
4631 ereport(ERROR,
4632 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4633 errmsg("timestamps cannot be binned into intervals containing months or years")));
4634
4635 if (unlikely(pg_mul_s64_overflow(stride->day, USECS_PER_DAY, &stride_usecs)) ||
4636 unlikely(pg_add_s64_overflow(stride_usecs, stride->time, &stride_usecs)))
4637 ereport(ERROR,
4638 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4639 errmsg("interval out of range")));
4640
4641 if (stride_usecs <= 0)
4642 ereport(ERROR,
4643 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4644 errmsg("stride must be greater than zero")));
4645
4646 if (unlikely(pg_sub_s64_overflow(timestamp, origin, &tm_diff)))
4647 ereport(ERROR,
4648 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4649 errmsg("interval out of range")));
4650
4651 /* These calculations cannot overflow */
4652 tm_modulo = tm_diff % stride_usecs;
4653 tm_delta = tm_diff - tm_modulo;
4654 result = origin + tm_delta;
4655
4656 /*
4657 * We want to round towards -infinity, not 0, when tm_diff is negative and
4658 * not a multiple of stride_usecs. This adjustment *can* cause overflow,
4659 * since the result might now be out of the range origin .. timestamp.
4660 */
4661 if (tm_modulo < 0)
4662 {
4663 if (unlikely(pg_sub_s64_overflow(result, stride_usecs, &result)) ||
4664 !IS_VALID_TIMESTAMP(result))
4665 ereport(ERROR,
4666 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4667 errmsg("timestamp out of range")));
4668 }
4669
4670 PG_RETURN_TIMESTAMP(result);
4671}

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

2460{
2461 Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2463
2465}
int32 timestamp_cmp_timestamptz_internal(Timestamp timestampVal, TimestampTz dt2)
Definition: timestamp.c:2384

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

2385{
2386 TimestampTz dt1;
2387 int overflow;
2388
2389 dt1 = timestamp2timestamptz_opt_overflow(timestampVal, &overflow);
2390 if (overflow > 0)
2391 {
2392 /* dt1 is larger than any finite timestamp, but less than infinity */
2393 return TIMESTAMP_IS_NOEND(dt2) ? -1 : +1;
2394 }
2395 if (overflow < 0)
2396 {
2397 /* dt1 is less than any finite timestamp, but more than -infinity */
2398 return TIMESTAMP_IS_NOBEGIN(dt2) ? +1 : -1;
2399 }
2400
2401 return timestamptz_cmp_internal(dt1, dt2);
2402}
#define timestamptz_cmp_internal(dt1, dt2)
Definition: timestamp.h:143

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

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

◆ timestamp_decrement()

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

Definition at line 2310 of file timestamp.c.

2311{
2312 Timestamp texisting = DatumGetTimestamp(existing);
2313
2314 if (texisting == PG_INT64_MIN)
2315 {
2316 /* return value is undefined */
2317 *underflow = true;
2318 return (Datum) 0;
2319 }
2320
2321 *underflow = false;
2322 return TimestampGetDatum(texisting - 1);
2323}
#define PG_INT64_MIN
Definition: c.h:562

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

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

Definition at line 2281 of file timestamp.c.

2282{
2285
2286 return timestamp_cmp_internal(a, b);
2287}
int y
Definition: isn.c:76
int b
Definition: isn.c:74
int x
Definition: isn.c:75
int a
Definition: isn.c:73

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

Referenced by timestamp_sortsupport().

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

2451{
2452 Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2454
2455 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) >= 0);
2456}

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

Datum timestamp_hash ( PG_FUNCTION_ARGS  )

Definition at line 2356 of file timestamp.c.

2357{
2358 return hashint8(fcinfo);
2359}

References hashint8().

◆ timestamp_hash_extended()

Datum timestamp_hash_extended ( PG_FUNCTION_ARGS  )

Definition at line 2362 of file timestamp.c.

2363{
2364 return hashint8extended(fcinfo);
2365}

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:988
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 2327 of file timestamp.c.

2328{
2329 Timestamp texisting = DatumGetTimestamp(existing);
2330
2331 if (texisting == PG_INT64_MAX)
2332 {
2333 /* return value is undefined */
2334 *overflow = true;
2335 return (Datum) 0;
2336 }
2337
2338 *overflow = false;
2339 return TimestampGetDatum(texisting + 1);
2340}
#define PG_INT64_MAX
Definition: c.h:563

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

Referenced by timestamp_skipsupport().

◆ timestamp_izone()

Datum timestamp_izone ( PG_FUNCTION_ARGS  )

Definition at line 6391 of file timestamp.c.

6392{
6395 TimestampTz result;
6396 int tz;
6397
6400
6402 ereport(ERROR,
6403 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6404 errmsg("interval time zone \"%s\" must be finite",
6406 PointerGetDatum(zone))))));
6407
6408 if (zone->month != 0 || zone->day != 0)
6409 ereport(ERROR,
6410 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6411 errmsg("interval time zone \"%s\" must not include months or days",
6413 PointerGetDatum(zone))))));
6414
6415 tz = zone->time / USECS_PER_SEC;
6416
6417 result = dt2local(timestamp, tz);
6418
6419 if (!IS_VALID_TIMESTAMP(result))
6420 ereport(ERROR,
6421 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6422 errmsg("timestamp out of range")));
6423
6424 PG_RETURN_TIMESTAMPTZ(result);
6425} /* timestamp_izone() */
Datum interval_out(PG_FUNCTION_ARGS)
Definition: timestamp.c:973
static char * DatumGetCString(Datum X)
Definition: postgres.h:340

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

2831{
2834 Timestamp result;
2835
2836 if (timestamp_cmp_internal(dt1, dt2) > 0)
2837 result = dt1;
2838 else
2839 result = dt2;
2840 PG_RETURN_TIMESTAMP(result);
2841}

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

2442{
2443 Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2445
2446 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) <= 0);
2447}

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

Datum timestamp_mi ( PG_FUNCTION_ARGS  )

Definition at line 2845 of file timestamp.c.

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

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 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_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:4458
void EncodeSpecialTimestamp(Timestamp dt, char *str)
Definition: timestamp.c:1587
int DateStyle
Definition: globals.c:126

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

5758{
5759 return timestamp_part_common(fcinfo, false);
5760}

References timestamp_part_common().

◆ timestamp_part_common()

static Datum timestamp_part_common ( PG_FUNCTION_ARGS  ,
bool  retnumeric 
)
static

Definition at line 5499 of file timestamp.c.

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

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

Referenced by extract_timestamp(), and timestamp_part().

◆ timestamp_pl_interval()

Datum timestamp_pl_interval ( PG_FUNCTION_ARGS  )

Definition at line 3108 of file timestamp.c.

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

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

2344{
2346
2351
2353}
static Datum timestamp_increment(Relation rel, Datum existing, bool *overflow)
Definition: timestamp.c:2327
static Datum timestamp_decrement(Relation rel, Datum existing, bool *underflow)
Definition: timestamp.c:2310
#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 2815 of file timestamp.c.

2816{
2819 Timestamp result;
2820
2821 /* use timestamp_cmp_internal to be sure this agrees with comparisons */
2822 if (timestamp_cmp_internal(dt1, dt2) < 0)
2823 result = dt1;
2824 else
2825 result = dt2;
2826 PG_RETURN_TIMESTAMP(result);
2827}

References PG_GETARG_TIMESTAMP, PG_RETURN_TIMESTAMP, and timestamp_cmp_internal().

◆ timestamp_sortsupport()

Datum timestamp_sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 2291 of file timestamp.c.

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

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

◆ timestamp_support()

Datum timestamp_support ( PG_FUNCTION_ARGS  )

Definition at line 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:4956

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

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

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

6327{
6330 TimestampTz result;
6331 int tz;
6332 char tzname[TZ_STRLEN_MAX + 1];
6333 int type,
6334 val;
6335 pg_tz *tzp;
6336 struct pg_tm tm;
6337 fsec_t fsec;
6338
6341
6342 /*
6343 * Look up the requested timezone.
6344 */
6345 text_to_cstring_buffer(zone, tzname, sizeof(tzname));
6346
6347 type = DecodeTimezoneName(tzname, &val, &tzp);
6348
6350 {
6351 /* fixed-offset abbreviation */
6352 tz = val;
6353 result = dt2local(timestamp, tz);
6354 }
6355 else if (type == TZNAME_DYNTZ)
6356 {
6357 /* dynamic-offset abbreviation, resolve using specified time */
6358 if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, tzp) != 0)
6359 ereport(ERROR,
6360 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6361 errmsg("timestamp out of range")));
6362 tz = -DetermineTimeZoneAbbrevOffset(&tm, tzname, tzp);
6363 result = dt2local(timestamp, tz);
6364 }
6365 else
6366 {
6367 /* full zone name, rotate to that zone */
6368 if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, tzp) != 0)
6369 ereport(ERROR,
6370 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6371 errmsg("timestamp out of range")));
6372 tz = DetermineTimeZoneOffset(&tm, tzp);
6373 if (tm2timestamp(&tm, fsec, &tz, &result) != 0)
6374 ereport(ERROR,
6375 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6376 errmsg("timestamp out of range")));
6377 }
6378
6379 if (!IS_VALID_TIMESTAMP(result))
6380 ereport(ERROR,
6381 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6382 errmsg("timestamp out of range")));
6383
6384 PG_RETURN_TIMESTAMPTZ(result);
6385}

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

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(), pg_get_process_memory_contexts(), pgfdw_get_cleanup_result(), pgstat_report_analyze(), pgstat_report_vacuum(), recoveryApplyDelay(), WaitForWalSummarization(), WaitForWALToBecomeAvailable(), WalReceiverMain(), and WalSndComputeSleeptime().

◆ TimestampTimestampTzRequiresRewrite()

bool TimestampTimestampTzRequiresRewrite ( void  )

Definition at line 6435 of file timestamp.c.

6436{
6437 long offset;
6438
6439 if (pg_get_timezone_offset(session_timezone, &offset) && offset == 0)
6440 return false;
6441 return true;
6442}
bool pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff)
Definition: localtime.c:1965

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

6536{
6537 Timestamp result;
6538 struct pg_tm tt,
6539 *tm = &tt;
6540 fsec_t fsec;
6541 int tz;
6542
6544 result = timestamp;
6545 else
6546 {
6547 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
6548 ereport(ERROR,
6549 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6550 errmsg("timestamp out of range")));
6551 if (tm2timestamp(tm, fsec, NULL, &result) != 0)
6552 ereport(ERROR,
6553 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6554 errmsg("timestamp out of range")));
6555 }
6556 return result;
6557}

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

Referenced by GetSQLLocalTimestamp(), and timestamptz_timestamp().

◆ timestamptz_age()

Datum timestamptz_age ( PG_FUNCTION_ARGS  )

Definition at line 4452 of file timestamp.c.

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

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

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

References timestamptz_timestamp().

◆ timestamptz_bin()

Datum timestamptz_bin ( PG_FUNCTION_ARGS  )

Definition at line 4841 of file timestamp.c.

4842{
4843 Interval *stride = PG_GETARG_INTERVAL_P(0);
4846 TimestampTz result,
4847 stride_usecs,
4848 tm_diff,
4849 tm_modulo,
4850 tm_delta;
4851
4854
4855 if (TIMESTAMP_NOT_FINITE(origin))
4856 ereport(ERROR,
4857 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4858 errmsg("origin out of range")));
4859
4860 if (INTERVAL_NOT_FINITE(stride))
4861 ereport(ERROR,
4862 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4863 errmsg("timestamps cannot be binned into infinite intervals")));
4864
4865 if (stride->month != 0)
4866 ereport(ERROR,
4867 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4868 errmsg("timestamps cannot be binned into intervals containing months or years")));
4869
4870 if (unlikely(pg_mul_s64_overflow(stride->day, USECS_PER_DAY, &stride_usecs)) ||
4871 unlikely(pg_add_s64_overflow(stride_usecs, stride->time, &stride_usecs)))
4872 ereport(ERROR,
4873 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4874 errmsg("interval out of range")));
4875
4876 if (stride_usecs <= 0)
4877 ereport(ERROR,
4878 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4879 errmsg("stride must be greater than zero")));
4880
4881 if (unlikely(pg_sub_s64_overflow(timestamp, origin, &tm_diff)))
4882 ereport(ERROR,
4883 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4884 errmsg("interval out of range")));
4885
4886 /* These calculations cannot overflow */
4887 tm_modulo = tm_diff % stride_usecs;
4888 tm_delta = tm_diff - tm_modulo;
4889 result = origin + tm_delta;
4890
4891 /*
4892 * We want to round towards -infinity, not 0, when tm_diff is negative and
4893 * not a multiple of stride_usecs. This adjustment *can* cause overflow,
4894 * since the result might now be out of the range origin .. timestamp.
4895 */
4896 if (tm_modulo < 0)
4897 {
4898 if (unlikely(pg_sub_s64_overflow(result, stride_usecs, &result)) ||
4899 !IS_VALID_TIMESTAMP(result))
4900 ereport(ERROR,
4901 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4902 errmsg("timestamp out of range")));
4903 }
4904
4905 PG_RETURN_TIMESTAMPTZ(result);
4906}

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

Datum timestamptz_ge_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2513 of file timestamp.c.

2514{
2516 Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
2517
2518 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) <= 0);
2519}

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

Datum timestamptz_hash ( PG_FUNCTION_ARGS  )

Definition at line 2368 of file timestamp.c.

2369{
2370 return hashint8(fcinfo);
2371}

References hashint8().

◆ timestamptz_hash_extended()

Datum timestamptz_hash_extended ( PG_FUNCTION_ARGS  )

Definition at line 2374 of file timestamp.c.

2375{
2376 return hashint8extended(fcinfo);
2377}

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

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

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

2505{
2507 Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
2508
2509 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) >= 0);
2510}

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

3386{
3387 Interval tspan;
3388
3389 interval_um_internal(span, &tspan);
3390
3391 return timestamptz_pl_interval_internal(timestamp, &tspan, attimezone);
3392}

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

6030{
6031 return timestamptz_part_common(fcinfo, false);
6032}

References timestamptz_part_common().

◆ timestamptz_part_common()

static Datum timestamptz_part_common ( PG_FUNCTION_ARGS  ,
bool  retnumeric 
)
static

Definition at line 5772 of file timestamp.c.

5773{
5774 text *units = PG_GETARG_TEXT_PP(0);
5776 int64 intresult;
5778 int tz;
5779 int type,
5780 val;
5781 char *lowunits;
5782 fsec_t fsec;
5783 struct pg_tm tt,
5784 *tm = &tt;
5785
5786 lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
5787 VARSIZE_ANY_EXHDR(units),
5788 false);
5789
5790 type = DecodeUnits(0, lowunits, &val);
5791 if (type == UNKNOWN_FIELD)
5792 type = DecodeSpecial(0, lowunits, &val);
5793
5795 {
5796 double r = NonFiniteTimestampTzPart(type, val, lowunits,
5798 true);
5799
5800 if (r != 0.0)
5801 {
5802 if (retnumeric)
5803 {
5804 if (r < 0)
5806 CStringGetDatum("-Infinity"),
5808 Int32GetDatum(-1));
5809 else if (r > 0)
5811 CStringGetDatum("Infinity"),
5813 Int32GetDatum(-1));
5814 }
5815 else
5817 }
5818 else
5820 }
5821
5822 if (type == UNITS)
5823 {
5824 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
5825 ereport(ERROR,
5826 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
5827 errmsg("timestamp out of range")));
5828
5829 switch (val)
5830 {
5831 case DTK_TZ:
5832 intresult = -tz;
5833 break;
5834
5835 case DTK_TZ_MINUTE:
5836 intresult = (-tz / SECS_PER_MINUTE) % MINS_PER_HOUR;
5837 break;
5838
5839 case DTK_TZ_HOUR:
5840 intresult = -tz / SECS_PER_HOUR;
5841 break;
5842
5843 case DTK_MICROSEC:
5844 intresult = tm->tm_sec * INT64CONST(1000000) + fsec;
5845 break;
5846
5847 case DTK_MILLISEC:
5848 if (retnumeric)
5849 /*---
5850 * tm->tm_sec * 1000 + fsec / 1000
5851 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
5852 */
5854 else
5855 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0);
5856 break;
5857
5858 case DTK_SECOND:
5859 if (retnumeric)
5860 /*---
5861 * tm->tm_sec + fsec / 1'000'000
5862 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
5863 */
5865 else
5866 PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0);
5867 break;
5868
5869 case DTK_MINUTE:
5870 intresult = tm->tm_min;
5871 break;
5872
5873 case DTK_HOUR:
5874 intresult = tm->tm_hour;
5875 break;
5876
5877 case DTK_DAY:
5878 intresult = tm->tm_mday;
5879 break;
5880
5881 case DTK_MONTH:
5882 intresult = tm->tm_mon;
5883 break;
5884
5885 case DTK_QUARTER:
5886 intresult = (tm->tm_mon - 1) / 3 + 1;
5887 break;
5888
5889 case DTK_WEEK:
5890 intresult = date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday);
5891 break;
5892
5893 case DTK_YEAR:
5894 if (tm->tm_year > 0)
5895 intresult = tm->tm_year;
5896 else
5897 /* there is no year 0, just 1 BC and 1 AD */
5898 intresult = tm->tm_year - 1;
5899 break;
5900
5901 case DTK_DECADE:
5902 /* see comments in timestamp_part */
5903 if (tm->tm_year > 0)
5904 intresult = tm->tm_year / 10;
5905 else
5906 intresult = -((8 - (tm->tm_year - 1)) / 10);
5907 break;
5908
5909 case DTK_CENTURY:
5910 /* see comments in timestamp_part */
5911 if (tm->tm_year > 0)
5912 intresult = (tm->tm_year + 99) / 100;
5913 else
5914 intresult = -((99 - (tm->tm_year - 1)) / 100);
5915 break;
5916
5917 case DTK_MILLENNIUM:
5918 /* see comments in timestamp_part */
5919 if (tm->tm_year > 0)
5920 intresult = (tm->tm_year + 999) / 1000;
5921 else
5922 intresult = -((999 - (tm->tm_year - 1)) / 1000);
5923 break;
5924
5925 case DTK_JULIAN:
5926 if (retnumeric)
5930 NULL),
5931 NULL));
5932 else
5935 tm->tm_sec + (fsec / 1000000.0)) / (double) SECS_PER_DAY);
5936 break;
5937
5938 case DTK_ISOYEAR:
5939 intresult = date2isoyear(tm->tm_year, tm->tm_mon, tm->tm_mday);
5940 /* Adjust BC years */
5941 if (intresult <= 0)
5942 intresult -= 1;
5943 break;
5944
5945 case DTK_DOW:
5946 case DTK_ISODOW:
5947 intresult = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday));
5948 if (val == DTK_ISODOW && intresult == 0)
5949 intresult = 7;
5950 break;
5951
5952 case DTK_DOY:
5953 intresult = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)
5954 - date2j(tm->tm_year, 1, 1) + 1);
5955 break;
5956
5957 default:
5958 ereport(ERROR,
5959 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5960 errmsg("unit \"%s\" not supported for type %s",
5961 lowunits, format_type_be(TIMESTAMPTZOID))));
5962 intresult = 0;
5963 }
5964 }
5965 else if (type == RESERV)
5966 {
5967 switch (val)
5968 {
5969 case DTK_EPOCH:
5971 /* (timestamp - epoch) / 1000000 */
5972 if (retnumeric)
5973 {
5974 Numeric result;
5975
5976 if (timestamp < (PG_INT64_MAX + epoch))
5978 else
5979 {
5982 NULL),
5983 int64_to_numeric(1000000),
5984 NULL);
5986 NumericGetDatum(result),
5987 Int32GetDatum(6)));
5988 }
5989 PG_RETURN_NUMERIC(result);
5990 }
5991 else
5992 {
5993 float8 result;
5994
5995 /* try to avoid precision loss in subtraction */
5996 if (timestamp < (PG_INT64_MAX + epoch))
5997 result = (timestamp - epoch) / 1000000.0;
5998 else
5999 result = ((float8) timestamp - epoch) / 1000000.0;
6000 PG_RETURN_FLOAT8(result);
6001 }
6002 break;
6003
6004 default:
6005 ereport(ERROR,
6006 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6007 errmsg("unit \"%s\" not supported for type %s",
6008 lowunits, format_type_be(TIMESTAMPTZOID))));
6009 intresult = 0;
6010 }
6011 }
6012 else
6013 {
6014 ereport(ERROR,
6015 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6016 errmsg("unit \"%s\" not recognized for type %s",
6017 lowunits, format_type_be(TIMESTAMPTZOID))));
6018
6019 intresult = 0;
6020 }
6021
6022 if (retnumeric)
6024 else
6025 PG_RETURN_FLOAT8(intresult);
6026}
#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_opt_error(), numeric_div_opt_error(), numeric_in(), numeric_round(), numeric_sub_opt_error(), NumericGetDatum(), ObjectIdGetDatum(), PG_GETARG_TEXT_PP, PG_GETARG_TIMESTAMPTZ, PG_INT64_MAX, PG_RETURN_FLOAT8, PG_RETURN_NULL, PG_RETURN_NUMERIC, RESERV, SECS_PER_DAY, SECS_PER_HOUR, SECS_PER_MINUTE, SetEpochTimestamp(), timestamp2tm(), TIMESTAMP_IS_NOBEGIN, TIMESTAMP_NOT_FINITE, tm, pg_tm::tm_hour, pg_tm::tm_mday, pg_tm::tm_min, pg_tm::tm_mon, pg_tm::tm_sec, pg_tm::tm_year, type, UNITS, UNKNOWN_FIELD, val, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by extract_timestamptz(), and timestamptz_part().

◆ timestamptz_pl_interval()

◆ timestamptz_pl_interval_at_zone()

◆ timestamptz_pl_interval_internal()

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

Definition at line 3251 of file timestamp.c.

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

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

5094{
5095 text *units = PG_GETARG_TEXT_PP(0);
5097 TimestampTz result;
5098
5100
5101 PG_RETURN_TIMESTAMPTZ(result);
5102}
static TimestampTz timestamptz_trunc_internal(text *units, TimestampTz timestamp, pg_tz *tzp)
Definition: timestamp.c:4915

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

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

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, PG_RETURN_TIMESTAMPTZ, 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 5108 of file timestamp.c.

5109{
5110 text *units = PG_GETARG_TEXT_PP(0);
5113 TimestampTz result;
5114 pg_tz *tzp;
5115
5116 /*
5117 * Look up the requested timezone.
5118 */
5119 tzp = lookup_timezone(zone);
5120
5121 result = timestamptz_trunc_internal(units, timestamp, tzp);
5122
5123 PG_RETURN_TIMESTAMPTZ(result);
5124}

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

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

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