*** a/doc/src/sgml/ref/reindex.sgml --- b/doc/src/sgml/ref/reindex.sgml *************** *** 21,27 **** PostgreSQL documentation ! REINDEX { INDEX | TABLE | DATABASE | SYSTEM } name [ FORCE ] --- 21,27 ---- ! REINDEX { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } name [ FORCE ] *************** *** 101,106 **** REINDEX { INDEX | TABLE | DATABASE | SYSTEM } nam --- 101,116 ---- + SCHEMA + + + Recreate all indexes of all tables of the specified schema. If the table has a + secondary TOAST table, that is reindexed as well. + + + + + DATABASE *** a/src/backend/catalog/index.c --- b/src/backend/catalog/index.c *************** *** 3402,3407 **** reindex_relation(Oid relid, int flags) --- 3402,3465 ---- return result; } + /* + * reindex_schema - This routine is used to recreate all indexes + * of all relation of a namespace + */ + bool + reindex_schema(Oid schemaOid) + { + ScanKeyData key[2]; + HeapScanDesc scan; + HeapTuple tuple; + Relation relationRelation; + List *relids = NULL; + ListCell *l; + + AssertArg(schemaOid); + + ScanKeyInit(&key[0], + Anum_pg_class_relnamespace, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(schemaOid)); + ScanKeyInit(&key[1], + Anum_pg_class_relkind, + BTEqualStrategyNumber, F_CHAREQ, + 'r'); + + /* + * Scan pg_class by relnamespace to build a list of the relations we need to reindex. + */ + relationRelation = heap_open(RelationRelationId, AccessShareLock); + scan = heap_beginscan_catalog(relationRelation, 2, key); + + while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + { + relids = lappend_oid(relids, HeapTupleGetOid(tuple)); + } + + heap_endscan(scan); + heap_close(relationRelation, AccessShareLock); + + if (relids == NULL) + /* The schema does not have any table */ + return false; + + /* now reindex each relation by using reindex_relation */ + foreach(l, relids) + { + Oid relid = lfirst_oid(l); + if (reindex_relation(relid, + REINDEX_REL_PROCESS_TOAST | + REINDEX_REL_CHECK_CONSTRAINTS)) + ereport(NOTICE, + (errmsg("table \"%s.%s\" was reindexed", + get_namespace_name(schemaOid), + get_rel_name(relid)))); + } + + return true; + } /* ---------------------------------------------------------------- * System index reindexing support *** a/src/backend/commands/indexcmds.c --- b/src/backend/commands/indexcmds.c *************** *** 1769,1774 **** ReindexTable(RangeVar *relation) --- 1769,1789 ---- return heapOid; } + Oid + ReindexSchema(RangeVar *schema) + { + Oid heapOid; + + heapOid = get_namespace_oid(schema->relname, false); + + if (!reindex_schema(heapOid)) + ereport(NOTICE, + (errmsg("schema\"%s\" does not hava any table", + schema->relname))); + + return heapOid; + } + /* * ReindexDatabase * Recreate indexes of a database. *** a/src/backend/parser/gram.y --- b/src/backend/parser/gram.y *************** *** 7211,7216 **** ReindexStmt: --- 7211,7217 ---- reindex_type: INDEX { $$ = OBJECT_INDEX; } | TABLE { $$ = OBJECT_TABLE; } + | SCHEMA { $$ = OBJECT_SCHEMA; } ; opt_force: FORCE { $$ = TRUE; } *** a/src/backend/tcop/utility.c --- b/src/backend/tcop/utility.c *************** *** 755,760 **** standard_ProcessUtility(Node *parsetree, --- 755,763 ---- case OBJECT_MATVIEW: ReindexTable(stmt->relation); break; + case OBJECT_SCHEMA: + ReindexSchema(stmt->relation); + break; case OBJECT_DATABASE: /* *** a/src/include/catalog/index.h --- b/src/include/catalog/index.h *************** *** 110,115 **** extern void reindex_index(Oid indexId, bool skip_constraint_checks); --- 110,116 ---- #define REINDEX_REL_CHECK_CONSTRAINTS 0x04 extern bool reindex_relation(Oid relid, int flags); + extern bool reindex_schema(Oid schemaOid); extern bool ReindexIsProcessingHeap(Oid heapOid); extern bool ReindexIsProcessingIndex(Oid indexOid); *** a/src/include/commands/defrem.h --- b/src/include/commands/defrem.h *************** *** 30,35 **** extern Oid DefineIndex(Oid relationId, --- 30,36 ---- bool quiet); extern Oid ReindexIndex(RangeVar *indexRelation); extern Oid ReindexTable(RangeVar *relation); + extern Oid ReindexSchema(RangeVar *schema); extern Oid ReindexDatabase(const char *databaseName, bool do_system, bool do_user); extern char *makeObjectName(const char *name1, const char *name2,