|
11 | 11 | *
|
12 | 12 | *
|
13 | 13 | * IDENTIFICATION
|
14 |
| - * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.622 2008/09/02 20:37:54 tgl Exp $ |
| 14 | + * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.623 2008/09/11 15:27:30 tgl Exp $ |
15 | 15 | *
|
16 | 16 | * HISTORY
|
17 | 17 | * AUTHOR DATE MAJOR EVENT
|
@@ -292,7 +292,7 @@ static TypeName *TableFuncTypeName(List *columns);
|
292 | 292 |
|
293 | 293 | %type <list> extract_list overlay_list position_list
|
294 | 294 | %type <list> substr_list trim_list
|
295 |
| -%type <ival> opt_interval |
| 295 | +%type <list> opt_interval interval_second |
296 | 296 | %type <node> overlay_placing substr_from substr_for
|
297 | 297 |
|
298 | 298 | %type <boolean> opt_instead opt_analyze
|
@@ -1222,28 +1222,39 @@ zone_value:
|
1222 | 1222 | | ConstInterval Sconst opt_interval
|
1223 | 1223 | {
|
1224 | 1224 | TypeName *t = $1;
|
1225 |
| - if ($3 != INTERVAL_FULL_RANGE) |
| 1225 | + if ($3 != NIL) |
1226 | 1226 | {
|
1227 |
| - if (($3 & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0) |
| 1227 | + A_Const *n = (A_Const *) linitial($3); |
| 1228 | + if ((n->val.val.ival & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0) |
1228 | 1229 | ereport(ERROR,
|
1229 | 1230 | (errcode(ERRCODE_SYNTAX_ERROR),
|
1230 | 1231 | errmsg("time zone interval must be HOUR or HOUR TO MINUTE"),
|
1231 | 1232 | scanner_errposition(@3)));
|
1232 |
| - t->typmods = list_make1(makeIntConst($3, @3)); |
1233 | 1233 | }
|
| 1234 | + t->typmods = $3; |
1234 | 1235 | $$ = makeStringConstCast($2, @2, t);
|
1235 | 1236 | }
|
1236 | 1237 | | ConstInterval '(' Iconst ')' Sconst opt_interval
|
1237 | 1238 | {
|
1238 | 1239 | TypeName *t = $1;
|
1239 |
| - if (($6 != INTERVAL_FULL_RANGE) |
1240 |
| - && (($6 & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0)) |
1241 |
| - ereport(ERROR, |
1242 |
| - (errcode(ERRCODE_SYNTAX_ERROR), |
1243 |
| - errmsg("time zone interval must be HOUR or HOUR TO MINUTE"), |
1244 |
| - scanner_errposition(@6))); |
1245 |
| - t->typmods = list_make2(makeIntConst($6, @6), |
1246 |
| - makeIntConst($3, @3)); |
| 1240 | + if ($6 != NIL) |
| 1241 | + { |
| 1242 | + A_Const *n = (A_Const *) linitial($6); |
| 1243 | + if ((n->val.val.ival & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0) |
| 1244 | + ereport(ERROR, |
| 1245 | + (errcode(ERRCODE_SYNTAX_ERROR), |
| 1246 | + errmsg("time zone interval must be HOUR or HOUR TO MINUTE"), |
| 1247 | + scanner_errposition(@6))); |
| 1248 | + if (list_length($6) != 1) |
| 1249 | + ereport(ERROR, |
| 1250 | + (errcode(ERRCODE_SYNTAX_ERROR), |
| 1251 | + errmsg("interval precision specified twice"), |
| 1252 | + scanner_errposition(@1))); |
| 1253 | + t->typmods = lappend($6, makeIntConst($3, @3)); |
| 1254 | + } |
| 1255 | + else |
| 1256 | + t->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1), |
| 1257 | + makeIntConst($3, @3)); |
1247 | 1258 | $$ = makeStringConstCast($5, @5, t);
|
1248 | 1259 | }
|
1249 | 1260 | | NumericOnly { $$ = makeAConst($1, @1); }
|
@@ -6983,14 +6994,23 @@ SimpleTypename:
|
6983 | 6994 | | ConstInterval opt_interval
|
6984 | 6995 | {
|
6985 | 6996 | $$ = $1;
|
6986 |
| - if ($2 != INTERVAL_FULL_RANGE) |
6987 |
| - $$->typmods = list_make1(makeIntConst($2, @2)); |
| 6997 | + $$->typmods = $2; |
6988 | 6998 | }
|
6989 | 6999 | | ConstInterval '(' Iconst ')' opt_interval
|
6990 | 7000 | {
|
6991 | 7001 | $$ = $1;
|
6992 |
| - $$->typmods = list_make2(makeIntConst($5, @5), |
6993 |
| - makeIntConst($3, @3)); |
| 7002 | + if ($5 != NIL) |
| 7003 | + { |
| 7004 | + if (list_length($5) != 1) |
| 7005 | + ereport(ERROR, |
| 7006 | + (errcode(ERRCODE_SYNTAX_ERROR), |
| 7007 | + errmsg("interval precision specified twice"), |
| 7008 | + scanner_errposition(@1))); |
| 7009 | + $$->typmods = lappend($5, makeIntConst($3, @3)); |
| 7010 | + } |
| 7011 | + else |
| 7012 | + $$->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1), |
| 7013 | + makeIntConst($3, @3)); |
6994 | 7014 | }
|
6995 | 7015 | ;
|
6996 | 7016 |
|
@@ -7337,30 +7357,74 @@ opt_timezone:
|
7337 | 7357 | ;
|
7338 | 7358 |
|
7339 | 7359 | opt_interval:
|
7340 |
| - YEAR_P { $$ = INTERVAL_MASK(YEAR); } |
7341 |
| - | MONTH_P { $$ = INTERVAL_MASK(MONTH); } |
7342 |
| - | DAY_P { $$ = INTERVAL_MASK(DAY); } |
7343 |
| - | HOUR_P { $$ = INTERVAL_MASK(HOUR); } |
7344 |
| - | MINUTE_P { $$ = INTERVAL_MASK(MINUTE); } |
7345 |
| - | SECOND_P { $$ = INTERVAL_MASK(SECOND); } |
| 7360 | + YEAR_P |
| 7361 | + { $$ = list_make1(makeIntConst(INTERVAL_MASK(YEAR), @1)); } |
| 7362 | + | MONTH_P |
| 7363 | + { $$ = list_make1(makeIntConst(INTERVAL_MASK(MONTH), @1)); } |
| 7364 | + | DAY_P |
| 7365 | + { $$ = list_make1(makeIntConst(INTERVAL_MASK(DAY), @1)); } |
| 7366 | + | HOUR_P |
| 7367 | + { $$ = list_make1(makeIntConst(INTERVAL_MASK(HOUR), @1)); } |
| 7368 | + | MINUTE_P |
| 7369 | + { $$ = list_make1(makeIntConst(INTERVAL_MASK(MINUTE), @1)); } |
| 7370 | + | interval_second |
| 7371 | + { $$ = $1; } |
7346 | 7372 | | YEAR_P TO MONTH_P
|
7347 |
| - { $$ = INTERVAL_MASK(YEAR) | INTERVAL_MASK(MONTH); } |
| 7373 | + { |
| 7374 | + $$ = list_make1(makeIntConst(INTERVAL_MASK(YEAR) | |
| 7375 | + INTERVAL_MASK(MONTH), @1)); |
| 7376 | + } |
7348 | 7377 | | DAY_P TO HOUR_P
|
7349 |
| - { $$ = INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR); } |
| 7378 | + { |
| 7379 | + $$ = list_make1(makeIntConst(INTERVAL_MASK(DAY) | |
| 7380 | + INTERVAL_MASK(HOUR), @1)); |
| 7381 | + } |
7350 | 7382 | | DAY_P TO MINUTE_P
|
7351 |
| - { $$ = INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) |
7352 |
| - | INTERVAL_MASK(MINUTE); } |
7353 |
| - | DAY_P TO SECOND_P |
7354 |
| - { $$ = INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) |
7355 |
| - | INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND); } |
| 7383 | + { |
| 7384 | + $$ = list_make1(makeIntConst(INTERVAL_MASK(DAY) | |
| 7385 | + INTERVAL_MASK(HOUR) | |
| 7386 | + INTERVAL_MASK(MINUTE), @1)); |
| 7387 | + } |
| 7388 | + | DAY_P TO interval_second |
| 7389 | + { |
| 7390 | + $$ = $3; |
| 7391 | + linitial($$) = makeIntConst(INTERVAL_MASK(DAY) | |
| 7392 | + INTERVAL_MASK(HOUR) | |
| 7393 | + INTERVAL_MASK(MINUTE) | |
| 7394 | + INTERVAL_MASK(SECOND), @1); |
| 7395 | + } |
7356 | 7396 | | HOUR_P TO MINUTE_P
|
7357 |
| - { $$ = INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE); } |
7358 |
| - | HOUR_P TO SECOND_P |
7359 |
| - { $$ = INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE) |
7360 |
| - | INTERVAL_MASK(SECOND); } |
7361 |
| - | MINUTE_P TO SECOND_P |
7362 |
| - { $$ = INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND); } |
7363 |
| - | /*EMPTY*/ { $$ = INTERVAL_FULL_RANGE; } |
| 7397 | + { |
| 7398 | + $$ = list_make1(makeIntConst(INTERVAL_MASK(HOUR) | |
| 7399 | + INTERVAL_MASK(MINUTE), @1)); |
| 7400 | + } |
| 7401 | + | HOUR_P TO interval_second |
| 7402 | + { |
| 7403 | + $$ = $3; |
| 7404 | + linitial($$) = makeIntConst(INTERVAL_MASK(HOUR) | |
| 7405 | + INTERVAL_MASK(MINUTE) | |
| 7406 | + INTERVAL_MASK(SECOND), @1); |
| 7407 | + } |
| 7408 | + | MINUTE_P TO interval_second |
| 7409 | + { |
| 7410 | + $$ = $3; |
| 7411 | + linitial($$) = makeIntConst(INTERVAL_MASK(MINUTE) | |
| 7412 | + INTERVAL_MASK(SECOND), @1); |
| 7413 | + } |
| 7414 | + | /*EMPTY*/ |
| 7415 | + { $$ = NIL; } |
| 7416 | + ; |
| 7417 | + |
| 7418 | +interval_second: |
| 7419 | + SECOND_P |
| 7420 | + { |
| 7421 | + $$ = list_make1(makeIntConst(INTERVAL_MASK(SECOND), @1)); |
| 7422 | + } |
| 7423 | + | SECOND_P '(' Iconst ')' |
| 7424 | + { |
| 7425 | + $$ = list_make2(makeIntConst(INTERVAL_MASK(SECOND), @1), |
| 7426 | + makeIntConst($3, @3)); |
| 7427 | + } |
7364 | 7428 | ;
|
7365 | 7429 |
|
7366 | 7430 |
|
@@ -9014,16 +9078,24 @@ AexprConst: Iconst
|
9014 | 9078 | | ConstInterval Sconst opt_interval
|
9015 | 9079 | {
|
9016 | 9080 | TypeName *t = $1;
|
9017 |
| - /* precision is not specified, but fields may be... */ |
9018 |
| - if ($3 != INTERVAL_FULL_RANGE) |
9019 |
| - t->typmods = list_make1(makeIntConst($3, @3)); |
| 9081 | + t->typmods = $3; |
9020 | 9082 | $$ = makeStringConstCast($2, @2, t);
|
9021 | 9083 | }
|
9022 | 9084 | | ConstInterval '(' Iconst ')' Sconst opt_interval
|
9023 | 9085 | {
|
9024 | 9086 | TypeName *t = $1;
|
9025 |
| - t->typmods = list_make2(makeIntConst($6, @6), |
9026 |
| - makeIntConst($3, @3)); |
| 9087 | + if ($6 != NIL) |
| 9088 | + { |
| 9089 | + if (list_length($6) != 1) |
| 9090 | + ereport(ERROR, |
| 9091 | + (errcode(ERRCODE_SYNTAX_ERROR), |
| 9092 | + errmsg("interval precision specified twice"), |
| 9093 | + scanner_errposition(@1))); |
| 9094 | + t->typmods = lappend($6, makeIntConst($3, @3)); |
| 9095 | + } |
| 9096 | + else |
| 9097 | + t->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1), |
| 9098 | + makeIntConst($3, @3)); |
9027 | 9099 | $$ = makeStringConstCast($5, @5, t);
|
9028 | 9100 | }
|
9029 | 9101 | | TRUE_P
|
|
0 commit comments