Commit 8ecd5351 authored by Peter Eisentraut's avatar Peter Eisentraut

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
parent 53a5026b
<!--
$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
-->
......@@ -26,6 +26,7 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE <replaceable class="PARAMETER">tablespace</replaceable> ]
AS <replaceable>query</replaceable>
[ WITH [ NO ] DATA ]
</synopsis>
</refsynopsisdiv>
......@@ -201,6 +202,18 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name
</para>
</listitem>
</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>
</refsect1>
......@@ -265,7 +278,7 @@ CREATE TEMP TABLE films_recent WITH (OIDS) ON COMMIT DROP AS
<para>
<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">
<listitem>
......@@ -278,12 +291,8 @@ CREATE TEMP TABLE films_recent WITH (OIDS) ON COMMIT DROP AS
<listitem>
<para>
The standard defines a <literal>WITH [ NO ] DATA</literal> clause;
this is not currently implemented by <productname>PostgreSQL</>.
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.
In the standard, the <literal>WITH [ NO ] DATA</literal> clause
is required; in PostgreSQL it is optional.
</para>
</listitem>
......
......@@ -408,7 +408,7 @@ T141 SIMILAR predicate YES
T151 DISTINCT predicate YES
T152 DISTINCT predicate with negation 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
T174 Identity columns NO
T175 Generated columns NO
......
......@@ -11,7 +11,7 @@
*
*
* 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
* AUTHOR DATE MAJOR EVENT
......@@ -216,7 +216,7 @@ static TypeName *TableFuncTypeName(List *columns);
%type <ival> opt_lock lock_type cast_context
%type <boolean> opt_force opt_or_replace
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 <defelt> OptRoleElem
......@@ -485,7 +485,7 @@ static TypeName *TableFuncTypeName(List *columns);
* list and so can never be entered directly. The filter in parser.c
* 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 */
%token <str> IDENT FCONST SCONST BCONST XCONST Op
......@@ -2416,7 +2416,7 @@ OptConsTableSpace: USING INDEX TABLESPACE name { $$ = $4; }
*/
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
......@@ -2433,6 +2433,9 @@ CreateAsStmt:
scanner_errposition(exprLocation((Node *) n->intoClause))));
$4->rel->istemp = $2;
n->intoClause = $4;
/* Implement WITH NO DATA by forcing top-level LIMIT 0 */
if (!$7)
((SelectStmt *) $6)->limitCount = makeIntConst(0, -1);
$$ = $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:
WITH_CHECK OPTION
WITH CHECK OPTION
{
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("WITH CHECK OPTION is not implemented")));
}
| WITH_CASCADED CHECK OPTION
| WITH CASCADED CHECK OPTION
{
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("WITH CHECK OPTION is not implemented")));
}
| WITH_LOCAL CHECK OPTION
| WITH LOCAL CHECK OPTION
{
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
......@@ -7509,7 +7514,7 @@ ConstInterval:
;
opt_timezone:
WITH TIME ZONE { $$ = TRUE; }
WITH_TIME ZONE { $$ = TRUE; }
| WITHOUT TIME ZONE { $$ = FALSE; }
| /*EMPTY*/ { $$ = FALSE; }
;
......
......@@ -14,7 +14,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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:
/*
* WITH CASCADED, LOCAL, or CHECK 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.
* WITH TIME must be reduced to one token
*/
cur_yylval = base_yylval;
cur_yylloc = base_yylloc;
next_token = base_yylex();
switch (next_token)
{
case CASCADED:
cur_token = WITH_CASCADED;
break;
case LOCAL:
cur_token = WITH_LOCAL;
break;
case CHECK:
cur_token = WITH_CHECK;
case TIME:
cur_token = WITH_TIME;
break;
default:
/* save the lookahead token for next time */
......
......@@ -14,7 +14,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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:
/*
* WITH CASCADED, LOCAL, or CHECK 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.
* WITH TIME must be reduced to one token
*/
cur_yylval = base_yylval;
cur_yylloc = base_yylloc;
next_token = base_yylex();
switch (next_token)
{
case CASCADED:
cur_token = WITH_CASCADED;
break;
case LOCAL:
cur_token = WITH_LOCAL;
break;
case CHECK:
cur_token = WITH_CHECK;
case TIME:
cur_token = WITH_TIME;
break;
default:
/* save the lookahead token for next time */
......
/* $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 */
%{
......@@ -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
* 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 */
%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); }
;
/*
* We use merged tokens here to avoid creating shift/reduce conflicts against
* a whole lot of other uses of WITH.
*/
opt_check_option:
WITH_CHECK OPTION
WITH CHECK OPTION
{
mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented");
$$ = EMPTY;
}
| WITH_CASCADED CHECK OPTION
| WITH CASCADED CHECK OPTION
{
mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented");
$$ = EMPTY;
}
| WITH_LOCAL CHECK OPTION
| WITH LOCAL CHECK OPTION
{
mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented");
$$ = EMPTY;
......@@ -4155,7 +4151,7 @@ ConstInterval: INTERVAL
{ $$ = make_str("interval"); }
;
opt_timezone: WITH TIME ZONE
opt_timezone: WITH_TIME ZONE
{ $$ = make_str("with time zone"); }
| WITHOUT TIME ZONE
{ $$ = make_str("without time zone"); }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment