2424#include "access/xact.h"
2525#include "catalog/pg_type.h"
2626#include "common/hashfn.h"
27+ #include "common/int.h"
2728#include "libpq/pqformat.h"
2829#include "miscadmin.h"
2930#include "nodes/supportnodes.h"
@@ -2013,6 +2014,11 @@ interval_time(PG_FUNCTION_ARGS)
20132014 Interval * span = PG_GETARG_INTERVAL_P (0 );
20142015 TimeADT result ;
20152016
2017+ if (INTERVAL_NOT_FINITE (span ))
2018+ ereport (ERROR ,
2019+ (errcode (ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
2020+ errmsg ("cannot convert infinite interval to time" )));
2021+
20162022 result = span -> time % USECS_PER_DAY ;
20172023 if (result < 0 )
20182024 result += USECS_PER_DAY ;
@@ -2049,6 +2055,11 @@ time_pl_interval(PG_FUNCTION_ARGS)
20492055 Interval * span = PG_GETARG_INTERVAL_P (1 );
20502056 TimeADT result ;
20512057
2058+ if (INTERVAL_NOT_FINITE (span ))
2059+ ereport (ERROR ,
2060+ (errcode (ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
2061+ errmsg ("cannot add infinite interval to time" )));
2062+
20522063 result = time + span -> time ;
20532064 result -= result / USECS_PER_DAY * USECS_PER_DAY ;
20542065 if (result < INT64CONST (0 ))
@@ -2067,6 +2078,11 @@ time_mi_interval(PG_FUNCTION_ARGS)
20672078 Interval * span = PG_GETARG_INTERVAL_P (1 );
20682079 TimeADT result ;
20692080
2081+ if (INTERVAL_NOT_FINITE (span ))
2082+ ereport (ERROR ,
2083+ (errcode (ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
2084+ errmsg ("cannot subtract infinite interval from time" )));
2085+
20702086 result = time - span -> time ;
20712087 result -= result / USECS_PER_DAY * USECS_PER_DAY ;
20722088 if (result < INT64CONST (0 ))
@@ -2090,7 +2106,8 @@ in_range_time_interval(PG_FUNCTION_ARGS)
20902106
20912107 /*
20922108 * Like time_pl_interval/time_mi_interval, we disregard the month and day
2093- * fields of the offset. So our test for negative should too.
2109+ * fields of the offset. So our test for negative should too. This also
2110+ * catches -infinity, so we only need worry about +infinity below.
20942111 */
20952112 if (offset -> time < 0 )
20962113 ereport (ERROR ,
@@ -2100,13 +2117,14 @@ in_range_time_interval(PG_FUNCTION_ARGS)
21002117 /*
21012118 * We can't use time_pl_interval/time_mi_interval here, because their
21022119 * wraparound behavior would give wrong (or at least undesirable) answers.
2103- * Fortunately the equivalent non-wrapping behavior is trivial, especially
2104- * since we don't worry about integer overflow.
2120+ * Fortunately the equivalent non-wrapping behavior is trivial, except
2121+ * that adding an infinite (or very large) interval might cause integer
2122+ * overflow. Subtraction cannot overflow here.
21052123 */
21062124 if (sub )
21072125 sum = base - offset -> time ;
2108- else
2109- sum = base + offset -> time ;
2126+ else if ( pg_add_s64_overflow ( base , offset -> time , & sum ))
2127+ PG_RETURN_BOOL ( less ) ;
21102128
21112129 if (less )
21122130 PG_RETURN_BOOL (val <= sum );
@@ -2581,6 +2599,11 @@ timetz_pl_interval(PG_FUNCTION_ARGS)
25812599 Interval * span = PG_GETARG_INTERVAL_P (1 );
25822600 TimeTzADT * result ;
25832601
2602+ if (INTERVAL_NOT_FINITE (span ))
2603+ ereport (ERROR ,
2604+ (errcode (ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
2605+ errmsg ("cannot add infinite interval to time" )));
2606+
25842607 result = (TimeTzADT * ) palloc (sizeof (TimeTzADT ));
25852608
25862609 result -> time = time -> time + span -> time ;
@@ -2603,6 +2626,11 @@ timetz_mi_interval(PG_FUNCTION_ARGS)
26032626 Interval * span = PG_GETARG_INTERVAL_P (1 );
26042627 TimeTzADT * result ;
26052628
2629+ if (INTERVAL_NOT_FINITE (span ))
2630+ ereport (ERROR ,
2631+ (errcode (ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
2632+ errmsg ("cannot subtract infinite interval from time" )));
2633+
26062634 result = (TimeTzADT * ) palloc (sizeof (TimeTzADT ));
26072635
26082636 result -> time = time -> time - span -> time ;
@@ -2630,7 +2658,8 @@ in_range_timetz_interval(PG_FUNCTION_ARGS)
26302658
26312659 /*
26322660 * Like timetz_pl_interval/timetz_mi_interval, we disregard the month and
2633- * day fields of the offset. So our test for negative should too.
2661+ * day fields of the offset. So our test for negative should too. This
2662+ * also catches -infinity, so we only need worry about +infinity below.
26342663 */
26352664 if (offset -> time < 0 )
26362665 ereport (ERROR ,
@@ -2640,13 +2669,14 @@ in_range_timetz_interval(PG_FUNCTION_ARGS)
26402669 /*
26412670 * We can't use timetz_pl_interval/timetz_mi_interval here, because their
26422671 * wraparound behavior would give wrong (or at least undesirable) answers.
2643- * Fortunately the equivalent non-wrapping behavior is trivial, especially
2644- * since we don't worry about integer overflow.
2672+ * Fortunately the equivalent non-wrapping behavior is trivial, except
2673+ * that adding an infinite (or very large) interval might cause integer
2674+ * overflow. Subtraction cannot overflow here.
26452675 */
26462676 if (sub )
26472677 sum .time = base -> time - offset -> time ;
2648- else
2649- sum . time = base -> time + offset -> time ;
2678+ else if ( pg_add_s64_overflow ( base -> time , offset -> time , & sum . time ))
2679+ PG_RETURN_BOOL ( less ) ;
26502680 sum .zone = base -> zone ;
26512681
26522682 if (less )
@@ -3096,6 +3126,13 @@ timetz_izone(PG_FUNCTION_ARGS)
30963126 TimeTzADT * result ;
30973127 int tz ;
30983128
3129+ if (INTERVAL_NOT_FINITE (zone ))
3130+ ereport (ERROR ,
3131+ (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
3132+ errmsg ("interval time zone \"%s\" must be finite" ,
3133+ DatumGetCString (DirectFunctionCall1 (interval_out ,
3134+ PointerGetDatum (zone ))))));
3135+
30993136 if (zone -> month != 0 || zone -> day != 0 )
31003137 ereport (ERROR ,
31013138 (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
0 commit comments