File tree Expand file tree Collapse file tree
contrib/babelfishpg_common/src Expand file tree Collapse file tree Original file line number Diff line number Diff line change 99#include "postgres.h"
1010
1111#include "fmgr.h"
12+ #include "common/int.h"
1213#include "utils/builtins.h"
1314#include "utils/date.h"
1415#include "utils/datetime.h"
@@ -491,7 +492,22 @@ date_datetime2(PG_FUNCTION_ARGS)
491492 else if (DATE_IS_NOEND (dateVal ))
492493 TIMESTAMP_NOEND (result );
493494 else
494- result = dateVal * USECS_PER_DAY ;
495+ {
496+ /*
497+ * Use overflow-safe multiplication to prevent int64 overflow.
498+ * dateVal * USECS_PER_DAY can overflow for dates outside the
499+ * valid datetime2 range (0001-01-01 to 9999-12-31).
500+ */
501+ int64 product ;
502+
503+ if (pg_mul_s64_overflow ((int64 ) dateVal , USECS_PER_DAY , & product ) ||
504+ !IS_VALID_DATETIME2 (product ))
505+ ereport (ERROR ,
506+ (errcode (ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
507+ errmsg ("data out of range for datetime2" )));
508+
509+ result = (Timestamp ) product ;
510+ }
495511
496512 PG_RETURN_TIMESTAMP (result );
497513}
Original file line number Diff line number Diff line change 1+
2+ -- Test DATE to DATETIME2 cast with out-of-range dates (BABEL-4527)
3+ -- Out-of-range: year 999999 (exceeds datetime2 max of 9999-12-31)
4+ SELECT CAST(CAST('999999-12-31' AS DATE) AS datetime2);
5+ GO
6+ ~~START~~
7+ datetime2
8+ ~~ERROR (Code: 33557097)~~
9+
10+ ~~ERROR (Message: data out of range for datetime2)~~
11+
12+
13+ -- Out-of-range: year 10000 (just past valid range)
14+ SELECT CAST(CAST('10000-01-01' AS DATE) AS datetime2);
15+ GO
16+ ~~START~~
17+ datetime2
18+ ~~ERROR (Code: 33557097)~~
19+
20+ ~~ERROR (Message: data out of range for datetime2)~~
21+
22+
23+ -- Valid boundary: max datetime2 date
24+ SELECT CAST(CAST('9999-12-31' AS DATE) AS datetime2);
25+ GO
26+ ~~START~~
27+ datetime2
28+ 9999-12-31 00:00:00.0000000
29+ ~~END~~
30+
31+
32+ -- Out-of-range: date before datetime2 min (PostgreSQL min date, 4714-11-24 BC)
33+ SELECT CAST(CAST('4714-11-24 BC' AS DATE) AS datetime2);
34+ GO
35+ ~~START~~
36+ datetime2
37+ ~~ERROR (Code: 33557097)~~
38+
39+ ~~ERROR (Message: data out of range for datetime2)~~
40+
41+
42+ -- Valid boundary: min datetime2 date
43+ SELECT CAST(CAST('0001-01-01' AS DATE) AS datetime2);
44+ GO
45+ ~~START~~
46+ datetime2
47+ 0001-01-01 00:00:00.0000000
48+ ~~END~~
49+
Original file line number Diff line number Diff line change 1+ -- Test DATE to DATETIME2 cast with out-of-range dates (BABEL-4527)
2+
3+ -- Out-of-range: year 999999 (exceeds datetime2 max of 9999-12-31)
4+ SELECT CAST (CAST (' 999999-12-31' AS DATE ) AS datetime2 );
5+ GO
6+
7+ -- Out-of-range: year 10000 (just past valid range)
8+ SELECT CAST (CAST (' 10000-01-01' AS DATE ) AS datetime2 );
9+ GO
10+
11+ -- Valid boundary: max datetime2 date
12+ SELECT CAST (CAST (' 9999-12-31' AS DATE ) AS datetime2 );
13+ GO
14+
15+ -- Out-of-range: date before datetime2 min (PostgreSQL min date, 4714-11-24 BC)
16+ SELECT CAST (CAST (' 4714-11-24 BC' AS DATE ) AS datetime2 );
17+ GO
18+
19+ -- Valid boundary: min datetime2 date
20+ SELECT CAST (CAST (' 0001-01-01' AS DATE ) AS datetime2 );
21+ GO
You can’t perform that action at this time.
0 commit comments