|
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 | int ftype[MAXDATEFIELDS];
|
58 | 58 | char lowstr[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 | int dtype;
|
519 | 522 | int ftype[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 | static void
|
610 | 623 | AdjustTimeForTypmod(TimeADT *time, int32 typmod)
|
611 | 624 | {
|
612 |
| - if ((typmod >= 0) && (typmod <= MAX_TIME_PRECISION)) |
613 |
| - { |
614 | 625 | #ifdef HAVE_INT64_TIMESTAMP
|
615 |
| - static int64 TimeScale = INT64CONST(1000000); |
| 626 | + static const int64 TimeScales[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 | + static const int64 TimeOffsets[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 |
| - static double TimeScale = 1; |
| 646 | + static const double TimeScales[MAX_TIMESTAMP_PRECISION+1] = { |
| 647 | + 1, |
| 648 | + 10, |
| 649 | + 100, |
| 650 | + 1000, |
| 651 | + 10000, |
| 652 | + 100000, |
| 653 | + 1000000 |
| 654 | + }; |
| 655 | + |
| 656 | + static const double TimeOffsets[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 |
| - static int32 TimeTypmod = 0; |
620 | 666 |
|
621 |
| - if (typmod != TimeTypmod) |
622 |
| - { |
| 667 | + if ((typmod >= 0) && (typmod <= MAX_TIME_PRECISION)) |
| 668 | + { |
623 | 669 | #ifdef HAVE_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 |
| -#ifdef HAVE_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 | int dtype;
|
1270 | 1324 | int ftype[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);
|
|
0 commit comments