diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c index 869c586..31af8e1 100644 --- a/src/backend/commands/matview.c +++ b/src/backend/commands/matview.c @@ -216,6 +216,43 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString, "the rule for materialized view \"%s\" is not a single action", RelationGetRelationName(matviewRel)); + /* When CONCURRENTLY refresh, we need at least one unique index. */ + if (concurrent) + { + List *indexoidlist = RelationGetIndexList(matviewRel); + ListCell *indexoidscan; + bool hasUniqueIndex = false; + + foreach(indexoidscan, indexoidlist) + { + Oid indexoid = lfirst_oid(indexoidscan); + Relation indexRel; + Form_pg_index indexStruct; + + indexRel = index_open(indexoid, RowExclusiveLock); + indexStruct = indexRel->rd_index; + + if (indexStruct->indisunique && + IndexIsValid(indexStruct) && + RelationGetIndexExpressions(indexRel) == NIL && + RelationGetIndexPredicate(indexRel) == NIL) + hasUniqueIndex = true; + + index_close(indexRel, RowExclusiveLock); + } + + list_free(indexoidlist); + + if (!hasUniqueIndex) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot refresh materialized view \"%s\" concurrently", + quote_qualified_identifier(get_namespace_name(RelationGetNamespace(matviewRel)), + RelationGetRelationName(matviewRel))), + errhint("Create a unique index with no WHERE clause on one or more columns of the materialized view."))); + } + + /* * The stored query was rewritten at the time of the MV definition, but * has not been scribbled on by the planner. @@ -695,12 +732,8 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner, list_free(indexoidlist); - if (!foundUniqueIndex) - ereport(ERROR, - (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("cannot refresh materialized view \"%s\" concurrently", - matviewname), - errhint("Create a unique index with no WHERE clause on one or more columns of the materialized view."))); + /* Must have at least one unique index */ + Assert(foundUniqueIndex); appendStringInfoString(&querybuf, " AND newdata OPERATOR(pg_catalog.*=) mv) "