@@ -4620,9 +4620,6 @@ timestamp_trunc(PG_FUNCTION_ARGS)
4620
4620
struct pg_tm tt ,
4621
4621
* tm = & tt ;
4622
4622
4623
- if (TIMESTAMP_NOT_FINITE (timestamp ))
4624
- PG_RETURN_TIMESTAMP (timestamp );
4625
-
4626
4623
lowunits = downcase_truncate_identifier (VARDATA_ANY (units ),
4627
4624
VARSIZE_ANY_EXHDR (units ),
4628
4625
false);
@@ -4631,6 +4628,39 @@ timestamp_trunc(PG_FUNCTION_ARGS)
4631
4628
4632
4629
if (type == UNITS )
4633
4630
{
4631
+ if (TIMESTAMP_NOT_FINITE (timestamp ))
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 :
4653
+ PG_RETURN_TIMESTAMP (timestamp );
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
+
4634
4664
if (timestamp2tm (timestamp , NULL , tm , & fsec , NULL , NULL ) != 0 )
4635
4665
ereport (ERROR ,
4636
4666
(errcode (ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
@@ -4836,6 +4866,40 @@ timestamptz_trunc_internal(text *units, TimestampTz timestamp, pg_tz *tzp)
4836
4866
4837
4867
if (type == UNITS )
4838
4868
{
4869
+ if (TIMESTAMP_NOT_FINITE (timestamp ))
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 :
4891
+ PG_RETURN_TIMESTAMPTZ (timestamp );
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
+
4839
4903
if (timestamp2tm (timestamp , & tz , tm , & fsec , NULL , tzp ) != 0 )
4840
4904
ereport (ERROR ,
4841
4905
(errcode (ERRCODE_DATETIME_VALUE_OUT_OF_RANGE ),
@@ -4966,9 +5030,6 @@ timestamptz_trunc(PG_FUNCTION_ARGS)
4966
5030
TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ (1 );
4967
5031
TimestampTz result ;
4968
5032
4969
- if (TIMESTAMP_NOT_FINITE (timestamp ))
4970
- PG_RETURN_TIMESTAMPTZ (timestamp );
4971
-
4972
5033
result = timestamptz_trunc_internal (units , timestamp , session_timezone );
4973
5034
4974
5035
PG_RETURN_TIMESTAMPTZ (result );
@@ -4986,13 +5047,6 @@ timestamptz_trunc_zone(PG_FUNCTION_ARGS)
4986
5047
TimestampTz result ;
4987
5048
pg_tz * tzp ;
4988
5049
4989
- /*
4990
- * timestamptz_zone() doesn't look up the zone for infinite inputs, so we
4991
- * don't do so here either.
4992
- */
4993
- if (TIMESTAMP_NOT_FINITE (timestamp ))
4994
- PG_RETURN_TIMESTAMP (timestamp );
4995
-
4996
5050
/*
4997
5051
* Look up the requested timezone.
4998
5052
*/
@@ -5020,12 +5074,6 @@ interval_trunc(PG_FUNCTION_ARGS)
5020
5074
5021
5075
result = (Interval * ) palloc (sizeof (Interval ));
5022
5076
5023
- if (INTERVAL_NOT_FINITE (interval ))
5024
- {
5025
- memcpy (result , interval , sizeof (Interval ));
5026
- PG_RETURN_INTERVAL_P (result );
5027
- }
5028
-
5029
5077
lowunits = downcase_truncate_identifier (VARDATA_ANY (units ),
5030
5078
VARSIZE_ANY_EXHDR (units ),
5031
5079
false);
@@ -5034,6 +5082,41 @@ interval_trunc(PG_FUNCTION_ARGS)
5034
5082
5035
5083
if (type == UNITS )
5036
5084
{
5085
+ if (INTERVAL_NOT_FINITE (interval ))
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
+
5037
5120
interval2itm (* interval , tm );
5038
5121
switch (val )
5039
5122
{
0 commit comments