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

Commit57bfb27

Browse files
committed
Fix interval input parser so that fractional weeks and months are
cascaded first to days and only what is leftover into seconds. Thisseems to satisfy the principle of least surprise given the generalconversion to three-part interval values --- it was an oversight thatthese cases weren't dealt with in 8.1. Michael Glaesemann
1 parent091fe03 commit57bfb27

File tree

4 files changed

+72
-30
lines changed

4 files changed

+72
-30
lines changed

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

Lines changed: 29 additions & 15 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.169 2006/07/25 03:51:21 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.170 2006/09/04 01:26:27 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -2920,16 +2920,23 @@ DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct pg_tm * tm,
29202920
tm->tm_mday+=val*7;
29212921
if (fval!=0)
29222922
{
2923-
intsec;
2924-
2925-
fval *=7*SECS_PER_DAY;
2926-
sec=fval;
2927-
tm->tm_sec+=sec;
2923+
intextra_days;
2924+
fval *=7;
2925+
extra_days= (int32)fval;
2926+
tm->tm_mday+=extra_days;
2927+
fval-=extra_days;
2928+
if (fval!=0)
2929+
{
2930+
intsec;
2931+
fval *=SECS_PER_DAY;
2932+
sec=fval;
2933+
tm->tm_sec+=sec;
29282934
#ifdefHAVE_INT64_TIMESTAMP
2929-
*fsec+= (fval-sec)*1000000;
2935+
*fsec+= (fval-sec)*1000000;
29302936
#else
2931-
*fsec+=fval-sec;
2937+
*fsec+=fval-sec;
29322938
#endif
2939+
}
29332940
}
29342941
tmask= (fmask&DTK_M(DAY)) ?0 :DTK_M(DAY);
29352942
break;
@@ -2938,16 +2945,23 @@ DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct pg_tm * tm,
29382945
tm->tm_mon+=val;
29392946
if (fval!=0)
29402947
{
2941-
intsec;
2942-
2943-
fval *=DAYS_PER_MONTH*SECS_PER_DAY;
2944-
sec=fval;
2945-
tm->tm_sec+=sec;
2948+
intday;
2949+
fval *=DAYS_PER_MONTH;
2950+
day=fval;
2951+
tm->tm_mday+=day;
2952+
fval-=day;
2953+
if (fval!=0)
2954+
{
2955+
intsec;
2956+
fval *=SECS_PER_DAY;
2957+
sec=fval;
2958+
tm->tm_sec+=sec;
29462959
#ifdefHAVE_INT64_TIMESTAMP
2947-
*fsec+= (fval-sec)*1000000;
2960+
*fsec+= (fval-sec)*1000000;
29482961
#else
2949-
*fsec+=fval-sec;
2962+
*fsec+=fval-sec;
29502963
#endif
2964+
}
29512965
}
29522966
tmask=DTK_M(MONTH);
29532967
break;

‎src/interfaces/ecpg/pgtypeslib/interval.c

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/interval.c,v 1.32 2006/06/06 11:31:55 meskes Exp $ */
1+
/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/interval.c,v 1.33 2006/09/04 01:26:28 tgl Exp $ */
22

33
#include"postgres_fe.h"
44
#include<time.h>
@@ -307,16 +307,23 @@ DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct tm * tm, fse
307307
tm->tm_mday+=val*7;
308308
if (fval!=0)
309309
{
310-
intsec;
311-
312-
fval *=7*SECS_PER_DAY;
313-
sec=fval;
314-
tm->tm_sec+=sec;
310+
intextra_days;
311+
fval *=7;
312+
extra_days= (int32)fval;
313+
tm->tm_mday+=extra_days;
314+
fval-=extra_days;
315+
if (fval!=0)
316+
{
317+
intsec;
318+
fval *=SECS_PER_DAY;
319+
sec=fval;
320+
tm->tm_sec+=sec;
315321
#ifdefHAVE_INT64_TIMESTAMP
316-
*fsec+= (fval-sec)*1000000;
322+
*fsec+= (fval-sec)*1000000;
317323
#else
318-
*fsec+=fval-sec;
324+
*fsec+=fval-sec;
319325
#endif
326+
}
320327
}
321328
tmask= (fmask&DTK_M(DAY)) ?0 :DTK_M(DAY);
322329
break;
@@ -325,16 +332,23 @@ DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct tm * tm, fse
325332
tm->tm_mon+=val;
326333
if (fval!=0)
327334
{
328-
intsec;
329-
330-
fval *=DAYS_PER_MONTH*SECS_PER_DAY;
331-
sec=fval;
332-
tm->tm_sec+=sec;
335+
intday;
336+
fval *=DAYS_PER_MONTH;
337+
day=fval;
338+
tm->tm_mday+=day;
339+
fval-=day;
340+
if (fval!=0)
341+
{
342+
intsec;
343+
fval *=SECS_PER_DAY;
344+
sec=fval;
345+
tm->tm_sec+=sec;
333346
#ifdefHAVE_INT64_TIMESTAMP
334-
*fsec+= (fval-sec)*1000000;
347+
*fsec+= (fval-sec)*1000000;
335348
#else
336-
*fsec+=fval-sec;
349+
*fsec+=fval-sec;
337350
#endif
351+
}
338352
}
339353
tmask=DTK_M(MONTH);
340354
break;

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,18 @@ SELECT INTERVAL '-1 days +02:03' AS "22 hours ago...";
3939
-1 days +02:03:00
4040
(1 row)
4141

42+
SELECT INTERVAL '1.5 weeks' AS "Ten days twelve hours";
43+
Ten days twelve hours
44+
-----------------------
45+
10 days 12:00:00
46+
(1 row)
47+
48+
SELECT INTERVAL '1.5 months' AS "One month 15 days";
49+
One month 15 days
50+
-------------------
51+
1 mon 15 days
52+
(1 row)
53+
4254
SELECT INTERVAL '10 years -11 month -12 days +13:14' AS "9 years...";
4355
9 years...
4456
----------------------------------

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ SELECT INTERVAL '-08:00' AS "Eight hours";
1111
SELECT INTERVAL'-05'AS"Five hours";
1212
SELECT INTERVAL'-1 +02:03'AS"22 hours ago...";
1313
SELECT INTERVAL'-1 days +02:03'AS"22 hours ago...";
14+
SELECT INTERVAL'1.5 weeks'AS"Ten days twelve hours";
15+
SELECT INTERVAL'1.5 months'AS"One month 15 days";
1416
SELECT INTERVAL'10 years -11 month -12 days +13:14'AS"9 years...";
1517

1618
CREATETABLEINTERVAL_TBL (f1 interval);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp