diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml index ab929728a7ff5c7647bc214936ecd672a640dd09..c7288413a9925efd2abbb7aaf0442251b9874580 100644 --- a/doc/src/sgml/ref/alter_table.sgml +++ b/doc/src/sgml/ref/alter_table.sgml @@ -1,5 +1,5 @@ @@ -33,7 +33,7 @@ where action is one of: ADD [ COLUMN ] column type [ column_constraint [ ... ] ] DROP [ COLUMN ] column [ RESTRICT | CASCADE ] - ALTER [ COLUMN ] column TYPE type [ USING expression ] + ALTER [ COLUMN ] column [ SET DATA ] TYPE type [ USING expression ] ALTER [ COLUMN ] column SET DEFAULT expression ALTER [ COLUMN ] column DROP DEFAULT ALTER [ COLUMN ] column { SET | DROP } NOT NULL @@ -93,7 +93,7 @@ where action is one of: - ALTER COLUMN TYPE + SET DATA TYPE This form changes the type of a column of a table. Indexes and @@ -760,7 +760,7 @@ ALTER TABLE distributors with time zone via a USING clause: ALTER TABLE foo - ALTER COLUMN foo_timestamp TYPE timestamp with time zone + ALTER COLUMN foo_timestamp SET DATA TYPE timestamp with time zone USING timestamp with time zone 'epoch' + foo_timestamp * interval '1 second'; @@ -868,8 +868,9 @@ ALTER TABLE myschema.distributors SET SCHEMA yourschema; Compatibility - The ADD, DROP, and SET DEFAULT - forms conform with the SQL standard. The other forms are + The forms ADD, DROP, SET DEFAULT, + and SET DATA TYPE (without USING) + conform with the SQL standard. The other forms are PostgreSQL extensions of the SQL standard. Also, the ability to specify more than one manipulation in a single ALTER TABLE command is an extension. diff --git a/src/backend/catalog/sql_features.txt b/src/backend/catalog/sql_features.txt index 6e4871fbf182f1bbf64b4e28c48d07f62fe6a241..4c50a22a0afa9ba94fcc98f8a683a045e601b692 100644 --- a/src/backend/catalog/sql_features.txt +++ b/src/backend/catalog/sql_features.txt @@ -236,7 +236,7 @@ F381 Extended schema manipulation YES F381 Extended schema manipulation 01 ALTER TABLE statement: ALTER COLUMN clause YES F381 Extended schema manipulation 02 ALTER TABLE statement: ADD CONSTRAINT clause YES F381 Extended schema manipulation 03 ALTER TABLE statement: DROP CONSTRAINT clause YES -F382 Alter column data type NO PostgreSQL syntax differs +F382 Alter column data type YES F391 Long identifiers YES F392 Unicode escapes in identifiers NO F393 Unicode escapes in literals NO diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 55e5828e32186647b644ee4fc36a40e044a08a8d..aa5f33b41147f22026a5b93cbd3c62a6854432f3 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.626 2008/10/20 14:26:28 petere Exp $ + * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.627 2008/10/21 08:38:15 petere Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -304,7 +304,7 @@ static TypeName *TableFuncTypeName(List *columns); %type copy_from -%type opt_column event cursor_options opt_hold +%type opt_column event cursor_options opt_hold opt_set_data %type reindex_type drop_type comment_type %type fetch_direction select_limit_value select_offset_value @@ -407,7 +407,7 @@ static TypeName *TableFuncTypeName(List *columns); CREATEROLE CREATEUSER CROSS CSV CTYPE CURRENT_P CURRENT_DATE CURRENT_ROLE CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE - DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS + DATA_P DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DESC DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P DOUBLE_P DROP @@ -1534,16 +1534,16 @@ alter_table_cmd: $$ = (Node *)n; } /* - * ALTER TABLE ALTER [COLUMN] TYPE + * ALTER TABLE ALTER [COLUMN] [SET DATA] TYPE * [ USING ] */ - | ALTER opt_column ColId TYPE_P Typename alter_using + | ALTER opt_column ColId opt_set_data TYPE_P Typename alter_using { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_AlterColumnType; n->name = $3; - n->def = (Node *) $5; - n->transform = $6; + n->def = (Node *) $6; + n->transform = $7; $$ = (Node *)n; } /* ALTER TABLE ADD CONSTRAINT ... */ @@ -4854,6 +4854,10 @@ opt_column: COLUMN { $$ = COLUMN; } | /*EMPTY*/ { $$ = 0; } ; +opt_set_data: SET DATA_P { $$ = 1; } + | /*EMPTY*/ { $$ = 0; } + ; + /***************************************************************************** * * ALTER THING name SET SCHEMA name @@ -9317,6 +9321,7 @@ unreserved_keyword: | CURRENT_P | CURSOR | CYCLE + | DATA_P | DATABASE | DAY_P | DEALLOCATE diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c index c55bfd8b5cde512d33c8ccf5186cb7a093df6229..7c6aa71572a99292c54b3e67ef7b5954425b3d84 100644 --- a/src/backend/parser/keywords.c +++ b/src/backend/parser/keywords.c @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.202 2008/10/04 21:56:54 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.203 2008/10/21 08:38:15 petere Exp $ * *------------------------------------------------------------------------- */ @@ -123,6 +123,7 @@ const ScanKeyword ScanKeywords[] = { {"current_user", CURRENT_USER, RESERVED_KEYWORD}, {"cursor", CURSOR, UNRESERVED_KEYWORD}, {"cycle", CYCLE, UNRESERVED_KEYWORD}, + {"data", DATA_P, UNRESERVED_KEYWORD}, {"database", DATABASE, UNRESERVED_KEYWORD}, {"day", DAY_P, UNRESERVED_KEYWORD}, {"deallocate", DEALLOCATE, UNRESERVED_KEYWORD}, diff --git a/src/interfaces/ecpg/preproc/ecpg_keywords.c b/src/interfaces/ecpg/preproc/ecpg_keywords.c index 3d8db4053791bc35e395ff3a789e5fabd10c254e..ae2c3aa4bd2181472ebdd679e88384a5e704c5a0 100644 --- a/src/interfaces/ecpg/preproc/ecpg_keywords.c +++ b/src/interfaces/ecpg/preproc/ecpg_keywords.c @@ -4,7 +4,7 @@ * lexical token lookup for reserved words in postgres embedded SQL * * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg_keywords.c,v 1.38 2008/05/20 23:17:32 meskes Exp $ + * $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg_keywords.c,v 1.39 2008/10/21 08:38:16 petere Exp $ * *------------------------------------------------------------------------- */ @@ -34,7 +34,6 @@ static const ScanKeyword ScanECPGKeywords[] = { {"cardinality", SQL_CARDINALITY, 0}, {"connect", SQL_CONNECT, 0}, {"count", SQL_COUNT, 0}, - {"data", SQL_DATA, 0}, {"datetime_interval_code", SQL_DATETIME_INTERVAL_CODE, 0}, {"datetime_interval_precision", SQL_DATETIME_INTERVAL_PRECISION, 0}, {"describe", SQL_DESCRIBE, 0}, diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y index c4ad9d81b2ba14fc31eca861fc36cd4523e00e2b..7220deff68a419d4ab9a88e0055c8a99cb29270f 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.376 2008/10/14 09:31:04 meskes Exp $ */ +/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.377 2008/10/21 08:38:16 petere Exp $ */ /* Copyright comment */ %{ @@ -392,7 +392,7 @@ add_typedef(char *name, char * dimension, char * length, enum ECPGttype type_enu /* special embedded SQL token */ %token SQL_ALLOCATE SQL_AUTOCOMMIT SQL_BOOL SQL_BREAK SQL_CALL SQL_CARDINALITY SQL_CONNECT - SQL_COUNT SQL_DATA + SQL_COUNT SQL_DATETIME_INTERVAL_CODE SQL_DATETIME_INTERVAL_PRECISION SQL_DESCRIBE SQL_DESCRIPTOR SQL_DISCONNECT SQL_FOUND @@ -431,7 +431,7 @@ add_typedef(char *name, char * dimension, char * length, enum ECPGttype type_enu CREATEROLE CREATEUSER CROSS CSV CTYPE CURRENT_P CURRENT_DATE CURRENT_ROLE CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE - DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS + DATA_P DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DESC DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P DOUBLE_P DROP @@ -584,7 +584,7 @@ add_typedef(char *name, char * dimension, char * length, enum ECPGttype type_enu %type def_elem def_list definition DefineStmt select_with_parens %type opt_instead event RuleActionList opt_using CreateAssertStmt %type RuleActionStmtOrEmpty RuleActionMulti func_as reindex_type -%type RuleStmt opt_column oper_argtypes NumConst var_name +%type RuleStmt opt_column opt_set_data oper_argtypes NumConst var_name %type MathOp RemoveFuncStmt ECPGunreserved_con opt_database_name %type RemoveAggrStmt opt_procedural select_no_parens CreateCastStmt %type RemoveOperStmt RenameStmt all_Op opt_trusted opt_lancompiler @@ -1398,9 +1398,9 @@ alter_table_cmd: /* ALTER TABLE DROP [COLUMN] {RESTRICT|CASCADE} */ | DROP opt_column ColId opt_drop_behavior { $$ = cat_str(4, make_str("drop"), $2, $3, $4); } -/* ALTER TABLE ALTER [COLUMN] TYPE [ USING ] */ - | ALTER opt_column ColId TYPE_P Typename alter_using - { $$ = cat_str(6, make_str("alter"), $2, $3, make_str("type"), $5, $6); } +/* ALTER TABLE ALTER [COLUMN] [SET DATA] TYPE [ USING ] */ + | ALTER opt_column ColId opt_set_data TYPE_P Typename alter_using + { $$ = cat_str(7, make_str("alter"), $2, $3, $4, make_str("type"), $6, $7); } /* ALTER TABLE ADD CONSTRAINT ... */ | ADD_P TableConstraint { $$ = cat_str(2, make_str("add"), $2); } @@ -2891,6 +2891,10 @@ opt_column: COLUMN { $$ = make_str("column"); } | /*EMPTY*/ { $$ = EMPTY; } ; +opt_set_data: SET DATA_P { $$ = make_str("set data"); } + | /*EMPTY*/ { $$ = EMPTY; } + ; + /***************************************************************************** * * ALTER THING name SET SCHEMA name @@ -6140,7 +6144,7 @@ ECPGSetDescItem: descriptor_item '=' AllConstVar descriptor_item: SQL_CARDINALITY { $$ = ECPGd_cardinality; } - | SQL_DATA { $$ = ECPGd_data; } + | DATA_P { $$ = ECPGd_data; } | SQL_DATETIME_INTERVAL_CODE { $$ = ECPGd_di_code; } | SQL_DATETIME_INTERVAL_PRECISION { $$ = ECPGd_di_precision; } | SQL_INDICATOR { $$ = ECPGd_indicator; } @@ -6360,7 +6364,6 @@ ECPGKeywords_vanames: SQL_BREAK { $$ = make_str("break"); } | SQL_CALL { $$ = make_str("call"); } | SQL_CARDINALITY { $$ = make_str("cardinality"); } | SQL_COUNT { $$ = make_str("count"); } - | SQL_DATA { $$ = make_str("data"); } | SQL_DATETIME_INTERVAL_CODE { $$ = make_str("datetime_interval_code"); } | SQL_DATETIME_INTERVAL_PRECISION { $$ = make_str("datetime_interval_precision"); } | SQL_FOUND { $$ = make_str("found"); } @@ -6557,6 +6560,7 @@ ECPGunreserved_con: ABORT_P { $$ = make_str("abort"); } | CTYPE { $$ = make_str("ctype"); } | CURSOR { $$ = make_str("cursor"); } | CYCLE { $$ = make_str("cycle"); } + | DATA_P { $$ = make_str("data"); } | DATABASE { $$ = make_str("database"); } /* | DAY_P { $$ = make_str("day"); }*/ | DEALLOCATE { $$ = make_str("deallocate"); } diff --git a/src/interfaces/ecpg/test/expected/sql-parser.c b/src/interfaces/ecpg/test/expected/sql-parser.c index 41193a4d2f0c43e68c98dd5e03416ee82a6a6621..bdc9908d16ca909b7cbea6fdde2bb5e833280788 100644 --- a/src/interfaces/ecpg/test/expected/sql-parser.c +++ b/src/interfaces/ecpg/test/expected/sql-parser.c @@ -101,7 +101,7 @@ if (sqlca.sqlcode < 0) sqlprint();} for (i=0; i<3; i++) printf("item[%d] = %d\n", i, ind[i] ? -1 : item[i]); - { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table T ", ECPGt_EOIT, ECPGt_EORT); + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "alter table T alter Item1 type bigint ", ECPGt_EOIT, ECPGt_EORT); #line 31 "parser.pgc" if (sqlca.sqlwarn[0] == 'W') sqlprint(); @@ -110,15 +110,34 @@ if (sqlca.sqlwarn[0] == 'W') sqlprint(); if (sqlca.sqlcode < 0) sqlprint();} #line 31 "parser.pgc" + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "alter table T alter column Item2 set data type smallint ", ECPGt_EOIT, ECPGt_EORT); +#line 32 "parser.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 32 "parser.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 32 "parser.pgc" + + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table T ", ECPGt_EOIT, ECPGt_EORT); +#line 34 "parser.pgc" + +if (sqlca.sqlwarn[0] == 'W') sqlprint(); +#line 34 "parser.pgc" + +if (sqlca.sqlcode < 0) sqlprint();} +#line 34 "parser.pgc" + { ECPGdisconnect(__LINE__, "ALL"); -#line 33 "parser.pgc" +#line 36 "parser.pgc" if (sqlca.sqlwarn[0] == 'W') sqlprint(); -#line 33 "parser.pgc" +#line 36 "parser.pgc" if (sqlca.sqlcode < 0) sqlprint();} -#line 33 "parser.pgc" +#line 36 "parser.pgc" return 0; diff --git a/src/interfaces/ecpg/test/expected/sql-parser.stderr b/src/interfaces/ecpg/test/expected/sql-parser.stderr index e372cd6710d2bacf7c5afafa38ba1eb4b3f8a6ca..05ac75348c0c4d0a8a062c2237dfa3f85814ec70 100644 --- a/src/interfaces/ecpg/test/expected/sql-parser.stderr +++ b/src/interfaces/ecpg/test/expected/sql-parser.stderr @@ -40,11 +40,23 @@ [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ecpg_get_data on line 26: RESULT: offset: -1; array: yes [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 31: query: drop table T ; with 0 parameter(s) on connection regress1 +[NO_PID]: ecpg_execute on line 31: query: alter table T alter Item1 type bigint ; with 0 parameter(s) on connection regress1 [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ecpg_execute on line 31: using PQexec [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ecpg_execute on line 31: OK: DROP TABLE +[NO_PID]: ecpg_execute on line 31: OK: ALTER TABLE +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 32: query: alter table T alter column Item2 set data type smallint ; with 0 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 32: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 32: OK: ALTER TABLE +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 34: query: drop table T ; with 0 parameter(s) on connection regress1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 34: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 34: OK: DROP TABLE [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ecpg_finish: connection regress1 closed [NO_PID]: sqlca: code: 0, state: 00000 diff --git a/src/interfaces/ecpg/test/sql/parser.pgc b/src/interfaces/ecpg/test/sql/parser.pgc index 97ccedda289237ad444b5b27d7f1dd86291b2ece..806aabb70f9c8c998d4e41ceea09c8d46bc142b0 100644 --- a/src/interfaces/ecpg/test/sql/parser.pgc +++ b/src/interfaces/ecpg/test/sql/parser.pgc @@ -28,6 +28,9 @@ int main(int argc, char* argv[]) { for (i=0; i<3; i++) printf("item[%d] = %d\n", i, ind[i] ? -1 : item[i]); + EXEC SQL ALTER TABLE T ALTER Item1 TYPE bigint; + EXEC SQL ALTER TABLE T ALTER COLUMN Item2 SET DATA TYPE smallint; + EXEC SQL DROP TABLE T; EXEC SQL DISCONNECT ALL;