-- Test non-error-throwing API SELECT pg_input_is_valid('1.5 weeks', 'interval'); SELECT pg_input_is_valid('garbage', 'interval'); SELECT pg_input_is_valid('@ 30 eons ago', 'interval'); SELECT * FROM pg_input_error_info('garbage', 'interval'); SELECT * FROM pg_input_error_info('@ 30 eons ago', 'interval');
-- test interval operators
SELECT * FROM INTERVAL_TBL;
SELECT * FROM INTERVAL_TBL WHERE INTERVAL_TBL.f1 <> interval'@ 10 days';
SELECT * FROM INTERVAL_TBL WHERE INTERVAL_TBL.f1 <= interval'@ 5 hours';
SELECT * FROM INTERVAL_TBL WHERE INTERVAL_TBL.f1 < interval'@ 1 day';
SELECT * FROM INTERVAL_TBL WHERE INTERVAL_TBL.f1 = interval'@ 34 years';
SELECT * FROM INTERVAL_TBL WHERE INTERVAL_TBL.f1 >= interval'@ 1 month';
SELECT * FROM INTERVAL_TBL WHERE INTERVAL_TBL.f1 > interval'@ 3 seconds ago';
SELECT r1.*, r2.* FROM INTERVAL_TBL r1, INTERVAL_TBL r2 WHERE r1.f1 > r2.f1 ORDERBY r1.f1, r2.f1;
-- test unary minus
SELECT f1, -f1 FROM INTERVAL_TBL; SELECT -('-2147483648 months'::interval); -- should fail SELECT -('-2147483647 months'::interval); -- ok SELECT -('-2147483648 days'::interval); -- should fail SELECT -('-2147483647 days'::interval); -- ok SELECT -('-9223372036854775808 us'::interval); -- should fail SELECT -('-9223372036854775807 us'::interval); -- ok SELECT -('-2147483647 months -2147483647 days -9223372036854775807 us'::interval); -- should fail
-- Test intervals that are large enough to overflow 64 bits in comparisons CREATE TEMP TABLE INTERVAL_TBL_OF (f1 interval); INSERTINTO INTERVAL_TBL_OF (f1) VALUES
('2147483647 days 2147483647 months'),
('2147483647 days -2147483648 months'),
('1 year'),
('-2147483648 days 2147483647 months'),
('-2147483648 days -2147483648 months'); -- these should fail as out-of-range INSERTINTO INTERVAL_TBL_OF (f1) VALUES ('2147483648 days'); INSERTINTO INTERVAL_TBL_OF (f1) VALUES ('-2147483649 days'); INSERTINTO INTERVAL_TBL_OF (f1) VALUES ('2147483647 years'); INSERTINTO INTERVAL_TBL_OF (f1) VALUES ('-2147483648 years');
-- Test edge-case overflow detection in interval multiplication select extract(epoch from'256 microseconds'::interval * (2^55)::float8);
SELECT r1.*, r2.* FROM INTERVAL_TBL_OF r1, INTERVAL_TBL_OF r2 WHERE r1.f1 > r2.f1 ORDERBY r1.f1, r2.f1;
CREATEINDEXON INTERVAL_TBL_OF USING btree (f1); SET enable_seqscan TOfalse; EXPLAIN (COSTS OFF) SELECT f1 FROM INTERVAL_TBL_OF r1 ORDERBY f1; SELECT f1 FROM INTERVAL_TBL_OF r1 ORDERBY f1;
RESET enable_seqscan;
-- subtracting about-to-overflow values should result in 0 SELECT f1 - f1 FROM INTERVAL_TBL_OF;
DROPTABLE INTERVAL_TBL_OF;
-- Test multiplication and division with intervals. -- Floating point arithmetic rounding errors can lead to unexpected results, -- though the code attempts to do the right thing and round up to days and -- minutes to avoid results such as '3 days 24:00 hours' or '14:20:60'. -- Note that it is expected for some day components to be greater than 29 and -- some time components be greater than 23:59:59 due to how intervals are -- stored internally.
CREATETABLE INTERVAL_MULDIV_TBL (span interval);
COPY INTERVAL_MULDIV_TBL FROM STDIN; 41 mon 12 days 360:00
-41 mon -12 days +360:00
-12 days 9 mon -27 days 12:34:56
-3 years 482 days 76:54:32.189 4 mon 14 mon 999 mon 999 days
\.
SELECT span * 0.3AS product FROM INTERVAL_MULDIV_TBL;
SELECT span * 8.2AS product FROM INTERVAL_MULDIV_TBL;
SELECT span / 10AS quotient FROM INTERVAL_MULDIV_TBL;
SELECT span / 100AS quotient FROM INTERVAL_MULDIV_TBL;
DROPTABLE INTERVAL_MULDIV_TBL;
SET DATESTYLE = 'postgres'; SET IntervalStyle to postgres_verbose;
-- test avg(interval), which is somewhat fragile since people have been -- known to change the allowed input syntax for type interval without -- updating pg_aggregate.agginitval
select avg(f1) from interval_tbl where isfinite(f1);
-- test long interval input select'4 millenniums 5 centuries 4 decades 1 year 4 months 4 days 17 minutes 31 seconds'::interval;
-- test long interval output -- Note: the actual maximum length of the interval output is longer, -- but we need the test to work for both integer and floating-point -- timestamps. select'100000000y 10mon -1000000000d -100000h -10min -10.000001s ago'::interval;
-- test justify_hours() and justify_days()
SELECT justify_hours(interval'6 months 3 days 52 hours 3 minutes 2 seconds') as"6 mons 5 days 4 hours 3 mins 2 seconds"; SELECT justify_days(interval'6 months 36 days 5 hours 4 minutes 3 seconds') as"7 mons 6 days 5 hours 4 mins 3 seconds";
SELECT justify_hours(interval'2147483647 days 24 hrs'); SELECT justify_days(interval'2147483647 months 30 days');
SELECT'1 second 2 seconds'::interval; -- error SELECT'10 milliseconds 20 milliseconds'::interval; -- error SELECT'5.5 seconds 3 milliseconds'::interval; -- error SELECT'1:20:05 5 microseconds'::interval; -- error SELECT'1 day 1 day'::interval; -- error SELECTinterval'1-2'; -- SQL year-month literal SELECTinterval'999' second; -- oversize leading field is ok SELECTinterval'999' minute; SELECTinterval'999' hour; SELECTinterval'999' day; SELECTinterval'999' month;
-- test SQL-spec syntaxes for restricted field sets SELECTinterval'1' year; SELECTinterval'2' month; SELECTinterval'3' day; SELECTinterval'4' hour; SELECTinterval'5' minute; SELECTinterval'6' second; SELECTinterval'1' year to month; SELECTinterval'1-2' year to month; SELECTinterval'1 2' day to hour; SELECTinterval'1 2:03' day to hour; SELECTinterval'1 2:03:04' day to hour; SELECTinterval'1 2' day to minute; SELECTinterval'1 2:03' day to minute; SELECTinterval'1 2:03:04' day to minute; SELECTinterval'1 2' day to second; SELECTinterval'1 2:03' day to second; SELECTinterval'1 2:03:04' day to second; SELECTinterval'1 2' hour to minute; SELECTinterval'1 2:03' hour to minute; SELECTinterval'1 2:03:04' hour to minute; SELECTinterval'1 2' hour to second; SELECTinterval'1 2:03' hour to second; SELECTinterval'1 2:03:04' hour to second; SELECTinterval'1 2' minute to second; SELECTinterval'1 2:03' minute to second; SELECTinterval'1 2:03:04' minute to second; SELECTinterval'1 +2:03' minute to second; SELECTinterval'1 +2:03:04' minute to second; SELECTinterval'1 -2:03' minute to second; SELECTinterval'1 -2:03:04' minute to second; SELECTinterval'123 11' day to hour; -- ok SELECTinterval'123 11' day; -- not ok SELECTinterval'123 11'; -- not ok, too ambiguous SELECTinterval'123 2:03 -2:04'; -- not ok, redundant hh:mm fields
-- test syntaxes for restricted precision SELECTinterval(0) '1 day 01:23:45.6789'; SELECTinterval(2) '1 day 01:23:45.6789'; SELECTinterval'12:34.5678' minute to second(2); -- per SQL spec SELECTinterval'1.234' second; SELECTinterval'1.234' second(2); SELECTinterval'1 2.345' day to second(2); SELECTinterval'1 2:03' day to second(2); SELECTinterval'1 2:03.4567' day to second(2); SELECTinterval'1 2:03:04.5678' day to second(2); SELECTinterval'1 2.345' hour to second(2); SELECTinterval'1 2:03.45678' hour to second(2); SELECTinterval'1 2:03:04.5678' hour to second(2); SELECTinterval'1 2.3456' minute to second(2); SELECTinterval'1 2:03.5678' minute to second(2); SELECTinterval'1 2:03:04.5678' minute to second(2); SELECTinterval'2562047788:00:54.775807' second(2); -- out of range SELECTinterval'-2562047788:00:54.775807' second(2); -- out of range
-- test casting to restricted precision (bug #14479) SELECT f1, f1::INTERVAL DAY TO MINUTE AS"minutes",
(f1 + INTERVAL'1 month')::INTERVAL MONTH::INTERVAL YEAR AS"years" FROM interval_tbl;
-- test inputting and outputting SQL standard interval literals SET IntervalStyle TO sql_standard; SELECTinterval'0'AS"zero", interval'1-2' year to month AS"year-month", interval'1 2:03:04' day to second AS"day-time",
- interval'1-2'AS"negative year-month",
- interval'1 2:03:04'AS"negative day-time";
-- test input of some not-quite-standard interval values in the sql style SET IntervalStyle TO postgres; SELECTinterval'+1 -1:00:00', interval'-1 +1:00:00', interval'+1-2 -3 +4:05:06.789', interval'-1-2 +3 -4:05:06.789';
-- cases that trigger sign-matching rules in the sql style SELECTinterval'-23 hours 45 min 12.34 sec', interval'-1 day 23 hours 45 min 12.34 sec', interval'-1 year 2 months 1 day 23 hours 45 min 12.34 sec', interval'-1 year 2 months 1 day 23 hours 45 min +12.34 sec';
-- test output of couple non-standard interval values in the sql style SET IntervalStyle TO sql_standard; SELECTinterval'1 day -1 hours', interval'-1 days +1 hours', interval'1 years 2 months -3 days 4 hours 5 minutes 6.789 seconds',
- interval'1 years 2 months -3 days 4 hours 5 minutes 6.789 seconds';
-- cases that trigger sign-matching rules in the sql style SELECTinterval'-23 hours 45 min 12.34 sec', interval'-1 day 23 hours 45 min 12.34 sec', interval'-1 year 2 months 1 day 23 hours 45 min 12.34 sec', interval'-1 year 2 months 1 day 23 hours 45 min +12.34 sec';
-- edge case for sign-matching rules SELECTinterval''; -- error
-- test outputting iso8601 intervals SET IntervalStyle to iso_8601; selectinterval'0'AS"zero", interval'1-2'AS"a year 2 months", interval'1 2:03:04'AS"a bit over a day", interval'2:03:04.45679'AS"a bit over 2 hours",
(interval'1-2' + interval'3 4:05:06.7') AS"all fields",
(interval'1-2' - interval'3 4:05:06.7') AS"mixed sign",
(- interval'1-2' + interval'3 4:05:06.7') AS"negative";
-- test inputting ISO 8601 4.4.2.1 "Format With Time Unit Designators" SET IntervalStyle to sql_standard; selectinterval'P0Y'AS"zero", interval'P1Y2M'AS"a year 2 months", interval'P1W'AS"a week", interval'P1DT2H3M4S'AS"a bit over a day", interval'P1Y2M3DT4H5M6.7S'AS"all fields", interval'P-1Y-2M-3DT-4H-5M-6.7S'AS"negative", interval'PT-0.1S'AS"fractional second";
-- test inputting ISO 8601 4.4.2.2 "Alternative Format" SET IntervalStyle to postgres; selectinterval'P00021015T103020'AS"ISO8601 Basic Format", interval'P0002-10-15T10:30:20'AS"ISO8601 Extended Format";
-- Make sure optional ISO8601 alternative format fields are optional. selectinterval'P0002'AS"year only", interval'P0002-10'AS"year month", interval'P0002-10-15'AS"year month day", interval'P0002T1S'AS"year only plus time", interval'P0002-10T1S'AS"year month plus time", interval'P0002-10-15T1S'AS"year month day plus time", interval'PT10'AS"hour only", interval'PT10:30'AS"hour minute";
-- Check handling of fractional fields in ISO8601 format. selectinterval'P1Y0M3DT4H5M6S'; selectinterval'P1.0Y0M3DT4H5M6S'; selectinterval'P1.1Y0M3DT4H5M6S'; selectinterval'P1.Y0M3DT4H5M6S'; selectinterval'P.1Y0M3DT4H5M6S'; selectinterval'P10.5e4Y'; -- not per spec, but we've historically taken it selectinterval'P.Y0M3DT4H5M6S'; -- error
-- test a couple rounding cases that changed since 8.3 w/ HAVE_INT64_TIMESTAMP. SET IntervalStyle to postgres_verbose; selectinterval'-10 mons -3 days +03:55:06.70'; selectinterval'1 year 2 mons 3 days 04:05:06.699999'; selectinterval'0:0:0.7', interval'@ 0.70 secs', interval'0.7 seconds';
-- test time fields using entire 64 bit microseconds range selectinterval'2562047788.01521550194 hours'; selectinterval'-2562047788.01521550222 hours'; selectinterval'153722867280.912930117 minutes'; selectinterval'-153722867280.912930133 minutes'; selectinterval'9223372036854.775807 seconds'; selectinterval'-9223372036854.775808 seconds'; selectinterval'9223372036854775.807 milliseconds'; selectinterval'-9223372036854775.808 milliseconds'; selectinterval'9223372036854775807 microseconds'; selectinterval'-9223372036854775808 microseconds';
selectinterval'2147483647 years 1 decade'; selectinterval'2147483647 years 1 century'; selectinterval'2147483647 years 1 millennium'; selectinterval'-2147483648 years -1 decade'; selectinterval'-2147483648 years -1 century'; selectinterval'-2147483648 years -1 millennium';
-- overflowing with fractional fields - ISO8601 alternative format selectinterval'P0.1-2147483647-00'; selectinterval'P00-0.1-2147483647'; selectinterval'P00-0.01-00T2562047788:00:54.775807'; selectinterval'P00-00-0.1T2562047788:00:54.775807'; selectinterval'PT2562047788.1:00:54.775807'; selectinterval'PT2562047788:01.:54.775807';
-- overflowing with fractional fields - SQL standard format selectinterval'0.1 2562047788:0:54.775807'; selectinterval'0.1 2562047788:0:54.775808 ago';
-- overflowing using AGO with INT_MIN selectinterval'-2147483648 months ago'; selectinterval'-2147483648 days ago'; selectinterval'-9223372036854775808 microseconds ago'; selectinterval'-2147483648 months -2147483648 days -9223372036854775808 microseconds ago';
-- test that INT_MIN number is formatted properly SET IntervalStyle to postgres; selectinterval'-2147483647 months -2147483648 days -9223372036854775808 us'; SET IntervalStyle to sql_standard; selectinterval'-2147483647 months -2147483648 days -9223372036854775808 us'; SET IntervalStyle to iso_8601; selectinterval'-2147483647 months -2147483648 days -9223372036854775808 us'; SET IntervalStyle to postgres_verbose; selectinterval'-2147483647 months -2147483648 days -9223372036854775808 us';
-- check that '30 days' equals '1 month' according to the hash function select'30 days'::interval = '1 month'::intervalas t; select interval_hash('30 days'::interval) = interval_hash('1 month'::interval) as t;
-- -- test EXTRACT -- SELECT f1,
EXTRACT(MICROSECOND FROM f1) AS MICROSECOND,
EXTRACT(MILLISECOND FROM f1) AS MILLISECOND,
EXTRACT(SECOND FROM f1) AS SECOND,
EXTRACT(MINUTE FROM f1) AS MINUTE,
EXTRACT(HOUR FROM f1) AS HOUR,
EXTRACT(DAY FROM f1) AS DAY,
EXTRACT(WEEK FROM f1) AS WEEK,
EXTRACT(MONTH FROM f1) AS MONTH,
EXTRACT(QUARTER FROM f1) AS QUARTER,
EXTRACT(YEAR FROM f1) AS YEAR,
EXTRACT(DECADE FROM f1) AS DECADE,
EXTRACT(CENTURY FROM f1) AS CENTURY,
EXTRACT(MILLENNIUM FROM f1) AS MILLENNIUM,
EXTRACT(EPOCH FROM f1) AS EPOCH FROM INTERVAL_TBL;
SELECT -f1,
EXTRACT(MICROSECOND FROM -f1) AS MICROSECOND,
EXTRACT(MILLISECOND FROM -f1) AS MILLISECOND,
EXTRACT(SECOND FROM -f1) AS SECOND,
EXTRACT(MINUTE FROM -f1) AS MINUTE,
EXTRACT(HOUR FROM -f1) AS HOUR,
EXTRACT(DAY FROM -f1) AS DAY,
EXTRACT(WEEK FROM -f1) AS WEEK,
EXTRACT(MONTH FROM -f1) AS MONTH,
EXTRACT(QUARTER FROM -f1) AS QUARTER,
EXTRACT(YEAR FROM -f1) AS YEAR,
EXTRACT(DECADE FROM -f1) AS DECADE,
EXTRACT(CENTURY FROM -f1) AS CENTURY,
EXTRACT(MILLENNIUM FROM -f1) AS MILLENNIUM,
EXTRACT(EPOCH FROM -f1) AS EPOCH FROM INTERVAL_TBL;
-- date_part implementation is mostly the same as extract, so only -- test a few cases for additional coverage. SELECT f1,
date_part('microsecond', f1) AS microsecond,
date_part('millisecond', f1) AS millisecond,
date_part('second', f1) AS second,
date_part('epoch', f1) AS epoch FROM INTERVAL_TBL;
-- internal overflow test case SELECT extract(epoch frominterval'1000000000 days');
-- -- test infinite intervals --
-- largest finite intervals SELECTinterval'-2147483648 months -2147483648 days -9223372036854775807 us'; SELECTinterval'2147483647 months 2147483647 days 9223372036854775806 us';
-- infinite intervals SELECTinterval'-2147483648 months -2147483648 days -9223372036854775808 us'; SELECTinterval'2147483647 months 2147483647 days 9223372036854775807 us';
CREATETABLE INFINITE_INTERVAL_TBL (i interval); INSERTINTO INFINITE_INTERVAL_TBL VALUES ('infinity'), ('-infinity'), ('1 year 2 days 3 hours');
SELECT i, isfinite(i) FROM INFINITE_INTERVAL_TBL;
-- test basic arithmetic CREATE FUNCTION eval(expr text)
RETURNS text AS
$$ DECLARE
result text;
BEGIN
EXECUTE 'select '||expr INTO result; RETURN result;
EXCEPTION WHEN OTHERS THEN RETURN SQLERRM;
END
$$
LANGUAGE plpgsql;
SELECT d AS date, i ASinterval,
eval(format('date %L + interval %L', d, i)) AS plus,
eval(format('date %L - interval %L', d, i)) AS minus FROM (VALUES (date '-infinity'),
(date '1995-08-06'),
(date 'infinity')) AS t1(d),
(VALUES (interval'-infinity'),
(interval'infinity')) AS t2(i);
SELECT i1 AS interval1, i2 AS interval2,
eval(format('interval %L + interval %L', i1, i2)) AS plus,
eval(format('interval %L - interval %L', i1, i2)) AS minus FROM (VALUES (interval'-infinity'),
(interval'2 months'),
(interval'infinity')) AS t1(i1),
(VALUES (interval'-infinity'),
(interval'10 days'),
(interval'infinity')) AS t2(i2);
SELECTinterval'2147483646 months 2147483646 days 9223372036854775806 us' + interval'1 month 1 day 1 us'; SELECTinterval'-2147483647 months -2147483647 days -9223372036854775807 us' + interval'-1 month -1 day -1 us'; SELECTinterval'2147483646 months 2147483646 days 9223372036854775806 us' - interval'-1 month -1 day -1 us'; SELECTinterval'-2147483647 months -2147483647 days -9223372036854775807 us' - interval'1 month 1 day 1 us';
SELECT t AS timestamp, i ASinterval,
eval(format('timestamp %L + interval %L', t, i)) AS plus,
eval(format('timestamp %L - interval %L', t, i)) AS minus FROM (VALUES (timestamp '-infinity'),
(timestamp '1995-08-06 12:30:15'),
(timestamp 'infinity')) AS t1(t),
(VALUES (interval'-infinity'),
(interval'infinity')) AS t2(i);
SELECT t AT TIME ZONE 'GMT'AS timestamptz, i ASinterval,
eval(format('timestamptz %L + interval %L', t, i)) AS plus,
eval(format('timestamptz %L - interval %L', t, i)) AS minus FROM (VALUES (timestamptz '-infinity'),
(timestamptz '1995-08-06 12:30:15 GMT'),
(timestamptz 'infinity')) AS t1(t),
(VALUES (interval'-infinity'),
(interval'infinity')) AS t2(i);
-- time +/- infinite interval not supported SELECT time '11:27:42' + interval'infinity'; SELECT time '11:27:42' + interval'-infinity'; SELECT time '11:27:42' - interval'infinity'; SELECT time '11:27:42' - interval'-infinity'; SELECT timetz '11:27:42' + interval'infinity'; SELECT timetz '11:27:42' + interval'-infinity'; SELECT timetz '11:27:42' - interval'infinity'; SELECT timetz '11:27:42' - interval'-infinity';
SELECT lhst.i lhs,
rhst.i rhs,
lhst.i < rhst.i AS lt,
lhst.i <= rhst.i AS le,
lhst.i = rhst.i AS eq,
lhst.i > rhst.i AS gt,
lhst.i >= rhst.i AS ge,
lhst.i <> rhst.i AS ne FROM INFINITE_INTERVAL_TBL lhst CROSSJOIN INFINITE_INTERVAL_TBL rhst WHERENOT isfinite(lhst.i);
SELECT i ASinterval,
-i AS um,
i * 2.0AS mul,
i * -2.0AS mul_neg,
i * 'infinity'AS mul_inf,
i * '-infinity'AS mul_inf_neg,
i / 3.0ASdiv,
i / -3.0AS div_neg FROM INFINITE_INTERVAL_TBL WHERENOT isfinite(i);
-- "ago" can only appear once at the end of an interval. SELECTINTERVAL'42 days 2 seconds ago ago'; SELECTINTERVAL'2 minutes ago 5 days';
-- consecutive and dangling units are not allowed. SELECTINTERVAL'hour 5 months'; SELECTINTERVAL'1 year months days 5 hours';
-- unacceptable reserved words in interval. Only "infinity", "+infinity" and -- "-infinity" are allowed. SELECTINTERVAL'now'; SELECTINTERVAL'today'; SELECTINTERVAL'tomorrow'; SELECTINTERVAL'allballs'; SELECTINTERVAL'epoch'; SELECTINTERVAL'yesterday';
-- infinity specification should be the only thing SELECTINTERVAL'infinity years'; SELECTINTERVAL'infinity ago'; SELECTINTERVAL'+infinity -infinity';
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.17 Sekunden
(vorverarbeitet am 2026-08-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.