|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.69 2002/06/20 20:29:36 momjian Exp $ |
| 11 | + * $Header: /cvsroot/pgsql/src/backend/utils/adt/date.c,v 1.70 2002/08/04 06:44:47 thomas Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -57,6 +57,9 @@ date_in(PG_FUNCTION_ARGS)
|
57 | 57 | intftype[MAXDATEFIELDS];
|
58 | 58 | charlowstr[MAXDATELEN+1];
|
59 | 59 |
|
| 60 | +if (strlen(str) >=sizeof(lowstr)) |
| 61 | +elog(ERROR,"Bad date external representation (too long) '%s'",str); |
| 62 | + |
60 | 63 | if ((ParseDateTime(str,lowstr,field,ftype,MAXDATEFIELDS,&nf)!=0)
|
61 | 64 | || (DecodeDateTime(field,ftype,nf,&dtype,tm,&fsec,&tzp)!=0))
|
62 | 65 | elog(ERROR,"Bad date external representation '%s'",str);
|
@@ -518,6 +521,9 @@ time_in(PG_FUNCTION_ARGS)
|
518 | 521 | intdtype;
|
519 | 522 | intftype[MAXDATEFIELDS];
|
520 | 523 |
|
| 524 | +if (strlen(str) >=sizeof(lowstr)) |
| 525 | +elog(ERROR,"Bad time external representation (too long) '%s'",str); |
| 526 | + |
521 | 527 | if ((ParseDateTime(str,lowstr,field,ftype,MAXDATEFIELDS,&nf)!=0)
|
522 | 528 | || (DecodeTimeOnly(field,ftype,nf,&dtype,tm,&fsec,NULL)!=0))
|
523 | 529 | elog(ERROR,"Bad time external representation '%s'",str);
|
@@ -606,37 +612,85 @@ time_scale(PG_FUNCTION_ARGS)
|
606 | 612 | PG_RETURN_TIMEADT(result);
|
607 | 613 | }
|
608 | 614 |
|
| 615 | +/* AdjustTimeForTypmod() |
| 616 | + * Force the precision of the time value to a specified value. |
| 617 | + * Uses *exactly* the same code as in AdjustTimestampForTypemod() |
| 618 | + * but we make a separate copy because those types do not |
| 619 | + * have a fundamental tie together but rather a coincidence of |
| 620 | + * implementation. - thomas |
| 621 | + */ |
609 | 622 | staticvoid
|
610 | 623 | AdjustTimeForTypmod(TimeADT*time,int32typmod)
|
611 | 624 | {
|
612 |
| -if ((typmod >=0)&& (typmod <=MAX_TIME_PRECISION)) |
613 |
| -{ |
614 | 625 | #ifdefHAVE_INT64_TIMESTAMP
|
615 |
| -staticint64TimeScale=INT64CONST(1000000); |
| 626 | +staticconstint64TimeScales[MAX_TIMESTAMP_PRECISION+1]= { |
| 627 | +INT64CONST(1000000), |
| 628 | +INT64CONST(100000), |
| 629 | +INT64CONST(10000), |
| 630 | +INT64CONST(1000), |
| 631 | +INT64CONST(100), |
| 632 | +INT64CONST(10), |
| 633 | +INT64CONST(1) |
| 634 | +}; |
| 635 | + |
| 636 | +staticconstint64TimeOffsets[MAX_TIMESTAMP_PRECISION+1]= { |
| 637 | +INT64CONST(-500000), |
| 638 | +INT64CONST(-50000), |
| 639 | +INT64CONST(-5000), |
| 640 | +INT64CONST(-500), |
| 641 | +INT64CONST(-50), |
| 642 | +INT64CONST(-5), |
| 643 | +INT64CONST(0) |
| 644 | +}; |
616 | 645 | #else
|
617 |
| -staticdoubleTimeScale=1; |
| 646 | +staticconstdoubleTimeScales[MAX_TIMESTAMP_PRECISION+1]= { |
| 647 | +1, |
| 648 | +10, |
| 649 | +100, |
| 650 | +1000, |
| 651 | +10000, |
| 652 | +100000, |
| 653 | +1000000 |
| 654 | +}; |
| 655 | + |
| 656 | +staticconstdoubleTimeOffsets[MAX_TIMESTAMP_PRECISION+1]= { |
| 657 | +0.5, |
| 658 | +0.05, |
| 659 | +0.005, |
| 660 | +0.0005, |
| 661 | +0.00005, |
| 662 | +0.000005, |
| 663 | +0.0000005 |
| 664 | +}; |
618 | 665 | #endif
|
619 |
| -staticint32TimeTypmod=0; |
620 | 666 |
|
621 |
| -if (typmod!=TimeTypmod) |
622 |
| -{ |
| 667 | +if ((typmod>=0)&& (typmod <=MAX_TIME_PRECISION)) |
| 668 | +{ |
623 | 669 | #ifdefHAVE_INT64_TIMESTAMP
|
624 |
| -TimeScale=pow(10.0, (MAX_TIME_PRECISION-typmod)); |
625 |
| -#else |
626 |
| -TimeScale=pow(10.0,typmod); |
627 |
| -#endif |
628 |
| -TimeTypmod=typmod; |
| 670 | +/* we have different truncation behavior depending on sign */ |
| 671 | +if (*time >=INT64CONST(0)) |
| 672 | +{ |
| 673 | +*time= ((*time /TimeScales[typmod]) |
| 674 | +*TimeScales[typmod]); |
| 675 | +} |
| 676 | +else |
| 677 | +{ |
| 678 | +*time= (((*time+TimeOffsets[typmod]) /TimeScales[typmod]) |
| 679 | +*TimeScales[typmod]); |
629 | 680 | }
|
630 |
| - |
631 |
| -#ifdefHAVE_INT64_TIMESTAMP |
632 |
| -*time= ((*time /TimeScale)*TimeScale); |
633 |
| -if (*time >=INT64CONST(86400000000)) |
634 |
| -*time-=INT64CONST(86400000000); |
635 | 681 | #else
|
636 |
| -*time= (rint(((double)*time)*TimeScale) /TimeScale); |
637 |
| - |
638 |
| -if (*time >=86400) |
639 |
| -*time-=86400; |
| 682 | +/* we have different truncation behavior depending on sign */ |
| 683 | +if (*time >=0) |
| 684 | +{ |
| 685 | +*time= (rint(((double)*time)*TimeScales[typmod]) |
| 686 | + /TimeScales[typmod]); |
| 687 | +} |
| 688 | +else |
| 689 | +{ |
| 690 | +/* Scale and truncate first, then add to help the rounding behavior */ |
| 691 | +*time= (rint((((double)*time)*TimeScales[typmod])+TimeOffsets[typmod]) |
| 692 | + /TimeScales[typmod]); |
| 693 | +} |
640 | 694 | #endif
|
641 | 695 | }
|
642 | 696 |
|
@@ -1269,6 +1323,10 @@ timetz_in(PG_FUNCTION_ARGS)
|
1269 | 1323 | intdtype;
|
1270 | 1324 | intftype[MAXDATEFIELDS];
|
1271 | 1325 |
|
| 1326 | +if (strlen(str) >=sizeof(lowstr)) |
| 1327 | +elog(ERROR,"Bad time with time zone" |
| 1328 | +" external representation (too long) '%s'",str); |
| 1329 | + |
1272 | 1330 | if ((ParseDateTime(str,lowstr,field,ftype,MAXDATEFIELDS,&nf)!=0)
|
1273 | 1331 | || (DecodeTimeOnly(field,ftype,nf,&dtype,tm,&fsec,&tz)!=0))
|
1274 | 1332 | elog(ERROR,"Bad time external representation '%s'",str);
|
|