Re: CREATE TABLE AS WITH NO DATA - Mailing list pgsql-hackers
From | Tom Lane |
---|---|
Subject | Re: CREATE TABLE AS WITH NO DATA |
Date | |
Msg-id | 11076.1225155122@sss.pgh.pa.us Whole thread Raw |
In response to | Re: CREATE TABLE AS WITH NO DATA (Tom Lane <tgl@sss.pgh.pa.us>) |
List | pgsql-hackers |
I wrote: > I'd like us to be trying to get rid of the special cases in base_yylex > not add more. (It strikes me that now that WITH is fully reserved, > we might not need some of the ones that are there anymore.) In fact, it looks like what we should do is heed the existing comment in parser.c: remove the existing WITH_foo combined tokens and invent WITH_TIME instead. Then, no additional combined tokens are needed to handle WITH [NO] DATA. So I propose the attached form of the patch instead (docs omitted). regards, tom lane Index: src/backend/parser/gram.y =================================================================== RCS file: /cvsroot/pgsql/src/backend/parser/gram.y,v retrieving revision 2.630 diff -c -r2.630 gram.y *** src/backend/parser/gram.y 27 Oct 2008 09:37:47 -0000 2.630 --- src/backend/parser/gram.y 28 Oct 2008 00:46:25 -0000 *************** *** 216,222 **** %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 %type <list> OptRoleList %type <defelt> OptRoleElem --- 216,222 ---- %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_with_data %type <list> OptRoleList %type <defelt> OptRoleElem *************** *** 485,491 **** * 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 /* Special token types, not actually keywords - see the "lex" file */ %token <str> IDENT FCONST SCONST BCONST XCONST Op --- 485,491 ---- * list and so can never be entered directly. The filter in parser.c * creates these tokens when required. */ ! %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,2422 **** */ CreateAsStmt: ! CREATE OptTemp TABLE create_as_target AS SelectStmt { /* * When the SelectStmt is a set-operation tree, we must --- 2416,2422 ---- */ CreateAsStmt: ! CREATE OptTemp TABLE create_as_target AS SelectStmt opt_with_data { /* * When the SelectStmt is a set-operation tree, we must *************** *** 2433,2438 **** --- 2433,2441 ---- 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,2480 **** --- 2478,2489 ---- } ; + opt_with_data: + WITH DATA_P { $$ = TRUE; } + | WITH NO DATA_P { $$ = FALSE; } + | /*EMPTY*/ { $$ = TRUE; } + ; + /***************************************************************************** * *************** *** 5387,5410 **** } ; - /* - * 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 { ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("WITH CHECK OPTION is not implemented"))); } ! | WITH_CASCADED CHECK OPTION { ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("WITH CHECK OPTION is not implemented"))); } ! | WITH_LOCAL CHECK OPTION { ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), --- 5396,5415 ---- } ; opt_check_option: ! WITH CHECK OPTION { ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("WITH CHECK OPTION is not implemented"))); } ! | WITH CASCADED CHECK OPTION { ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("WITH CHECK OPTION is not implemented"))); } ! | WITH LOCAL CHECK OPTION { ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), *************** *** 7509,7515 **** ; opt_timezone: ! WITH TIME ZONE { $$ = TRUE; } | WITHOUT TIME ZONE { $$ = FALSE; } | /*EMPTY*/ { $$ = FALSE; } ; --- 7514,7520 ---- ; opt_timezone: ! WITH_TIME ZONE { $$ = TRUE; } | WITHOUT TIME ZONE { $$ = FALSE; } | /*EMPTY*/ { $$ = FALSE; } ; Index: src/backend/parser/parser.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/parser/parser.c,v retrieving revision 1.74 diff -c -r1.74 parser.c *** src/backend/parser/parser.c 29 Aug 2008 13:02:32 -0000 1.74 --- src/backend/parser/parser.c 28 Oct 2008 00:46:25 -0000 *************** *** 129,156 **** 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. */ 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; break; default: /* save the lookahead token for next time */ --- 129,143 ---- case WITH: /* ! * WITH TIME must be reduced to one token */ cur_yylval = base_yylval; cur_yylloc = base_yylloc; next_token = base_yylex(); switch (next_token) { ! case TIME: ! cur_token = WITH_TIME; break; default: /* save the lookahead token for next time */ Index: src/interfaces/ecpg/preproc/parser.c =================================================================== RCS file: /cvsroot/pgsql/src/interfaces/ecpg/preproc/parser.c,v retrieving revision 1.3 diff -c -r1.3 parser.c *** src/interfaces/ecpg/preproc/parser.c 1 Jan 2008 19:45:59 -0000 1.3 --- src/interfaces/ecpg/preproc/parser.c 28 Oct 2008 00:46:25 -0000 *************** *** 98,125 **** 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. */ 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; break; default: /* save the lookahead token for next time */ --- 98,112 ---- case WITH: /* ! * WITH TIME must be reduced to one token */ cur_yylval = base_yylval; cur_yylloc = base_yylloc; next_token = base_yylex(); switch (next_token) { ! case TIME: ! cur_token = WITH_TIME; break; default: /* save the lookahead token for next time */ Index: src/interfaces/ecpg/preproc/preproc.y =================================================================== RCS file: /cvsroot/pgsql/src/interfaces/ecpg/preproc/preproc.y,v retrieving revision 1.378 diff -c -r1.378 preproc.y *** src/interfaces/ecpg/preproc/preproc.y 27 Oct 2008 09:37:47 -0000 1.378 --- src/interfaces/ecpg/preproc/preproc.y 28 Oct 2008 00:46:25 -0000 *************** *** 505,511 **** * 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 /* Special token types, not actually keywords - see the "lex" file */ %token <str> IDENT SCONST Op CSTRING CVARIABLE CPP_LINE IP BCONST --- 505,511 ---- * list and so can never be entered directly. The filter in parser.c * creates these tokens when required. */ ! %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,3121 **** { $$ = 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 { mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented"); $$ = EMPTY; } ! | WITH_CASCADED CHECK OPTION { mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented"); $$ = EMPTY; } ! | WITH_LOCAL CHECK OPTION { mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented"); $$ = EMPTY; --- 3100,3117 ---- { $$ = cat_str(8, make_str("create or replace"), $4, make_str("view"), $6, $7, make_str("as"), $9, $10); } ; opt_check_option: ! WITH CHECK OPTION { mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented"); $$ = EMPTY; } ! | WITH CASCADED CHECK OPTION { mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented"); $$ = EMPTY; } ! | WITH LOCAL CHECK OPTION { mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented"); $$ = EMPTY; *************** *** 4155,4161 **** { $$ = make_str("interval"); } ; ! opt_timezone: WITH TIME ZONE { $$ = make_str("with time zone"); } | WITHOUT TIME ZONE { $$ = make_str("without time zone"); } --- 4151,4157 ---- { $$ = make_str("interval"); } ; ! opt_timezone: WITH_TIME ZONE { $$ = make_str("with time zone"); } | WITHOUT TIME ZONE { $$ = make_str("without time zone"); }
pgsql-hackers by date: