On Thu, Mar 12, 2015 at 6:36 AM, Jim Nasby <[email protected]> wrote:
> On 3/11/15 6:33 AM, Sawada Masahiko wrote:
>>>>>>>
>>>>>>> As a refresher, current commands are:
>>>>>>> >>>>>
>>>>>>> >>>>> VACUUM (ANALYZE, VERBOSE) table1 (col1);
>>>>>>> >>>>> REINDEX INDEX index1 FORCE;
>>>>>>> >>>>> COPY table1 FROM 'file.txt' WITH (FORMAT csv);
>>>>>>> >>>>> CREATE MATERIALIZED VIEW mv1 WITH (storageparam, ...) AS qry
>>>>>>> >>>>> WITH
>>>>>>> >>>>>DATA;
>>>>>>> >>>>> CREATE EXTENSION ext1 WITH SCHEMA s1 VERSION v1 FROM over;
>>>>>>> >>>>> CREATE ROLE role WITH LOGIN;
>>>>>>> >>>>> GRANT .... WITH GRANT OPTION;
>>>>>>> >>>>> CREATE VIEW v1 AS qry WITH CASCADED CHECK OPTION;
>>>>>>> >>>>> ALTER DATABASE db1 WITH CONNECTION LIMIT 50;
>>>>>>> >>>>> DECLARE c1 INSENSITIVE SCROLL CURSOR WITH HOLD;
>>>>>
>>>>> >>>
>>>>> >>>
>>>>> >>>
>>>>> >>>BTW, I'm fine with Tom's bare-word with WITH idea. That seems to be
>>>>> >>> the
>>>>> >>>most
>>>>> >>>consistent with everything else. Is there a problem with doing that?
>>>>> >>> I
>>>>> >>>know
>>>>> >>>getting syntax is one of the hard parts of new features, but it
>>>>> >>> seems
>>>>> >>>like
>>>>> >>>we reached consensus here...
>>>>
>>>> >>
>>>> >>
>>>> >>Attached is latest version patch based on Tom's idea as follows.
>>>> >>REINDEX { INDEX | ... } name WITH ( options [, ...] )
>>>
>>> >
>>> >
>>> >Are the parenthesis necessary? No other WITH option requires them, other
>>> >than create table/matview (COPY doesn't actually require them).
>>> >
>>
>> I was imagining EXPLAIN syntax.
>> Is there some possibility of supporting multiple options for REINDEX
>> command in future?
>> If there is, syntax will be as follows, REINDEX { INDEX | ... } name
>> WITH VERBOSE, XXX, XXX;
>> I thought style with parenthesis is better than above style.
>
>
> The thing is, ()s are actually an odd-duck. Very little supports it, and
> while COPY allows it they're not required. EXPLAIN is a different story,
> because that's not WITH; we're actually using () *instead of* WITH.
>
> So because almost all commands that use WITH doen't even accept (), I don't
> think this should either. It certainly shouldn't require them, because
> unlike EXPLAIN, there's no need to require them.
>
I understood what your point is.
Attached patch is changed syntax, it does not have parenthesis.
Regards,
-------
Sawada Masahiko
diff --git a/doc/src/sgml/ref/reindex.sgml b/doc/src/sgml/ref/reindex.sgml
index 0a4c7d4..3cea35f 100644
--- a/doc/src/sgml/ref/reindex.sgml
+++ b/doc/src/sgml/ref/reindex.sgml
@@ -22,6 +22,11 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
REINDEX { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } <replaceable class="PARAMETER">name</replaceable> [ FORCE ]
+REINDEX { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } <replaceable class="PARAMETER">name</replaceable> WITH <replaceable class="PARAMETER">options</replaceable> [, ...]
+
+<phrase>where <replaceable class="PARAMETER">option</replaceable> can be one of:</phrase>
+
+ VERBOSE
</synopsis>
</refsynopsisdiv>
@@ -159,6 +164,15 @@ REINDEX { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } <replaceable class="PARAM
</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><literal>VERBOSE</literal></term>
+ <listitem>
+ <para>
+ Prints a progress report as each index is reindexed.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index f85ed93..786f173 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -63,6 +63,7 @@
#include "utils/inval.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
+#include "utils/pg_rusage.h"
#include "utils/syscache.h"
#include "utils/tuplesort.h"
#include "utils/snapmgr.h"
@@ -3130,13 +3131,18 @@ IndexGetRelation(Oid indexId, bool missing_ok)
* reindex_index - This routine is used to recreate a single index
*/
void
-reindex_index(Oid indexId, bool skip_constraint_checks, char persistence)
+reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
+ bool verbose)
{
Relation iRel,
heapRelation;
Oid heapId;
IndexInfo *indexInfo;
volatile bool skipped_constraint = false;
+ int elevel = verbose ? INFO : DEBUG2;
+ PGRUsage ru0;
+
+ pg_rusage_init(&ru0);
/*
* Open and lock the parent heap relation. ShareLock is sufficient since
@@ -3280,6 +3286,13 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence)
heap_close(pg_index, RowExclusiveLock);
}
+ /* Log what we did */
+ ereport(elevel,
+ (errmsg("index \"%s\" was reindexed.",
+ get_rel_name(indexId)),
+ errdetail("%s.",
+ pg_rusage_show(&ru0))));
+
/* Close rels, but keep locks */
index_close(iRel, NoLock);
heap_close(heapRelation, NoLock);
@@ -3321,7 +3334,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence)
* index rebuild.
*/
bool
-reindex_relation(Oid relid, int flags)
+reindex_relation(Oid relid, int flags, bool verbose)
{
Relation rel;
Oid toast_relid;
@@ -3412,7 +3425,7 @@ reindex_relation(Oid relid, int flags)
RelationSetIndexList(rel, doneIndexes, InvalidOid);
reindex_index(indexOid, !(flags & REINDEX_REL_CHECK_CONSTRAINTS),
- persistence);
+ persistence, verbose);
CommandCounterIncrement();
@@ -3447,7 +3460,7 @@ reindex_relation(Oid relid, int flags)
* still hold the lock on the master table.
*/
if ((flags & REINDEX_REL_PROCESS_TOAST) && OidIsValid(toast_relid))
- result |= reindex_relation(toast_relid, flags);
+ result |= reindex_relation(toast_relid, flags, verbose);
return result;
}
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index 3febdd5..34ffaba 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -1532,7 +1532,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
else if (newrelpersistence == RELPERSISTENCE_PERMANENT)
reindex_flags |= REINDEX_REL_FORCE_INDEXES_PERMANENT;
- reindex_relation(OIDOldHeap, reindex_flags);
+ reindex_relation(OIDOldHeap, reindex_flags, false);
/*
* If the relation being rebuild is pg_class, swap_relation_files()
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 1c1d0da..4f0ef08 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -1681,10 +1681,24 @@ ChooseIndexColumnNames(List *indexElems)
* Recreate a specific index.
*/
Oid
-ReindexIndex(RangeVar *indexRelation)
+ReindexIndex(RangeVar *indexRelation, List *options)
{
Oid indOid;
Oid heapOid = InvalidOid;
+ bool verbose = false;
+ ListCell *lc;
+
+ /* Parse list of options */
+ foreach(lc, options)
+ {
+ char *opt = (char *) lfirst(lc);
+ if (strcmp(opt, "verbose") == 0)
+ verbose = true;
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("unrecognized REINDEX option \"%s\"", opt)));
+ }
/* lock level used here should match index lock reindex_index() */
indOid = RangeVarGetRelidExtended(indexRelation, AccessExclusiveLock,
@@ -1692,7 +1706,7 @@ ReindexIndex(RangeVar *indexRelation)
RangeVarCallbackForReindexIndex,
(void *) &heapOid);
- reindex_index(indOid, false, indexRelation->relpersistence);
+ reindex_index(indOid, false, indexRelation->relpersistence, verbose);
return indOid;
}
@@ -1761,9 +1775,23 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation,
* Recreate all indexes of a table (and of its toast table, if any)
*/
Oid
-ReindexTable(RangeVar *relation)
+ReindexTable(RangeVar *relation, List *options)
{
Oid heapOid;
+ bool verbose = false;
+ ListCell *lc;
+
+ /* Parse list of options */
+ foreach(lc, options)
+ {
+ char *opt = (char *) lfirst(lc);
+ if (strcmp(opt, "verbose") == 0)
+ verbose = true;
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("unrecognized REINDEX option \"%s\"", opt)));
+ }
/* The lock level used here should match reindex_relation(). */
heapOid = RangeVarGetRelidExtended(relation, ShareLock, false, false,
@@ -1771,7 +1799,8 @@ ReindexTable(RangeVar *relation)
if (!reindex_relation(heapOid,
REINDEX_REL_PROCESS_TOAST |
- REINDEX_REL_CHECK_CONSTRAINTS))
+ REINDEX_REL_CHECK_CONSTRAINTS,
+ verbose))
ereport(NOTICE,
(errmsg("table \"%s\" has no indexes",
relation->relname)));
@@ -1788,7 +1817,7 @@ ReindexTable(RangeVar *relation)
* That means this must not be called within a user transaction block!
*/
void
-ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind)
+ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, List *options)
{
Oid objectOid;
Relation relationRelation;
@@ -1800,12 +1829,29 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind)
List *relids = NIL;
ListCell *l;
int num_keys;
+ bool verbose;
+ int elevel = DEBUG2;
AssertArg(objectName);
Assert(objectKind == REINDEX_OBJECT_SCHEMA ||
objectKind == REINDEX_OBJECT_SYSTEM ||
objectKind == REINDEX_OBJECT_DATABASE);
+ /* Parse list of options */
+ foreach(l, options)
+ {
+ char *opt = (char *) lfirst(l);
+ if (strcmp(opt, "verbose") == 0)
+ {
+ verbose = true;
+ elevel = INFO;
+ }
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("unrecognized REINDEX option \"%s\"", opt)));
+ }
+
/*
* Get OID of object to reindex, being the database currently being used
* by session for a database or for system catalogs, or the schema defined
@@ -1924,9 +1970,10 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind)
PushActiveSnapshot(GetTransactionSnapshot());
if (reindex_relation(relid,
REINDEX_REL_PROCESS_TOAST |
- REINDEX_REL_CHECK_CONSTRAINTS))
- ereport(DEBUG1,
- (errmsg("table \"%s.%s\" was reindexed",
+ REINDEX_REL_CHECK_CONSTRAINTS,
+ verbose))
+ ereport(elevel,
+ (errmsg("indexes of whole table \"%s.%s\" were reindexed",
get_namespace_name(get_rel_namespace(relid)),
get_rel_name(relid))));
PopActiveSnapshot();
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 623e6bf..6359b6f 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -1225,7 +1225,7 @@ ExecuteTruncate(TruncateStmt *stmt)
/*
* Reconstruct the indexes to match, and we're done.
*/
- reindex_relation(heap_relid, REINDEX_REL_PROCESS_TOAST);
+ reindex_relation(heap_relid, REINDEX_REL_PROCESS_TOAST, false);
}
pgstat_count_truncate(rel);
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index cf0d317..382ebcd 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -457,6 +457,12 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
%type <node> explain_option_arg
%type <defelt> explain_option_elem
%type <list> explain_option_list
+
+%type <str> reindex_option_name
+%type <ival> reindex_target_type
+%type <ival> reindex_target_multitable
+%type <list> reindex_option_list
+
%type <node> copy_generic_opt_arg copy_generic_opt_arg_list_item
%type <defelt> copy_generic_opt_elem
%type <list> copy_generic_opt_list copy_generic_opt_arg_list
@@ -7295,57 +7301,75 @@ opt_if_exists: IF_P EXISTS { $$ = TRUE; }
* QUERY:
*
* REINDEX type <name> [FORCE]
+ * REINDEX type <name> WITH options
*
* FORCE no longer does anything, but we accept it for backwards compatibility
*****************************************************************************/
ReindexStmt:
- REINDEX INDEX qualified_name opt_force
+ REINDEX reindex_target_type qualified_name opt_force
{
ReindexStmt *n = makeNode(ReindexStmt);
- n->kind = REINDEX_OBJECT_INDEX;
+ n->kind = $2;
n->relation = $3;
n->name = NULL;
+ n->options = NULL;
$$ = (Node *)n;
}
- | REINDEX TABLE qualified_name opt_force
+ | REINDEX reindex_target_type qualified_name WITH reindex_option_list
{
ReindexStmt *n = makeNode(ReindexStmt);
- n->kind = REINDEX_OBJECT_TABLE;
+ n->kind = $2;
n->relation = $3;
n->name = NULL;
+ n->options = $5;
$$ = (Node *)n;
}
- | REINDEX SCHEMA name opt_force
+ | REINDEX reindex_target_multitable name opt_force
{
ReindexStmt *n = makeNode(ReindexStmt);
- n->kind = REINDEX_OBJECT_SCHEMA;
+ n->kind = $2;
n->name = $3;
n->relation = NULL;
+ n->options = NULL;
$$ = (Node *)n;
}
- | REINDEX SYSTEM_P name opt_force
+ | REINDEX reindex_target_multitable name WITH reindex_option_list
{
ReindexStmt *n = makeNode(ReindexStmt);
- n->kind = REINDEX_OBJECT_SYSTEM;
+ n->kind = $2;
n->name = $3;
n->relation = NULL;
+ n->options = $5;
$$ = (Node *)n;
}
- | REINDEX DATABASE name opt_force
+ ;
+reindex_target_type:
+ INDEX { $$ = REINDEX_OBJECT_INDEX; }
+ | TABLE { $$ = REINDEX_OBJECT_TABLE; }
+;
+reindex_target_multitable:
+ SCHEMA { $$ = REINDEX_OBJECT_SCHEMA; }
+ | SYSTEM_P { $$ = REINDEX_OBJECT_SYSTEM; }
+ | DATABASE { $$ = REINDEX_OBJECT_DATABASE; }
+;
+opt_force:
+ FORCE { $$ = TRUE; }
+ | /* EMPTY */ { $$ = FALSE; }
+;
+reindex_option_list:
+ reindex_option_name
{
- ReindexStmt *n = makeNode(ReindexStmt);
- n->kind = REINDEX_OBJECT_DATABASE;
- n->name = $3;
- n->relation = NULL;
- $$ = (Node *)n;
+ $$ = list_make1($1);
}
- ;
-
-opt_force: FORCE { $$ = TRUE; }
- | /* EMPTY */ { $$ = FALSE; }
- ;
-
+ | reindex_option_list ',' reindex_option_name
+ {
+ $$ = lappend($1, $3);
+ }
+;
+reindex_option_name:
+ VERBOSE { $$ = "verbose"; }
+;
/*****************************************************************************
*
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 126e38d..0b41701 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -737,10 +737,10 @@ standard_ProcessUtility(Node *parsetree,
switch (stmt->kind)
{
case REINDEX_OBJECT_INDEX:
- ReindexIndex(stmt->relation);
+ ReindexIndex(stmt->relation, stmt->options);
break;
case REINDEX_OBJECT_TABLE:
- ReindexTable(stmt->relation);
+ ReindexTable(stmt->relation, stmt->options);
break;
case REINDEX_OBJECT_SCHEMA:
case REINDEX_OBJECT_SYSTEM:
@@ -756,7 +756,7 @@ standard_ProcessUtility(Node *parsetree,
(stmt->kind == REINDEX_OBJECT_SCHEMA) ? "REINDEX SCHEMA" :
(stmt->kind == REINDEX_OBJECT_SYSTEM) ? "REINDEX SYSTEM" :
"REINDEX DATABASE");
- ReindexMultipleTables(stmt->name, stmt->kind);
+ ReindexMultipleTables(stmt->name, stmt->kind, stmt->options);
break;
default:
elog(ERROR, "unrecognized object type: %d",
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index e39a07c..46c8365 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -3342,12 +3342,32 @@ psql_completion(const char *text, int start, int end)
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, NULL);
else if (pg_strcasecmp(prev_wd, "INDEX") == 0)
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL);
- else if (pg_strcasecmp(prev_wd, "SCHEMA") == 0 )
+ else if (pg_strcasecmp(prev_wd, "SCHEMA") == 0)
COMPLETE_WITH_QUERY(Query_for_list_of_schemas);
else if (pg_strcasecmp(prev_wd, "SYSTEM") == 0 ||
pg_strcasecmp(prev_wd, "DATABASE") == 0)
COMPLETE_WITH_QUERY(Query_for_list_of_databases);
}
+ else if (pg_strcasecmp(prev3_wd, "REINDEX") == 0)
+ {
+ if (pg_strcasecmp(prev2_wd, "TABLE") == 0 ||
+ pg_strcasecmp(prev2_wd, "INDEX") == 0 ||
+ pg_strcasecmp(prev2_wd, "SCHEMA") == 0 ||
+ pg_strcasecmp(prev2_wd, "SYSTEM") == 0 ||
+ pg_strcasecmp(prev2_wd, "DATABASE") == 0)
+ COMPLETE_WITH_CONST("WITH");
+ }
+ else if (pg_strcasecmp(prev4_wd, "REINDEX") == 0)
+ {
+ if ((pg_strcasecmp(prev3_wd, "TABLE") == 0 ||
+ pg_strcasecmp(prev3_wd, "INDEX") == 0 ||
+ pg_strcasecmp(prev3_wd, "SCHEMA") == 0 ||
+ pg_strcasecmp(prev3_wd, "SYSTEM") == 0 ||
+ pg_strcasecmp(prev3_wd, "DATABASE") == 0) &&
+ pg_strcasecmp(prev_wd, "WITH") == 0)
+ COMPLETE_WITH_CONST("VERBOSE");
+ }
+
/* SECURITY LABEL */
else if (pg_strcasecmp(prev_wd, "SECURITY") == 0)
diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h
index e7cc7a0..48f8660 100644
--- a/src/include/catalog/index.h
+++ b/src/include/catalog/index.h
@@ -112,7 +112,7 @@ extern void validate_index(Oid heapId, Oid indexId, Snapshot snapshot);
extern void index_set_state_flags(Oid indexId, IndexStateFlagsAction action);
extern void reindex_index(Oid indexId, bool skip_constraint_checks,
- char relpersistence);
+ char relpersistence, bool verbose);
/* Flag bits for reindex_relation(): */
#define REINDEX_REL_PROCESS_TOAST 0x01
@@ -121,7 +121,7 @@ extern void reindex_index(Oid indexId, bool skip_constraint_checks,
#define REINDEX_REL_FORCE_INDEXES_UNLOGGED 0x08
#define REINDEX_REL_FORCE_INDEXES_PERMANENT 0x10
-extern bool reindex_relation(Oid relid, int flags);
+extern bool reindex_relation(Oid relid, int flags, bool verbose);
extern bool ReindexIsProcessingHeap(Oid heapOid);
extern bool ReindexIsProcessingIndex(Oid indexOid);
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index a9c6783..0b5d023 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -29,9 +29,9 @@ extern ObjectAddress DefineIndex(Oid relationId,
bool check_rights,
bool skip_build,
bool quiet);
-extern Oid ReindexIndex(RangeVar *indexRelation);
-extern Oid ReindexTable(RangeVar *relation);
-extern void ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind);
+extern Oid ReindexIndex(RangeVar *indexRelation, List *options);
+extern Oid ReindexTable(RangeVar *relation, List *optionsc);
+extern void ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, List *options);
extern char *makeObjectName(const char *name1, const char *name2,
const char *label);
extern char *ChooseRelationName(const char *name1, const char *name2,
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 38ed661..d66fd3b 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -2764,6 +2764,7 @@ typedef struct ReindexStmt
ReindexObjectType kind; /* REINDEX_OBJECT_INDEX, REINDEX_OBJECT_TABLE, etc. */
RangeVar *relation; /* Table or index to reindex */
const char *name; /* name of database to reindex */
+ List *options; /* list of options */
} ReindexStmt;
/* ----------------------
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers