Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6af0488

Browse files
author
Neil Conway
committed
Fix a bug in input processing for the "interval" type. Previously,
"microsecond" and "millisecond" units were not considered valid inputby themselves, which caused inputs like "1 millisecond" to be rejectederroneously.Update the docs, add regression tests, and backport to 8.2 and 8.1
1 parente78720f commit6af0488

File tree

5 files changed

+66
-15
lines changed

5 files changed

+66
-15
lines changed

‎doc/src/sgml/datatype.sgml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.201 2007/05/21 17:10:28 petere Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.202 2007/05/29 04:58:43 neilc Exp $ -->
22

33
<chapter id="datatype">
44
<title id="datatype-title">Data Types</title>
@@ -1880,7 +1880,8 @@ January 8 04:05:06 1999 PST
18801880
</programlisting>
18811881

18821882
Where: <replaceable>quantity</> is a number (possibly signed);
1883-
<replaceable>unit</> is <literal>second</literal>,
1883+
<replaceable>unit</> is <literal>microsecond</literal>,
1884+
<literal>millisecond</literal>, <literal>second</literal>,
18841885
<literal>minute</literal>, <literal>hour</literal>, <literal>day</literal>,
18851886
<literal>week</literal>, <literal>month</literal>, <literal>year</literal>,
18861887
<literal>decade</literal>, <literal>century</literal>, <literal>millennium</literal>,

‎src/backend/utils/adt/datetime.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.179 2007/05/27 20:32:16 neilc Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.180 2007/05/29 04:58:43 neilc Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -924,6 +924,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
924924
#else
925925
*fsec=frac;
926926
#endif
927+
tmask=DTK_ALL_SECS_M;
927928
}
928929
break;
929930

@@ -1699,6 +1700,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
16991700
#else
17001701
*fsec=frac;
17011702
#endif
1703+
tmask=DTK_ALL_SECS_M;
17021704
}
17031705
break;
17041706

@@ -2805,6 +2807,7 @@ DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct pg_tm * tm,
28052807
#else
28062808
*fsec+= (val+fval)*1e-6;
28072809
#endif
2810+
tmask=DTK_M(MICROSECOND);
28082811
break;
28092812

28102813
caseDTK_MILLISEC:
@@ -2813,6 +2816,7 @@ DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct pg_tm * tm,
28132816
#else
28142817
*fsec+= (val+fval)*1e-3;
28152818
#endif
2819+
tmask=DTK_M(MILLISECOND);
28162820
break;
28172821

28182822
caseDTK_SECOND:
@@ -2822,7 +2826,15 @@ DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct pg_tm * tm,
28222826
#else
28232827
*fsec+=fval;
28242828
#endif
2825-
tmask=DTK_M(SECOND);
2829+
/*
2830+
* If any subseconds were specified, consider
2831+
* this microsecond and millisecond input as
2832+
* well.
2833+
*/
2834+
if (fval==0)
2835+
tmask=DTK_M(SECOND);
2836+
else
2837+
tmask=DTK_ALL_SECS_M;
28262838
break;
28272839

28282840
caseDTK_MINUTE:

‎src/include/utils/datetime.h

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
1010
* Portions Copyright (c) 1994, Regents of the University of California
1111
*
12-
* $PostgreSQL: pgsql/src/include/utils/datetime.h,v 1.65 2007/02/19 17:41:39 momjian Exp $
12+
* $PostgreSQL: pgsql/src/include/utils/datetime.h,v 1.66 2007/05/29 04:58:43 neilc Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -100,17 +100,19 @@
100100
#defineHOUR10
101101
#defineMINUTE11
102102
#defineSECOND12
103-
#defineDOY13
104-
#defineDOW14
105-
#defineUNITS15
106-
#defineADBC16
103+
#defineMILLISECOND 13
104+
#defineMICROSECOND 14
105+
#defineDOY15
106+
#defineDOW16
107+
#defineUNITS17
108+
#defineADBC18
107109
/* these are only for relative dates */
108-
#defineAGO17
109-
#defineABS_BEFORE18
110-
#defineABS_AFTER19
110+
#defineAGO19
111+
#defineABS_BEFORE20
112+
#defineABS_AFTER21
111113
/* generic fields to help with parsing */
112-
#defineISODATE20
113-
#defineISOTIME21
114+
#defineISODATE22
115+
#defineISOTIME23
114116
/* reserved for unrecognized string values */
115117
#defineUNKNOWN_FIELD31
116118

@@ -175,8 +177,10 @@
175177

176178
#defineDTK_M(t)(0x01 << (t))
177179

180+
/* Convenvience: a second, plus any fractional component */
181+
#defineDTK_ALL_SECS_M(DTK_M(SECOND) | DTK_M(MILLISECOND) | DTK_M(MICROSECOND))
178182
#defineDTK_DATE_M(DTK_M(YEAR) | DTK_M(MONTH) | DTK_M(DAY))
179-
#defineDTK_TIME_M(DTK_M(HOUR) | DTK_M(MINUTE) |DTK_M(SECOND))
183+
#defineDTK_TIME_M(DTK_M(HOUR) | DTK_M(MINUTE) |DTK_ALL_SECS_M)
180184

181185
#defineMAXDATELEN63/* maximum possible length of an input date
182186
* string (not counting tr. null) */

‎src/test/regress/expected/interval.out

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,3 +326,26 @@ SELECT justify_interval(interval '1 month -1 hour') as "1 month -1 hour";
326326
@ 29 days 23 hours
327327
(1 row)
328328

329+
-- test fractional second input, and detection of duplicate units
330+
SET DATESTYLE = 'ISO';
331+
SELECT '1 millisecond'::interval, '1 microsecond'::interval,
332+
'500 seconds 99 milliseconds 51 microseconds'::interval;
333+
interval | interval | interval
334+
--------------+-----------------+-----------------
335+
00:00:00.001 | 00:00:00.000001 | 00:08:20.099051
336+
(1 row)
337+
338+
SELECT '3 days 5 milliseconds'::interval;
339+
interval
340+
---------------------
341+
3 days 00:00:00.005
342+
(1 row)
343+
344+
SELECT '1 second 2 seconds'::interval; -- error
345+
ERROR: invalid input syntax for type interval: "1 second 2 seconds"
346+
SELECT '10 milliseconds 20 milliseconds'::interval; -- error
347+
ERROR: invalid input syntax for type interval: "10 milliseconds 20 milliseconds"
348+
SELECT '5.5 seconds 3 milliseconds'::interval; -- error
349+
ERROR: invalid input syntax for type interval: "5.5 seconds 3 milliseconds"
350+
SELECT '1:20:05 5 microseconds'::interval; -- error
351+
ERROR: invalid input syntax for type interval: "1:20:05 5 microseconds"

‎src/test/regress/sql/interval.sql

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,14 @@ SELECT justify_days(interval '6 months 36 days 5 hours 4 minutes 3 seconds') as
116116
-- test justify_interval()
117117

118118
SELECT justify_interval(interval'1 month -1 hour')as"1 month -1 hour";
119+
120+
-- test fractional second input, and detection of duplicate units
121+
SET DATESTYLE='ISO';
122+
SELECT'1 millisecond'::interval,'1 microsecond'::interval,
123+
'500 seconds 99 milliseconds 51 microseconds'::interval;
124+
SELECT'3 days 5 milliseconds'::interval;
125+
126+
SELECT'1 second 2 seconds'::interval;-- error
127+
SELECT'10 milliseconds 20 milliseconds'::interval;-- error
128+
SELECT'5.5 seconds 3 milliseconds'::interval;-- error
129+
SELECT'1:20:05 5 microseconds'::interval;-- error

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp