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

Commit424d938

Browse files
author
Thomas G. Lockhart
committed
Fix transposed arguments for typmod for one INTERVAL production.
Mask both typmod subfields for INTERVAL to avoid setting the high bit, per dire warning from Tom Lane.Clear tmask for DTK_ISO_TIME case to avoid time zone troubles. Symptom reported by Tom Lane.Clean up checking for valid time zone info in output routine. This should now work for both SQL99 and Unix-style time zones.Put in explicit check for INTERVAL() typmod rounding to avoid accumulating cruft in the lower bits. Not sure that this helps, but we'll need to do something. The symptom is visible with a query like select interval(2) '10000 days 01:02:03.040506';Regression tests are patched to repair the Tom Lane symptom, and all pass.
1 parent3a484d9 commit424d938

File tree

6 files changed

+114
-57
lines changed

6 files changed

+114
-57
lines changed

‎src/backend/parser/gram.y

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.264 2001/10/18 23:16:09 tgl Exp $
14+
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.265 2001/10/20 01:02:14 thomas Exp $
1515
*
1616
* HISTORY
1717
* AUTHORDATEMAJOR EVENT
@@ -887,13 +887,18 @@ zone_value: Sconst
887887
|ConstIntervalSconstopt_interval
888888
{
889889
A_Const *n = (A_Const *) makeStringConst($2,$1);
890-
n->typename->typmod = (($3 <<16) |0xFFFF);
890+
if ($3 != -1)
891+
n->typename->typmod = (($3 <<16) |0xFFFF);
891892
$$ = (Node *)n;
892893
}
893894
|ConstInterval'('Iconst')'Sconstopt_interval
894895
{
895896
A_Const *n = (A_Const *) makeStringConst($5,$1);
896-
n->typename->typmod = (($3 <<16) |$6);
897+
if ($6 != -1)
898+
n->typename->typmod = (($6 <<16) |$3);
899+
else
900+
n->typename->typmod = ((0x7FFF <<16) |$3);
901+
897902
$$ = (Node *)n;
898903
}
899904
|FCONST
@@ -4044,12 +4049,13 @@ SimpleTypename: ConstTypename
40444049
|ConstIntervalopt_interval
40454050
{
40464051
$$ =$1;
4047-
$$->typmod = (($2 <<16) |0xFFFF);
4052+
if ($2 != -1)
4053+
$$->typmod = ((($2 &0x7FFF) <<16) |0xFFFF);
40484054
}
40494055
|ConstInterval'('Iconst')'opt_interval
40504056
{
40514057
$$ =$1;
4052-
$$->typmod = (($5 <<16) |$3);
4058+
$$->typmod = ((($5 &0x7FFF) <<16) |$3);
40534059
}
40544060
;
40554061

@@ -5625,7 +5631,9 @@ AexprConst: Iconst
56255631
n->typename =$1;
56265632
n->val.type = T_String;
56275633
n->val.val.str =$2;
5628-
n->typename->typmod = (($3 <<16) |0xFFFF);
5634+
/* precision is not specified, but fields may be...*/
5635+
if ($3 != -1)
5636+
n->typename->typmod = ((($3 &0x7FFF) <<16) |0xFFFF);
56295637
$$ = (Node *)n;
56305638
}
56315639
|ConstInterval'('Iconst')'Sconstopt_interval
@@ -5634,7 +5642,9 @@ AexprConst: Iconst
56345642
n->typename =$1;
56355643
n->val.type = T_String;
56365644
n->val.val.str =$5;
5637-
n->typename->typmod = (($6 <<16) |$3);
5645+
/* precision specified, and fields may be...*/
5646+
n->typename->typmod = ((($6 &0x7FFF) <<16) |$3);
5647+
56385648
$$ = (Node *)n;
56395649
}
56405650
|ParamNo

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

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.73 2001/10/18 17:30:15 thomas Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.74 2001/10/20 01:02:18 thomas Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -385,17 +385,22 @@ j2day(int date)
385385
}/* j2day() */
386386

387387

388+
/* TrimTrailingZeros()
389+
* ... resulting from printing numbers with full precision.
390+
*/
388391
void
389392
TrimTrailingZeros(char*str)
390393
{
391394
intlen=strlen(str);
392395

396+
#if0
393397
/* chop off trailing one to cope with interval rounding */
394398
if (strcmp((str+len-4),"0001")==0)
395399
{
396400
len-=4;
397401
*(str+len)='\0';
398402
}
403+
#endif
399404

400405
/* chop off trailing zeros... */
401406
while ((*(str+len-1)=='0')
@@ -905,11 +910,12 @@ DecodeDateTime(char **field, int *ftype, int nf,
905910
break;
906911

907912
caseUNITS:
908-
ptype=val;
909913
tmask=0;
914+
ptype=val;
910915
break;
911916

912917
caseDTK_ISO_TIME:
918+
tmask=0;
913919
if ((i<1)|| (i >= (nf-1))
914920
|| (ftype[i-1]!=DTK_DATE)
915921
|| (ftype[i+1]!=DTK_TIME))
@@ -2267,10 +2273,10 @@ EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, cha
22672273
}
22682274

22692275
/* tzp == NULL indicates that we don't want *any* time zone info in the output string.
2270-
* *tzn != NULL indicates that we*have* time zone info available.
2276+
* *tzn != NULL indicates that we have alpha time zone info available.
22712277
* tm_isdst != -1 indicates that we have a valid time zone translation.
22722278
*/
2273-
if ((tzp!=NULL)&& (*tzn!=NULL)&& (tm->tm_isdst >=0))
2279+
if ((tzp!=NULL)&& (tm->tm_isdst >=0))
22742280
{
22752281
hour=-(*tzp /3600);
22762282
min= ((abs(*tzp) /60) %60);
@@ -2315,14 +2321,18 @@ EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, cha
23152321
sprintf((str+strlen(str)),":%02.0f",sec);
23162322
}
23172323

2318-
if ((*tzn!=NULL)&& (tm->tm_isdst >=0))
2319-
sprintf((str+strlen(str))," %.*s",MAXTZLEN,*tzn);
2320-
2321-
elseif (tzp!=NULL)
2324+
if ((tzp!=NULL)&& (tm->tm_isdst >=0))
23222325
{
2323-
hour=-(*tzp /3600);
2324-
min= ((abs(*tzp) /60) %60);
2325-
sprintf((str+strlen(str)), ((min!=0) ?"%+03d:%02d" :"%+03d"),hour,min);
2326+
if (*tzn!=NULL)
2327+
{
2328+
sprintf((str+strlen(str))," %.*s",MAXTZLEN,*tzn);
2329+
}
2330+
else
2331+
{
2332+
hour=-(*tzp /3600);
2333+
min= ((abs(*tzp) /60) %60);
2334+
sprintf((str+strlen(str)), ((min!=0) ?"%+03d:%02d" :"%+03d"),hour,min);
2335+
}
23262336
}
23272337
}
23282338
else
@@ -2353,14 +2363,18 @@ EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, cha
23532363
sprintf((str+strlen(str)),":%02.0f",sec);
23542364
}
23552365

2356-
if ((*tzn!=NULL)&& (tm->tm_isdst >=0))
2357-
sprintf((str+strlen(str))," %.*s",MAXTZLEN,*tzn);
2358-
2359-
elseif (tzp!=NULL)
2366+
if ((tzp!=NULL)&& (tm->tm_isdst >=0))
23602367
{
2361-
hour=-(*tzp /3600);
2362-
min= ((abs(*tzp) /60) %60);
2363-
sprintf((str+strlen(str)), ((min!=0) ?"%+03d:%02d" :"%+03d"),hour,min);
2368+
if (*tzn!=NULL)
2369+
{
2370+
sprintf((str+strlen(str))," %.*s",MAXTZLEN,*tzn);
2371+
}
2372+
else
2373+
{
2374+
hour=-(*tzp /3600);
2375+
min= ((abs(*tzp) /60) %60);
2376+
sprintf((str+strlen(str)), ((min!=0) ?"%+03d:%02d" :"%+03d"),hour,min);
2377+
}
23642378
}
23652379
}
23662380
else
@@ -2403,14 +2417,23 @@ EncodeDateTime(struct tm * tm, double fsec, int *tzp, char **tzn, int style, cha
24032417

24042418
sprintf((str+strlen(str))," %04d",tm->tm_year);
24052419

2406-
if ((tzp!=NULL)&& (*tzn!=NULL)&& (tm->tm_isdst >=0))
2407-
sprintf((str+strlen(str))," %.*s",MAXTZLEN,*tzn);
2408-
2409-
elseif (HasCTZSet&& (tzp!=NULL))
2420+
if ((tzp!=NULL)&& (tm->tm_isdst >=0))
24102421
{
2411-
hour=-(*tzp /3600);
2412-
min= ((abs(*tzp) /60) %60);
2413-
sprintf((str+strlen(str)), ((min!=0) ?"%+03d:%02d" :"%+03d"),hour,min);
2422+
if (*tzn!=NULL)
2423+
{
2424+
sprintf((str+strlen(str))," %.*s",MAXTZLEN,*tzn);
2425+
}
2426+
else
2427+
{
2428+
/* We have a time zone, but no string version.
2429+
* Use the numeric form, but be sure to include a leading space
2430+
* to avoid formatting something which would be rejected by the
2431+
* date/time parser later. - thomas 2001-10-19
2432+
*/
2433+
hour=-(*tzp /3600);
2434+
min= ((abs(*tzp) /60) %60);
2435+
sprintf((str+strlen(str)), ((min!=0) ?" %+03d:%02d" :" %+03d"),hour,min);
2436+
}
24142437
}
24152438
}
24162439
else

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

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.89 2001/10/18 19:52:03 tgl Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.90 2001/10/20 01:02:18 thomas Exp $
1313
*
1414
* NOTES
1515
*
@@ -256,7 +256,7 @@ GetCurrentAbsoluteTimeUsec(int *usec)
256256
};
257257

258258
return (AbsoluteTime)now;
259-
}/*GetCurrentAbsoluteTime() */
259+
}/*GetCurrentAbsoluteTimeUsec() */
260260

261261

262262
void
@@ -344,7 +344,7 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char **tzn)
344344
{
345345
*tzp=CTimeZone;
346346
tm->tm_gmtoff=CTimeZone;
347-
tm->tm_isdst=-1;
347+
tm->tm_isdst=0;
348348
tm->tm_zone=NULL;
349349
if (tzn!=NULL)
350350
*tzn=NULL;
@@ -366,6 +366,10 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char **tzn)
366366
}
367367
}
368368
}
369+
else
370+
{
371+
tm->tm_isdst=-1;
372+
}
369373
#elif defined(HAVE_INT_TIMEZONE)
370374
if (tzp!=NULL)
371375
{
@@ -376,7 +380,7 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char **tzn)
376380
if (HasCTZSet)
377381
{
378382
*tzp=CTimeZone;
379-
tm->tm_isdst=-1;
383+
tm->tm_isdst=0;
380384
if (tzn!=NULL)
381385
*tzn=NULL;
382386
}
@@ -397,6 +401,10 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char **tzn)
397401
}
398402
}
399403
}
404+
else
405+
{
406+
tm->tm_isdst=-1;
407+
}
400408
#endif
401409
#else/* not (HAVE_TM_ZONE || HAVE_INT_TIMEZONE) */
402410
if (tzp!=NULL)
@@ -426,6 +434,10 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char **tzn)
426434
}
427435
}
428436
}
437+
else
438+
{
439+
tm->tm_isdst=-1;
440+
}
429441
#endif
430442

431443
return;

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

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.57 2001/10/18 19:54:59 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.58 2001/10/20 01:02:18 thomas Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -374,14 +374,14 @@ AdjustIntervalForTypmod(Interval *interval, int32 typmod)
374374
{
375375
if (typmod!=-1)
376376
{
377-
intrange= ((typmod >>16)&0xFFFF);
377+
intrange= ((typmod >>16)&0x7FFF);
378378
intprecision= (typmod&0xFFFF);
379379

380-
if (range==0xFFFF)
380+
if (range==0x7FFF)
381381
{
382382
/* Do nothing... */
383383
}
384-
if (range==MASK(YEAR))
384+
elseif (range==MASK(YEAR))
385385
{
386386
interval->month= ((interval->month /12)*12);
387387
interval->time=0;
@@ -483,7 +483,18 @@ AdjustIntervalForTypmod(Interval *interval, int32 typmod)
483483
IntervalScale=pow(10.0,IntervalTypmod);
484484
}
485485

486-
interval->time= (rint(interval->time*IntervalScale) /IntervalScale);
486+
/* Hmm. For the time field, we can get to a large value
487+
* since we store everything related to an absolute interval
488+
* (e.g. years worth of days) in this one field. So we have
489+
* precision problems doing rint() on this field if the field
490+
* is too large. This resulted in an annoying "...0001" appended
491+
* to the printed result on my Linux box.
492+
* I hate doing an expensive math operation like log10()
493+
* to avoid this, but what else can we do??
494+
* - thomas 2001-10-19
495+
*/
496+
if ((log10(interval->time)+IntervalTypmod) <=13)
497+
interval->time= (rint(interval->time*IntervalScale) /IntervalScale);
487498
}
488499
}
489500

@@ -671,14 +682,15 @@ timestamp2tm(Timestamp dt, int *tzp, struct tm * tm, double *fsec, char **tzn)
671682
else
672683
{
673684
*tzp=0;
674-
tm->tm_isdst=0;
685+
/* Mark this as *no* time zone available */
686+
tm->tm_isdst=-1;
675687
if (tzn!=NULL)
676688
*tzn=NULL;
677689
}
678690
}
679691
else
680692
{
681-
tm->tm_isdst=0;
693+
tm->tm_isdst=-1;
682694
if (tzn!=NULL)
683695
*tzn=NULL;
684696
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ SELECT '' AS "64", d1 + interval '1 year' AS one_year FROM TIMESTAMPTZ_TBL;
359359
| Tue Feb 10 17:32:01 1998 PST
360360
| Tue Feb 10 17:32:01 1998 PST
361361
| Wed Jun 10 17:32:01 1998 PDT
362-
| Sun Sep 2211:19:20 2002 PDT
362+
| Sun Sep 2218:19:20 2002 PDT
363363
| Thu Mar 15 08:14:01 2001 PST
364364
| Thu Mar 15 04:14:02 2001 PST
365365
| Thu Mar 15 02:14:03 2001 PST
@@ -428,7 +428,7 @@ SELECT '' AS "64", d1 - interval '1 year' AS one_year FROM TIMESTAMPTZ_TBL;
428428
| Sat Feb 10 17:32:01 1996 PST
429429
| Sat Feb 10 17:32:01 1996 PST
430430
| Mon Jun 10 17:32:01 1996 PDT
431-
| Fri Sep 2211:19:20 2000 PDT
431+
| Fri Sep 2218:19:20 2000 PDT
432432
| Mon Mar 15 08:14:01 1999 PST
433433
| Mon Mar 15 04:14:02 1999 PST
434434
| Mon Mar 15 02:14:03 1999 PST

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp