<!--
-$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
-->
<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> } [, ... ]
)
<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.
</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>
</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
<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
</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>
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>
*
*
* 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
| 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))
/*
* 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; }
;
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;
}
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); }
if ($7 != NULL)
elog(NOTICE,"CREATE DOMAIN / COLLATE %s not yet "
- "implemented; clause ignored", $7);
+ "implemented; clause ignored", $7);
$$ = (Node *)n;
}
;
}
| 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;
}
| 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
* - 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
$$ = 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
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);
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);
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);
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);
break;
default:
elog(ERROR,
- "Improper qualified name "
- "(too many dotted names): %s",
+ "Improper qualified name "
+ "(too many dotted names): %s",
NameListToString($1));
break;
}
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;
}