Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit ac5fdea

Browse files
committed
When a TIMESTAMP, TIME, or INTERVAL precision is specified larger than our
implementation limits, do not issue an ERROR; instead issue a NOTICE and use the max supported value. Per pgsql-general discussion of 28-Apr, this is needed to allow easy porting from pre-7.3 releases where the limits were higher. Unrelated change in same area: accept GLOBAL TEMP/TEMPORARY as a synonym for TEMPORARY, as per pgsql-hackers discussion of 15-Apr. We previously rejected it, but that was based on a misreading of the spec --- SQL92's GLOBAL temp tables are really closer to what we have than their LOCAL ones.
1 parent 2286971 commit ac5fdea

File tree

3 files changed

+118
-62
lines changed

3 files changed

+118
-62
lines changed

doc/src/sgml/ref/create_table.sgml

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_table.sgml,v 1.67 2003/04/22 10:08:08 petere Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_table.sgml,v 1.68 2003/05/04 00:03:55 tgl Exp $
33
PostgreSQL documentation
44
-->
55

@@ -16,7 +16,7 @@ PostgreSQL documentation
1616

1717
<refsynopsisdiv>
1818
<synopsis>
19-
CREATE [ [ LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PARAMETER">table_name</replaceable> (
19+
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PARAMETER">table_name</replaceable> (
2020
{ <replaceable class="PARAMETER">column_name</replaceable> <replaceable class="PARAMETER">data_type</replaceable> [ DEFAULT <replaceable>default_expr</> ] [ <replaceable class="PARAMETER">column_constraint</replaceable> [, ... ] ]
2121
| <replaceable>table_constraint</replaceable> } [, ... ]
2222
)
@@ -101,7 +101,7 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
101101
<variablelist>
102102

103103
<varlistentry>
104-
<term><literal>[LOCAL] TEMPORARY</> or <literal>[LOCAL] TEMP</></term>
104+
<term><literal>TEMPORARY</> or <literal>TEMP</></term>
105105
<listitem>
106106
<para>
107107
If specified, the table is created as a temporary table.
@@ -115,7 +115,9 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
115115
</para>
116116

117117
<para>
118-
The <literal>LOCAL</literal> word is optional. But see under
118+
Optionally, <literal>GLOBAL</literal> or <literal>LOCAL</literal>
119+
can be written before <literal>TEMPORARY</> or <literal>TEMP</>.
120+
This makes no difference in <productname>PostgreSQL</>, but see
119121
<xref linkend="sql-createtable-compatibility"
120122
endterm="sql-createtable-compatibility-title">.
121123
</para>
@@ -195,7 +197,7 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
195197
</para>
196198
<!--
197199
<para>
198-
<application>PostgreSQL</application> automatically allows the
200+
<productname>PostgreSQL</> automatically allows the
199201
created table to inherit
200202
functions on tables above it in the inheritance hierarchy; that
201203
is, if we create table <literal>foo</literal> inheriting from
@@ -786,7 +788,8 @@ CREATE TABLE distributors (
786788

787789
<para>
788790
Although the syntax of <literal>CREATE TEMPORARY TABLE</literal>
789-
resembles that of SQL standard, the effect is not the same. In the standard,
791+
resembles that of the SQL standard, the effect is not the same. In the
792+
standard,
790793
temporary tables are defined just once and automatically exist (starting
791794
with empty contents) in every session that needs them.
792795
<productname>PostgreSQL</productname> instead
@@ -798,7 +801,7 @@ CREATE TABLE distributors (
798801
</para>
799802

800803
<para>
801-
The behavior of temporary tables mandated by the standard is
804+
The standard's definition of the behavior of temporary tables is
802805
widely ignored. <productname>PostgreSQL</productname>'s behavior
803806
on this point is similar to that of several other SQL databases.
804807
</para>
@@ -808,6 +811,9 @@ CREATE TABLE distributors (
808811
is not in <productname>PostgreSQL</productname>, since that distinction
809812
depends on the concept of modules, which
810813
<productname>PostgreSQL</productname> does not have.
814+
For compatibility's sake, <productname>PostgreSQL</productname> will
815+
accept the <literal>GLOBAL</literal> and <literal>LOCAL</literal> keywords
816+
in a temporary table declaration, but they have no effect.
811817
</para>
812818

813819
<para>

doc/src/sgml/ref/create_table_as.sgml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_table_as.sgml,v 1.12 2003/04/22 10:08:08 petere Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_table_as.sgml,v 1.13 2003/05/04 00:03:55 tgl Exp $
33
PostgreSQL documentation
44
-->
55

@@ -16,7 +16,7 @@ PostgreSQL documentation
1616

1717
<refsynopsisdiv>
1818
<synopsis>
19-
CREATE [ [ LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name</replaceable> [ (<replaceable>column_name</replaceable> [, ...] ) ]
19+
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name</replaceable> [ (<replaceable>column_name</replaceable> [, ...] ) ]
2020
AS <replaceable>query</replaceable>
2121
</synopsis>
2222
</refsynopsisdiv>
@@ -49,7 +49,7 @@ CREATE [ [ LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name</replace
4949

5050
<variablelist>
5151
<varlistentry>
52-
<term><literal>[LOCAL] TEMPORARY</> or <literal>[LOCAL] TEMP</></term>
52+
<term><literal>TEMPORARY</> or <literal>TEMP</></term>
5353
<listitem>
5454
<para>
5555
If specified, the table is created as a temporary table.

src/backend/parser/gram.y

Lines changed: 102 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.412 2003/04/29 03:21:29 tgl Exp $
14+
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.413 2003/05/04 00:03:55 tgl Exp $
1515
*
1616
* HISTORY
1717
* AUTHOR DATE MAJOR EVENT
@@ -964,10 +964,17 @@ zone_value:
964964
| ConstInterval '(' Iconst ')' Sconst opt_interval
965965
{
966966
A_Const *n = (A_Const *) makeStringConst($5, $1);
967-
if (($3 < 0) || ($3 > MAX_INTERVAL_PRECISION))
967+
if ($3 < 0)
968968
elog(ERROR,
969-
"INTERVAL(%d) precision must be between %d and %d",
970-
$3, 0, MAX_INTERVAL_PRECISION);
969+
"INTERVAL(%d) precision must not be negative",
970+
$3);
971+
if ($3 > MAX_INTERVAL_PRECISION)
972+
{
973+
elog(NOTICE,
974+
"INTERVAL(%d) precision reduced to maximum allowed, %d",
975+
$3, MAX_INTERVAL_PRECISION);
976+
$3 = MAX_INTERVAL_PRECISION;
977+
}
971978

972979
if (($6 != INTERVAL_FULL_RANGE)
973980
&& (($6 & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0))
@@ -1414,23 +1421,16 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
14141421
/*
14151422
* Redundancy here is needed to avoid shift/reduce conflicts,
14161423
* since TEMP is not a reserved word. See also OptTempTableName.
1424+
*
1425+
* NOTE: we accept both GLOBAL and LOCAL options; since we have no modules
1426+
* the LOCAL keyword is really meaningless.
14171427
*/
14181428
OptTemp: TEMPORARY { $$ = TRUE; }
14191429
| TEMP { $$ = TRUE; }
14201430
| LOCAL TEMPORARY { $$ = TRUE; }
14211431
| LOCAL TEMP { $$ = TRUE; }
1422-
| GLOBAL TEMPORARY
1423-
{
1424-
elog(ERROR,
1425-
"GLOBAL TEMPORARY TABLE is not currently supported");
1426-
$$ = TRUE;
1427-
}
1428-
| GLOBAL TEMP
1429-
{
1430-
elog(ERROR,
1431-
"GLOBAL TEMPORARY TABLE is not currently supported");
1432-
$$ = TRUE;
1433-
}
1432+
| GLOBAL TEMPORARY { $$ = TRUE; }
1433+
| GLOBAL TEMP { $$ = TRUE; }
14341434
| /*EMPTY*/ { $$ = FALSE; }
14351435
;
14361436

@@ -1466,8 +1466,8 @@ columnDef: ColId Typename ColQualList opt_collate
14661466

14671467
if ($4 != NULL)
14681468
elog(NOTICE,
1469-
"CREATE TABLE / COLLATE %s not yet implemented; "
1470-
"clause ignored", $4);
1469+
"CREATE TABLE / COLLATE %s not yet implemented; "
1470+
"clause ignored", $4);
14711471

14721472
$$ = (Node *)n;
14731473
}
@@ -3240,7 +3240,7 @@ RemoveOperStmt:
32403240
oper_argtypes:
32413241
Typename
32423242
{
3243-
elog(ERROR,"parser: argument type missing (use NONE for unary operators)");
3243+
elog(ERROR, "parser: argument type missing (use NONE for unary operators)");
32443244
}
32453245
| Typename ',' Typename
32463246
{ $$ = makeList2($1, $3); }
@@ -3768,7 +3768,7 @@ CreateDomainStmt:
37683768

37693769
if ($7 != NULL)
37703770
elog(NOTICE,"CREATE DOMAIN / COLLATE %s not yet "
3771-
"implemented; clause ignored", $7);
3771+
"implemented; clause ignored", $7);
37723772
$$ = (Node *)n;
37733773
}
37743774
;
@@ -4426,15 +4426,11 @@ OptTempTableName:
44264426
}
44274427
| GLOBAL TEMPORARY opt_table qualified_name
44284428
{
4429-
elog(ERROR,
4430-
"GLOBAL TEMPORARY TABLE is not currently supported");
44314429
$$ = $4;
44324430
$$->istemp = true;
44334431
}
44344432
| GLOBAL TEMP opt_table qualified_name
44354433
{
4436-
elog(ERROR,
4437-
"GLOBAL TEMPORARY TABLE is not currently supported");
44384434
$$ = $4;
44394435
$$->istemp = true;
44404436
}
@@ -5031,10 +5027,17 @@ SimpleTypename:
50315027
| ConstInterval '(' Iconst ')' opt_interval
50325028
{
50335029
$$ = $1;
5034-
if (($3 < 0) || ($3 > MAX_INTERVAL_PRECISION))
5030+
if ($3 < 0)
50355031
elog(ERROR,
5036-
"INTERVAL(%d) precision must be between %d and %d",
5037-
$3, 0, MAX_INTERVAL_PRECISION);
5032+
"INTERVAL(%d) precision must not be negative",
5033+
$3);
5034+
if ($3 > MAX_INTERVAL_PRECISION)
5035+
{
5036+
elog(NOTICE,
5037+
"INTERVAL(%d) precision reduced to maximum allowed, %d",
5038+
$3, MAX_INTERVAL_PRECISION);
5039+
$3 = MAX_INTERVAL_PRECISION;
5040+
}
50385041
$$->typmod = INTERVAL_TYPMOD($3, $5);
50395042
}
50405043
| type_name attrs
@@ -5390,11 +5393,18 @@ ConstDatetime:
53905393
* - thomas 2001-09-06
53915394
*/
53925395
$$->timezone = $5;
5393-
if (($3 < 0) || ($3 > MAX_TIMESTAMP_PRECISION))
5396+
if ($3 < 0)
53945397
elog(ERROR,
5395-
"TIMESTAMP(%d)%s precision must be between %d and %d",
5396-
$3, ($5 ? " WITH TIME ZONE": ""), 0,
5398+
"TIMESTAMP(%d)%s precision must not be negative",
5399+
$3, ($5 ? " WITH TIME ZONE": ""));
5400+
if ($3 > MAX_TIMESTAMP_PRECISION)
5401+
{
5402+
elog(NOTICE,
5403+
"TIMESTAMP(%d)%s precision reduced to maximum allowed, %d",
5404+
$3, ($5 ? " WITH TIME ZONE": ""),
53975405
MAX_TIMESTAMP_PRECISION);
5406+
$3 = MAX_TIMESTAMP_PRECISION;
5407+
}
53985408
$$->typmod = $3;
53995409
}
54005410
| TIMESTAMP opt_timezone
@@ -5422,11 +5432,18 @@ ConstDatetime:
54225432
$$ = SystemTypeName("timetz");
54235433
else
54245434
$$ = SystemTypeName("time");
5425-
if (($3 < 0) || ($3 > MAX_TIME_PRECISION))
5435+
if ($3 < 0)
54265436
elog(ERROR,
5427-
"TIME(%d)%s precision must be between %d and %d",
5428-
$3, ($5 ? " WITH TIME ZONE": ""), 0,
5437+
"TIME(%d)%s precision must not be negative",
5438+
$3, ($5 ? " WITH TIME ZONE": ""));
5439+
if ($3 > MAX_TIME_PRECISION)
5440+
{
5441+
elog(NOTICE,
5442+
"TIME(%d)%s precision reduced to maximum allowed, %d",
5443+
$3, ($5 ? " WITH TIME ZONE": ""),
54295444
MAX_TIME_PRECISION);
5445+
$3 = MAX_TIME_PRECISION;
5446+
}
54305447
$$->typmod = $3;
54315448
}
54325449
| TIME opt_timezone
@@ -6218,10 +6235,17 @@ c_expr: columnref { $$ = (Node *) $1; }
62186235
s->val.val.str = "now";
62196236
s->typename = SystemTypeName("text");
62206237
d = SystemTypeName("timetz");
6221-
if (($3 < 0) || ($3 > MAX_TIME_PRECISION))
6238+
if ($3 < 0)
62226239
elog(ERROR,
6223-
"CURRENT_TIME(%d) precision must be between %d and %d",
6224-
$3, 0, MAX_TIME_PRECISION);
6240+
"CURRENT_TIME(%d) precision must not be negative",
6241+
$3);
6242+
if ($3 > MAX_TIME_PRECISION)
6243+
{
6244+
elog(NOTICE,
6245+
"CURRENT_TIME(%d) precision reduced to maximum allowed, %d",
6246+
$3, MAX_TIME_PRECISION);
6247+
$3 = MAX_TIME_PRECISION;
6248+
}
62256249
d->typmod = $3;
62266250

62276251
$$ = (Node *)makeTypeCast((Node *)s, d);
@@ -6263,11 +6287,17 @@ c_expr: columnref { $$ = (Node *) $1; }
62636287
s->typename = SystemTypeName("text");
62646288

62656289
d = SystemTypeName("timestamptz");
6266-
if (($3 < 0) || ($3 > MAX_TIMESTAMP_PRECISION))
6290+
if ($3 < 0)
62676291
elog(ERROR,
6268-
"CURRENT_TIMESTAMP(%d) precision "
6269-
"must be between %d and %d",
6270-
$3, 0, MAX_TIMESTAMP_PRECISION);
6292+
"CURRENT_TIMESTAMP(%d) precision must not be negative",
6293+
$3);
6294+
if ($3 > MAX_TIMESTAMP_PRECISION)
6295+
{
6296+
elog(NOTICE,
6297+
"CURRENT_TIMESTAMP(%d) precision reduced to maximum allowed, %d",
6298+
$3, MAX_TIMESTAMP_PRECISION);
6299+
$3 = MAX_TIMESTAMP_PRECISION;
6300+
}
62716301
d->typmod = $3;
62726302

62736303
$$ = (Node *)makeTypeCast((Node *)s, d);
@@ -6308,10 +6338,17 @@ c_expr: columnref { $$ = (Node *) $1; }
63086338
s->val.val.str = "now";
63096339
s->typename = SystemTypeName("text");
63106340
d = SystemTypeName("time");
6311-
if (($3 < 0) || ($3 > MAX_TIME_PRECISION))
6341+
if ($3 < 0)
63126342
elog(ERROR,
6313-
"LOCALTIME(%d) precision must be between %d and %d",
6314-
$3, 0, MAX_TIME_PRECISION);
6343+
"LOCALTIME(%d) precision must not be negative",
6344+
$3);
6345+
if ($3 > MAX_TIME_PRECISION)
6346+
{
6347+
elog(NOTICE,
6348+
"LOCALTIME(%d) precision reduced to maximum allowed, %d",
6349+
$3, MAX_TIME_PRECISION);
6350+
$3 = MAX_TIME_PRECISION;
6351+
}
63156352
d->typmod = $3;
63166353

63176354
$$ = (Node *)makeTypeCast((Node *)s, d);
@@ -6353,11 +6390,17 @@ c_expr: columnref { $$ = (Node *) $1; }
63536390
s->typename = SystemTypeName("text");
63546391

63556392
d = SystemTypeName("timestamp");
6356-
if (($3 < 0) || ($3 > MAX_TIMESTAMP_PRECISION))
6393+
if ($3 < 0)
63576394
elog(ERROR,
6358-
"LOCALTIMESTAMP(%d) precision must be "
6359-
"between %d and %d",
6360-
$3, 0, MAX_TIMESTAMP_PRECISION);
6395+
"LOCALTIMESTAMP(%d) precision must not be negative",
6396+
$3);
6397+
if ($3 > MAX_TIMESTAMP_PRECISION)
6398+
{
6399+
elog(NOTICE,
6400+
"LOCALTIMESTAMP(%d) precision reduced to maximum allowed, %d",
6401+
$3, MAX_TIMESTAMP_PRECISION);
6402+
$3 = MAX_TIMESTAMP_PRECISION;
6403+
}
63616404
d->typmod = $3;
63626405

63636406
$$ = (Node *)makeTypeCast((Node *)s, d);
@@ -6934,8 +6977,8 @@ qualified_name:
69346977
break;
69356978
default:
69366979
elog(ERROR,
6937-
"Improper qualified name "
6938-
"(too many dotted names): %s",
6980+
"Improper qualified name "
6981+
"(too many dotted names): %s",
69396982
NameListToString($1));
69406983
break;
69416984
}
@@ -7038,10 +7081,17 @@ AexprConst: Iconst
70387081
n->val.type = T_String;
70397082
n->val.val.str = $5;
70407083
/* precision specified, and fields may be... */
7041-
if (($3 < 0) || ($3 > MAX_INTERVAL_PRECISION))
7084+
if ($3 < 0)
70427085
elog(ERROR,
7043-
"INTERVAL(%d) precision must be between %d and %d",
7044-
$3, 0, MAX_INTERVAL_PRECISION);
7086+
"INTERVAL(%d) precision must not be negative",
7087+
$3);
7088+
if ($3 > MAX_INTERVAL_PRECISION)
7089+
{
7090+
elog(NOTICE,
7091+
"INTERVAL(%d) precision reduced to maximum allowed, %d",
7092+
$3, MAX_INTERVAL_PRECISION);
7093+
$3 = MAX_INTERVAL_PRECISION;
7094+
}
70457095
n->typename->typmod = INTERVAL_TYPMOD($3, $6);
70467096
$$ = (Node *)n;
70477097
}

0 commit comments

Comments
 (0)