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

Commitb73c0c2

Browse files
committed
Clean up a couple of weird corner cases in interval parsing: make -yyyy-mm be
interpreted as expected (the sign should affect months too), and get rid ofhard-wired assumption that unmarked signed values must be hours (if integers)or seconds (if floats). The former was just a bug in my previous patch,while the latter may have made sense at one time but seems illogical nowthat we support determination of the units from typmod information.Ron Mayer and myself.
1 parent30df79a commitb73c0c2

File tree

3 files changed

+13
-38
lines changed

3 files changed

+13
-38
lines changed

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

Lines changed: 13 additions & 31 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.192 2008/09/11 15:27:30 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.193 2008/09/16 22:31:21 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -448,7 +448,7 @@ TrimTrailingZeros(char *str)
448448
*DTK_TIME - digits, colon delimiters, and possibly a decimal point
449449
*DTK_STRING - text (no digits or punctuation)
450450
*DTK_SPECIAL - leading "+" or "-" followed by text
451-
*DTK_TZ - leading "+" or "-" followed by digits (also eats ':' or '.')
451+
*DTK_TZ - leading "+" or "-" followed by digits (also eats ':', '.', '-')
452452
*
453453
* Note that some field types can hold unexpected items:
454454
*DTK_NUMBER can hold date fields (yy.ddd)
@@ -610,12 +610,13 @@ ParseDateTime(const char *timestr, char *workbuf, size_t buflen,
610610
while (isspace((unsignedchar)*cp))
611611
cp++;
612612
/* numeric timezone? */
613+
/* note that "DTK_TZ" could also be a signed float or yyyy-mm */
613614
if (isdigit((unsignedchar)*cp))
614615
{
615616
ftype[nf]=DTK_TZ;
616617
APPEND_CHAR(bufp,bufend,*cp++);
617618
while (isdigit((unsignedchar)*cp)||
618-
*cp==':'||*cp=='.')
619+
*cp==':'||*cp=='.'||*cp=='-')
619620
APPEND_CHAR(bufp,bufend,*cp++);
620621
}
621622
/* special? */
@@ -2774,19 +2775,17 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
27742775

27752776
/*
27762777
* Timezone is a token with a leading sign character and
2777-
* otherwise the same as a non-signed time field
2778+
* at least one digit; there could be ':', '.', '-'
2779+
* embedded in it as well.
27782780
*/
27792781
Assert(*field[i]=='-'||*field[i]=='+');
27802782

27812783
/*
2782-
*A single signed number ends up here, but will be rejected
2783-
*by DecodeTime(). So, work this out to drop through to
2784-
*DTK_NUMBER, which *can* tolerate this.
2784+
*Try for hh:mm or hh:mm:ss. If not, fall through to
2785+
*DTK_NUMBER case, which can handle signed float numbers
2786+
*and signed year-month values.
27852787
*/
2786-
cp=field[i]+1;
2787-
while (*cp!='\0'&&*cp!=':'&&*cp!='.')
2788-
cp++;
2789-
if (*cp==':'&&
2788+
if (strchr(field[i]+1,':')!=NULL&&
27902789
DecodeTime(field[i]+1,fmask,INTERVAL_FULL_RANGE,
27912790
&tmask,tm,fsec)==0)
27922791
{
@@ -2808,32 +2807,13 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
28082807
tmask=DTK_M(TZ);
28092808
break;
28102809
}
2811-
elseif (type==IGNORE_DTF)
2812-
{
2813-
if (*cp=='.')
2814-
{
2815-
/*
2816-
* Got a decimal point? Then assume some sort of
2817-
* seconds specification
2818-
*/
2819-
type=DTK_SECOND;
2820-
}
2821-
elseif (*cp=='\0')
2822-
{
2823-
/*
2824-
* Only a signed integer? Then must assume a
2825-
* timezone-like usage
2826-
*/
2827-
type=DTK_HOUR;
2828-
}
2829-
}
28302810
/* FALL THROUGH */
28312811

28322812
caseDTK_DATE:
28332813
caseDTK_NUMBER:
28342814
if (type==IGNORE_DTF)
28352815
{
2836-
/* use typmod to decide what rightmostintegerfield is */
2816+
/* use typmod to decide what rightmost field is */
28372817
switch (range)
28382818
{
28392819
caseINTERVAL_MASK(YEAR):
@@ -2883,6 +2863,8 @@ DecodeInterval(char **field, int *ftype, int nf, int range,
28832863
if (*cp!='\0')
28842864
returnDTERR_BAD_FORMAT;
28852865
type=DTK_MONTH;
2866+
if (val<0)
2867+
val2=-val2;
28862868
val=val*MONTHS_PER_YEAR+val2;
28872869
fval=0;
28882870
}

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,6 @@ SELECT INTERVAL '-08:00' AS "Eight hours";
2121
-08:00:00
2222
(1 row)
2323

24-
SELECT INTERVAL '-05' AS "Five hours";
25-
Five hours
26-
------------
27-
-05:00:00
28-
(1 row)
29-
3024
SELECT INTERVAL '-1 +02:03' AS "22 hours ago...";
3125
22 hours ago...
3226
-------------------

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ SET DATESTYLE = 'ISO';
88
SELECT INTERVAL'01:00'AS"One hour";
99
SELECT INTERVAL'+02:00'AS"Two hours";
1010
SELECT INTERVAL'-08:00'AS"Eight hours";
11-
SELECT INTERVAL'-05'AS"Five hours";
1211
SELECT INTERVAL'-1 +02:03'AS"22 hours ago...";
1312
SELECT INTERVAL'-1 days +02:03'AS"22 hours ago...";
1413
SELECT INTERVAL'1.5 weeks'AS"Ten days twelve hours";

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp