Skip to content

Commit 9d9f79b

Browse files
authored
Validate units in date_trunc for infinity (#29)
1 parent 7d5168c commit 9d9f79b

File tree

4 files changed

+46
-99
lines changed

4 files changed

+46
-99
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ To execute all tests run:
77
```bash
88
make
99
make install
10-
mask installcheck
10+
make installcheck
1111
```
1212

1313
You must have a running PostgreSQL server and the default user must have `LOGIN` and `SUPERUSER` privileges.

src/pg_duration.c

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -722,12 +722,6 @@ duration_trunc(PG_FUNCTION_ARGS)
722722
struct pg_itm tt,
723723
*tm = &tt;
724724

725-
if (DURATION_NOT_FINITE(duration))
726-
{
727-
result = duration;
728-
PG_RETURN_DURATION(result);
729-
}
730-
731725
lowunits = downcase_truncate_identifier(VARDATA_ANY(units),
732726
VARSIZE_ANY_EXHDR(units),
733727
false);
@@ -736,6 +730,33 @@ duration_trunc(PG_FUNCTION_ARGS)
736730

737731
if (type == UNITS)
738732
{
733+
if (DURATION_NOT_FINITE(duration))
734+
{
735+
/*
736+
* Errors thrown here for invalid units should exactly match those
737+
* below, else there will be unexpected discrepancies between
738+
* finite- and infinite-input cases.
739+
*/
740+
switch (val)
741+
{
742+
case DTK_HOUR:
743+
case DTK_MINUTE:
744+
case DTK_SECOND:
745+
case DTK_MILLISEC:
746+
case DTK_MICROSEC:
747+
result = duration;
748+
PG_RETURN_DURATION(result);
749+
break;
750+
751+
default:
752+
ereport(ERROR,
753+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
754+
errmsg("unit \"%s\" not supported for type duration",
755+
lowunits)));
756+
result = 0;
757+
}
758+
}
759+
739760
duration2itm(duration, tm);
740761
switch (val)
741762
{

test/expected/duration.out

Lines changed: 18 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -723,113 +723,41 @@ SELECT f, d, date_trunc(f, d) FROM valid_fields, inf_table WHERE NOT isfinite(d)
723723
(10 rows)
724724

725725
SELECT date_trunc('epoch', duration 'infinity');
726-
date_trunc
727-
------------
728-
infinity
729-
(1 row)
730-
726+
ERROR: unit "epoch" not recognized for type duration
731727
SELECT date_trunc('millennium', duration 'infinity');
732-
date_trunc
733-
------------
734-
infinity
735-
(1 row)
736-
728+
ERROR: unit "millennium" not supported for type duration
737729
SELECT date_trunc('century', duration 'infinity');
738-
date_trunc
739-
------------
740-
infinity
741-
(1 row)
742-
730+
ERROR: unit "century" not supported for type duration
743731
SELECT date_trunc('decade', duration 'infinity');
744-
date_trunc
745-
------------
746-
infinity
747-
(1 row)
748-
732+
ERROR: unit "decade" not supported for type duration
749733
SELECT date_trunc('year', duration 'infinity');
750-
date_trunc
751-
------------
752-
infinity
753-
(1 row)
754-
734+
ERROR: unit "year" not supported for type duration
755735
SELECT date_trunc('quarter', duration 'infinity');
756-
date_trunc
757-
------------
758-
infinity
759-
(1 row)
760-
736+
ERROR: unit "quarter" not supported for type duration
761737
SELECT date_trunc('month', duration 'infinity');
762-
date_trunc
763-
------------
764-
infinity
765-
(1 row)
766-
738+
ERROR: unit "month" not supported for type duration
767739
SELECT date_trunc('week', duration 'infinity');
768-
date_trunc
769-
------------
770-
infinity
771-
(1 row)
772-
740+
ERROR: unit "week" not supported for type duration
773741
SELECT date_trunc('day', duration 'infinity');
774-
date_trunc
775-
------------
776-
infinity
777-
(1 row)
778-
742+
ERROR: unit "day" not supported for type duration
779743
SELECT date_trunc('epoch', duration '-infinity');
780-
date_trunc
781-
------------
782-
-infinity
783-
(1 row)
784-
744+
ERROR: unit "epoch" not recognized for type duration
785745
SELECT date_trunc('millennium', duration '-infinity');
786-
date_trunc
787-
------------
788-
-infinity
789-
(1 row)
790-
746+
ERROR: unit "millennium" not supported for type duration
791747
SELECT date_trunc('century', duration '-infinity');
792-
date_trunc
793-
------------
794-
-infinity
795-
(1 row)
796-
748+
ERROR: unit "century" not supported for type duration
797749
SELECT date_trunc('decade', duration '-infinity');
798-
date_trunc
799-
------------
800-
-infinity
801-
(1 row)
802-
750+
ERROR: unit "decade" not supported for type duration
803751
SELECT date_trunc('year', duration '-infinity');
804-
date_trunc
805-
------------
806-
-infinity
807-
(1 row)
808-
752+
ERROR: unit "year" not supported for type duration
809753
SELECT date_trunc('quarter', duration '-infinity');
810-
date_trunc
811-
------------
812-
-infinity
813-
(1 row)
814-
754+
ERROR: unit "quarter" not supported for type duration
815755
SELECT date_trunc('month', duration '-infinity');
816-
date_trunc
817-
------------
818-
-infinity
819-
(1 row)
820-
756+
ERROR: unit "month" not supported for type duration
821757
SELECT date_trunc('week', duration '-infinity');
822-
date_trunc
823-
------------
824-
-infinity
825-
(1 row)
826-
758+
ERROR: unit "week" not supported for type duration
827759
SELECT date_trunc('day', duration '-infinity');
828-
date_trunc
829-
------------
830-
-infinity
831-
(1 row)
832-
760+
ERROR: unit "day" not supported for type duration
833761
-- date_part
834762
SELECT f, d, date_part(f, d) FROM valid_fields, inf_table WHERE NOT isfinite(d);
835763
f | d | date_part
@@ -997,7 +925,6 @@ ERROR: duration out of range
997925
SELECT sum(d) FROM inf_table;
998926
ERROR: duration out of range
999927
-- Overflow
1000-
-- This matches PostgreSQL semantics, but is probably incorrect.
1001928
SELECT duration '9223372036854775807 us';
1002929
duration
1003930
----------

test/sql/duration.sql

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,6 @@ SELECT max(d), min(d) FROM inf_table;
349349
SELECT avg(d) FROM inf_table;
350350
SELECT sum(d) FROM inf_table;
351351
-- Overflow
352-
-- This matches PostgreSQL semantics, but is probably incorrect.
353352
SELECT duration '9223372036854775807 us';
354353
SELECT duration '-9223372036854775808 us';
355354

0 commit comments

Comments
 (0)