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.
This commit is contained in:
Tom Lane 2003-05-04 00:03:55 +00:00
parent 228697179a
commit ac5fdea687
3 changed files with 118 additions and 62 deletions

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_table.sgml,v 1.67 2003/04/22 10:08:08 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_table.sgml,v 1.68 2003/05/04 00:03:55 tgl Exp $
PostgreSQL documentation
-->
@ -16,7 +16,7 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
CREATE [ [ LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PARAMETER">table_name</replaceable> (
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PARAMETER">table_name</replaceable> (
{ <replaceable class="PARAMETER">column_name</replaceable> <replaceable class="PARAMETER">data_type</replaceable> [ DEFAULT <replaceable>default_expr</> ] [ <replaceable class="PARAMETER">column_constraint</replaceable> [, ... ] ]
| <replaceable>table_constraint</replaceable> } [, ... ]
)
@ -101,7 +101,7 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
<variablelist>
<varlistentry>
<term><literal>[LOCAL] TEMPORARY</> or <literal>[LOCAL] TEMP</></term>
<term><literal>TEMPORARY</> or <literal>TEMP</></term>
<listitem>
<para>
If specified, the table is created as a temporary table.
@ -115,7 +115,9 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
</para>
<para>
The <literal>LOCAL</literal> word is optional. But see under
Optionally, <literal>GLOBAL</literal> or <literal>LOCAL</literal>
can be written before <literal>TEMPORARY</> or <literal>TEMP</>.
This makes no difference in <productname>PostgreSQL</>, but see
<xref linkend="sql-createtable-compatibility"
endterm="sql-createtable-compatibility-title">.
</para>
@ -195,7 +197,7 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
</para>
<!--
<para>
<application>PostgreSQL</application> automatically allows the
<productname>PostgreSQL</> automatically allows the
created table to inherit
functions on tables above it in the inheritance hierarchy; that
is, if we create table <literal>foo</literal> inheriting from
@ -786,7 +788,8 @@ CREATE TABLE distributors (
<para>
Although the syntax of <literal>CREATE TEMPORARY TABLE</literal>
resembles that of SQL standard, the effect is not the same. In the standard,
resembles that of the SQL standard, the effect is not the same. In the
standard,
temporary tables are defined just once and automatically exist (starting
with empty contents) in every session that needs them.
<productname>PostgreSQL</productname> instead
@ -798,7 +801,7 @@ CREATE TABLE distributors (
</para>
<para>
The behavior of temporary tables mandated by the standard is
The standard's definition of the behavior of temporary tables is
widely ignored. <productname>PostgreSQL</productname>'s behavior
on this point is similar to that of several other SQL databases.
</para>
@ -808,6 +811,9 @@ CREATE TABLE distributors (
is not in <productname>PostgreSQL</productname>, since that distinction
depends on the concept of modules, which
<productname>PostgreSQL</productname> does not have.
For compatibility's sake, <productname>PostgreSQL</productname> will
accept the <literal>GLOBAL</literal> and <literal>LOCAL</literal> keywords
in a temporary table declaration, but they have no effect.
</para>
<para>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_table_as.sgml,v 1.12 2003/04/22 10:08:08 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_table_as.sgml,v 1.13 2003/05/04 00:03:55 tgl Exp $
PostgreSQL documentation
-->
@ -16,7 +16,7 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
CREATE [ [ LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name</replaceable> [ (<replaceable>column_name</replaceable> [, ...] ) ]
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name</replaceable> [ (<replaceable>column_name</replaceable> [, ...] ) ]
AS <replaceable>query</replaceable>
</synopsis>
</refsynopsisdiv>
@ -49,7 +49,7 @@ CREATE [ [ LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name</replace
<variablelist>
<varlistentry>
<term><literal>[LOCAL] TEMPORARY</> or <literal>[LOCAL] TEMP</></term>
<term><literal>TEMPORARY</> or <literal>TEMP</></term>
<listitem>
<para>
If specified, the table is created as a temporary table.

View File

@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.412 2003/04/29 03:21:29 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.413 2003/05/04 00:03:55 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@ -964,10 +964,17 @@ zone_value:
| ConstInterval '(' Iconst ')' Sconst opt_interval
{
A_Const *n = (A_Const *) makeStringConst($5, $1);
if (($3 < 0) || ($3 > MAX_INTERVAL_PRECISION))
if ($3 < 0)
elog(ERROR,
"INTERVAL(%d) precision must be between %d and %d",
$3, 0, MAX_INTERVAL_PRECISION);
"INTERVAL(%d) precision must not be negative",
$3);
if ($3 > MAX_INTERVAL_PRECISION)
{
elog(NOTICE,
"INTERVAL(%d) precision reduced to maximum allowed, %d",
$3, MAX_INTERVAL_PRECISION);
$3 = MAX_INTERVAL_PRECISION;
}
if (($6 != INTERVAL_FULL_RANGE)
&& (($6 & ~(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE))) != 0))
@ -1414,23 +1421,16 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
/*
* Redundancy here is needed to avoid shift/reduce conflicts,
* since TEMP is not a reserved word. See also OptTempTableName.
*
* NOTE: we accept both GLOBAL and LOCAL options; since we have no modules
* the LOCAL keyword is really meaningless.
*/
OptTemp: TEMPORARY { $$ = TRUE; }
| TEMP { $$ = TRUE; }
| LOCAL TEMPORARY { $$ = TRUE; }
| LOCAL TEMP { $$ = TRUE; }
| GLOBAL TEMPORARY
{
elog(ERROR,
"GLOBAL TEMPORARY TABLE is not currently supported");
$$ = TRUE;
}
| GLOBAL TEMP
{
elog(ERROR,
"GLOBAL TEMPORARY TABLE is not currently supported");
$$ = TRUE;
}
| GLOBAL TEMPORARY { $$ = TRUE; }
| GLOBAL TEMP { $$ = TRUE; }
| /*EMPTY*/ { $$ = FALSE; }
;
@ -1466,8 +1466,8 @@ columnDef: ColId Typename ColQualList opt_collate
if ($4 != NULL)
elog(NOTICE,
"CREATE TABLE / COLLATE %s not yet implemented; "
"clause ignored", $4);
"CREATE TABLE / COLLATE %s not yet implemented; "
"clause ignored", $4);
$$ = (Node *)n;
}
@ -3240,7 +3240,7 @@ RemoveOperStmt:
oper_argtypes:
Typename
{
elog(ERROR,"parser: argument type missing (use NONE for unary operators)");
elog(ERROR, "parser: argument type missing (use NONE for unary operators)");
}
| Typename ',' Typename
{ $$ = makeList2($1, $3); }
@ -3768,7 +3768,7 @@ CreateDomainStmt:
if ($7 != NULL)
elog(NOTICE,"CREATE DOMAIN / COLLATE %s not yet "
"implemented; clause ignored", $7);
"implemented; clause ignored", $7);
$$ = (Node *)n;
}
;
@ -4426,15 +4426,11 @@ OptTempTableName:
}
| GLOBAL TEMPORARY opt_table qualified_name
{
elog(ERROR,
"GLOBAL TEMPORARY TABLE is not currently supported");
$$ = $4;
$$->istemp = true;
}
| GLOBAL TEMP opt_table qualified_name
{
elog(ERROR,
"GLOBAL TEMPORARY TABLE is not currently supported");
$$ = $4;
$$->istemp = true;
}
@ -5031,10 +5027,17 @@ SimpleTypename:
| ConstInterval '(' Iconst ')' opt_interval
{
$$ = $1;
if (($3 < 0) || ($3 > MAX_INTERVAL_PRECISION))
if ($3 < 0)
elog(ERROR,
"INTERVAL(%d) precision must be between %d and %d",
$3, 0, MAX_INTERVAL_PRECISION);
"INTERVAL(%d) precision must not be negative",
$3);
if ($3 > MAX_INTERVAL_PRECISION)
{
elog(NOTICE,
"INTERVAL(%d) precision reduced to maximum allowed, %d",
$3, MAX_INTERVAL_PRECISION);
$3 = MAX_INTERVAL_PRECISION;
}
$$->typmod = INTERVAL_TYPMOD($3, $5);
}
| type_name attrs
@ -5390,11 +5393,18 @@ ConstDatetime:
* - thomas 2001-09-06
*/
$$->timezone = $5;
if (($3 < 0) || ($3 > MAX_TIMESTAMP_PRECISION))
if ($3 < 0)
elog(ERROR,
"TIMESTAMP(%d)%s precision must be between %d and %d",
$3, ($5 ? " WITH TIME ZONE": ""), 0,
"TIMESTAMP(%d)%s precision must not be negative",
$3, ($5 ? " WITH TIME ZONE": ""));
if ($3 > MAX_TIMESTAMP_PRECISION)
{
elog(NOTICE,
"TIMESTAMP(%d)%s precision reduced to maximum allowed, %d",
$3, ($5 ? " WITH TIME ZONE": ""),
MAX_TIMESTAMP_PRECISION);
$3 = MAX_TIMESTAMP_PRECISION;
}
$$->typmod = $3;
}
| TIMESTAMP opt_timezone
@ -5422,11 +5432,18 @@ ConstDatetime:
$$ = SystemTypeName("timetz");
else
$$ = SystemTypeName("time");
if (($3 < 0) || ($3 > MAX_TIME_PRECISION))
if ($3 < 0)
elog(ERROR,
"TIME(%d)%s precision must be between %d and %d",
$3, ($5 ? " WITH TIME ZONE": ""), 0,
"TIME(%d)%s precision must not be negative",
$3, ($5 ? " WITH TIME ZONE": ""));
if ($3 > MAX_TIME_PRECISION)
{
elog(NOTICE,
"TIME(%d)%s precision reduced to maximum allowed, %d",
$3, ($5 ? " WITH TIME ZONE": ""),
MAX_TIME_PRECISION);
$3 = MAX_TIME_PRECISION;
}
$$->typmod = $3;
}
| TIME opt_timezone
@ -6218,10 +6235,17 @@ c_expr: columnref { $$ = (Node *) $1; }
s->val.val.str = "now";
s->typename = SystemTypeName("text");
d = SystemTypeName("timetz");
if (($3 < 0) || ($3 > MAX_TIME_PRECISION))
if ($3 < 0)
elog(ERROR,
"CURRENT_TIME(%d) precision must be between %d and %d",
$3, 0, MAX_TIME_PRECISION);
"CURRENT_TIME(%d) precision must not be negative",
$3);
if ($3 > MAX_TIME_PRECISION)
{
elog(NOTICE,
"CURRENT_TIME(%d) precision reduced to maximum allowed, %d",
$3, MAX_TIME_PRECISION);
$3 = MAX_TIME_PRECISION;
}
d->typmod = $3;
$$ = (Node *)makeTypeCast((Node *)s, d);
@ -6263,11 +6287,17 @@ c_expr: columnref { $$ = (Node *) $1; }
s->typename = SystemTypeName("text");
d = SystemTypeName("timestamptz");
if (($3 < 0) || ($3 > MAX_TIMESTAMP_PRECISION))
if ($3 < 0)
elog(ERROR,
"CURRENT_TIMESTAMP(%d) precision "
"must be between %d and %d",
$3, 0, MAX_TIMESTAMP_PRECISION);
"CURRENT_TIMESTAMP(%d) precision must not be negative",
$3);
if ($3 > MAX_TIMESTAMP_PRECISION)
{
elog(NOTICE,
"CURRENT_TIMESTAMP(%d) precision reduced to maximum allowed, %d",
$3, MAX_TIMESTAMP_PRECISION);
$3 = MAX_TIMESTAMP_PRECISION;
}
d->typmod = $3;
$$ = (Node *)makeTypeCast((Node *)s, d);
@ -6308,10 +6338,17 @@ c_expr: columnref { $$ = (Node *) $1; }
s->val.val.str = "now";
s->typename = SystemTypeName("text");
d = SystemTypeName("time");
if (($3 < 0) || ($3 > MAX_TIME_PRECISION))
if ($3 < 0)
elog(ERROR,
"LOCALTIME(%d) precision must be between %d and %d",
$3, 0, MAX_TIME_PRECISION);
"LOCALTIME(%d) precision must not be negative",
$3);
if ($3 > MAX_TIME_PRECISION)
{
elog(NOTICE,
"LOCALTIME(%d) precision reduced to maximum allowed, %d",
$3, MAX_TIME_PRECISION);
$3 = MAX_TIME_PRECISION;
}
d->typmod = $3;
$$ = (Node *)makeTypeCast((Node *)s, d);
@ -6353,11 +6390,17 @@ c_expr: columnref { $$ = (Node *) $1; }
s->typename = SystemTypeName("text");
d = SystemTypeName("timestamp");
if (($3 < 0) || ($3 > MAX_TIMESTAMP_PRECISION))
if ($3 < 0)
elog(ERROR,
"LOCALTIMESTAMP(%d) precision must be "
"between %d and %d",
$3, 0, MAX_TIMESTAMP_PRECISION);
"LOCALTIMESTAMP(%d) precision must not be negative",
$3);
if ($3 > MAX_TIMESTAMP_PRECISION)
{
elog(NOTICE,
"LOCALTIMESTAMP(%d) precision reduced to maximum allowed, %d",
$3, MAX_TIMESTAMP_PRECISION);
$3 = MAX_TIMESTAMP_PRECISION;
}
d->typmod = $3;
$$ = (Node *)makeTypeCast((Node *)s, d);
@ -6934,8 +6977,8 @@ qualified_name:
break;
default:
elog(ERROR,
"Improper qualified name "
"(too many dotted names): %s",
"Improper qualified name "
"(too many dotted names): %s",
NameListToString($1));
break;
}
@ -7038,10 +7081,17 @@ AexprConst: Iconst
n->val.type = T_String;
n->val.val.str = $5;
/* precision specified, and fields may be... */
if (($3 < 0) || ($3 > MAX_INTERVAL_PRECISION))
if ($3 < 0)
elog(ERROR,
"INTERVAL(%d) precision must be between %d and %d",
$3, 0, MAX_INTERVAL_PRECISION);
"INTERVAL(%d) precision must not be negative",
$3);
if ($3 > MAX_INTERVAL_PRECISION)
{
elog(NOTICE,
"INTERVAL(%d) precision reduced to maximum allowed, %d",
$3, MAX_INTERVAL_PRECISION);
$3 = MAX_INTERVAL_PRECISION;
}
n->typename->typmod = INTERVAL_TYPMOD($3, $6);
$$ = (Node *)n;
}