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/sortsupport.h"
Include dependency graph for timestamp.c:

Go to the source code of this file.

Data Structures

struct  generate_series_timestamp_fctx
 
struct  generate_series_timestamptz_fctx
 
struct  IntervalAggState
 

Macros

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

Typedefs

typedef struct IntervalAggState IntervalAggState
 

Functions

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

Variables

TimestampTz PgStartTime
 
TimestampTz PgReloadTime
 

Macro Definition Documentation

◆ IA_TOTAL_COUNT

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

Definition at line 88 of file timestamp.c.

◆ INTERVAL_TO_MICROSECONDS

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

◆ SAMESIGN

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

Definition at line 50 of file timestamp.c.

◆ TIMESTAMP_GT

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

◆ TIMESTAMP_LT

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

Typedef Documentation

◆ IntervalAggState

Function Documentation

◆ AdjustIntervalForTypmod()

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

Definition at line 1349 of file timestamp.c.

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

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

References ereturn, errcode(), errmsg(), 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 124 of file timestamp.c.

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

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

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

◆ anytimestamp_typmodin()

static int32 anytimestamp_typmodin ( bool  istz,
ArrayType ta 
)
static

Definition at line 103 of file timestamp.c.

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

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

Referenced by timestamptypmodin(), and timestamptztypmodin().

◆ anytimestamp_typmodout()

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

Definition at line 146 of file timestamp.c.

147{
148 const char *tz = istz ? " with time zone" : " without time zone";
149
150 if (typmod >= 0)
151 return psprintf("(%d)%s", (int) typmod, tz);
152 else
153 return pstrdup(tz);
154}
char * pstrdup(const char *in)
Definition: mcxt.c:1696
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 1620 of file timestamp.c.

1621{
1623}
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1644
#define PG_RETURN_TIMESTAMPTZ(x)
Definition: timestamp.h:68

References GetCurrentTimestamp(), and PG_RETURN_TIMESTAMPTZ.

◆ date2isoweek()

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

Definition at line 5247 of file timestamp.c.

5248{
5249 float8 result;
5250 int day0,
5251 day4,
5252 dayn;
5253
5254 /* current day */
5255 dayn = date2j(year, mon, mday);
5256
5257 /* fourth day of current year */
5258 day4 = date2j(year, 1, 4);
5259
5260 /* day0 == offset to first day of week (Monday) */
5261 day0 = j2day(day4 - 1);
5262
5263 /*
5264 * We need the first week containing a Thursday, otherwise this day falls
5265 * into the previous year for purposes of counting weeks
5266 */
5267 if (dayn < day4 - day0)
5268 {
5269 day4 = date2j(year - 1, 1, 4);
5270
5271 /* day0 == offset to first day of week (Monday) */
5272 day0 = j2day(day4 - 1);
5273 }
5274
5275 result = (dayn - (day4 - day0)) / 7 + 1;
5276
5277 /*
5278 * Sometimes the last few days in a year will fall into the first week of
5279 * the next year, so check for this.
5280 */
5281 if (result >= 52)
5282 {
5283 day4 = date2j(year + 1, 1, 4);
5284
5285 /* day0 == offset to first day of week (Monday) */
5286 day0 = j2day(day4 - 1);
5287
5288 if (dayn >= day4 - day0)
5289 result = (dayn - (day4 - day0)) / 7 + 1;
5290 }
5291
5292 return (int) result;
5293}
int j2day(int date)
Definition: datetime.c:344
int date2j(int year, int month, int day)
Definition: datetime.c:286
double float8
Definition: c.h:584

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

5303{
5304 float8 result;
5305 int day0,
5306 day4,
5307 dayn;
5308
5309 /* current day */
5310 dayn = date2j(year, mon, mday);
5311
5312 /* fourth day of current year */
5313 day4 = date2j(year, 1, 4);
5314
5315 /* day0 == offset to first day of week (Monday) */
5316 day0 = j2day(day4 - 1);
5317
5318 /*
5319 * We need the first week containing a Thursday, otherwise this day falls
5320 * into the previous year for purposes of counting weeks
5321 */
5322 if (dayn < day4 - day0)
5323 {
5324 day4 = date2j(year - 1, 1, 4);
5325
5326 /* day0 == offset to first day of week (Monday) */
5327 day0 = j2day(day4 - 1);
5328
5329 year--;
5330 }
5331
5332 result = (dayn - (day4 - day0)) / 7 + 1;
5333
5334 /*
5335 * Sometimes the last few days in a year will fall into the first week of
5336 * the next year, so check for this.
5337 */
5338 if (result >= 52)
5339 {
5340 day4 = date2j(year + 1, 1, 4);
5341
5342 /* day0 == offset to first day of week (Monday) */
5343 day0 = j2day(day4 - 1);
5344
5345 if (dayn >= day4 - day0)
5346 year++;
5347 }
5348
5349 return year;
5350}

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

5360{
5361 return date2j(year, mon, mday) - isoweek2j(date2isoyear(year, mon, mday), 1) + 1;
5362}
int isoweek2j(int year, int week)
Definition: timestamp.c:5196
int date2isoyear(int year, int mon, int mday)
Definition: timestamp.c:5302

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

Referenced by DCH_to_char().

◆ do_interval_accum()

static void do_interval_accum ( IntervalAggState state,
Interval newval 
)
static

Definition at line 3941 of file timestamp.c.

3942{
3943 /* Infinite inputs are counted separately, and do not affect "N" */
3945 {
3946 state->nInfcount++;
3947 return;
3948 }
3949
3951 {
3952 state->pInfcount++;
3953 return;
3954 }
3955
3956 finite_interval_pl(&state->sumX, newval, &state->sumX);
3957 state->N++;
3958}
static void finite_interval_pl(const Interval *span1, const Interval *span2, Interval *result)
Definition: timestamp.c:3440
#define INTERVAL_IS_NOBEGIN(i)
Definition: timestamp.h:182
#define INTERVAL_IS_NOEND(i)
Definition: timestamp.h:192
#define newval
Definition: regguts.h:323

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

Referenced by interval_avg_accum().

◆ do_interval_discard()

static void do_interval_discard ( IntervalAggState state,
Interval newval 
)
static

Definition at line 3964 of file timestamp.c.

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

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

Referenced by interval_avg_accum_inv().

◆ dt2local()

static Timestamp dt2local ( Timestamp  dt,
int  timezone 
)
static

Definition at line 2115 of file timestamp.c.

2116{
2117 dt -= (timezone * USECS_PER_SEC);
2118 return dt;
2119}
#define USECS_PER_SEC
Definition: timestamp.h:134

References USECS_PER_SEC.

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

◆ dt2time()

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

Definition at line 1864 of file timestamp.c.

1865{
1866 TimeOffset time;
1867
1868 time = jd;
1869
1870 *hour = time / USECS_PER_HOUR;
1871 time -= (*hour) * USECS_PER_HOUR;
1872 *min = time / USECS_PER_MINUTE;
1873 time -= (*min) * USECS_PER_MINUTE;
1874 *sec = time / USECS_PER_SEC;
1875 *fsec = time - (*sec * USECS_PER_SEC);
1876} /* dt2time() */
int64 TimeOffset
Definition: timestamp.h:40

References USECS_PER_HOUR, USECS_PER_MINUTE, and USECS_PER_SEC.

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

◆ EncodeSpecialInterval()

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

Definition at line 1597 of file timestamp.c.

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

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

Referenced by interval_out().

◆ EncodeSpecialTimestamp()

void EncodeSpecialTimestamp ( Timestamp  dt,
char *  str 
)

Definition at line 1586 of file timestamp.c.

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

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

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

◆ extract_interval()

Datum extract_interval ( PG_FUNCTION_ARGS  )

Definition at line 6245 of file timestamp.c.

6246{
6247 return interval_part_common(fcinfo, true);
6248}
static Datum interval_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition: timestamp.c:6032

References interval_part_common().

◆ extract_timestamp()

Datum extract_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 5697 of file timestamp.c.

5698{
5699 return timestamp_part_common(fcinfo, true);
5700}
static Datum timestamp_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition: timestamp.c:5433

References timestamp_part_common().

◆ extract_timestamptz()

Datum extract_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 5969 of file timestamp.c.

5970{
5971 return timestamptz_part_common(fcinfo, true);
5972}
static Datum timestamptz_part_common(PG_FUNCTION_ARGS, bool retnumeric)
Definition: timestamp.c:5706

References timestamptz_part_common().

◆ finite_interval_mi()

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

Definition at line 3496 of file timestamp.c.

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

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

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

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

◆ generate_series_timestamp()

Datum generate_series_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 6602 of file timestamp.c.

6603{
6604 FuncCallContext *funcctx;
6606 Timestamp result;
6607
6608 /* stuff done only on the first call of the function */
6609 if (SRF_IS_FIRSTCALL())
6610 {
6612 Timestamp finish = PG_GETARG_TIMESTAMP(1);
6613 Interval *step = PG_GETARG_INTERVAL_P(2);
6614 MemoryContext oldcontext;
6615
6616 /* create a function context for cross-call persistence */
6617 funcctx = SRF_FIRSTCALL_INIT();
6618
6619 /*
6620 * switch to memory context appropriate for multiple function calls
6621 */
6622 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
6623
6624 /* allocate memory for user context */
6627
6628 /*
6629 * Use fctx to keep state from call to call. Seed current with the
6630 * original start value
6631 */
6632 fctx->current = start;
6633 fctx->finish = finish;
6634 fctx->step = *step;
6635
6636 /* Determine sign of the interval */
6637 fctx->step_sign = interval_sign(&fctx->step);
6638
6639 if (fctx->step_sign == 0)
6640 ereport(ERROR,
6641 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6642 errmsg("step size cannot equal zero")));
6643
6644 if (INTERVAL_NOT_FINITE((&fctx->step)))
6645 ereport(ERROR,
6646 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6647 errmsg("step size cannot be infinite")));
6648
6649 funcctx->user_fctx = fctx;
6650 MemoryContextSwitchTo(oldcontext);
6651 }
6652
6653 /* stuff done on every call of the function */
6654 funcctx = SRF_PERCALL_SETUP();
6655
6656 /*
6657 * get the saved state and use current as the result for this iteration
6658 */
6659 fctx = funcctx->user_fctx;
6660 result = fctx->current;
6661
6662 if (fctx->step_sign > 0 ?
6663 timestamp_cmp_internal(result, fctx->finish) <= 0 :
6664 timestamp_cmp_internal(result, fctx->finish) >= 0)
6665 {
6666 /* increment current in preparation for next iteration */
6669 PointerGetDatum(&fctx->step)));
6670
6671 /* do when there is more left to send */
6672 SRF_RETURN_NEXT(funcctx, TimestampGetDatum(result));
6673 }
6674 else
6675 {
6676 /* do when there is no more left */
6677 SRF_RETURN_DONE(funcctx);
6678 }
6679}
int timestamp_cmp_internal(Timestamp dt1, Timestamp dt2)
Definition: timestamp.c:2191
Datum timestamp_pl_interval(PG_FUNCTION_ARGS)
Definition: timestamp.c:3042
static int interval_sign(const Interval *interval)
Definition: timestamp.c:2507
int64 Timestamp
Definition: timestamp.h:38
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:643
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:304
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:308
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:310
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:306
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:328
return str start
void * palloc(Size size)
Definition: mcxt.c:1317
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
MemoryContextSwitchTo(old_ctx)
void * user_fctx
Definition: funcapi.h:82
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:101
static Datum TimestampGetDatum(Timestamp X)
Definition: timestamp.h:46
#define PG_GETARG_TIMESTAMP(n)
Definition: timestamp.h:63
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:65
static Timestamp DatumGetTimestamp(Datum X)
Definition: timestamp.h:28

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

◆ generate_series_timestamp_support()

Datum generate_series_timestamp_support ( PG_FUNCTION_ARGS  )

Definition at line 6783 of file timestamp.c.

6784{
6785 Node *rawreq = (Node *) PG_GETARG_POINTER(0);
6786 Node *ret = NULL;
6787
6788 if (IsA(rawreq, SupportRequestRows))
6789 {
6790 /* Try to estimate the number of rows returned */
6791 SupportRequestRows *req = (SupportRequestRows *) rawreq;
6792
6793 if (is_funcclause(req->node)) /* be paranoid */
6794 {
6795 List *args = ((FuncExpr *) req->node)->args;
6796 Node *arg1,
6797 *arg2,
6798 *arg3;
6799
6800 /* We can use estimated argument values here */
6804
6805 /*
6806 * If any argument is constant NULL, we can safely assume that
6807 * zero rows are returned. Otherwise, if they're all non-NULL
6808 * constants, we can calculate the number of rows that will be
6809 * returned.
6810 */
6811 if ((IsA(arg1, Const) && ((Const *) arg1)->constisnull) ||
6812 (IsA(arg2, Const) && ((Const *) arg2)->constisnull) ||
6813 (IsA(arg3, Const) && ((Const *) arg3)->constisnull))
6814 {
6815 req->rows = 0;
6816 ret = (Node *) req;
6817 }
6818 else if (IsA(arg1, Const) && IsA(arg2, Const) && IsA(arg3, Const))
6819 {
6821 finish;
6822 Interval *step;
6823 Datum diff;
6824 double dstep;
6825 int64 dummy;
6826
6827 start = DatumGetTimestamp(((Const *) arg1)->constvalue);
6828 finish = DatumGetTimestamp(((Const *) arg2)->constvalue);
6829 step = DatumGetIntervalP(((Const *) arg3)->constvalue);
6830
6831 /*
6832 * Perform some prechecks which could cause timestamp_mi to
6833 * raise an ERROR. It's much better to just return some
6834 * default estimate than error out in a support function.
6835 */
6837 !pg_sub_s64_overflow(finish, start, &dummy))
6838 {
6840 TimestampGetDatum(finish),
6842
6843#define INTERVAL_TO_MICROSECONDS(i) ((((double) (i)->month * DAYS_PER_MONTH + (i)->day)) * USECS_PER_DAY + (i)->time)
6844
6845 dstep = INTERVAL_TO_MICROSECONDS(step);
6846
6847 /* This equation works for either sign of step */
6848 if (dstep != 0.0)
6849 {
6850 Interval *idiff = DatumGetIntervalP(diff);
6851 double ddiff = INTERVAL_TO_MICROSECONDS(idiff);
6852
6853 req->rows = floor(ddiff / dstep + 1.0);
6854 ret = (Node *) req;
6855 }
6856#undef INTERVAL_TO_MICROSECONDS
6857 }
6858 }
6859 }
6860 }
6861
6862 PG_RETURN_POINTER(ret);
6863}
Datum timestamp_mi(PG_FUNCTION_ARGS)
Definition: timestamp.c:2779
#define INTERVAL_TO_MICROSECONDS(i)
Node * estimate_expression_value(PlannerInfo *root, Node *node)
Definition: clauses.c:2394
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
static bool is_funcclause(const void *clause)
Definition: nodeFuncs.h:69
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
#define lthird(l)
Definition: pg_list.h:188
#define linitial(l)
Definition: pg_list.h:178
#define lsecond(l)
Definition: pg_list.h:183
uintptr_t Datum
Definition: postgres.h:64
Definition: pg_list.h:54
Definition: nodes.h:129
struct PlannerInfo * root
Definition: supportnodes.h:163
static Interval * DatumGetIntervalP(Datum X)
Definition: timestamp.h:40

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

◆ generate_series_timestamptz()

Datum generate_series_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 6768 of file timestamp.c.

6769{
6771}
static Datum generate_series_timestamptz_internal(FunctionCallInfo fcinfo)
Definition: timestamp.c:6686

References generate_series_timestamptz_internal().

◆ generate_series_timestamptz_at_zone()

Datum generate_series_timestamptz_at_zone ( PG_FUNCTION_ARGS  )

Definition at line 6774 of file timestamp.c.

6775{
6777}

References generate_series_timestamptz_internal().

◆ generate_series_timestamptz_internal()

static Datum generate_series_timestamptz_internal ( FunctionCallInfo  fcinfo)
static

Definition at line 6686 of file timestamp.c.

6687{
6688 FuncCallContext *funcctx;
6690 TimestampTz result;
6691
6692 /* stuff done only on the first call of the function */
6693 if (SRF_IS_FIRSTCALL())
6694 {
6697 Interval *step = PG_GETARG_INTERVAL_P(2);
6698 text *zone = (PG_NARGS() == 4) ? PG_GETARG_TEXT_PP(3) : NULL;
6699 MemoryContext oldcontext;
6700
6701 /* create a function context for cross-call persistence */
6702 funcctx = SRF_FIRSTCALL_INIT();
6703
6704 /*
6705 * switch to memory context appropriate for multiple function calls
6706 */
6707 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
6708
6709 /* allocate memory for user context */
6712
6713 /*
6714 * Use fctx to keep state from call to call. Seed current with the
6715 * original start value
6716 */
6717 fctx->current = start;
6718 fctx->finish = finish;
6719 fctx->step = *step;
6721
6722 /* Determine sign of the interval */
6723 fctx->step_sign = interval_sign(&fctx->step);
6724
6725 if (fctx->step_sign == 0)
6726 ereport(ERROR,
6727 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6728 errmsg("step size cannot equal zero")));
6729
6730 if (INTERVAL_NOT_FINITE((&fctx->step)))
6731 ereport(ERROR,
6732 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6733 errmsg("step size cannot be infinite")));
6734
6735 funcctx->user_fctx = fctx;
6736 MemoryContextSwitchTo(oldcontext);
6737 }
6738
6739 /* stuff done on every call of the function */
6740 funcctx = SRF_PERCALL_SETUP();
6741
6742 /*
6743 * get the saved state and use current as the result for this iteration
6744 */
6745 fctx = funcctx->user_fctx;
6746 result = fctx->current;
6747
6748 if (fctx->step_sign > 0 ?
6749 timestamp_cmp_internal(result, fctx->finish) <= 0 :
6750 timestamp_cmp_internal(result, fctx->finish) >= 0)
6751 {
6752 /* increment current in preparation for next iteration */
6754 &fctx->step,
6755 fctx->attimezone);
6756
6757 /* do when there is more left to send */
6758 SRF_RETURN_NEXT(funcctx, TimestampTzGetDatum(result));
6759 }
6760 else
6761 {
6762 /* do when there is no more left */
6763 SRF_RETURN_DONE(funcctx);
6764 }
6765}
static pg_tz * lookup_timezone(text *zone)
Definition: timestamp.c:559
static TimestampTz timestamptz_pl_interval_internal(TimestampTz timestamp, Interval *span, pg_tz *attimezone)
Definition: timestamp.c:3185
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_NARGS()
Definition: fmgr.h:203
PGDLLIMPORT pg_tz * session_timezone
Definition: pgtz.c:28
Definition: c.h:641
Definition: zic.c:94
static Datum TimestampTzGetDatum(TimestampTz X)
Definition: timestamp.h:52
#define PG_GETARG_TIMESTAMPTZ(n)
Definition: timestamp.h:64

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

Referenced by generate_series_timestamptz(), and generate_series_timestamptz_at_zone().

◆ GetCurrentTimestamp()

TimestampTz GetCurrentTimestamp ( void  )

Definition at line 1644 of file timestamp.c.

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

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

Referenced by ApplyLauncherMain(), asyncQueueFillWarning(), autoprewarm_main(), BackgroundWriterMain(), bbsink_copystream_archive_contents(), bbsink_copystream_end_archive(), bbsink_copystream_new(), bbsink_throttle_begin_backup(), check_log_duration(), CheckPointGuts(), CleanupBackend(), clock_timestamp(), CreateCheckPoint(), CreateEndOfRecoveryRecord(), CreateOverwriteContrecordRecord(), CreateRestartPoint(), dblink_cancel_query(), DetermineSleepTime(), disable_timeout(), disable_timeouts(), do_analyze_rel(), do_start_worker(), enable_startup_progress_timeout(), enable_timeout_after(), enable_timeout_at(), enable_timeout_every(), enable_timeouts(), entry_alloc(), entry_reset(), get_role_password(), GetCurrentTransactionStopTimestamp(), GetReplicationApplyDelay(), handle_sig_alarm(), has_startup_progress_timeout_expired(), heap_vacuum_rel(), initialize_prng(), InitProcessGlobals(), KnownAssignedXidsCompress(), launcher_determine_sleep(), libpqsrv_cancel(), LockBufferForCleanup(), log_disconnections(), LogCheckpointEnd(), logicalrep_worker_launch(), LogicalRepApplyLoop(), maybe_start_bgworkers(), pa_send_data(), PerformWalRecovery(), pgfdw_abort_cleanup_begin(), pgfdw_cancel_query(), pgfdw_exec_cleanup_query(), pgfdw_finish_abort_cleanup(), pgfdw_get_cleanup_result(), pgss_shmem_startup(), pgstat_build_snapshot(), pgstat_report_activity(), pgstat_report_analyze(), pgstat_report_archiver(), pgstat_report_autovac(), pgstat_report_checksum_failures_in_db(), pgstat_report_stat(), pgstat_report_vacuum(), pgstat_reset(), pgstat_reset_after_failure(), pgstat_reset_counters(), pgstat_reset_of_kind(), pgstat_reset_slru(), PostgresSingleUserMain(), PostmasterMain(), PrepareTransaction(), process_syncing_tables_for_apply(), ProcessConfigFileInternal(), ProcessPendingWrites(), ProcessRepliesIfAny(), ProcessStandbyReplyMessage(), ProcessWalSndrMessage(), ProcSleep(), rebuild_database_list(), RecordTransactionAbort(), RecordTransactionAbortPrepared(), RecordTransactionCommitPrepared(), recoveryApplyDelay(), ReplicationSlotRelease(), reschedule_timeouts(), ResolveRecoveryConflictWithBufferPin(), ResolveRecoveryConflictWithLock(), ResolveRecoveryConflictWithVirtualXIDs(), RestoreSlotFromDisk(), send_feedback(), SetCurrentStatementStartTimestamp(), SetupApplyOrSyncWorker(), 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 2149 of file timestamp.c.

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

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

References AdjustTimestampForTypmod(), and GetCurrentTransactionStartTimestamp().

Referenced by ExecEvalSQLValueFunction().

◆ GetSQLLocalTimestamp()

Timestamp GetSQLLocalTimestamp ( int32  typmod)

Definition at line 1676 of file timestamp.c.

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

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

Referenced by ExecEvalSQLValueFunction().

◆ in_range_interval_interval()

Datum in_range_interval_interval ( PG_FUNCTION_ARGS  )

Definition at line 3869 of file timestamp.c.

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

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

◆ in_range_timestamp_interval()

Datum in_range_timestamp_interval ( PG_FUNCTION_ARGS  )

Definition at line 3828 of file timestamp.c.

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

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

Referenced by in_range_date_interval().

◆ in_range_timestamptz_interval()

Datum in_range_timestamptz_interval ( PG_FUNCTION_ARGS  )

Definition at line 3791 of file timestamp.c.

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

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

◆ interval2itm()

void interval2itm ( Interval  span,
struct pg_itm itm 
)

Definition at line 2028 of file timestamp.c.

2029{
2030 TimeOffset time;
2031 TimeOffset tfrac;
2032
2033 itm->tm_year = span.month / MONTHS_PER_YEAR;
2034 itm->tm_mon = span.month % MONTHS_PER_YEAR;
2035 itm->tm_mday = span.day;
2036 time = span.time;
2037
2038 tfrac = time / USECS_PER_HOUR;
2039 time -= tfrac * USECS_PER_HOUR;
2040 itm->tm_hour = tfrac;
2041 tfrac = time / USECS_PER_MINUTE;
2042 time -= tfrac * USECS_PER_MINUTE;
2043 itm->tm_min = (int) tfrac;
2044 tfrac = time / USECS_PER_SEC;
2045 time -= tfrac * USECS_PER_SEC;
2046 itm->tm_sec = (int) tfrac;
2047 itm->tm_usec = (int) time;
2048}
int64 tm_hour
Definition: timestamp.h:70
int tm_year
Definition: timestamp.h:73
int tm_mon
Definition: timestamp.h:72
int tm_mday
Definition: timestamp.h:71
int tm_sec
Definition: timestamp.h:68
int tm_min
Definition: timestamp.h:69
int tm_usec
Definition: timestamp.h:67

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

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

◆ interval_avg()

Datum interval_avg ( PG_FUNCTION_ARGS  )

Definition at line 4160 of file timestamp.c.

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

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

◆ interval_avg_accum()

Datum interval_avg_accum ( PG_FUNCTION_ARGS  )

Definition at line 3995 of file timestamp.c.

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

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

◆ interval_avg_accum_inv()

Datum interval_avg_accum_inv ( PG_FUNCTION_ARGS  )

Definition at line 4142 of file timestamp.c.

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

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

◆ interval_avg_combine()

Datum interval_avg_combine ( PG_FUNCTION_ARGS  )

Definition at line 4018 of file timestamp.c.

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

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

◆ interval_avg_deserialize()

Datum interval_avg_deserialize ( PG_FUNCTION_ARGS  )

Definition at line 4099 of file timestamp.c.

4100{
4101 bytea *sstate;
4102 IntervalAggState *result;
4104
4105 if (!AggCheckCallContext(fcinfo, NULL))
4106 elog(ERROR, "aggregate function called in non-aggregate context");
4107
4108 sstate = PG_GETARG_BYTEA_PP(0);
4109
4110 /*
4111 * Initialize a StringInfo so that we can "receive" it using the standard
4112 * recv-function infrastructure.
4113 */
4115 VARSIZE_ANY_EXHDR(sstate));
4116
4117 result = (IntervalAggState *) palloc0(sizeof(IntervalAggState));
4118
4119 /* N */
4120 result->N = pq_getmsgint64(&buf);
4121
4122 /* sumX */
4123 result->sumX.time = pq_getmsgint64(&buf);
4124 result->sumX.day = pq_getmsgint(&buf, 4);
4125 result->sumX.month = pq_getmsgint(&buf, 4);
4126
4127 /* pInfcount */
4128 result->pInfcount = pq_getmsgint64(&buf);
4129
4130 /* nInfcount */
4131 result->nInfcount = pq_getmsgint64(&buf);
4132
4133 pq_getmsgend(&buf);
4134
4135 PG_RETURN_POINTER(result);
4136}
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
void * palloc0(Size size)
Definition: mcxt.c:1347
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4511
static char * buf
Definition: pg_test_fsync.c: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:130
#define VARDATA_ANY(PTR)
Definition: varatt.h:324
#define VARSIZE_ANY_EXHDR(PTR)
Definition: varatt.h:317

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

◆ interval_avg_serialize()

Datum interval_avg_serialize ( PG_FUNCTION_ARGS  )

Definition at line 4061 of file timestamp.c.

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

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

◆ interval_cmp()

Datum interval_cmp ( PG_FUNCTION_ARGS  )

Definition at line 2570 of file timestamp.c.

2571{
2572 Interval *interval1 = PG_GETARG_INTERVAL_P(0);
2573 Interval *interval2 = PG_GETARG_INTERVAL_P(1);
2574
2575 PG_RETURN_INT32(interval_cmp_internal(interval1, interval2));
2576}
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_INT32.

Referenced by gbt_intvkey_cmp().

◆ interval_cmp_internal()

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

Definition at line 2498 of file timestamp.c.

2499{
2500 INT128 span1 = interval_cmp_value(interval1);
2501 INT128 span2 = interval_cmp_value(interval2);
2502
2503 return int128_compare(span1, span2);
2504}
static INT128 interval_cmp_value(const Interval *interval)
Definition: timestamp.c:2476
static int int128_compare(INT128 x, INT128 y)
Definition: int128.h:238
Definition: int128.h:108

References int128_compare(), and interval_cmp_value().

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

◆ interval_cmp_value()

static INT128 interval_cmp_value ( const Interval interval)
inlinestatic

Definition at line 2476 of file timestamp.c.

2477{
2478 INT128 span;
2479 int64 days;
2480
2481 /*
2482 * Combine the month and day fields into an integral number of days.
2483 * Because the inputs are int32, int64 arithmetic suffices here.
2484 */
2485 days = interval->month * INT64CONST(30);
2486 days += interval->day;
2487
2488 /* Widen time field to 128 bits */
2489 span = int64_to_int128(interval->time);
2490
2491 /* Scale up days to microseconds, forming a 128-bit product */
2493
2494 return span;
2495}
const char *const days[]
Definition: datetime.c:84
#define USECS_PER_DAY
Definition: timestamp.h:131
static INT128 int64_to_int128(int64 v)
Definition: int128.h:255
static void int128_add_int64_mul_int64(INT128 *i128, int64 x, int64 y)
Definition: int128.h:177

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

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

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

Referenced by interval_avg().

◆ interval_eq()

Datum interval_eq ( PG_FUNCTION_ARGS  )

Definition at line 2516 of file timestamp.c.

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

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by gbt_intveq().

◆ interval_finite()

Datum interval_finite ( PG_FUNCTION_ARGS  )

◆ interval_ge()

Datum interval_ge ( PG_FUNCTION_ARGS  )

Definition at line 2561 of file timestamp.c.

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

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by gbt_intvge().

◆ interval_gt()

Datum interval_gt ( PG_FUNCTION_ARGS  )

Definition at line 2543 of file timestamp.c.

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

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by gbt_intvgt().

◆ interval_hash()

Datum interval_hash ( PG_FUNCTION_ARGS  )

Definition at line 2586 of file timestamp.c.

2587{
2590 int64 span64;
2591
2592 /*
2593 * Use only the least significant 64 bits for hashing. The upper 64 bits
2594 * seldom add any useful information, and besides we must do it like this
2595 * for compatibility with hashes calculated before use of INT128 was
2596 * introduced.
2597 */
2598 span64 = int128_to_int64(span);
2599
2601}
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:641
Datum hashint8(PG_FUNCTION_ARGS)
Definition: hashfunc.c:83
static int64 int128_to_int64(INT128 val)
Definition: int128.h:269
#define Int64GetDatumFast(X)
Definition: postgres.h:554

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

◆ interval_hash_extended()

Datum interval_hash_extended ( PG_FUNCTION_ARGS  )

Definition at line 2604 of file timestamp.c.

2605{
2608 int64 span64;
2609
2610 /* Same approach as interval_hash */
2611 span64 = int128_to_int64(span);
2612
2614 PG_GETARG_DATUM(1));
2615}
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
Datum hashint8extended(PG_FUNCTION_ARGS)
Definition: hashfunc.c:103

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

◆ interval_in()

Datum interval_in ( PG_FUNCTION_ARGS  )

Definition at line 890 of file timestamp.c.

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

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

Referenced by check_timezone(), and flatten_set_variable_args().

◆ interval_justify_days()

Datum interval_justify_days ( PG_FUNCTION_ARGS  )

Definition at line 2995 of file timestamp.c.

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

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

◆ interval_justify_hours()

Datum interval_justify_hours ( PG_FUNCTION_ARGS  )

Definition at line 2953 of file timestamp.c.

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

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

Referenced by timestamp_mi().

◆ interval_justify_interval()

Datum interval_justify_interval ( PG_FUNCTION_ARGS  )

Definition at line 2873 of file timestamp.c.

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

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

◆ interval_larger()

Datum interval_larger ( PG_FUNCTION_ARGS  )

Definition at line 3426 of file timestamp.c.

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

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_INTERVAL_P.

◆ interval_le()

Datum interval_le ( PG_FUNCTION_ARGS  )

Definition at line 2552 of file timestamp.c.

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

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by gbt_intvle().

◆ interval_lt()

Datum interval_lt ( PG_FUNCTION_ARGS  )

Definition at line 2534 of file timestamp.c.

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

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

Referenced by abs_interval(), and gbt_intvlt().

◆ interval_mi()

Datum interval_mi ( PG_FUNCTION_ARGS  )

Definition at line 3511 of file timestamp.c.

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

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

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

◆ interval_mul()

Datum interval_mul ( PG_FUNCTION_ARGS  )

Definition at line 3560 of file timestamp.c.

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

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

Referenced by interval_lerp(), and mul_d_interval().

◆ interval_ne()

Datum interval_ne ( PG_FUNCTION_ARGS  )

Definition at line 2525 of file timestamp.c.

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

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_BOOL.

◆ interval_out()

Datum interval_out ( PG_FUNCTION_ARGS  )

Definition at line 972 of file timestamp.c.

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

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

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

◆ interval_part()

Datum interval_part ( PG_FUNCTION_ARGS  )

Definition at line 6239 of file timestamp.c.

6240{
6241 return interval_part_common(fcinfo, false);
6242}

References interval_part_common().

◆ interval_part_common()

static Datum interval_part_common ( PG_FUNCTION_ARGS  ,
bool  retnumeric 
)
static

Definition at line 6032 of file timestamp.c.

6033{
6034 text *units = PG_GETARG_TEXT_PP(0);
6036 int64 intresult;
6037 int type,
6038 val;
6039 char *lowunits;
6040 struct pg_itm tt,
6041 *tm = &tt;
6042
6043 lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
6044 VARSIZE_ANY_EXHDR(units),
6045 false);
6046
6047 type = DecodeUnits(0, lowunits, &val);
6048 if (type == UNKNOWN_FIELD)
6049 type = DecodeSpecial(0, lowunits, &val);
6050
6052 {
6053 double r = NonFiniteIntervalPart(type, val, lowunits,
6055
6056 if (r != 0.0)
6057 {
6058 if (retnumeric)
6059 {
6060 if (r < 0)
6062 CStringGetDatum("-Infinity"),
6064 Int32GetDatum(-1));
6065 else if (r > 0)
6067 CStringGetDatum("Infinity"),
6069 Int32GetDatum(-1));
6070 }
6071 else
6073 }
6074 else
6076 }
6077
6078 if (type == UNITS)
6079 {
6081 switch (val)
6082 {
6083 case DTK_MICROSEC:
6084 intresult = tm->tm_sec * INT64CONST(1000000) + tm->tm_usec;
6085 break;
6086
6087 case DTK_MILLISEC:
6088 if (retnumeric)
6089 /*---
6090 * tm->tm_sec * 1000 + fsec / 1000
6091 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
6092 */
6094 else
6095 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + tm->tm_usec / 1000.0);
6096 break;
6097
6098 case DTK_SECOND:
6099 if (retnumeric)
6100 /*---
6101 * tm->tm_sec + fsec / 1'000'000
6102 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
6103 */
6105 else
6106 PG_RETURN_FLOAT8(tm->tm_sec + tm->tm_usec / 1000000.0);
6107 break;
6108
6109 case DTK_MINUTE:
6110 intresult = tm->tm_min;
6111 break;
6112
6113 case DTK_HOUR:
6114 intresult = tm->tm_hour;
6115 break;
6116
6117 case DTK_DAY:
6118 intresult = tm->tm_mday;
6119 break;
6120
6121 case DTK_WEEK:
6122 intresult = tm->tm_mday / 7;
6123 break;
6124
6125 case DTK_MONTH:
6126 intresult = tm->tm_mon;
6127 break;
6128
6129 case DTK_QUARTER:
6130
6131 /*
6132 * We want to maintain the rule that a field extracted from a
6133 * negative interval is the negative of the field's value for
6134 * the sign-reversed interval. The broken-down tm_year and
6135 * tm_mon aren't very helpful for that, so work from
6136 * interval->month.
6137 */
6138 if (interval->month >= 0)
6139 intresult = (tm->tm_mon / 3) + 1;
6140 else
6141 intresult = -(((-interval->month % MONTHS_PER_YEAR) / 3) + 1);
6142 break;
6143
6144 case DTK_YEAR:
6145 intresult = tm->tm_year;
6146 break;
6147
6148 case DTK_DECADE:
6149 /* caution: C division may have negative remainder */
6150 intresult = tm->tm_year / 10;
6151 break;
6152
6153 case DTK_CENTURY:
6154 /* caution: C division may have negative remainder */
6155 intresult = tm->tm_year / 100;
6156 break;
6157
6158 case DTK_MILLENNIUM:
6159 /* caution: C division may have negative remainder */
6160 intresult = tm->tm_year / 1000;
6161 break;
6162
6163 default:
6164 ereport(ERROR,
6165 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6166 errmsg("unit \"%s\" not supported for type %s",
6167 lowunits, format_type_be(INTERVALOID))));
6168 intresult = 0;
6169 }
6170 }
6171 else if (type == RESERV && val == DTK_EPOCH)
6172 {
6173 if (retnumeric)
6174 {
6175 Numeric result;
6176 int64 secs_from_day_month;
6177 int64 val;
6178
6179 /*
6180 * To do this calculation in integer arithmetic even though
6181 * DAYS_PER_YEAR is fractional, multiply everything by 4 and then
6182 * divide by 4 again at the end. This relies on DAYS_PER_YEAR
6183 * being a multiple of 0.25 and on SECS_PER_DAY being a multiple
6184 * of 4.
6185 */
6186 secs_from_day_month = ((int64) (4 * DAYS_PER_YEAR) * (interval->month / MONTHS_PER_YEAR) +
6188 (int64) 4 * interval->day) * (SECS_PER_DAY / 4);
6189
6190 /*---
6191 * result = secs_from_day_month + interval->time / 1'000'000
6192 * = (secs_from_day_month * 1'000'000 + interval->time) / 1'000'000
6193 */
6194
6195 /*
6196 * Try the computation inside int64; if it overflows, do it in
6197 * numeric (slower). This overflow happens around 10^9 days, so
6198 * not common in practice.
6199 */
6200 if (!pg_mul_s64_overflow(secs_from_day_month, 1000000, &val) &&
6202 result = int64_div_fast_to_numeric(val, 6);
6203 else
6204 result =
6206 int64_to_numeric(secs_from_day_month),
6207 NULL);
6208
6209 PG_RETURN_NUMERIC(result);
6210 }
6211 else
6212 {
6213 float8 result;
6214
6215 result = interval->time / 1000000.0;
6216 result += ((double) DAYS_PER_YEAR * SECS_PER_DAY) * (interval->month / MONTHS_PER_YEAR);
6217 result += ((double) DAYS_PER_MONTH * SECS_PER_DAY) * (interval->month % MONTHS_PER_YEAR);
6218 result += ((double) SECS_PER_DAY) * interval->day;
6219
6220 PG_RETURN_FLOAT8(result);
6221 }
6222 }
6223 else
6224 {
6225 ereport(ERROR,
6226 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6227 errmsg("unit \"%s\" not recognized for type %s",
6228 lowunits, format_type_be(INTERVALOID))));
6229 intresult = 0;
6230 }
6231
6232 if (retnumeric)
6234 else
6235 PG_RETURN_FLOAT8(intresult);
6236}
int DecodeUnits(int field, const char *lowtoken, int *val)
Definition: datetime.c:4047
int DecodeSpecial(int field, const char *lowtoken, int *val)
Definition: datetime.c:3148
Numeric int64_to_numeric(int64 val)
Definition: numeric.c: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:5986
#define DAYS_PER_YEAR
Definition: timestamp.h:107
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:367
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Definition: fmgr.h:645
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
#define DTK_EPOCH
Definition: datetime.h:152
#define UNKNOWN_FIELD
Definition: datetime.h:124
#define DTK_DECADE
Definition: datetime.h:168
#define DTK_SECOND
Definition: datetime.h:160
#define DTK_QUARTER
Definition: datetime.h:166
#define DTK_CENTURY
Definition: datetime.h:169
#define DTK_DAY
Definition: datetime.h:163
#define RESERV
Definition: datetime.h:90
#define DTK_MILLENNIUM
Definition: datetime.h:170
#define DTK_HOUR
Definition: datetime.h:162
#define DTK_WEEK
Definition: datetime.h:164
#define DTK_MICROSEC
Definition: datetime.h:172
#define DTK_YEAR
Definition: datetime.h:167
#define DTK_MILLISEC
Definition: datetime.h:171
#define DTK_MONTH
Definition: datetime.h:165
#define DTK_MINUTE
Definition: datetime.h:161
#define UNITS
Definition: datetime.h:107
static bool pg_mul_s64_overflow(int64 a, int64 b, int64 *result)
Definition: int.h:293
#define PG_RETURN_NUMERIC(x)
Definition: numeric.h:80
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:212
#define InvalidOid
Definition: postgres_ext.h:36
char * downcase_truncate_identifier(const char *ident, int len, bool warn)
Definition: scansup.c:37
const char * type

References CStringGetDatum(), DAYS_PER_MONTH, DAYS_PER_YEAR, DecodeSpecial(), DecodeUnits(), DirectFunctionCall3, downcase_truncate_identifier(), DTK_CENTURY, DTK_DAY, DTK_DECADE, DTK_EPOCH, DTK_HOUR, DTK_MICROSEC, DTK_MILLENNIUM, DTK_MILLISEC, DTK_MINUTE, DTK_MONTH, DTK_QUARTER, DTK_SECOND, DTK_WEEK, DTK_YEAR, ereport, errcode(), errmsg(), ERROR, format_type_be(), Int32GetDatum(), int64_div_fast_to_numeric(), int64_to_numeric(), 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 3455 of file timestamp.c.

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

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

Referenced by in_range_interval_interval(), and interval_lerp().

◆ interval_recv()

Datum interval_recv ( PG_FUNCTION_ARGS  )

Definition at line 996 of file timestamp.c.

997{
999
1000#ifdef NOT_USED
1001 Oid typelem = PG_GETARG_OID(1);
1002#endif
1003 int32 typmod = PG_GETARG_INT32(2);
1005
1006 interval = (Interval *) palloc(sizeof(Interval));
1007
1009 interval->day = pq_getmsgint(buf, sizeof(interval->day));
1011
1012 AdjustIntervalForTypmod(interval, typmod, NULL);
1013
1015}
StringInfoData * StringInfo
Definition: stringinfo.h:54

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

◆ interval_scale()

Datum interval_scale ( PG_FUNCTION_ARGS  )

Definition at line 1327 of file timestamp.c.

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

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

◆ interval_send()

◆ interval_sign()

static int interval_sign ( const Interval interval)
static

◆ interval_smaller()

Datum interval_smaller ( PG_FUNCTION_ARGS  )

Definition at line 3411 of file timestamp.c.

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

References interval_cmp_internal(), PG_GETARG_INTERVAL_P, and PG_RETURN_INTERVAL_P.

◆ interval_sum()

Datum interval_sum ( PG_FUNCTION_ARGS  )

Definition at line 4200 of file timestamp.c.

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

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

◆ interval_support()

Datum interval_support ( PG_FUNCTION_ARGS  )

Definition at line 1264 of file timestamp.c.

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

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

◆ interval_trunc()

Datum interval_trunc ( PG_FUNCTION_ARGS  )

Definition at line 5064 of file timestamp.c.

5065{
5066 text *units = PG_GETARG_TEXT_PP(0);
5068 Interval *result;
5069 int type,
5070 val;
5071 char *lowunits;
5072 struct pg_itm tt,
5073 *tm = &tt;
5074
5075 result = (Interval *) palloc(sizeof(Interval));
5076
5077 lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
5078 VARSIZE_ANY_EXHDR(units),
5079 false);
5080
5081 type = DecodeUnits(0, lowunits, &val);
5082
5083 if (type == UNITS)
5084 {
5086 {
5087 /*
5088 * Errors thrown here for invalid units should exactly match those
5089 * below, else there will be unexpected discrepancies between
5090 * finite- and infinite-input cases.
5091 */
5092 switch (val)
5093 {
5094 case DTK_MILLENNIUM:
5095 case DTK_CENTURY:
5096 case DTK_DECADE:
5097 case DTK_YEAR:
5098 case DTK_QUARTER:
5099 case DTK_MONTH:
5100 case DTK_DAY:
5101 case DTK_HOUR:
5102 case DTK_MINUTE:
5103 case DTK_SECOND:
5104 case DTK_MILLISEC:
5105 case DTK_MICROSEC:
5106 memcpy(result, interval, sizeof(Interval));
5107 PG_RETURN_INTERVAL_P(result);
5108 break;
5109
5110 default:
5111 ereport(ERROR,
5112 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5113 errmsg("unit \"%s\" not supported for type %s",
5114 lowunits, format_type_be(INTERVALOID)),
5115 (val == DTK_WEEK) ? errdetail("Months usually have fractional weeks.") : 0));
5116 result = 0;
5117 }
5118 }
5119
5121 switch (val)
5122 {
5123 case DTK_MILLENNIUM:
5124 /* caution: C division may have negative remainder */
5125 tm->tm_year = (tm->tm_year / 1000) * 1000;
5126 /* FALL THRU */
5127 case DTK_CENTURY:
5128 /* caution: C division may have negative remainder */
5129 tm->tm_year = (tm->tm_year / 100) * 100;
5130 /* FALL THRU */
5131 case DTK_DECADE:
5132 /* caution: C division may have negative remainder */
5133 tm->tm_year = (tm->tm_year / 10) * 10;
5134 /* FALL THRU */
5135 case DTK_YEAR:
5136 tm->tm_mon = 0;
5137 /* FALL THRU */
5138 case DTK_QUARTER:
5139 tm->tm_mon = 3 * (tm->tm_mon / 3);
5140 /* FALL THRU */
5141 case DTK_MONTH:
5142 tm->tm_mday = 0;
5143 /* FALL THRU */
5144 case DTK_DAY:
5145 tm->tm_hour = 0;
5146 /* FALL THRU */
5147 case DTK_HOUR:
5148 tm->tm_min = 0;
5149 /* FALL THRU */
5150 case DTK_MINUTE:
5151 tm->tm_sec = 0;
5152 /* FALL THRU */
5153 case DTK_SECOND:
5154 tm->tm_usec = 0;
5155 break;
5156 case DTK_MILLISEC:
5157 tm->tm_usec = (tm->tm_usec / 1000) * 1000;
5158 break;
5159 case DTK_MICROSEC:
5160 break;
5161
5162 default:
5163 ereport(ERROR,
5164 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5165 errmsg("unit \"%s\" not supported for type %s",
5166 lowunits, format_type_be(INTERVALOID)),
5167 (val == DTK_WEEK) ? errdetail("Months usually have fractional weeks.") : 0));
5168 }
5169
5170 if (itm2interval(tm, result) != 0)
5171 ereport(ERROR,
5172 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
5173 errmsg("interval out of range")));
5174 }
5175 else
5176 {
5177 ereport(ERROR,
5178 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5179 errmsg("unit \"%s\" not recognized for type %s",
5180 lowunits, format_type_be(INTERVALOID))));
5181 }
5182
5183 PG_RETURN_INTERVAL_P(result);
5184}
int itm2interval(struct pg_itm *itm, Interval *span)
Definition: timestamp.c:2058
int errdetail(const char *fmt,...)
Definition: elog.c:1203

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

◆ interval_um()

Datum interval_um ( PG_FUNCTION_ARGS  )

Definition at line 3398 of file timestamp.c.

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

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

Referenced by abs_interval().

◆ interval_um_internal()

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

Definition at line 3378 of file timestamp.c.

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

References Interval::day, ereport, errcode(), errmsg(), ERROR, 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 1046 of file timestamp.c.

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

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

◆ intervaltypmodleastfield()

static int intervaltypmodleastfield ( int32  typmod)
static

Definition at line 1211 of file timestamp.c.

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

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

Referenced by interval_support().

◆ intervaltypmodout()

Datum intervaltypmodout ( PG_FUNCTION_ARGS  )

Definition at line 1125 of file timestamp.c.

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

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

◆ isoweek2date()

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

Definition at line 5216 of file timestamp.c.

5217{
5218 j2date(isoweek2j(*year, woy), year, mon, mday);
5219}
void j2date(int jd, int *year, int *month, int *day)
Definition: datetime.c:311

References isoweek2j(), and j2date().

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

◆ isoweek2j()

int isoweek2j ( int  year,
int  week 
)

Definition at line 5196 of file timestamp.c.

5197{
5198 int day0,
5199 day4;
5200
5201 /* fourth day of current year */
5202 day4 = date2j(year, 1, 4);
5203
5204 /* day0 == offset to first day of week (Monday) */
5205 day0 = j2day(day4 - 1);
5206
5207 return ((week - 1) * 7) + (day4 - day0);
5208}

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

5230{
5231 int jday;
5232
5233 jday = isoweek2j(*year, isoweek);
5234 /* convert Gregorian week start (Sunday=1) to ISO week start (Monday=1) */
5235 if (wday > 1)
5236 jday += wday - 2;
5237 else
5238 jday += 6;
5239 j2date(jday, year, mon, mday);
5240}

References isoweek2j(), and j2date().

Referenced by do_to_timestamp().

◆ itm2interval()

int itm2interval ( struct pg_itm itm,
Interval span 
)

Definition at line 2058 of file timestamp.c.

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

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

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

◆ itmin2interval()

int itmin2interval ( struct pg_itm_in itm_in,
Interval span 
)

Definition at line 2096 of file timestamp.c.

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

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

Referenced by interval_in(), and pg_timezone_abbrevs().

◆ lookup_timezone()

static pg_tz * lookup_timezone ( text zone)
static

Definition at line 559 of file timestamp.c.

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

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

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

◆ make_interval()

Datum make_interval ( PG_FUNCTION_ARGS  )

Definition at line 1529 of file timestamp.c.

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

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

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

◆ make_timestamp_internal()

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

Definition at line 573 of file timestamp.c.

575{
576 struct pg_tm tm;
578 TimeOffset time;
579 int dterr;
580 bool bc = false;
581 Timestamp result;
582
583 tm.tm_year = year;
584 tm.tm_mon = month;
585 tm.tm_mday = day;
586
587 /* Handle negative years as BC */
588 if (tm.tm_year < 0)
589 {
590 bc = true;
591 tm.tm_year = -tm.tm_year;
592 }
593
594 dterr = ValidateDate(DTK_DATE_M, false, false, bc, &tm);
595
596 if (dterr != 0)
598 (errcode(ERRCODE_DATETIME_FIELD_OVERFLOW),
599 errmsg("date field value out of range: %d-%02d-%02d",
600 year, month, day)));
601
604 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
605 errmsg("date out of range: %d-%02d-%02d",
606 year, month, day)));
607
609
610 /* Check for time overflow */
611 if (float_time_overflows(hour, min, sec))
613 (errcode(ERRCODE_DATETIME_FIELD_OVERFLOW),
614 errmsg("time field value out of range: %d:%02d:%02g",
615 hour, min, sec)));
616
617 /* This should match tm2time */
618 time = (((hour * MINS_PER_HOUR + min) * SECS_PER_MINUTE)
619 * USECS_PER_SEC) + (int64) rint(sec * USECS_PER_SEC);
620
622 pg_add_s64_overflow(result, time, &result)))
624 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
625 errmsg("timestamp out of range: %d-%02d-%02d %d:%02d:%02g",
626 year, month, day,
627 hour, min, sec)));
628
629 /* final range check catches just-out-of-range timestamps */
630 if (!IS_VALID_TIMESTAMP(result))
632 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
633 errmsg("timestamp out of range: %d-%02d-%02d %d:%02d:%02g",
634 year, month, day,
635 hour, min, sec)));
636
637 return result;
638}
int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc, struct pg_tm *tm)
Definition: datetime.c:2508
#define unlikely(x)
Definition: c.h:330
#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:1470
#define DTK_DATE_M
Definition: datetime.h:191
long date
Definition: pgtypes_date.h:9

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

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

◆ make_timestamptz()

Datum make_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 664 of file timestamp.c.

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

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

◆ make_timestamptz_at_timezone()

Datum make_timestamptz_at_timezone ( PG_FUNCTION_ARGS  )

Definition at line 685 of file timestamp.c.

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

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

◆ makeIntervalAggState()

static IntervalAggState * makeIntervalAggState ( FunctionCallInfo  fcinfo)
static

Definition at line 3919 of file timestamp.c.

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

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

Referenced by interval_avg_accum(), and interval_avg_combine().

◆ mul_d_interval()

Datum mul_d_interval ( PG_FUNCTION_ARGS  )

Definition at line 3680 of file timestamp.c.

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

References DirectFunctionCall2, interval_mul(), and PG_GETARG_DATUM.

◆ NonFiniteIntervalPart()

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

Definition at line 5986 of file timestamp.c.

5987{
5988 if ((type != UNITS) && (type != RESERV))
5989 ereport(ERROR,
5990 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5991 errmsg("unit \"%s\" not recognized for type %s",
5992 lowunits, format_type_be(INTERVALOID))));
5993
5994 switch (unit)
5995 {
5996 /* Oscillating units */
5997 case DTK_MICROSEC:
5998 case DTK_MILLISEC:
5999 case DTK_SECOND:
6000 case DTK_MINUTE:
6001 case DTK_WEEK:
6002 case DTK_MONTH:
6003 case DTK_QUARTER:
6004 return 0.0;
6005
6006 /* Monotonically-increasing units */
6007 case DTK_HOUR:
6008 case DTK_DAY:
6009 case DTK_YEAR:
6010 case DTK_DECADE:
6011 case DTK_CENTURY:
6012 case DTK_MILLENNIUM:
6013 case DTK_EPOCH:
6014 if (isNegative)
6015 return -get_float8_infinity();
6016 else
6017 return get_float8_infinity();
6018
6019 default:
6020 ereport(ERROR,
6021 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
6022 errmsg("unit \"%s\" not supported for type %s",
6023 lowunits, format_type_be(INTERVALOID))));
6024 return 0.0; /* keep compiler quiet */
6025 }
6026}
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 5376 of file timestamp.c.

5378{
5379 if ((type != UNITS) && (type != RESERV))
5380 ereport(ERROR,
5381 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5382 errmsg("unit \"%s\" not recognized for type %s",
5383 lowunits,
5384 format_type_be(isTz ? TIMESTAMPTZOID : TIMESTAMPOID))));
5385
5386 switch (unit)
5387 {
5388 /* Oscillating units */
5389 case DTK_MICROSEC:
5390 case DTK_MILLISEC:
5391 case DTK_SECOND:
5392 case DTK_MINUTE:
5393 case DTK_HOUR:
5394 case DTK_DAY:
5395 case DTK_MONTH:
5396 case DTK_QUARTER:
5397 case DTK_WEEK:
5398 case DTK_DOW:
5399 case DTK_ISODOW:
5400 case DTK_DOY:
5401 case DTK_TZ:
5402 case DTK_TZ_MINUTE:
5403 case DTK_TZ_HOUR:
5404 return 0.0;
5405
5406 /* Monotonically-increasing units */
5407 case DTK_YEAR:
5408 case DTK_DECADE:
5409 case DTK_CENTURY:
5410 case DTK_MILLENNIUM:
5411 case DTK_JULIAN:
5412 case DTK_ISOYEAR:
5413 case DTK_EPOCH:
5414 if (isNegative)
5415 return -get_float8_infinity();
5416 else
5417 return get_float8_infinity();
5418
5419 default:
5420 ereport(ERROR,
5421 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5422 errmsg("unit \"%s\" not supported for type %s",
5423 lowunits,
5424 format_type_be(isTz ? TIMESTAMPTZOID : TIMESTAMPOID))));
5425 return 0.0; /* keep compiler quiet */
5426 }
5427}
#define DTK_JULIAN
Definition: datetime.h:173
#define DTK_TZ_HOUR
Definition: datetime.h:177
#define DTK_TZ_MINUTE
Definition: datetime.h:178
#define DTK_ISODOW
Definition: datetime.h:180
#define DTK_ISOYEAR
Definition: datetime.h:179
#define DTK_DOY
Definition: datetime.h:176
#define DTK_TZ
Definition: datetime.h:146
#define DTK_DOW
Definition: datetime.h:175

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

Referenced by timestamp_part_common(), and timestamptz_part_common().

◆ now()

Definition at line 1608 of file timestamp.c.

References GetCurrentTransactionStartTimestamp(), and PG_RETURN_TIMESTAMPTZ.

Referenced by advanceConnectionState(), ApplyLauncherMain(), BackgroundWriterMain(), bbsink_copystream_archive_contents(), CalculateCopyStreamSleeptime(), CheckArchiveTimeout(), CheckpointerMain(), doLog(), doRetry(), dumpTimestamp(), enable_timeout(), enable_timeout_after(), enable_timeout_at(), enable_timeout_every(), enable_timeouts(), executeMetaCommand(), flushAndSendFeedback(), handle_sig_alarm(), HandleCopyStream(), has_startup_progress_timeout_expired(), initialize_prng(), IsCheckpointOnSchedule(), LagTrackerRead(), launch_worker(), libpqsrv_cancel(), LockBufferForCleanup(), logicalrep_worker_launch(), LogicalRepApplyLoop(), LogRecoveryConflict(), maybe_start_bgworkers(), mxid_age(), OutputFsync(), PerformRadiusTransaction(), pg_clock_gettime_ns(), pg_time_now(), pg_time_now_lazy(), pg_timezone_abbrevs(), pgfdw_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(), schedule_alarm(), send_feedback(), sendFeedback(), ServerLoop(), set_next_rotation_time(), StreamLogicalLog(), SysLoggerMain(), threadRun(), timetz_zone(), update_synced_slots_inactive_since(), WaitForWALToBecomeAvailable(), WalRcvComputeNextWakeup(), WalRcvRunning(), WalRcvStreaming(), WalReceiverMain(), WalSndComputeSleeptime(), WalSndUpdateProgress(), WalSndWriteData(), xid_age(), XLogBackgroundFlush(), XLogWalRcvSendHSFeedback(), and XLogWalRcvSendReply().

◆ overlaps_timestamp()

Datum overlaps_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 2624 of file timestamp.c.

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

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

◆ parse_sane_timezone()

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

Definition at line 490 of file timestamp.c.

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

References DecodeTimezone(), DecodeTimezoneName(), DetermineTimeZoneAbbrevOffset(), DetermineTimeZoneOffset(), DTERR_BAD_FORMAT, DTERR_TZDISP_OVERFLOW, ereport, errcode(), errhint(), errmsg(), 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 1632 of file timestamp.c.

1633{
1635}
TimestampTz PgReloadTime
Definition: timestamp.c:56

References PG_RETURN_TIMESTAMPTZ, and PgReloadTime.

◆ pg_postmaster_start_time()

Datum pg_postmaster_start_time ( PG_FUNCTION_ARGS  )

Definition at line 1626 of file timestamp.c.

1627{
1629}
TimestampTz PgStartTime
Definition: timestamp.c:53

References PG_RETURN_TIMESTAMPTZ, and PgStartTime.

◆ SetEpochTimestamp()

Timestamp SetEpochTimestamp ( void  )

Definition at line 2171 of file timestamp.c.

2172{
2173 Timestamp dt;
2174 struct pg_tm tt,
2175 *tm = &tt;
2176
2178 /* we don't bother to test for failure ... */
2179 tm2timestamp(tm, 0, NULL, &dt);
2180
2181 return dt;
2182} /* SetEpochTimestamp() */
void GetEpochTime(struct pg_tm *tm)
Definition: timestamp.c:2149
int tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *result)
Definition: timestamp.c:1987

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

1615{
1617}
TimestampTz GetCurrentStatementStartTimestamp(void)
Definition: xact.c:878

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

2110{
2111 return (((((hour * MINS_PER_HOUR) + min) * SECS_PER_MINUTE) + sec) * USECS_PER_SEC) + fsec;
2112}

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

1802{
1803 TimestampTz result;
1804
1805 result = (TimestampTz) tm -
1807 result *= USECS_PER_SEC;
1808
1809 return result;
1810}

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

1691{
1692 struct timeval tp;
1693 char templ[128];
1694 char buf[128];
1695 pg_time_t tt;
1696
1697 gettimeofday(&tp, NULL);
1698 tt = (pg_time_t) tp.tv_sec;
1699 pg_strftime(templ, sizeof(templ), "%a %b %d %H:%M:%S.%%06d %Y %Z",
1701 snprintf(buf, sizeof(buf), templ, tp.tv_usec);
1702
1704}
#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:184

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

◆ timestamp2timestamptz()

static TimestampTz timestamp2timestamptz ( Timestamp  timestamp)
static

Definition at line 6452 of file timestamp.c.

6453{
6455}
TimestampTz timestamp2timestamptz_opt_overflow(Timestamp timestamp, int *overflow)
Definition: timestamp.c:6400

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

6401{
6402 TimestampTz result;
6403 struct pg_tm tt,
6404 *tm = &tt;
6405 fsec_t fsec;
6406 int tz;
6407
6408 if (overflow)
6409 *overflow = 0;
6410
6412 return timestamp;
6413
6414 /* We don't expect this to fail, but check it pro forma */
6415 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0)
6416 {
6418
6419 result = dt2local(timestamp, -tz);
6420
6421 if (IS_VALID_TIMESTAMP(result))
6422 {
6423 return result;
6424 }
6425 else if (overflow)
6426 {
6427 if (result < MIN_TIMESTAMP)
6428 {
6429 *overflow = -1;
6430 TIMESTAMP_NOBEGIN(result);
6431 }
6432 else
6433 {
6434 *overflow = 1;
6435 TIMESTAMP_NOEND(result);
6436 }
6437 return result;
6438 }
6439 }
6440
6441 ereport(ERROR,
6442 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6443 errmsg("timestamp out of range")));
6444
6445 return 0;
6446}
#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 1891 of file timestamp.c.

1892{
1894 Timestamp time;
1895 pg_time_t utime;
1896
1897 /* Use session timezone if caller asks for default */
1898 if (attimezone == NULL)
1899 attimezone = session_timezone;
1900
1901 time = dt;
1902 TMODULO(time, date, USECS_PER_DAY);
1903
1904 if (time < INT64CONST(0))
1905 {
1906 time += USECS_PER_DAY;
1907 date -= 1;
1908 }
1909
1910 /* add offset to go from J2000 back to standard Julian date */
1912
1913 /* Julian day routine does not work for negative Julian days */
1914 if (date < 0 || date > (Timestamp) INT_MAX)
1915 return -1;
1916
1917 j2date((int) date, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
1918 dt2time(time, &tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
1919
1920 /* Done if no TZ conversion wanted */
1921 if (tzp == NULL)
1922 {
1923 tm->tm_isdst = -1;
1924 tm->tm_gmtoff = 0;
1925 tm->tm_zone = NULL;
1926 if (tzn != NULL)
1927 *tzn = NULL;
1928 return 0;
1929 }
1930
1931 /*
1932 * If the time falls within the range of pg_time_t, use pg_localtime() to
1933 * rotate to the local time zone.
1934 *
1935 * First, convert to an integral timestamp, avoiding possibly
1936 * platform-specific roundoff-in-wrong-direction errors, and adjust to
1937 * Unix epoch. Then see if we can convert to pg_time_t without loss. This
1938 * coding avoids hardwiring any assumptions about the width of pg_time_t,
1939 * so it should behave sanely on machines without int64.
1940 */
1941 dt = (dt - *fsec) / USECS_PER_SEC +
1943 utime = (pg_time_t) dt;
1944 if ((Timestamp) utime == dt)
1945 {
1946 struct pg_tm *tx = pg_localtime(&utime, attimezone);
1947
1948 tm->tm_year = tx->tm_year + 1900;
1949 tm->tm_mon = tx->tm_mon + 1;
1950 tm->tm_mday = tx->tm_mday;
1951 tm->tm_hour = tx->tm_hour;
1952 tm->tm_min = tx->tm_min;
1953 tm->tm_sec = tx->tm_sec;
1954 tm->tm_isdst = tx->tm_isdst;
1955 tm->tm_gmtoff = tx->tm_gmtoff;
1956 tm->tm_zone = tx->tm_zone;
1957 *tzp = -tm->tm_gmtoff;
1958 if (tzn != NULL)
1959 *tzn = tm->tm_zone;
1960 }
1961 else
1962 {
1963 /*
1964 * When out of range of pg_time_t, treat as GMT
1965 */
1966 *tzp = 0;
1967 /* Mark this as *no* time zone available */
1968 tm->tm_isdst = -1;
1969 tm->tm_gmtoff = 0;
1970 tm->tm_zone = NULL;
1971 if (tzn != NULL)
1972 *tzn = NULL;
1973 }
1974
1975 return 0;
1976}
void dt2time(Timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec)
Definition: timestamp.c:1864
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 4240 of file timestamp.c.

4241{
4244 Interval *result;
4245 fsec_t fsec1,
4246 fsec2;
4247 struct pg_itm tt,
4248 *tm = &tt;
4249 struct pg_tm tt1,
4250 *tm1 = &tt1;
4251 struct pg_tm tt2,
4252 *tm2 = &tt2;
4253
4254 result = (Interval *) palloc(sizeof(Interval));
4255
4256 /*
4257 * Handle infinities.
4258 *
4259 * We treat anything that amounts to "infinity - infinity" as an error,
4260 * since the interval type has nothing equivalent to NaN.
4261 */
4262 if (TIMESTAMP_IS_NOBEGIN(dt1))
4263 {
4264 if (TIMESTAMP_IS_NOBEGIN(dt2))
4265 ereport(ERROR,
4266 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4267 errmsg("interval out of range")));
4268 else
4269 INTERVAL_NOBEGIN(result);
4270 }
4271 else if (TIMESTAMP_IS_NOEND(dt1))
4272 {
4273 if (TIMESTAMP_IS_NOEND(dt2))
4274 ereport(ERROR,
4275 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4276 errmsg("interval out of range")));
4277 else
4278 INTERVAL_NOEND(result);
4279 }
4280 else if (TIMESTAMP_IS_NOBEGIN(dt2))
4281 INTERVAL_NOEND(result);
4282 else if (TIMESTAMP_IS_NOEND(dt2))
4283 INTERVAL_NOBEGIN(result);
4284 else if (timestamp2tm(dt1, NULL, tm1, &fsec1, NULL, NULL) == 0 &&
4285 timestamp2tm(dt2, NULL, tm2, &fsec2, NULL, NULL) == 0)
4286 {
4287 /* form the symbolic difference */
4288 tm->tm_usec = fsec1 - fsec2;
4289 tm->tm_sec = tm1->tm_sec - tm2->tm_sec;
4290 tm->tm_min = tm1->tm_min - tm2->tm_min;
4291 tm->tm_hour = tm1->tm_hour - tm2->tm_hour;
4292 tm->tm_mday = tm1->tm_mday - tm2->tm_mday;
4293 tm->tm_mon = tm1->tm_mon - tm2->tm_mon;
4294 tm->tm_year = tm1->tm_year - tm2->tm_year;
4295
4296 /* flip sign if necessary... */
4297 if (dt1 < dt2)
4298 {
4299 tm->tm_usec = -tm->tm_usec;
4300 tm->tm_sec = -tm->tm_sec;
4301 tm->tm_min = -tm->tm_min;
4302 tm->tm_hour = -tm->tm_hour;
4303 tm->tm_mday = -tm->tm_mday;
4304 tm->tm_mon = -tm->tm_mon;
4305 tm->tm_year = -tm->tm_year;
4306 }
4307
4308 /* propagate any negative fields into the next higher field */
4309 while (tm->tm_usec < 0)
4310 {
4311 tm->tm_usec += USECS_PER_SEC;
4312 tm->tm_sec--;
4313 }
4314
4315 while (tm->tm_sec < 0)
4316 {
4318 tm->tm_min--;
4319 }
4320
4321 while (tm->tm_min < 0)
4322 {
4324 tm->tm_hour--;
4325 }
4326
4327 while (tm->tm_hour < 0)
4328 {
4330 tm->tm_mday--;
4331 }
4332
4333 while (tm->tm_mday < 0)
4334 {
4335 if (dt1 < dt2)
4336 {
4337 tm->tm_mday += day_tab[isleap(tm1->tm_year)][tm1->tm_mon - 1];
4338 tm->tm_mon--;
4339 }
4340 else
4341 {
4342 tm->tm_mday += day_tab[isleap(tm2->tm_year)][tm2->tm_mon - 1];
4343 tm->tm_mon--;
4344 }
4345 }
4346
4347 while (tm->tm_mon < 0)
4348 {
4350 tm->tm_year--;
4351 }
4352
4353 /* recover sign if necessary... */
4354 if (dt1 < dt2)
4355 {
4356 tm->tm_usec = -tm->tm_usec;
4357 tm->tm_sec = -tm->tm_sec;
4358 tm->tm_min = -tm->tm_min;
4359 tm->tm_hour = -tm->tm_hour;
4360 tm->tm_mday = -tm->tm_mday;
4361 tm->tm_mon = -tm->tm_mon;
4362 tm->tm_year = -tm->tm_year;
4363 }
4364
4365 if (itm2interval(tm, result) != 0)
4366 ereport(ERROR,
4367 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4368 errmsg("interval out of range")));
4369 }
4370 else
4371 ereport(ERROR,
4372 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4373 errmsg("timestamp out of range")));
4374
4375 PG_RETURN_INTERVAL_P(result);
4376}
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 6875 of file timestamp.c.

6876{
6877 return timestamp_timestamptz(fcinfo);
6878}
Datum timestamp_timestamptz(PG_FUNCTION_ARGS)
Definition: timestamp.c:6382

References timestamp_timestamptz().

◆ timestamp_bin()

Datum timestamp_bin ( PG_FUNCTION_ARGS  )

Definition at line 4540 of file timestamp.c.

4541{
4542 Interval *stride = PG_GETARG_INTERVAL_P(0);
4544 Timestamp origin = PG_GETARG_TIMESTAMP(2);
4545 Timestamp result,
4546 stride_usecs,
4547 tm_diff,
4548 tm_modulo,
4549 tm_delta;
4550
4553
4554 if (TIMESTAMP_NOT_FINITE(origin))
4555 ereport(ERROR,
4556 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4557 errmsg("origin out of range")));
4558
4559 if (INTERVAL_NOT_FINITE(stride))
4560 ereport(ERROR,
4561 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4562 errmsg("timestamps cannot be binned into infinite intervals")));
4563
4564 if (stride->month != 0)
4565 ereport(ERROR,
4566 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4567 errmsg("timestamps cannot be binned into intervals containing months or years")));
4568
4569 if (unlikely(pg_mul_s64_overflow(stride->day, USECS_PER_DAY, &stride_usecs)) ||
4570 unlikely(pg_add_s64_overflow(stride_usecs, stride->time, &stride_usecs)))
4571 ereport(ERROR,
4572 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4573 errmsg("interval out of range")));
4574
4575 if (stride_usecs <= 0)
4576 ereport(ERROR,
4577 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4578 errmsg("stride must be greater than zero")));
4579
4580 if (unlikely(pg_sub_s64_overflow(timestamp, origin, &tm_diff)))
4581 ereport(ERROR,
4582 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4583 errmsg("interval out of range")));
4584
4585 /* These calculations cannot overflow */
4586 tm_modulo = tm_diff % stride_usecs;
4587 tm_delta = tm_diff - tm_modulo;
4588 result = origin + tm_delta;
4589
4590 /*
4591 * We want to round towards -infinity, not 0, when tm_diff is negative and
4592 * not a multiple of stride_usecs. This adjustment *can* cause overflow,
4593 * since the result might now be out of the range origin .. timestamp.
4594 */
4595 if (tm_modulo < 0)
4596 {
4597 if (unlikely(pg_sub_s64_overflow(result, stride_usecs, &result)) ||
4598 !IS_VALID_TIMESTAMP(result))
4599 ereport(ERROR,
4600 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4601 errmsg("timestamp out of range")));
4602 }
4603
4604 PG_RETURN_TIMESTAMP(result);
4605}

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

2252{
2255
2257}

References PG_GETARG_TIMESTAMP, PG_RETURN_INT32, and timestamp_cmp_internal().

Referenced by compareDatetime(), 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 2393 of file timestamp.c.

2394{
2395 Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2397
2399}
int32 timestamp_cmp_timestamptz_internal(Timestamp timestampVal, TimestampTz dt2)
Definition: timestamp.c:2318

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

2319{
2320 TimestampTz dt1;
2321 int overflow;
2322
2323 dt1 = timestamp2timestamptz_opt_overflow(timestampVal, &overflow);
2324 if (overflow > 0)
2325 {
2326 /* dt1 is larger than any finite timestamp, but less than infinity */
2327 return TIMESTAMP_IS_NOEND(dt2) ? -1 : +1;
2328 }
2329 if (overflow < 0)
2330 {
2331 /* dt1 is less than any finite timestamp, but more than -infinity */
2332 return TIMESTAMP_IS_NOBEGIN(dt2) ? +1 : -1;
2333 }
2334
2335 return timestamptz_cmp_internal(dt1, dt2);
2336}
#define timestamptz_cmp_internal(dt1, dt2)
Definition: timestamp.h:131

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

Datum timestamp_eq ( PG_FUNCTION_ARGS  )

Definition at line 2197 of file timestamp.c.

2198{
2201
2202 PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) == 0);
2203}

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

2340{
2341 Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2343
2344 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) == 0);
2345}

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

2263{
2266
2267 return timestamp_cmp_internal(a, b);
2268}
int y
Definition: isn.c:71
int b
Definition: isn.c:69
int x
Definition: isn.c:70
int a
Definition: isn.c:68

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

2243{
2246
2247 PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) >= 0);
2248}

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

2385{
2386 Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2388
2389 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) >= 0);
2390}

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

2225{
2228
2230}

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

2367{
2368 Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2370
2371 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) > 0);
2372}

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

2291{
2292 return hashint8(fcinfo);
2293}

References hashint8().

◆ timestamp_hash_extended()

Datum timestamp_hash_extended ( PG_FUNCTION_ARGS  )

Definition at line 2296 of file timestamp.c.

2297{
2298 return hashint8extended(fcinfo);
2299}

References hashint8extended().

◆ timestamp_in()

Datum timestamp_in ( PG_FUNCTION_ARGS  )

Definition at line 165 of file timestamp.c.

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

Datum timestamp_izone ( PG_FUNCTION_ARGS  )

Definition at line 6325 of file timestamp.c.

6326{
6329 TimestampTz result;
6330 int tz;
6331
6334
6336 ereport(ERROR,
6337 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6338 errmsg("interval time zone \"%s\" must be finite",
6340 PointerGetDatum(zone))))));
6341
6342 if (zone->month != 0 || zone->day != 0)
6343 ereport(ERROR,
6344 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6345 errmsg("interval time zone \"%s\" must not include months or days",
6347 PointerGetDatum(zone))))));
6348
6349 tz = zone->time / USECS_PER_SEC;
6350
6351 result = dt2local(timestamp, tz);
6352
6353 if (!IS_VALID_TIMESTAMP(result))
6354 ereport(ERROR,
6355 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6356 errmsg("timestamp out of range")));
6357
6358 PG_RETURN_TIMESTAMPTZ(result);
6359} /* timestamp_izone() */
Datum interval_out(PG_FUNCTION_ARGS)
Definition: timestamp.c:972
static char * DatumGetCString(Datum X)
Definition: postgres.h:335

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

2765{
2768 Timestamp result;
2769
2770 if (timestamp_cmp_internal(dt1, dt2) > 0)
2771 result = dt1;
2772 else
2773 result = dt2;
2774 PG_RETURN_TIMESTAMP(result);
2775}

References PG_GETARG_TIMESTAMP, PG_RETURN_TIMESTAMP, and timestamp_cmp_internal().

◆ timestamp_le()

Datum timestamp_le ( PG_FUNCTION_ARGS  )

Definition at line 2233 of file timestamp.c.

2234{
2237
2238 PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) <= 0);
2239}

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

2376{
2377 Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2379
2380 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) <= 0);
2381}

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

2216{
2219
2221}

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

2358{
2359 Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2361
2362 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) < 0);
2363}

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

2780{
2783 Interval *result;
2784
2785 result = (Interval *) palloc(sizeof(Interval));
2786
2787 /*
2788 * Handle infinities.
2789 *
2790 * We treat anything that amounts to "infinity - infinity" as an error,
2791 * since the interval type has nothing equivalent to NaN.
2792 */
2794 {
2795 if (TIMESTAMP_IS_NOBEGIN(dt1))
2796 {
2797 if (TIMESTAMP_IS_NOBEGIN(dt2))
2798 ereport(ERROR,
2799 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2800 errmsg("interval out of range")));
2801 else
2802 INTERVAL_NOBEGIN(result);
2803 }
2804 else if (TIMESTAMP_IS_NOEND(dt1))
2805 {
2806 if (TIMESTAMP_IS_NOEND(dt2))
2807 ereport(ERROR,
2808 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2809 errmsg("interval out of range")));
2810 else
2811 INTERVAL_NOEND(result);
2812 }
2813 else if (TIMESTAMP_IS_NOBEGIN(dt2))
2814 INTERVAL_NOEND(result);
2815 else /* TIMESTAMP_IS_NOEND(dt2) */
2816 INTERVAL_NOBEGIN(result);
2817
2818 PG_RETURN_INTERVAL_P(result);
2819 }
2820
2821 if (unlikely(pg_sub_s64_overflow(dt1, dt2, &result->time)))
2822 ereport(ERROR,
2823 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2824 errmsg("interval out of range")));
2825
2826 result->month = 0;
2827 result->day = 0;
2828
2829 /*----------
2830 * This is wrong, but removing it breaks a lot of regression tests.
2831 * For example:
2832 *
2833 * test=> SET timezone = 'EST5EDT';
2834 * test=> SELECT
2835 * test-> ('2005-10-30 13:22:00-05'::timestamptz -
2836 * test(> '2005-10-29 13:22:00-04'::timestamptz);
2837 * ?column?
2838 * ----------------
2839 * 1 day 01:00:00
2840 * (1 row)
2841 *
2842 * so adding that to the first timestamp gets:
2843 *
2844 * test=> SELECT
2845 * test-> ('2005-10-29 13:22:00-04'::timestamptz +
2846 * test(> ('2005-10-30 13:22:00-05'::timestamptz -
2847 * test(> '2005-10-29 13:22:00-04'::timestamptz)) at time zone 'EST';
2848 * timezone
2849 * --------------------
2850 * 2005-10-30 14:22:00
2851 * (1 row)
2852 *----------
2853 */
2855 IntervalPGetDatum(result)));
2856
2857 PG_RETURN_INTERVAL_P(result);
2858}
Datum interval_justify_hours(PG_FUNCTION_ARGS)
Definition: timestamp.c:2953

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

2207{
2210
2211 PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) != 0);
2212}

References PG_GETARG_TIMESTAMP, PG_RETURN_BOOL, and timestamp_cmp_internal().

◆ timestamp_ne_timestamptz()

Datum timestamp_ne_timestamptz ( PG_FUNCTION_ARGS  )

Definition at line 2348 of file timestamp.c.

2349{
2350 Timestamp timestampVal = PG_GETARG_TIMESTAMP(0);
2352
2353 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) != 0);
2354}

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

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

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

5692{
5693 return timestamp_part_common(fcinfo, false);
5694}

References timestamp_part_common().

◆ timestamp_part_common()

static Datum timestamp_part_common ( PG_FUNCTION_ARGS  ,
bool  retnumeric 
)
static

Definition at line 5433 of file timestamp.c.

5434{
5435 text *units = PG_GETARG_TEXT_PP(0);
5437 int64 intresult;
5439 int type,
5440 val;
5441 char *lowunits;
5442 fsec_t fsec;
5443 struct pg_tm tt,
5444 *tm = &tt;
5445
5446 lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
5447 VARSIZE_ANY_EXHDR(units),
5448 false);
5449
5450 type = DecodeUnits(0, lowunits, &val);
5451 if (type == UNKNOWN_FIELD)
5452 type = DecodeSpecial(0, lowunits, &val);
5453
5455 {
5456 double r = NonFiniteTimestampTzPart(type, val, lowunits,
5458 false);
5459
5460 if (r != 0.0)
5461 {
5462 if (retnumeric)
5463 {
5464 if (r < 0)
5466 CStringGetDatum("-Infinity"),
5468 Int32GetDatum(-1));
5469 else if (r > 0)
5471 CStringGetDatum("Infinity"),
5473 Int32GetDatum(-1));
5474 }
5475 else
5477 }
5478 else
5480 }
5481
5482 if (type == UNITS)
5483 {
5484 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
5485 ereport(ERROR,
5486 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
5487 errmsg("timestamp out of range")));
5488
5489 switch (val)
5490 {
5491 case DTK_MICROSEC:
5492 intresult = tm->tm_sec * INT64CONST(1000000) + fsec;
5493 break;
5494
5495 case DTK_MILLISEC:
5496 if (retnumeric)
5497 /*---
5498 * tm->tm_sec * 1000 + fsec / 1000
5499 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
5500 */
5502 else
5503 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0);
5504 break;
5505
5506 case DTK_SECOND:
5507 if (retnumeric)
5508 /*---
5509 * tm->tm_sec + fsec / 1'000'000
5510 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
5511 */
5513 else
5514 PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0);
5515 break;
5516
5517 case DTK_MINUTE:
5518 intresult = tm->tm_min;
5519 break;
5520
5521 case DTK_HOUR:
5522 intresult = tm->tm_hour;
5523 break;
5524
5525 case DTK_DAY:
5526 intresult = tm->tm_mday;
5527 break;
5528
5529 case DTK_MONTH:
5530 intresult = tm->tm_mon;
5531 break;
5532
5533 case DTK_QUARTER:
5534 intresult = (tm->tm_mon - 1) / 3 + 1;
5535 break;
5536
5537 case DTK_WEEK:
5538 intresult = date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday);
5539 break;
5540
5541 case DTK_YEAR:
5542 if (tm->tm_year > 0)
5543 intresult = tm->tm_year;
5544 else
5545 /* there is no year 0, just 1 BC and 1 AD */
5546 intresult = tm->tm_year - 1;
5547 break;
5548
5549 case DTK_DECADE:
5550
5551 /*
5552 * what is a decade wrt dates? let us assume that decade 199
5553 * is 1990 thru 1999... decade 0 starts on year 1 BC, and -1
5554 * is 11 BC thru 2 BC...
5555 */
5556 if (tm->tm_year >= 0)
5557 intresult = tm->tm_year / 10;
5558 else
5559 intresult = -((8 - (tm->tm_year - 1)) / 10);
5560 break;
5561
5562 case DTK_CENTURY:
5563
5564 /* ----
5565 * centuries AD, c>0: year in [ (c-1)* 100 + 1 : c*100 ]
5566 * centuries BC, c<0: year in [ c*100 : (c+1) * 100 - 1]
5567 * there is no number 0 century.
5568 * ----
5569 */
5570 if (tm->tm_year > 0)
5571 intresult = (tm->tm_year + 99) / 100;
5572 else
5573 /* caution: C division may have negative remainder */
5574 intresult = -((99 - (tm->tm_year - 1)) / 100);
5575 break;
5576
5577 case DTK_MILLENNIUM:
5578 /* see comments above. */
5579 if (tm->tm_year > 0)
5580 intresult = (tm->tm_year + 999) / 1000;
5581 else
5582 intresult = -((999 - (tm->tm_year - 1)) / 1000);
5583 break;
5584
5585 case DTK_JULIAN:
5586 if (retnumeric)
5590 NULL),
5591 NULL));
5592 else
5595 tm->tm_sec + (fsec / 1000000.0)) / (double) SECS_PER_DAY);
5596 break;
5597
5598 case DTK_ISOYEAR:
5599 intresult = date2isoyear(tm->tm_year, tm->tm_mon, tm->tm_mday);
5600 /* Adjust BC years */
5601 if (intresult <= 0)
5602 intresult -= 1;
5603 break;
5604
5605 case DTK_DOW:
5606 case DTK_ISODOW:
5607 intresult = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday));
5608 if (val == DTK_ISODOW && intresult == 0)
5609 intresult = 7;
5610 break;
5611
5612 case DTK_DOY:
5613 intresult = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)
5614 - date2j(tm->tm_year, 1, 1) + 1);
5615 break;
5616
5617 case DTK_TZ:
5618 case DTK_TZ_MINUTE:
5619 case DTK_TZ_HOUR:
5620 default:
5621 ereport(ERROR,
5622 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5623 errmsg("unit \"%s\" not supported for type %s",
5624 lowunits, format_type_be(TIMESTAMPOID))));
5625 intresult = 0;
5626 }
5627 }
5628 else if (type == RESERV)
5629 {
5630 switch (val)
5631 {
5632 case DTK_EPOCH:
5634 /* (timestamp - epoch) / 1000000 */
5635 if (retnumeric)
5636 {
5637 Numeric result;
5638
5639 if (timestamp < (PG_INT64_MAX + epoch))
5641 else
5642 {
5645 NULL),
5646 int64_to_numeric(1000000),
5647 NULL);
5649 NumericGetDatum(result),
5650 Int32GetDatum(6)));
5651 }
5652 PG_RETURN_NUMERIC(result);
5653 }
5654 else
5655 {
5656 float8 result;
5657
5658 /* try to avoid precision loss in subtraction */
5659 if (timestamp < (PG_INT64_MAX + epoch))
5660 result = (timestamp - epoch) / 1000000.0;
5661 else
5662 result = ((float8) timestamp - epoch) / 1000000.0;
5663 PG_RETURN_FLOAT8(result);
5664 }
5665 break;
5666
5667 default:
5668 ereport(ERROR,
5669 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5670 errmsg("unit \"%s\" not supported for type %s",
5671 lowunits, format_type_be(TIMESTAMPOID))));
5672 intresult = 0;
5673 }
5674 }
5675 else
5676 {
5677 ereport(ERROR,
5678 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5679 errmsg("unit \"%s\" not recognized for type %s",
5680 lowunits, format_type_be(TIMESTAMPOID))));
5681 intresult = 0;
5682 }
5683
5684 if (retnumeric)
5686 else
5687 PG_RETURN_FLOAT8(intresult);
5688}
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:5376
int date2isoweek(int year, int mon, int mday)
Definition: timestamp.c:5247
#define PG_INT64_MAX
Definition: c.h:546
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 3042 of file timestamp.c.

3043{
3045 Interval *span = PG_GETARG_INTERVAL_P(1);
3046 Timestamp result;
3047
3048 /*
3049 * Handle infinities.
3050 *
3051 * We treat anything that amounts to "infinity - infinity" as an error,
3052 * since the timestamp type has nothing equivalent to NaN.
3053 */
3054 if (INTERVAL_IS_NOBEGIN(span))
3055 {
3057 ereport(ERROR,
3058 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3059 errmsg("timestamp out of range")));
3060 else
3061 TIMESTAMP_NOBEGIN(result);
3062 }
3063 else if (INTERVAL_IS_NOEND(span))
3064 {
3066 ereport(ERROR,
3067 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3068 errmsg("timestamp out of range")));
3069 else
3070 TIMESTAMP_NOEND(result);
3071 }
3073 result = timestamp;
3074 else
3075 {
3076 if (span->month != 0)
3077 {
3078 struct pg_tm tt,
3079 *tm = &tt;
3080 fsec_t fsec;
3081
3082 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
3083 ereport(ERROR,
3084 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3085 errmsg("timestamp out of range")));
3086
3087 if (pg_add_s32_overflow(tm->tm_mon, span->month, &tm->tm_mon))
3088 ereport(ERROR,
3089 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3090 errmsg("timestamp out of range")));
3091 if (tm->tm_mon > MONTHS_PER_YEAR)
3092 {
3093 tm->tm_year += (tm->tm_mon - 1) / MONTHS_PER_YEAR;
3094 tm->tm_mon = ((tm->tm_mon - 1) % MONTHS_PER_YEAR) + 1;
3095 }
3096 else if (tm->tm_mon < 1)
3097 {
3098 tm->tm_year += tm->tm_mon / MONTHS_PER_YEAR - 1;
3100 }
3101
3102 /* adjust for end of month boundary problems... */
3103 if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
3104 tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]);
3105
3106 if (tm2timestamp(tm, fsec, NULL, &timestamp) != 0)
3107 ereport(ERROR,
3108 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3109 errmsg("timestamp out of range")));
3110 }
3111
3112 if (span->day != 0)
3113 {
3114 struct pg_tm tt,
3115 *tm = &tt;
3116 fsec_t fsec;
3117 int julian;
3118
3119 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
3120 ereport(ERROR,
3121 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3122 errmsg("timestamp out of range")));
3123
3124 /*
3125 * Add days by converting to and from Julian. We need an overflow
3126 * check here since j2date expects a non-negative integer input.
3127 */
3128 julian = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday);
3129 if (pg_add_s32_overflow(julian, span->day, &julian) ||
3130 julian < 0)
3131 ereport(ERROR,
3132 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3133 errmsg("timestamp out of range")));
3134 j2date(julian, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
3135
3136 if (tm2timestamp(tm, fsec, NULL, &timestamp) != 0)
3137 ereport(ERROR,
3138 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3139 errmsg("timestamp out of range")));
3140 }
3141
3143 ereport(ERROR,
3144 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3145 errmsg("timestamp out of range")));
3146
3148 ereport(ERROR,
3149 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3150 errmsg("timestamp out of range")));
3151
3152 result = timestamp;
3153 }
3154
3155 PG_RETURN_TIMESTAMP(result);
3156}

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

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

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

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

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

◆ timestamp_send()

◆ timestamp_smaller()

Datum timestamp_smaller ( PG_FUNCTION_ARGS  )

Definition at line 2749 of file timestamp.c.

2750{
2753 Timestamp result;
2754
2755 /* use timestamp_cmp_internal to be sure this agrees with comparisons */
2756 if (timestamp_cmp_internal(dt1, dt2) < 0)
2757 result = dt1;
2758 else
2759 result = dt2;
2760 PG_RETURN_TIMESTAMP(result);
2761}

References PG_GETARG_TIMESTAMP, PG_RETURN_TIMESTAMP, and timestamp_cmp_internal().

◆ timestamp_sortsupport()

Datum timestamp_sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 2272 of file timestamp.c.

2273{
2275
2276#if SIZEOF_DATUM >= 8
2277
2278 /*
2279 * If this build has pass-by-value timestamps, then we can use a standard
2280 * comparator function.
2281 */
2282 ssup->comparator = ssup_datum_signed_cmp;
2283#else
2285#endif
2287}
static int timestamp_fastcmp(Datum x, Datum y, SortSupport ssup)
Definition: timestamp.c:2262
#define PG_RETURN_VOID()
Definition: fmgr.h:349
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 326 of file timestamp.c.

327{
328 Node *rawreq = (Node *) PG_GETARG_POINTER(0);
329 Node *ret = NULL;
330
331 if (IsA(rawreq, SupportRequestSimplify))
332 {
334
336 }
337
339}
Node * TemporalSimplify(int32 max_precis, Node *node)
Definition: datetime.c:4840

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

4612{
4613 text *units = PG_GETARG_TEXT_PP(0);
4615 Timestamp result;
4616 int type,
4617 val;
4618 char *lowunits;
4619 fsec_t fsec;
4620 struct pg_tm tt,
4621 *tm = &tt;
4622
4623 lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
4624 VARSIZE_ANY_EXHDR(units),
4625 false);
4626
4627 type = DecodeUnits(0, lowunits, &val);
4628
4629 if (type == UNITS)
4630 {
4632 {
4633 /*
4634 * Errors thrown here for invalid units should exactly match those
4635 * below, else there will be unexpected discrepancies between
4636 * finite- and infinite-input cases.
4637 */
4638 switch (val)
4639 {
4640 case DTK_WEEK:
4641 case DTK_MILLENNIUM:
4642 case DTK_CENTURY:
4643 case DTK_DECADE:
4644 case DTK_YEAR:
4645 case DTK_QUARTER:
4646 case DTK_MONTH:
4647 case DTK_DAY:
4648 case DTK_HOUR:
4649 case DTK_MINUTE:
4650 case DTK_SECOND:
4651 case DTK_MILLISEC:
4652 case DTK_MICROSEC:
4654 break;
4655 default:
4656 ereport(ERROR,
4657 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4658 errmsg("unit \"%s\" not supported for type %s",
4659 lowunits, format_type_be(TIMESTAMPOID))));
4660 result = 0;
4661 }
4662 }
4663
4664 if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
4665 ereport(ERROR,
4666 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4667 errmsg("timestamp out of range")));
4668
4669 switch (val)
4670 {
4671 case DTK_WEEK:
4672 {
4673 int woy;
4674
4676
4677 /*
4678 * If it is week 52/53 and the month is January, then the
4679 * week must belong to the previous year. Also, some
4680 * December dates belong to the next year.
4681 */
4682 if (woy >= 52 && tm->tm_mon == 1)
4683 --tm->tm_year;
4684 if (woy <= 1 && tm->tm_mon == MONTHS_PER_YEAR)
4685 ++tm->tm_year;
4686 isoweek2date(woy, &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
4687 tm->tm_hour = 0;
4688 tm->tm_min = 0;
4689 tm->tm_sec = 0;
4690 fsec = 0;
4691 break;
4692 }
4693 case DTK_MILLENNIUM:
4694 /* see comments in timestamptz_trunc */
4695 if (tm->tm_year > 0)
4696 tm->tm_year = ((tm->tm_year + 999) / 1000) * 1000 - 999;
4697 else
4698 tm->tm_year = -((999 - (tm->tm_year - 1)) / 1000) * 1000 + 1;
4699 /* FALL THRU */
4700 case DTK_CENTURY:
4701 /* see comments in timestamptz_trunc */
4702 if (tm->tm_year > 0)
4703 tm->tm_year = ((tm->tm_year + 99) / 100) * 100 - 99;
4704 else
4705 tm->tm_year = -((99 - (tm->tm_year - 1)) / 100) * 100 + 1;
4706 /* FALL THRU */
4707 case DTK_DECADE:
4708 /* see comments in timestamptz_trunc */
4709 if (val != DTK_MILLENNIUM && val != DTK_CENTURY)
4710 {
4711 if (tm->tm_year > 0)
4712 tm->tm_year = (tm->tm_year / 10) * 10;
4713 else
4714 tm->tm_year = -((8 - (tm->tm_year - 1)) / 10) * 10;
4715 }
4716 /* FALL THRU */
4717 case DTK_YEAR:
4718 tm->tm_mon = 1;
4719 /* FALL THRU */
4720 case DTK_QUARTER:
4721 tm->tm_mon = (3 * ((tm->tm_mon - 1) / 3)) + 1;
4722 /* FALL THRU */
4723 case DTK_MONTH:
4724 tm->tm_mday = 1;
4725 /* FALL THRU */
4726 case DTK_DAY:
4727 tm->tm_hour = 0;
4728 /* FALL THRU */
4729 case DTK_HOUR:
4730 tm->tm_min = 0;
4731 /* FALL THRU */
4732 case DTK_MINUTE:
4733 tm->tm_sec = 0;
4734 /* FALL THRU */
4735 case DTK_SECOND:
4736 fsec = 0;
4737 break;
4738
4739 case DTK_MILLISEC:
4740 fsec = (fsec / 1000) * 1000;
4741 break;
4742
4743 case DTK_MICROSEC:
4744 break;
4745
4746 default:
4747 ereport(ERROR,
4748 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4749 errmsg("unit \"%s\" not supported for type %s",
4750 lowunits, format_type_be(TIMESTAMPOID))));
4751 result = 0;
4752 }
4753
4754 if (tm2timestamp(tm, fsec, NULL, &result) != 0)
4755 ereport(ERROR,
4756 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4757 errmsg("timestamp out of range")));
4758 }
4759 else
4760 {
4761 ereport(ERROR,
4762 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4763 errmsg("unit \"%s\" not recognized for type %s",
4764 lowunits, format_type_be(TIMESTAMPOID))));
4765 result = 0;
4766 }
4767
4768 PG_RETURN_TIMESTAMP(result);
4769}
void isoweek2date(int woy, int *year, int *mon, int *mday)
Definition: timestamp.c:5216

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

6261{
6264 TimestampTz result;
6265 int tz;
6266 char tzname[TZ_STRLEN_MAX + 1];
6267 int type,
6268 val;
6269 pg_tz *tzp;
6270 struct pg_tm tm;
6271 fsec_t fsec;
6272
6275
6276 /*
6277 * Look up the requested timezone.
6278 */
6279 text_to_cstring_buffer(zone, tzname, sizeof(tzname));
6280
6281 type = DecodeTimezoneName(tzname, &val, &tzp);
6282
6284 {
6285 /* fixed-offset abbreviation */
6286 tz = val;
6287 result = dt2local(timestamp, tz);
6288 }
6289 else if (type == TZNAME_DYNTZ)
6290 {
6291 /* dynamic-offset abbreviation, resolve using specified time */
6292 if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, tzp) != 0)
6293 ereport(ERROR,
6294 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6295 errmsg("timestamp out of range")));
6296 tz = -DetermineTimeZoneAbbrevOffset(&tm, tzname, tzp);
6297 result = dt2local(timestamp, tz);
6298 }
6299 else
6300 {
6301 /* full zone name, rotate to that zone */
6302 if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, tzp) != 0)
6303 ereport(ERROR,
6304 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6305 errmsg("timestamp out of range")));
6306 tz = DetermineTimeZoneOffset(&tm, tzp);
6307 if (tm2timestamp(&tm, fsec, &tz, &result) != 0)
6308 ereport(ERROR,
6309 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6310 errmsg("timestamp out of range")));
6311 }
6312
6313 if (!IS_VALID_TIMESTAMP(result))
6314 ereport(ERROR,
6315 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6316 errmsg("timestamp out of range")));
6317
6318 PG_RETURN_TIMESTAMPTZ(result);
6319}

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

1722{
1723 TimestampTz diff = stop_time - start_time;
1724
1725 if (diff <= 0)
1726 {
1727 *secs = 0;
1728 *microsecs = 0;
1729 }
1730 else
1731 {
1732 *secs = (long) (diff / USECS_PER_SEC);
1733 *microsecs = (int) (diff % USECS_PER_SEC);
1734 }
1735}
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(), launcher_determine_sleep(), log_disconnections(), LogRecoveryConflict(), pgstat_report_activity(), pgstat_update_dbstats(), ProcSleep(), and schedule_alarm().

◆ TimestampDifferenceExceeds()

◆ TimestampDifferenceMilliseconds()

long TimestampDifferenceMilliseconds ( TimestampTz  start_time,
TimestampTz  stop_time 
)

Definition at line 1756 of file timestamp.c.

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

References INT64CONST, pg_sub_s64_overflow(), and start_time.

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

◆ TimestampTimestampTzRequiresRewrite()

bool TimestampTimestampTzRequiresRewrite ( void  )

Definition at line 6369 of file timestamp.c.

6370{
6371 long offset;
6372
6373 if (pg_get_timezone_offset(session_timezone, &offset) && offset == 0)
6374 return false;
6375 return true;
6376}
bool pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff)
Definition: localtime.c:1851

References pg_get_timezone_offset(), and session_timezone.

Referenced by ATColumnChangeRequiresRewrite().

◆ timestamptypmodin()

Datum timestamptypmodin ( PG_FUNCTION_ARGS  )

Definition at line 303 of file timestamp.c.

304{
306
308}
static int32 anytimestamp_typmodin(bool istz, ArrayType *ta)
Definition: timestamp.c:103

References anytimestamp_typmodin(), PG_GETARG_ARRAYTYPE_P, and PG_RETURN_INT32.

◆ timestamptypmodout()

Datum timestamptypmodout ( PG_FUNCTION_ARGS  )

Definition at line 311 of file timestamp.c.

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

References anytimestamp_typmodout(), PG_GETARG_INT32, and PG_RETURN_CSTRING.

◆ timestamptz2timestamp()

static Timestamp timestamptz2timestamp ( TimestampTz  timestamp)
static

Definition at line 6469 of file timestamp.c.

6470{
6471 Timestamp result;
6472 struct pg_tm tt,
6473 *tm = &tt;
6474 fsec_t fsec;
6475 int tz;
6476
6478 result = timestamp;
6479 else
6480 {
6481 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
6482 ereport(ERROR,
6483 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6484 errmsg("timestamp out of range")));
6485 if (tm2timestamp(tm, fsec, NULL, &result) != 0)
6486 ereport(ERROR,
6487 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6488 errmsg("timestamp out of range")));
6489 }
6490 return result;
6491}

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

4387{
4390 Interval *result;
4391 fsec_t fsec1,
4392 fsec2;
4393 struct pg_itm tt,
4394 *tm = &tt;
4395 struct pg_tm tt1,
4396 *tm1 = &tt1;
4397 struct pg_tm tt2,
4398 *tm2 = &tt2;
4399 int tz1;
4400 int tz2;
4401
4402 result = (Interval *) palloc(sizeof(Interval));
4403
4404 /*
4405 * Handle infinities.
4406 *
4407 * We treat anything that amounts to "infinity - infinity" as an error,
4408 * since the interval type has nothing equivalent to NaN.
4409 */
4410 if (TIMESTAMP_IS_NOBEGIN(dt1))
4411 {
4412 if (TIMESTAMP_IS_NOBEGIN(dt2))
4413 ereport(ERROR,
4414 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4415 errmsg("interval out of range")));
4416 else
4417 INTERVAL_NOBEGIN(result);
4418 }
4419 else if (TIMESTAMP_IS_NOEND(dt1))
4420 {
4421 if (TIMESTAMP_IS_NOEND(dt2))
4422 ereport(ERROR,
4423 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4424 errmsg("interval out of range")));
4425 else
4426 INTERVAL_NOEND(result);
4427 }
4428 else if (TIMESTAMP_IS_NOBEGIN(dt2))
4429 INTERVAL_NOEND(result);
4430 else if (TIMESTAMP_IS_NOEND(dt2))
4431 INTERVAL_NOBEGIN(result);
4432 else if (timestamp2tm(dt1, &tz1, tm1, &fsec1, NULL, NULL) == 0 &&
4433 timestamp2tm(dt2, &tz2, tm2, &fsec2, NULL, NULL) == 0)
4434 {
4435 /* form the symbolic difference */
4436 tm->tm_usec = fsec1 - fsec2;
4437 tm->tm_sec = tm1->tm_sec - tm2->tm_sec;
4438 tm->tm_min = tm1->tm_min - tm2->tm_min;
4439 tm->tm_hour = tm1->tm_hour - tm2->tm_hour;
4440 tm->tm_mday = tm1->tm_mday - tm2->tm_mday;
4441 tm->tm_mon = tm1->tm_mon - tm2->tm_mon;
4442 tm->tm_year = tm1->tm_year - tm2->tm_year;
4443
4444 /* flip sign if necessary... */
4445 if (dt1 < dt2)
4446 {
4447 tm->tm_usec = -tm->tm_usec;
4448 tm->tm_sec = -tm->tm_sec;
4449 tm->tm_min = -tm->tm_min;
4450 tm->tm_hour = -tm->tm_hour;
4451 tm->tm_mday = -tm->tm_mday;
4452 tm->tm_mon = -tm->tm_mon;
4453 tm->tm_year = -tm->tm_year;
4454 }
4455
4456 /* propagate any negative fields into the next higher field */
4457 while (tm->tm_usec < 0)
4458 {
4459 tm->tm_usec += USECS_PER_SEC;
4460 tm->tm_sec--;
4461 }
4462
4463 while (tm->tm_sec < 0)
4464 {
4466 tm->tm_min--;
4467 }
4468
4469 while (tm->tm_min < 0)
4470 {
4472 tm->tm_hour--;
4473 }
4474
4475 while (tm->tm_hour < 0)
4476 {
4478 tm->tm_mday--;
4479 }
4480
4481 while (tm->tm_mday < 0)
4482 {
4483 if (dt1 < dt2)
4484 {
4485 tm->tm_mday += day_tab[isleap(tm1->tm_year)][tm1->tm_mon - 1];
4486 tm->tm_mon--;
4487 }
4488 else
4489 {
4490 tm->tm_mday += day_tab[isleap(tm2->tm_year)][tm2->tm_mon - 1];
4491 tm->tm_mon--;
4492 }
4493 }
4494
4495 while (tm->tm_mon < 0)
4496 {
4498 tm->tm_year--;
4499 }
4500
4501 /*
4502 * Note: we deliberately ignore any difference between tz1 and tz2.
4503 */
4504
4505 /* recover sign if necessary... */
4506 if (dt1 < dt2)
4507 {
4508 tm->tm_usec = -tm->tm_usec;
4509 tm->tm_sec = -tm->tm_sec;
4510 tm->tm_min = -tm->tm_min;
4511 tm->tm_hour = -tm->tm_hour;
4512 tm->tm_mday = -tm->tm_mday;
4513 tm->tm_mon = -tm->tm_mon;
4514 tm->tm_year = -tm->tm_year;
4515 }
4516
4517 if (itm2interval(tm, result) != 0)
4518 ereport(ERROR,
4519 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4520 errmsg("interval out of range")));
4521 }
4522 else
4523 ereport(ERROR,
4524 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4525 errmsg("timestamp out of range")));
4526
4527 PG_RETURN_INTERVAL_P(result);
4528}

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

6882{
6883 return timestamptz_timestamp(fcinfo);
6884}
Datum timestamptz_timestamp(PG_FUNCTION_ARGS)
Definition: timestamp.c:6461

References timestamptz_timestamp().

◆ timestamptz_bin()

Datum timestamptz_bin ( PG_FUNCTION_ARGS  )

Definition at line 4775 of file timestamp.c.

4776{
4777 Interval *stride = PG_GETARG_INTERVAL_P(0);
4780 TimestampTz result,
4781 stride_usecs,
4782 tm_diff,
4783 tm_modulo,
4784 tm_delta;
4785
4788
4789 if (TIMESTAMP_NOT_FINITE(origin))
4790 ereport(ERROR,
4791 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4792 errmsg("origin out of range")));
4793
4794 if (INTERVAL_NOT_FINITE(stride))
4795 ereport(ERROR,
4796 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4797 errmsg("timestamps cannot be binned into infinite intervals")));
4798
4799 if (stride->month != 0)
4800 ereport(ERROR,
4801 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4802 errmsg("timestamps cannot be binned into intervals containing months or years")));
4803
4804 if (unlikely(pg_mul_s64_overflow(stride->day, USECS_PER_DAY, &stride_usecs)) ||
4805 unlikely(pg_add_s64_overflow(stride_usecs, stride->time, &stride_usecs)))
4806 ereport(ERROR,
4807 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4808 errmsg("interval out of range")));
4809
4810 if (stride_usecs <= 0)
4811 ereport(ERROR,
4812 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4813 errmsg("stride must be greater than zero")));
4814
4815 if (unlikely(pg_sub_s64_overflow(timestamp, origin, &tm_diff)))
4816 ereport(ERROR,
4817 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4818 errmsg("interval out of range")));
4819
4820 /* These calculations cannot overflow */
4821 tm_modulo = tm_diff % stride_usecs;
4822 tm_delta = tm_diff - tm_modulo;
4823 result = origin + tm_delta;
4824
4825 /*
4826 * We want to round towards -infinity, not 0, when tm_diff is negative and
4827 * not a multiple of stride_usecs. This adjustment *can* cause overflow,
4828 * since the result might now be out of the range origin .. timestamp.
4829 */
4830 if (tm_modulo < 0)
4831 {
4832 if (unlikely(pg_sub_s64_overflow(result, stride_usecs, &result)) ||
4833 !IS_VALID_TIMESTAMP(result))
4834 ereport(ERROR,
4835 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4836 errmsg("timestamp out of range")));
4837 }
4838
4839 PG_RETURN_TIMESTAMPTZ(result);
4840}

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

2403{
2405 Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
2406
2407 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) == 0);
2408}

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

2448{
2450 Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
2451
2452 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) <= 0);
2453}

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

2430{
2432 Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
2433
2434 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) < 0);
2435}

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

2303{
2304 return hashint8(fcinfo);
2305}

References hashint8().

◆ timestamptz_hash_extended()

Datum timestamptz_hash_extended ( PG_FUNCTION_ARGS  )

Definition at line 2308 of file timestamp.c.

2309{
2310 return hashint8extended(fcinfo);
2311}

References hashint8extended().

◆ timestamptz_in()

Datum timestamptz_in ( PG_FUNCTION_ARGS  )

Definition at line 417 of file timestamp.c.

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

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

6563{
6566 Timestamp result;
6567 int tz;
6568
6571
6573 ereport(ERROR,
6574 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6575 errmsg("interval time zone \"%s\" must be finite",
6577 PointerGetDatum(zone))))));
6578
6579 if (zone->month != 0 || zone->day != 0)
6580 ereport(ERROR,
6581 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6582 errmsg("interval time zone \"%s\" must not include months or days",
6584 PointerGetDatum(zone))))));
6585
6586 tz = -(zone->time / USECS_PER_SEC);
6587
6588 result = dt2local(timestamp, tz);
6589
6590 if (!IS_VALID_TIMESTAMP(result))
6591 ereport(ERROR,
6592 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6593 errmsg("timestamp out of range")));
6594
6595 PG_RETURN_TIMESTAMP(result);
6596}

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

2439{
2441 Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
2442
2443 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) >= 0);
2444}

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

2421{
2423 Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
2424
2425 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) > 0);
2426}

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

3320{
3321 Interval tspan;
3322
3323 interval_um_internal(span, &tspan);
3324
3325 return timestamptz_pl_interval_internal(timestamp, &tspan, attimezone);
3326}

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

2412{
2414 Timestamp timestampVal = PG_GETARG_TIMESTAMP(1);
2415
2416 PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) != 0);
2417}

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

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

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

5964{
5965 return timestamptz_part_common(fcinfo, false);
5966}

References timestamptz_part_common().

◆ timestamptz_part_common()

static Datum timestamptz_part_common ( PG_FUNCTION_ARGS  ,
bool  retnumeric 
)
static

Definition at line 5706 of file timestamp.c.

5707{
5708 text *units = PG_GETARG_TEXT_PP(0);
5710 int64 intresult;
5712 int tz;
5713 int type,
5714 val;
5715 char *lowunits;
5716 fsec_t fsec;
5717 struct pg_tm tt,
5718 *tm = &tt;
5719
5720 lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
5721 VARSIZE_ANY_EXHDR(units),
5722 false);
5723
5724 type = DecodeUnits(0, lowunits, &val);
5725 if (type == UNKNOWN_FIELD)
5726 type = DecodeSpecial(0, lowunits, &val);
5727
5729 {
5730 double r = NonFiniteTimestampTzPart(type, val, lowunits,
5732 true);
5733
5734 if (r != 0.0)
5735 {
5736 if (retnumeric)
5737 {
5738 if (r < 0)
5740 CStringGetDatum("-Infinity"),
5742 Int32GetDatum(-1));
5743 else if (r > 0)
5745 CStringGetDatum("Infinity"),
5747 Int32GetDatum(-1));
5748 }
5749 else
5751 }
5752 else
5754 }
5755
5756 if (type == UNITS)
5757 {
5758 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
5759 ereport(ERROR,
5760 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
5761 errmsg("timestamp out of range")));
5762
5763 switch (val)
5764 {
5765 case DTK_TZ:
5766 intresult = -tz;
5767 break;
5768
5769 case DTK_TZ_MINUTE:
5770 intresult = (-tz / SECS_PER_MINUTE) % MINS_PER_HOUR;
5771 break;
5772
5773 case DTK_TZ_HOUR:
5774 intresult = -tz / SECS_PER_HOUR;
5775 break;
5776
5777 case DTK_MICROSEC:
5778 intresult = tm->tm_sec * INT64CONST(1000000) + fsec;
5779 break;
5780
5781 case DTK_MILLISEC:
5782 if (retnumeric)
5783 /*---
5784 * tm->tm_sec * 1000 + fsec / 1000
5785 * = (tm->tm_sec * 1'000'000 + fsec) / 1000
5786 */
5788 else
5789 PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0);
5790 break;
5791
5792 case DTK_SECOND:
5793 if (retnumeric)
5794 /*---
5795 * tm->tm_sec + fsec / 1'000'000
5796 * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000
5797 */
5799 else
5800 PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0);
5801 break;
5802
5803 case DTK_MINUTE:
5804 intresult = tm->tm_min;
5805 break;
5806
5807 case DTK_HOUR:
5808 intresult = tm->tm_hour;
5809 break;
5810
5811 case DTK_DAY:
5812 intresult = tm->tm_mday;
5813 break;
5814
5815 case DTK_MONTH:
5816 intresult = tm->tm_mon;
5817 break;
5818
5819 case DTK_QUARTER:
5820 intresult = (tm->tm_mon - 1) / 3 + 1;
5821 break;
5822
5823 case DTK_WEEK:
5824 intresult = date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday);
5825 break;
5826
5827 case DTK_YEAR:
5828 if (tm->tm_year > 0)
5829 intresult = tm->tm_year;
5830 else
5831 /* there is no year 0, just 1 BC and 1 AD */
5832 intresult = tm->tm_year - 1;
5833 break;
5834
5835 case DTK_DECADE:
5836 /* see comments in timestamp_part */
5837 if (tm->tm_year > 0)
5838 intresult = tm->tm_year / 10;
5839 else
5840 intresult = -((8 - (tm->tm_year - 1)) / 10);
5841 break;
5842
5843 case DTK_CENTURY:
5844 /* see comments in timestamp_part */
5845 if (tm->tm_year > 0)
5846 intresult = (tm->tm_year + 99) / 100;
5847 else
5848 intresult = -((99 - (tm->tm_year - 1)) / 100);
5849 break;
5850
5851 case DTK_MILLENNIUM:
5852 /* see comments in timestamp_part */
5853 if (tm->tm_year > 0)
5854 intresult = (tm->tm_year + 999) / 1000;
5855 else
5856 intresult = -((999 - (tm->tm_year - 1)) / 1000);
5857 break;
5858
5859 case DTK_JULIAN:
5860 if (retnumeric)
5864 NULL),
5865 NULL));
5866 else
5869 tm->tm_sec + (fsec / 1000000.0)) / (double) SECS_PER_DAY);
5870 break;
5871
5872 case DTK_ISOYEAR:
5873 intresult = date2isoyear(tm->tm_year, tm->tm_mon, tm->tm_mday);
5874 /* Adjust BC years */
5875 if (intresult <= 0)
5876 intresult -= 1;
5877 break;
5878
5879 case DTK_DOW:
5880 case DTK_ISODOW:
5881 intresult = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday));
5882 if (val == DTK_ISODOW && intresult == 0)
5883 intresult = 7;
5884 break;
5885
5886 case DTK_DOY:
5887 intresult = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)
5888 - date2j(tm->tm_year, 1, 1) + 1);
5889 break;
5890
5891 default:
5892 ereport(ERROR,
5893 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5894 errmsg("unit \"%s\" not supported for type %s",
5895 lowunits, format_type_be(TIMESTAMPTZOID))));
5896 intresult = 0;
5897 }
5898 }
5899 else if (type == RESERV)
5900 {
5901 switch (val)
5902 {
5903 case DTK_EPOCH:
5905 /* (timestamp - epoch) / 1000000 */
5906 if (retnumeric)
5907 {
5908 Numeric result;
5909
5910 if (timestamp < (PG_INT64_MAX + epoch))
5912 else
5913 {
5916 NULL),
5917 int64_to_numeric(1000000),
5918 NULL);
5920 NumericGetDatum(result),
5921 Int32GetDatum(6)));
5922 }
5923 PG_RETURN_NUMERIC(result);
5924 }
5925 else
5926 {
5927 float8 result;
5928
5929 /* try to avoid precision loss in subtraction */
5930 if (timestamp < (PG_INT64_MAX + epoch))
5931 result = (timestamp - epoch) / 1000000.0;
5932 else
5933 result = ((float8) timestamp - epoch) / 1000000.0;
5934 PG_RETURN_FLOAT8(result);
5935 }
5936 break;
5937
5938 default:
5939 ereport(ERROR,
5940 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5941 errmsg("unit \"%s\" not supported for type %s",
5942 lowunits, format_type_be(TIMESTAMPTZOID))));
5943 intresult = 0;
5944 }
5945 }
5946 else
5947 {
5948 ereport(ERROR,
5949 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5950 errmsg("unit \"%s\" not recognized for type %s",
5951 lowunits, format_type_be(TIMESTAMPTZOID))));
5952
5953 intresult = 0;
5954 }
5955
5956 if (retnumeric)
5958 else
5959 PG_RETURN_FLOAT8(intresult);
5960}
#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 3185 of file timestamp.c.

3188{
3189 TimestampTz result;
3190 int tz;
3191
3192 /*
3193 * Handle infinities.
3194 *
3195 * We treat anything that amounts to "infinity - infinity" as an error,
3196 * since the timestamptz type has nothing equivalent to NaN.
3197 */
3198 if (INTERVAL_IS_NOBEGIN(span))
3199 {
3201 ereport(ERROR,
3202 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3203 errmsg("timestamp out of range")));
3204 else
3205 TIMESTAMP_NOBEGIN(result);
3206 }
3207 else if (INTERVAL_IS_NOEND(span))
3208 {
3210 ereport(ERROR,
3211 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3212 errmsg("timestamp out of range")));
3213 else
3214 TIMESTAMP_NOEND(result);
3215 }
3217 result = timestamp;
3218 else
3219 {
3220 /* Use session timezone if caller asks for default */
3221 if (attimezone == NULL)
3222 attimezone = session_timezone;
3223
3224 if (span->month != 0)
3225 {
3226 struct pg_tm tt,
3227 *tm = &tt;
3228 fsec_t fsec;
3229
3230 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, attimezone) != 0)
3231 ereport(ERROR,
3232 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3233 errmsg("timestamp out of range")));
3234
3235 if (pg_add_s32_overflow(tm->tm_mon, span->month, &tm->tm_mon))
3236 ereport(ERROR,
3237 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3238 errmsg("timestamp out of range")));
3239 if (tm->tm_mon > MONTHS_PER_YEAR)
3240 {
3241 tm->tm_year += (tm->tm_mon - 1) / MONTHS_PER_YEAR;
3242 tm->tm_mon = ((tm->tm_mon - 1) % MONTHS_PER_YEAR) + 1;
3243 }
3244 else if (tm->tm_mon < 1)
3245 {
3246 tm->tm_year += tm->tm_mon / MONTHS_PER_YEAR - 1;
3248 }
3249
3250 /* adjust for end of month boundary problems... */
3251 if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
3252 tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]);
3253
3254 tz = DetermineTimeZoneOffset(tm, attimezone);
3255
3256 if (tm2timestamp(tm, fsec, &tz, &timestamp) != 0)
3257 ereport(ERROR,
3258 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3259 errmsg("timestamp out of range")));
3260 }
3261
3262 if (span->day != 0)
3263 {
3264 struct pg_tm tt,
3265 *tm = &tt;
3266 fsec_t fsec;
3267 int julian;
3268
3269 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, attimezone) != 0)
3270 ereport(ERROR,
3271 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3272 errmsg("timestamp out of range")));
3273
3274 /*
3275 * Add days by converting to and from Julian. We need an overflow
3276 * check here since j2date expects a non-negative integer input.
3277 * In practice though, it will give correct answers for small
3278 * negative Julian dates; we should allow -1 to avoid
3279 * timezone-dependent failures, as discussed in timestamp.h.
3280 */
3281 julian = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday);
3282 if (pg_add_s32_overflow(julian, span->day, &julian) ||
3283 julian < -1)
3284 ereport(ERROR,
3285 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3286 errmsg("timestamp out of range")));
3287 j2date(julian, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
3288
3289 tz = DetermineTimeZoneOffset(tm, attimezone);
3290
3291 if (tm2timestamp(tm, fsec, &tz, &timestamp) != 0)
3292 ereport(ERROR,
3293 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3294 errmsg("timestamp out of range")));
3295 }
3296
3298 ereport(ERROR,
3299 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3300 errmsg("timestamp out of range")));
3301
3303 ereport(ERROR,
3304 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3305 errmsg("timestamp out of range")));
3306
3307 result = timestamp;
3308 }
3309
3310 return result;
3311}

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

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

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

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

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

1844{
1845 static char buf[MAXDATELEN + 1];
1846 int tz;
1847 struct pg_tm tt,
1848 *tm = &tt;
1849 fsec_t fsec;
1850 const char *tzn;
1851
1852 if (TIMESTAMP_NOT_FINITE(t))
1854 else if (timestamp2tm(t, &tz, tm, &fsec, &tzn, NULL) == 0)
1855 EncodeDateTime(tm, fsec, true, tz, tzn, USE_ISO_DATES, buf);
1856 else
1857 strlcpy(buf, "(timestamp out of range)", sizeof(buf));
1858
1859 return buf;
1860}
#define USE_ISO_DATES
Definition: miscadmin.h:236
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 1823 of file timestamp.c.

1824{
1825 pg_time_t result;
1826
1827 result = (pg_time_t) (t / USECS_PER_SEC +
1829
1830 return result;
1831}

References POSTGRES_EPOCH_JDATE, SECS_PER_DAY, UNIX_EPOCH_JDATE, and USECS_PER_SEC.

Referenced by DetermineTimeZoneAbbrevOffsetTS(), and InitProcessGlobals().

◆ timestamptz_trunc()

Datum timestamptz_trunc ( PG_FUNCTION_ARGS  )

Definition at line 5027 of file timestamp.c.

5028{
5029 text *units = PG_GETARG_TEXT_PP(0);
5031 TimestampTz result;
5032
5034
5035 PG_RETURN_TIMESTAMPTZ(result);
5036}
static TimestampTz timestamptz_trunc_internal(text *units, TimestampTz timestamp, pg_tz *tzp)
Definition: timestamp.c:4849

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

4850{
4851 TimestampTz result;
4852 int tz;
4853 int type,
4854 val;
4855 bool redotz = false;
4856 char *lowunits;
4857 fsec_t fsec;
4858 struct pg_tm tt,
4859 *tm = &tt;
4860
4861 lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
4862 VARSIZE_ANY_EXHDR(units),
4863 false);
4864
4865 type = DecodeUnits(0, lowunits, &val);
4866
4867 if (type == UNITS)
4868 {
4870 {
4871 /*
4872 * Errors thrown here for invalid units should exactly match those
4873 * below, else there will be unexpected discrepancies between
4874 * finite- and infinite-input cases.
4875 */
4876 switch (val)
4877 {
4878 case DTK_WEEK:
4879 case DTK_MILLENNIUM:
4880 case DTK_CENTURY:
4881 case DTK_DECADE:
4882 case DTK_YEAR:
4883 case DTK_QUARTER:
4884 case DTK_MONTH:
4885 case DTK_DAY:
4886 case DTK_HOUR:
4887 case DTK_MINUTE:
4888 case DTK_SECOND:
4889 case DTK_MILLISEC:
4890 case DTK_MICROSEC:
4892 break;
4893
4894 default:
4895 ereport(ERROR,
4896 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4897 errmsg("unit \"%s\" not supported for type %s",
4898 lowunits, format_type_be(TIMESTAMPTZOID))));
4899 result = 0;
4900 }
4901 }
4902
4903 if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, tzp) != 0)
4904 ereport(ERROR,
4905 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
4906 errmsg("timestamp out of range")));
4907
4908 switch (val)
4909 {
4910 case DTK_WEEK:
4911 {
4912 int woy;
4913
4915
4916 /*
4917 * If it is week 52/53 and the month is January, then the
4918 * week must belong to the previous year. Also, some
4919 * December dates belong to the next year.
4920 */
4921 if (woy >= 52 && tm->tm_mon == 1)
4922 --tm->tm_year;
4923 if (woy <= 1 && tm->tm_mon == MONTHS_PER_YEAR)
4924 ++tm->tm_year;
4925 isoweek2date(woy, &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday));
4926 tm->tm_hour = 0;
4927 tm->tm_min = 0;
4928 tm->tm_sec = 0;
4929 fsec = 0;
4930 redotz = true;
4931 break;
4932 }
4933 /* one may consider DTK_THOUSAND and DTK_HUNDRED... */
4934 case DTK_MILLENNIUM:
4935
4936 /*
4937 * truncating to the millennium? what is this supposed to
4938 * mean? let us put the first year of the millennium... i.e.
4939 * -1000, 1, 1001, 2001...
4940 */
4941 if (tm->tm_year > 0)
4942 tm->tm_year = ((tm->tm_year + 999) / 1000) * 1000 - 999;
4943 else
4944 tm->tm_year = -((999 - (tm->tm_year - 1)) / 1000) * 1000 + 1;
4945 /* FALL THRU */
4946 case DTK_CENTURY:
4947 /* truncating to the century? as above: -100, 1, 101... */
4948 if (tm->tm_year > 0)
4949 tm->tm_year = ((tm->tm_year + 99) / 100) * 100 - 99;
4950 else
4951 tm->tm_year = -((99 - (tm->tm_year - 1)) / 100) * 100 + 1;
4952 /* FALL THRU */
4953 case DTK_DECADE:
4954
4955 /*
4956 * truncating to the decade? first year of the decade. must
4957 * not be applied if year was truncated before!
4958 */
4959 if (val != DTK_MILLENNIUM && val != DTK_CENTURY)
4960 {
4961 if (tm->tm_year > 0)
4962 tm->tm_year = (tm->tm_year / 10) * 10;
4963 else
4964 tm->tm_year = -((8 - (tm->tm_year - 1)) / 10) * 10;
4965 }
4966 /* FALL THRU */
4967 case DTK_YEAR:
4968 tm->tm_mon = 1;
4969 /* FALL THRU */
4970 case DTK_QUARTER:
4971 tm->tm_mon = (3 * ((tm->tm_mon - 1) / 3)) + 1;
4972 /* FALL THRU */
4973 case DTK_MONTH:
4974 tm->tm_mday = 1;
4975 /* FALL THRU */
4976 case DTK_DAY:
4977 tm->tm_hour = 0;
4978 redotz = true; /* for all cases >= DAY */
4979 /* FALL THRU */
4980 case DTK_HOUR:
4981 tm->tm_min = 0;
4982 /* FALL THRU */
4983 case DTK_MINUTE:
4984 tm->tm_sec = 0;
4985 /* FALL THRU */
4986 case DTK_SECOND:
4987 fsec = 0;
4988 break;
4989 case DTK_MILLISEC:
4990 fsec = (fsec / 1000) * 1000;
4991 break;
4992 case DTK_MICROSEC:
4993 break;
4994
4995 default:
4996 ereport(ERROR,
4997 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4998 errmsg("unit \"%s\" not supported for type %s",
4999 lowunits, format_type_be(TIMESTAMPTZOID))));
5000 result = 0;
5001 }
5002
5003 if (redotz)
5004 tz = DetermineTimeZoneOffset(tm, tzp);
5005
5006 if (tm2timestamp(tm, fsec, &tz, &result) != 0)
5007 ereport(ERROR,
5008 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
5009 errmsg("timestamp out of range")));
5010 }
5011 else
5012 {
5013 ereport(ERROR,
5014 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5015 errmsg("unit \"%s\" not recognized for type %s",
5016 lowunits, format_type_be(TIMESTAMPTZOID))));
5017 result = 0;
5018 }
5019
5020 return result;
5021}

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

5043{
5044 text *units = PG_GETARG_TEXT_PP(0);
5047 TimestampTz result;
5048 pg_tz *tzp;
5049
5050 /*
5051 * Look up the requested timezone.
5052 */
5053 tzp = lookup_timezone(zone);
5054
5055 result = timestamptz_trunc_internal(units, timestamp, tzp);
5056
5057 PG_RETURN_TIMESTAMPTZ(result);
5058}

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

6499{
6502 Timestamp result;
6503 int tz;
6504 char tzname[TZ_STRLEN_MAX + 1];
6505 int type,
6506 val;
6507 pg_tz *tzp;
6508
6511
6512 /*
6513 * Look up the requested timezone.
6514 */
6515 text_to_cstring_buffer(zone, tzname, sizeof(tzname));
6516
6517 type = DecodeTimezoneName(tzname, &val, &tzp);
6518
6520 {
6521 /* fixed-offset abbreviation */
6522 tz = -val;
6523 result = dt2local(timestamp, tz);
6524 }
6525 else if (type == TZNAME_DYNTZ)
6526 {
6527 /* dynamic-offset abbreviation, resolve using specified time */
6528 int isdst;
6529
6530 tz = DetermineTimeZoneAbbrevOffsetTS(timestamp, tzname, tzp, &isdst);
6531 result = dt2local(timestamp, tz);
6532 }
6533 else
6534 {
6535 /* full zone name, rotate from that zone */
6536 struct pg_tm tm;
6537 fsec_t fsec;
6538
6539 if (timestamp2tm(timestamp, &tz, &tm, &fsec, NULL, tzp) != 0)
6540 ereport(ERROR,
6541 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6542 errmsg("timestamp out of range")));
6543 if (tm2timestamp(&tm, fsec, NULL, &result) != 0)
6544 ereport(ERROR,
6545 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6546 errmsg("timestamp out of range")));
6547 }
6548
6549 if (!IS_VALID_TIMESTAMP(result))
6550 ereport(ERROR,
6551 (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
6552 errmsg("timestamp out of range")));
6553
6554 PG_RETURN_TIMESTAMP(result);
6555}
int DetermineTimeZoneAbbrevOffsetTS(TimestampTz ts, const char *abbr, pg_tz *tzp, int *isdst)
Definition: datetime.c:1784

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

849{
851
853}

References anytimestamp_typmodin(), PG_GETARG_ARRAYTYPE_P, and PG_RETURN_INT32.

◆ timestamptztypmodout()

Datum timestamptztypmodout ( PG_FUNCTION_ARGS  )

Definition at line 856 of file timestamp.c.

857{
858 int32 typmod = PG_GETARG_INT32(0);
859
861}

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

1988{
1990 TimeOffset time;
1991
1992 /* Prevent overflow in Julian-day routines */
1994 {
1995 *result = 0; /* keep compiler quiet */
1996 return -1;
1997 }
1998
2000 time = time2t(tm->tm_hour, tm->tm_min, tm->tm_sec, fsec);
2001
2003 pg_add_s64_overflow(*result, time, result)))
2004 {
2005 *result = 0; /* keep compiler quiet */
2006 return -1;
2007 }
2008 if (tzp != NULL)
2009 *result = dt2local(*result, -(*tzp));
2010
2011 /* final range check catches just-out-of-range timestamps */
2012 if (!IS_VALID_TIMESTAMP(*result))
2013 {
2014 *result = 0; /* keep compiler quiet */
2015 return -1;
2016 }
2017
2018 return 0;
2019}
static TimeOffset time2t(const int hour, const int min, const int sec, const fsec_t fsec)
Definition: timestamp.c:2109

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

Referenced by pg_conf_load_time(), and ProcessConfigFileInternal().

◆ PgStartTime

TimestampTz PgStartTime

Definition at line 53 of file timestamp.c.

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