diff --git a/doc/src/sgml/keywords.sgml b/doc/src/sgml/keywords.sgml index 4e8b7d75023..deb72e79bc8 100644 --- a/doc/src/sgml/keywords.sgml +++ b/doc/src/sgml/keywords.sgml @@ -1,4 +1,4 @@ - + <acronym>SQL</acronym> Key Words @@ -921,7 +921,7 @@ CONCURRENTLY - non-reserved + reserved (can be function or type) diff --git a/doc/src/sgml/ref/create_index.sgml b/doc/src/sgml/ref/create_index.sgml index 49352accae0..1966cb9daeb 100644 --- a/doc/src/sgml/ref/create_index.sgml +++ b/doc/src/sgml/ref/create_index.sgml @@ -1,5 +1,5 @@ @@ -21,7 +21,7 @@ PostgreSQL documentation -CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table [ USING method ] +CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ name ] ON table [ USING method ] ( { column | ( expression ) } [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] ) [ WITH ( storage_parameter = value [, ... ] ) ] [ TABLESPACE tablespace ] @@ -33,8 +33,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] nameDescription - CREATE INDEX constructs an index named name on the specified table. + CREATE INDEX constructs an index + on the specified column(s) of the specified table. Indexes are primarily used to enhance database performance (though inappropriate use can result in slower performance). @@ -132,7 +132,9 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name The name of the index to be created. No schema name can be included here; the index is always created in the same schema as its parent - table. + table. If the name is omitted, PostgreSQL chooses a + suitable name based on the parent table's name and the indexed column + name(s). @@ -514,8 +516,10 @@ CREATE UNIQUE INDEX title_idx ON films (title); To create an index on the expression lower(title), allowing efficient case-insensitive searches: -CREATE INDEX lower_title_idx ON films ((lower(title))); +CREATE INDEX ON films ((lower(title))); + (In this example we have chosen to omit the index name, so the system + will choose a name, typically films_lower_idx.) @@ -544,7 +548,7 @@ CREATE INDEX gin_idx ON documents_table (locations) WITH (fastupdate = off); films and have the index reside in the tablespace indexspace: -CREATE INDEX code_idx ON films(code) TABLESPACE indexspace; +CREATE INDEX code_idx ON films (code) TABLESPACE indexspace; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 7ff46e05cb1..30663d578ea 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.698 2009/12/23 02:35:22 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.699 2009/12/23 17:41:43 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -253,7 +253,8 @@ static TypeName *TableFuncTypeName(List *columns); %type copy_file_name database_name access_method_clause access_method attr_name - index_name name cursor_name file_name cluster_index_specification + name cursor_name file_name + index_name opt_index_name cluster_index_specification %type func_name handler_name qual_Op qual_all_Op subquery_Op opt_class opt_inline_handler opt_validator validator_clause @@ -325,7 +326,7 @@ static TypeName *TableFuncTypeName(List *columns); %type overlay_placing substr_from substr_for %type opt_instead -%type index_opt_unique opt_verbose opt_full +%type opt_unique opt_concurrently opt_verbose opt_full %type opt_freeze opt_default opt_recheck %type opt_binary opt_oids copy_delimiter @@ -4822,36 +4823,17 @@ defacl_privilege_target: * * QUERY: CREATE INDEX * - * Note: we can't factor CONCURRENTLY into a separate production without - * making it a reserved word. - * * Note: we cannot put TABLESPACE clause after WHERE clause unless we are * willing to make TABLESPACE a fully reserved word. *****************************************************************************/ -IndexStmt: CREATE index_opt_unique INDEX index_name +IndexStmt: CREATE opt_unique INDEX opt_concurrently opt_index_name ON qualified_name access_method_clause '(' index_params ')' opt_reloptions OptTableSpace where_clause { IndexStmt *n = makeNode(IndexStmt); n->unique = $2; - n->concurrent = false; - n->idxname = $4; - n->relation = $6; - n->accessMethod = $7; - n->indexParams = $9; - n->options = $11; - n->tableSpace = $12; - n->whereClause = $13; - $$ = (Node *)n; - } - | CREATE index_opt_unique INDEX CONCURRENTLY index_name - ON qualified_name access_method_clause '(' index_params ')' - opt_reloptions OptTableSpace where_clause - { - IndexStmt *n = makeNode(IndexStmt); - n->unique = $2; - n->concurrent = true; + n->concurrent = $4; n->idxname = $5; n->relation = $7; n->accessMethod = $8; @@ -4863,11 +4845,21 @@ IndexStmt: CREATE index_opt_unique INDEX index_name } ; -index_opt_unique: +opt_unique: UNIQUE { $$ = TRUE; } | /*EMPTY*/ { $$ = FALSE; } ; +opt_concurrently: + CONCURRENTLY { $$ = TRUE; } + | /*EMPTY*/ { $$ = FALSE; } + ; + +opt_index_name: + index_name { $$ = $1; } + | /*EMPTY*/ { $$ = NULL; } + ; + access_method_clause: USING access_method { $$ = $2; } | /*EMPTY*/ { $$ = DEFAULT_INDEX_TYPE; } @@ -10696,7 +10688,6 @@ unreserved_keyword: | COMMENTS | COMMIT | COMMITTED - | CONCURRENTLY | CONFIGURATION | CONNECTION | CONSTRAINTS @@ -10988,6 +10979,7 @@ type_func_name_keyword: AUTHORIZATION | BETWEEN | BINARY + | CONCURRENTLY | CROSS | CURRENT_SCHEMA | FREEZE diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h index f07057c4306..d4c30b1e561 100644 --- a/src/include/parser/kwlist.h +++ b/src/include/parser/kwlist.h @@ -11,7 +11,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/include/parser/kwlist.h,v 1.7 2009/12/07 05:22:23 tgl Exp $ + * $PostgreSQL: pgsql/src/include/parser/kwlist.h,v 1.8 2009/12/23 17:41:44 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -83,7 +83,7 @@ PG_KEYWORD("comment", COMMENT, UNRESERVED_KEYWORD) PG_KEYWORD("comments", COMMENTS, UNRESERVED_KEYWORD) PG_KEYWORD("commit", COMMIT, UNRESERVED_KEYWORD) PG_KEYWORD("committed", COMMITTED, UNRESERVED_KEYWORD) -PG_KEYWORD("concurrently", CONCURRENTLY, UNRESERVED_KEYWORD) +PG_KEYWORD("concurrently", CONCURRENTLY, TYPE_FUNC_NAME_KEYWORD) PG_KEYWORD("configuration", CONFIGURATION, UNRESERVED_KEYWORD) PG_KEYWORD("connection", CONNECTION, UNRESERVED_KEYWORD) PG_KEYWORD("constraint", CONSTRAINT, RESERVED_KEYWORD) diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out index 079a64098c5..9dd54b39f09 100644 --- a/src/test/regress/expected/create_index.out +++ b/src/test/regress/expected/create_index.out @@ -689,7 +689,8 @@ DETAIL: Key (f2)=(b) is duplicated. -- test that expression indexes and partial indexes work concurrently CREATE INDEX CONCURRENTLY concur_index4 on concur_heap(f2) WHERE f1='a'; CREATE INDEX CONCURRENTLY concur_index5 on concur_heap(f2) WHERE f1='x'; -CREATE INDEX CONCURRENTLY concur_index6 on concur_heap((f2||f1)); +-- here we also check that you can default the index name +CREATE INDEX CONCURRENTLY on concur_heap((f2||f1)); -- You can't do a concurrent index build in a transaction BEGIN; CREATE INDEX CONCURRENTLY concur_index7 ON concur_heap(f1); @@ -711,10 +712,10 @@ Table "public.concur_heap" Indexes: "concur_index2" UNIQUE, btree (f1) "concur_index3" UNIQUE, btree (f2) INVALID + "concur_heap_expr_idx" btree ((f2 || f1)) "concur_index1" btree (f2, f1) "concur_index4" btree (f2) WHERE f1 = 'a'::text "concur_index5" btree (f2) WHERE f1 = 'x'::text - "concur_index6" btree ((f2 || f1)) "std_index" btree (f2) DROP TABLE concur_heap; diff --git a/src/test/regress/sql/create_index.sql b/src/test/regress/sql/create_index.sql index 9527ab7a7bf..b205afa34f7 100644 --- a/src/test/regress/sql/create_index.sql +++ b/src/test/regress/sql/create_index.sql @@ -300,7 +300,8 @@ CREATE UNIQUE INDEX CONCURRENTLY concur_index3 ON concur_heap(f2); -- test that expression indexes and partial indexes work concurrently CREATE INDEX CONCURRENTLY concur_index4 on concur_heap(f2) WHERE f1='a'; CREATE INDEX CONCURRENTLY concur_index5 on concur_heap(f2) WHERE f1='x'; -CREATE INDEX CONCURRENTLY concur_index6 on concur_heap((f2||f1)); +-- here we also check that you can default the index name +CREATE INDEX CONCURRENTLY on concur_heap((f2||f1)); -- You can't do a concurrent index build in a transaction BEGIN;