Commit 417f9248 authored by Bruce Momjian's avatar Bruce Momjian

interval: tighten precision specification

interval precision can only be specified after the "interval" keyword if
no units are specified.

Previously we incorrectly checked the units to see if the precision was
legal, causing confusion.

Report by Alvaro Herrera
parent 97d55487
...@@ -1552,25 +1552,9 @@ zone_value: ...@@ -1552,25 +1552,9 @@ zone_value:
t->typmods = $3; t->typmods = $3;
$$ = makeStringConstCast($2, @2, t); $$ = makeStringConstCast($2, @2, t);
} }
| ConstInterval '(' Iconst ')' Sconst opt_interval | ConstInterval '(' Iconst ')' Sconst
{ {
TypeName *t = $1; TypeName *t = $1;
if ($6 != NIL)
{
A_Const *n = (A_Const *) linitial($6);
if ((n->val.val.ival & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("time zone interval must be HOUR or HOUR TO MINUTE"),
parser_errposition(@6)));
if (list_length($6) != 1)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("interval precision specified twice"),
parser_errposition(@1)));
t->typmods = lappend($6, makeIntConst($3, @3));
}
else
t->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1), t->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1),
makeIntConst($3, @3)); makeIntConst($3, @3));
$$ = makeStringConstCast($5, @5, t); $$ = makeStringConstCast($5, @5, t);
...@@ -10582,19 +10566,9 @@ SimpleTypename: ...@@ -10582,19 +10566,9 @@ SimpleTypename:
$$ = $1; $$ = $1;
$$->typmods = $2; $$->typmods = $2;
} }
| ConstInterval '(' Iconst ')' opt_interval | ConstInterval '(' Iconst ')'
{ {
$$ = $1; $$ = $1;
if ($5 != NIL)
{
if (list_length($5) != 1)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("interval precision specified twice"),
parser_errposition(@1)));
$$->typmods = lappend($5, makeIntConst($3, @3));
}
else
$$->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1), $$->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1),
makeIntConst($3, @3)); makeIntConst($3, @3));
} }
...@@ -12923,19 +12897,9 @@ AexprConst: Iconst ...@@ -12923,19 +12897,9 @@ AexprConst: Iconst
t->typmods = $3; t->typmods = $3;
$$ = makeStringConstCast($2, @2, t); $$ = makeStringConstCast($2, @2, t);
} }
| ConstInterval '(' Iconst ')' Sconst opt_interval | ConstInterval '(' Iconst ')' Sconst
{ {
TypeName *t = $1; TypeName *t = $1;
if ($6 != NIL)
{
if (list_length($6) != 1)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("interval precision specified twice"),
parser_errposition(@1)));
t->typmods = lappend($6, makeIntConst($3, @3));
}
else
t->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1), t->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1),
makeIntConst($3, @3)); makeIntConst($3, @3));
$$ = makeStringConstCast($5, @5, t); $$ = makeStringConstCast($5, @5, t);
......
...@@ -616,16 +616,6 @@ SELECT interval '12:34.5678' minute to second(2); -- per SQL spec ...@@ -616,16 +616,6 @@ SELECT interval '12:34.5678' minute to second(2); -- per SQL spec
00:12:34.57 00:12:34.57
(1 row) (1 row)
SELECT interval(2) '12:34.5678' minute to second; -- historical PG
interval
-------------
00:12:34.57
(1 row)
SELECT interval(2) '12:34.5678' minute to second(2); -- syntax error
ERROR: interval precision specified twice
LINE 1: SELECT interval(2) '12:34.5678' minute to second(2);
^
SELECT interval '1.234' second; SELECT interval '1.234' second;
interval interval
-------------- --------------
......
...@@ -183,8 +183,6 @@ SELECT interval '123 2:03 -2:04'; -- not ok, redundant hh:mm fields ...@@ -183,8 +183,6 @@ SELECT interval '123 2:03 -2:04'; -- not ok, redundant hh:mm fields
SELECT interval(0) '1 day 01:23:45.6789'; SELECT interval(0) '1 day 01:23:45.6789';
SELECT interval(2) '1 day 01:23:45.6789'; SELECT interval(2) '1 day 01:23:45.6789';
SELECT interval '12:34.5678' minute to second(2); -- per SQL spec SELECT interval '12:34.5678' minute to second(2); -- per SQL spec
SELECT interval(2) '12:34.5678' minute to second; -- historical PG
SELECT interval(2) '12:34.5678' minute to second(2); -- syntax error
SELECT interval '1.234' second; SELECT interval '1.234' second;
SELECT interval '1.234' second(2); SELECT interval '1.234' second(2);
SELECT interval '1 2.345' day to second(2); SELECT interval '1 2.345' day to second(2);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment