mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Add WITH [NO] DATA clause to CREATE TABLE AS, per SQL.
Also, since WITH is now a reserved word, simplify the token merging code to only deal with WITH_TIME. by Tom Lane and myself
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/create_table_as.sgml,v 1.37 2007/06/03 17:06:12 tgl Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/create_table_as.sgml,v 1.38 2008/10/28 14:09:44 petere Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -26,6 +26,7 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name
|
|||||||
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
|
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
|
||||||
[ TABLESPACE <replaceable class="PARAMETER">tablespace</replaceable> ]
|
[ TABLESPACE <replaceable class="PARAMETER">tablespace</replaceable> ]
|
||||||
AS <replaceable>query</replaceable>
|
AS <replaceable>query</replaceable>
|
||||||
|
[ WITH [ NO ] DATA ]
|
||||||
</synopsis>
|
</synopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
|
|
||||||
@ -201,6 +202,18 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>WITH [ NO ] DATA</></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
This clause specifies whether or not the data produced by the query
|
||||||
|
should be copied into the new table. If not, only the table structure
|
||||||
|
is copied. The default is to copy the data.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
@ -265,7 +278,7 @@ CREATE TEMP TABLE films_recent WITH (OIDS) ON COMMIT DROP AS
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
<command>CREATE TABLE AS</command> conforms to the <acronym>SQL</acronym>
|
<command>CREATE TABLE AS</command> conforms to the <acronym>SQL</acronym>
|
||||||
standard, with the following exceptions:
|
standard. The following are nonstandard extensions:
|
||||||
|
|
||||||
<itemizedlist spacing="compact">
|
<itemizedlist spacing="compact">
|
||||||
<listitem>
|
<listitem>
|
||||||
@ -278,12 +291,8 @@ CREATE TEMP TABLE films_recent WITH (OIDS) ON COMMIT DROP AS
|
|||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
The standard defines a <literal>WITH [ NO ] DATA</literal> clause;
|
In the standard, the <literal>WITH [ NO ] DATA</literal> clause
|
||||||
this is not currently implemented by <productname>PostgreSQL</>.
|
is required; in PostgreSQL it is optional.
|
||||||
The behavior provided by <productname>PostgreSQL</> is equivalent
|
|
||||||
to the standard's <literal>WITH DATA</literal> case.
|
|
||||||
<literal>WITH NO DATA</literal> can be simulated by appending
|
|
||||||
<literal>LIMIT 0</> to the query.
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
|
@ -408,7 +408,7 @@ T141 SIMILAR predicate YES
|
|||||||
T151 DISTINCT predicate YES
|
T151 DISTINCT predicate YES
|
||||||
T152 DISTINCT predicate with negation YES
|
T152 DISTINCT predicate with negation YES
|
||||||
T171 LIKE clause in table definition YES
|
T171 LIKE clause in table definition YES
|
||||||
T172 AS subquery clause in table definition NO
|
T172 AS subquery clause in table definition YES
|
||||||
T173 Extended LIKE clause in table definition YES
|
T173 Extended LIKE clause in table definition YES
|
||||||
T174 Identity columns NO
|
T174 Identity columns NO
|
||||||
T175 Generated columns NO
|
T175 Generated columns NO
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.630 2008/10/27 09:37:47 petere Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.631 2008/10/28 14:09:45 petere Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -216,7 +216,7 @@ static TypeName *TableFuncTypeName(List *columns);
|
|||||||
%type <ival> opt_lock lock_type cast_context
|
%type <ival> opt_lock lock_type cast_context
|
||||||
%type <boolean> opt_force opt_or_replace
|
%type <boolean> opt_force opt_or_replace
|
||||||
opt_grant_grant_option opt_grant_admin_option
|
opt_grant_grant_option opt_grant_admin_option
|
||||||
opt_nowait opt_if_exists
|
opt_nowait opt_if_exists opt_with_data
|
||||||
|
|
||||||
%type <list> OptRoleList
|
%type <list> OptRoleList
|
||||||
%type <defelt> OptRoleElem
|
%type <defelt> OptRoleElem
|
||||||
@ -485,7 +485,7 @@ static TypeName *TableFuncTypeName(List *columns);
|
|||||||
* list and so can never be entered directly. The filter in parser.c
|
* list and so can never be entered directly. The filter in parser.c
|
||||||
* creates these tokens when required.
|
* creates these tokens when required.
|
||||||
*/
|
*/
|
||||||
%token NULLS_FIRST NULLS_LAST WITH_CASCADED WITH_LOCAL WITH_CHECK
|
%token NULLS_FIRST NULLS_LAST WITH_TIME
|
||||||
|
|
||||||
/* Special token types, not actually keywords - see the "lex" file */
|
/* Special token types, not actually keywords - see the "lex" file */
|
||||||
%token <str> IDENT FCONST SCONST BCONST XCONST Op
|
%token <str> IDENT FCONST SCONST BCONST XCONST Op
|
||||||
@ -2416,7 +2416,7 @@ OptConsTableSpace: USING INDEX TABLESPACE name { $$ = $4; }
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
CreateAsStmt:
|
CreateAsStmt:
|
||||||
CREATE OptTemp TABLE create_as_target AS SelectStmt
|
CREATE OptTemp TABLE create_as_target AS SelectStmt opt_with_data
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* When the SelectStmt is a set-operation tree, we must
|
* When the SelectStmt is a set-operation tree, we must
|
||||||
@ -2433,6 +2433,9 @@ CreateAsStmt:
|
|||||||
scanner_errposition(exprLocation((Node *) n->intoClause))));
|
scanner_errposition(exprLocation((Node *) n->intoClause))));
|
||||||
$4->rel->istemp = $2;
|
$4->rel->istemp = $2;
|
||||||
n->intoClause = $4;
|
n->intoClause = $4;
|
||||||
|
/* Implement WITH NO DATA by forcing top-level LIMIT 0 */
|
||||||
|
if (!$7)
|
||||||
|
((SelectStmt *) $6)->limitCount = makeIntConst(0, -1);
|
||||||
$$ = $6;
|
$$ = $6;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -2475,6 +2478,12 @@ CreateAsElement:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
opt_with_data:
|
||||||
|
WITH DATA_P { $$ = TRUE; }
|
||||||
|
| WITH NO DATA_P { $$ = FALSE; }
|
||||||
|
| /*EMPTY*/ { $$ = TRUE; }
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
@ -5387,24 +5396,20 @@ ViewStmt: CREATE OptTemp VIEW qualified_name opt_column_list
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
/*
|
|
||||||
* We use merged tokens here to avoid creating shift/reduce conflicts against
|
|
||||||
* a whole lot of other uses of WITH.
|
|
||||||
*/
|
|
||||||
opt_check_option:
|
opt_check_option:
|
||||||
WITH_CHECK OPTION
|
WITH CHECK OPTION
|
||||||
{
|
{
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
errmsg("WITH CHECK OPTION is not implemented")));
|
errmsg("WITH CHECK OPTION is not implemented")));
|
||||||
}
|
}
|
||||||
| WITH_CASCADED CHECK OPTION
|
| WITH CASCADED CHECK OPTION
|
||||||
{
|
{
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
errmsg("WITH CHECK OPTION is not implemented")));
|
errmsg("WITH CHECK OPTION is not implemented")));
|
||||||
}
|
}
|
||||||
| WITH_LOCAL CHECK OPTION
|
| WITH LOCAL CHECK OPTION
|
||||||
{
|
{
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
@ -7509,7 +7514,7 @@ ConstInterval:
|
|||||||
;
|
;
|
||||||
|
|
||||||
opt_timezone:
|
opt_timezone:
|
||||||
WITH TIME ZONE { $$ = TRUE; }
|
WITH_TIME ZONE { $$ = TRUE; }
|
||||||
| WITHOUT TIME ZONE { $$ = FALSE; }
|
| WITHOUT TIME ZONE { $$ = FALSE; }
|
||||||
| /*EMPTY*/ { $$ = FALSE; }
|
| /*EMPTY*/ { $$ = FALSE; }
|
||||||
;
|
;
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/parser.c,v 1.74 2008/08/29 13:02:32 petere Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/parser.c,v 1.75 2008/10/28 14:09:45 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -129,28 +129,15 @@ filtered_base_yylex(void)
|
|||||||
case WITH:
|
case WITH:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* WITH CASCADED, LOCAL, or CHECK must be reduced to one token
|
* WITH TIME must be reduced to one token
|
||||||
*
|
|
||||||
* XXX an alternative way is to recognize just WITH_TIME and put
|
|
||||||
* the ugliness into the datetime datatype productions instead of
|
|
||||||
* WITH CHECK OPTION. However that requires promoting WITH to a
|
|
||||||
* fully reserved word. If we ever have to do that anyway
|
|
||||||
* (perhaps for SQL99 recursive queries), come back and simplify
|
|
||||||
* this code.
|
|
||||||
*/
|
*/
|
||||||
cur_yylval = base_yylval;
|
cur_yylval = base_yylval;
|
||||||
cur_yylloc = base_yylloc;
|
cur_yylloc = base_yylloc;
|
||||||
next_token = base_yylex();
|
next_token = base_yylex();
|
||||||
switch (next_token)
|
switch (next_token)
|
||||||
{
|
{
|
||||||
case CASCADED:
|
case TIME:
|
||||||
cur_token = WITH_CASCADED;
|
cur_token = WITH_TIME;
|
||||||
break;
|
|
||||||
case LOCAL:
|
|
||||||
cur_token = WITH_LOCAL;
|
|
||||||
break;
|
|
||||||
case CHECK:
|
|
||||||
cur_token = WITH_CHECK;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* save the lookahead token for next time */
|
/* save the lookahead token for next time */
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/parser.c,v 1.3 2008/01/01 19:45:59 momjian Exp $
|
* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/parser.c,v 1.4 2008/10/28 14:09:45 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -98,28 +98,15 @@ filtered_base_yylex(void)
|
|||||||
case WITH:
|
case WITH:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* WITH CASCADED, LOCAL, or CHECK must be reduced to one token
|
* WITH TIME must be reduced to one token
|
||||||
*
|
|
||||||
* XXX an alternative way is to recognize just WITH_TIME and put
|
|
||||||
* the ugliness into the datetime datatype productions instead of
|
|
||||||
* WITH CHECK OPTION. However that requires promoting WITH to a
|
|
||||||
* fully reserved word. If we ever have to do that anyway
|
|
||||||
* (perhaps for SQL99 recursive queries), come back and simplify
|
|
||||||
* this code.
|
|
||||||
*/
|
*/
|
||||||
cur_yylval = base_yylval;
|
cur_yylval = base_yylval;
|
||||||
cur_yylloc = base_yylloc;
|
cur_yylloc = base_yylloc;
|
||||||
next_token = base_yylex();
|
next_token = base_yylex();
|
||||||
switch (next_token)
|
switch (next_token)
|
||||||
{
|
{
|
||||||
case CASCADED:
|
case TIME:
|
||||||
cur_token = WITH_CASCADED;
|
cur_token = WITH_TIME;
|
||||||
break;
|
|
||||||
case LOCAL:
|
|
||||||
cur_token = WITH_LOCAL;
|
|
||||||
break;
|
|
||||||
case CHECK:
|
|
||||||
cur_token = WITH_CHECK;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* save the lookahead token for next time */
|
/* save the lookahead token for next time */
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.378 2008/10/27 09:37:47 petere Exp $ */
|
/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.379 2008/10/28 14:09:45 petere Exp $ */
|
||||||
|
|
||||||
/* Copyright comment */
|
/* Copyright comment */
|
||||||
%{
|
%{
|
||||||
@ -505,7 +505,7 @@ add_typedef(char *name, char * dimension, char * length, enum ECPGttype type_enu
|
|||||||
* list and so can never be entered directly. The filter in parser.c
|
* list and so can never be entered directly. The filter in parser.c
|
||||||
* creates these tokens when required.
|
* creates these tokens when required.
|
||||||
*/
|
*/
|
||||||
%token NULLS_FIRST NULLS_LAST WITH_CASCADED WITH_LOCAL WITH_CHECK
|
%token NULLS_FIRST NULLS_LAST WITH_TIME
|
||||||
|
|
||||||
/* Special token types, not actually keywords - see the "lex" file */
|
/* Special token types, not actually keywords - see the "lex" file */
|
||||||
%token <str> IDENT SCONST Op CSTRING CVARIABLE CPP_LINE IP BCONST
|
%token <str> IDENT SCONST Op CSTRING CVARIABLE CPP_LINE IP BCONST
|
||||||
@ -3100,22 +3100,18 @@ ViewStmt: CREATE OptTemp VIEW qualified_name opt_column_list AS SelectStmt opt_
|
|||||||
{ $$ = cat_str(8, make_str("create or replace"), $4, make_str("view"), $6, $7, make_str("as"), $9, $10); }
|
{ $$ = cat_str(8, make_str("create or replace"), $4, make_str("view"), $6, $7, make_str("as"), $9, $10); }
|
||||||
;
|
;
|
||||||
|
|
||||||
/*
|
|
||||||
* We use merged tokens here to avoid creating shift/reduce conflicts against
|
|
||||||
* a whole lot of other uses of WITH.
|
|
||||||
*/
|
|
||||||
opt_check_option:
|
opt_check_option:
|
||||||
WITH_CHECK OPTION
|
WITH CHECK OPTION
|
||||||
{
|
{
|
||||||
mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented");
|
mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented");
|
||||||
$$ = EMPTY;
|
$$ = EMPTY;
|
||||||
}
|
}
|
||||||
| WITH_CASCADED CHECK OPTION
|
| WITH CASCADED CHECK OPTION
|
||||||
{
|
{
|
||||||
mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented");
|
mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented");
|
||||||
$$ = EMPTY;
|
$$ = EMPTY;
|
||||||
}
|
}
|
||||||
| WITH_LOCAL CHECK OPTION
|
| WITH LOCAL CHECK OPTION
|
||||||
{
|
{
|
||||||
mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented");
|
mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented");
|
||||||
$$ = EMPTY;
|
$$ = EMPTY;
|
||||||
@ -4155,7 +4151,7 @@ ConstInterval: INTERVAL
|
|||||||
{ $$ = make_str("interval"); }
|
{ $$ = make_str("interval"); }
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_timezone: WITH TIME ZONE
|
opt_timezone: WITH_TIME ZONE
|
||||||
{ $$ = make_str("with time zone"); }
|
{ $$ = make_str("with time zone"); }
|
||||||
| WITHOUT TIME ZONE
|
| WITHOUT TIME ZONE
|
||||||
{ $$ = make_str("without time zone"); }
|
{ $$ = make_str("without time zone"); }
|
||||||
|
Reference in New Issue
Block a user