aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2008-10-28 14:09:45 +0000
committerPeter Eisentraut <peter_e@gmx.net>2008-10-28 14:09:45 +0000
commit8ecd5351691210ba5b536cd4c1251ea1fce090bb (patch)
tree0e31a7de3a1d21e3b46db6435e6a30dc76b52bc5
parent53a5026b5cb359ec31e81fa6b20a69b053b87569 (diff)
downloadpostgresql-8ecd5351691210ba5b536cd4c1251ea1fce090bb.tar.gz
postgresql-8ecd5351691210ba5b536cd4c1251ea1fce090bb.zip
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
-rw-r--r--doc/src/sgml/ref/create_table_as.sgml25
-rw-r--r--src/backend/catalog/sql_features.txt2
-rw-r--r--src/backend/parser/gram.y29
-rw-r--r--src/backend/parser/parser.c21
-rw-r--r--src/interfaces/ecpg/preproc/parser.c21
-rw-r--r--src/interfaces/ecpg/preproc/preproc.y16
6 files changed, 49 insertions, 65 deletions
diff --git a/doc/src/sgml/ref/create_table_as.sgml b/doc/src/sgml/ref/create_table_as.sgml
index edc9ce5e6c5..c3f3c230aa5 100644
--- a/doc/src/sgml/ref/create_table_as.sgml
+++ b/doc/src/sgml/ref/create_table_as.sgml
@@ -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
-->
@@ -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>
diff --git a/src/backend/catalog/sql_features.txt b/src/backend/catalog/sql_features.txt
index be9974af271..b795a70f3cf 100644
--- a/src/backend/catalog/sql_features.txt
+++ b/src/backend/catalog/sql_features.txt
@@ -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
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 6a566fd400f..4759e041340 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -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; }
;
diff --git a/src/backend/parser/parser.c b/src/backend/parser/parser.c
index 1535318735c..979f4307fdf 100644
--- a/src/backend/parser/parser.c
+++ b/src/backend/parser/parser.c
@@ -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 */
diff --git a/src/interfaces/ecpg/preproc/parser.c b/src/interfaces/ecpg/preproc/parser.c
index 279b53c4770..9e23beaf6dc 100644
--- a/src/interfaces/ecpg/preproc/parser.c
+++ b/src/interfaces/ecpg/preproc/parser.c
@@ -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 */
diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y
index 038942da291..2fbbbd94fc7 100644
--- a/src/interfaces/ecpg/preproc/preproc.y
+++ b/src/interfaces/ecpg/preproc/preproc.y
@@ -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 */
%{
@@ -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"); }