#include "nodes/params.h"
#include "nodes/parsenodes.h"
#include "tcop/dest.h"
#include "utils/relcache.h"
Go to the source code of this file.
Functions | |
void | SetMatViewToPopulated (Relation relation) |
void | ExecRefreshMatView (RefreshMatViewStmt *stmt, const char *queryString, ParamListInfo params, char *completionTag) |
DestReceiver * | CreateTransientRelDestReceiver (Oid oid) |
DestReceiver* CreateTransientRelDestReceiver | ( | Oid | oid | ) |
Definition at line 263 of file matview.c.
References palloc0().
Referenced by CreateDestReceiver(), and ExecRefreshMatView().
{ DR_transientrel *self = (DR_transientrel *) palloc0(sizeof(DR_transientrel)); self->pub.receiveSlot = transientrel_receive; self->pub.rStartup = transientrel_startup; self->pub.rShutdown = transientrel_shutdown; self->pub.rDestroy = transientrel_destroy; self->pub.mydest = DestTransientRel; self->transientoid = transientoid; return (DestReceiver *) self; }
void ExecRefreshMatView | ( | RefreshMatViewStmt * | stmt, | |
const char * | queryString, | |||
ParamListInfo | params, | |||
char * | completionTag | |||
) |
Definition at line 110 of file matview.c.
References AccessExclusiveLock, RewriteRule::actions, Assert, CheckTableNotInUse(), CMD_SELECT, CreateTransientRelDestReceiver(), elog, ereport, errcode(), errmsg(), ERROR, RewriteRule::event, finish_heap_swap(), heap_close, heap_open(), IsA, RewriteRule::isInstead, IsSystemRelation(), linitial, list_length(), make_new_heap(), NoLock, NULL, RuleLock::numLocks, RangeVarCallbackOwnsTable(), RangeVarGetRelidExtended(), RelationData::rd_rel, RelationData::rd_rules, ReadNextMultiXactId(), RecentXmin, refresh_matview_datafill(), RefreshMatViewStmt::relation, RelationCacheInvalidateEntry(), RelationGetRelationName, RELKIND_MATVIEW, RuleLock::rules, and RefreshMatViewStmt::skipData.
Referenced by ProcessUtilitySlow().
{ Oid matviewOid; Relation matviewRel; RewriteRule *rule; List *actions; Query *dataQuery; Oid tableSpace; Oid OIDNewHeap; DestReceiver *dest; /* * Get a lock until end of transaction. */ matviewOid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock, false, false, RangeVarCallbackOwnsTable, NULL); matviewRel = heap_open(matviewOid, NoLock); /* Make sure it is a materialized view. */ if (matviewRel->rd_rel->relkind != RELKIND_MATVIEW) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("\"%s\" is not a materialized view", RelationGetRelationName(matviewRel)))); /* * We're not using materialized views in the system catalogs. */ Assert(!IsSystemRelation(matviewRel)); Assert(!matviewRel->rd_rel->relhasoids); /* * Check that everything is correct for a refresh. Problems at this point * are internal errors, so elog is sufficient. */ if (matviewRel->rd_rel->relhasrules == false || matviewRel->rd_rules->numLocks < 1) elog(ERROR, "materialized view \"%s\" is missing rewrite information", RelationGetRelationName(matviewRel)); if (matviewRel->rd_rules->numLocks > 1) elog(ERROR, "materialized view \"%s\" has too many rules", RelationGetRelationName(matviewRel)); rule = matviewRel->rd_rules->rules[0]; if (rule->event != CMD_SELECT || !(rule->isInstead)) elog(ERROR, "the rule for materialized view \"%s\" is not a SELECT INSTEAD OF rule", RelationGetRelationName(matviewRel)); actions = rule->actions; if (list_length(actions) != 1) elog(ERROR, "the rule for materialized view \"%s\" is not a single action", RelationGetRelationName(matviewRel)); /* * The stored query was rewritten at the time of the MV definition, but * has not been scribbled on by the planner. */ dataQuery = (Query *) linitial(actions); Assert(IsA(dataQuery, Query)); /* * Check for active uses of the relation in the current transaction, such * as open scans. * * NB: We count on this to protect us against problems with refreshing the * data using HEAP_INSERT_FROZEN. */ CheckTableNotInUse(matviewRel, "REFRESH MATERIALIZED VIEW"); tableSpace = matviewRel->rd_rel->reltablespace; heap_close(matviewRel, NoLock); /* Create the transient table that will receive the regenerated data. */ OIDNewHeap = make_new_heap(matviewOid, tableSpace); dest = CreateTransientRelDestReceiver(OIDNewHeap); if (!stmt->skipData) refresh_matview_datafill(dest, dataQuery, queryString); /* * Swap the physical files of the target and transient tables, then * rebuild the target's indexes and throw away the transient table. */ finish_heap_swap(matviewOid, OIDNewHeap, false, false, true, true, RecentXmin, ReadNextMultiXactId()); RelationCacheInvalidateEntry(matviewOid); }
void SetMatViewToPopulated | ( | Relation | relation | ) |
Definition at line 64 of file matview.c.
References Assert, log_newpage(), MAIN_FORKNUM, PageInit(), PageSetChecksumInplace(), palloc(), pfree(), RelationData::rd_id, RelationData::rd_ispopulated, RelationData::rd_node, RelationData::rd_rel, RelationData::rd_smgr, RelationCacheInvalidateEntry(), RelationNeedsWAL, RelationOpenSmgr, RELKIND_MATVIEW, smgrextend(), and smgrimmedsync().
Referenced by copy_heap_data(), intorel_startup(), and transientrel_startup().
{ Page page; Assert(relation->rd_rel->relkind == RELKIND_MATVIEW); Assert(relation->rd_ispopulated == false); page = (Page) palloc(BLCKSZ); PageInit(page, BLCKSZ, 0); if (RelationNeedsWAL(relation)) log_newpage(&(relation->rd_node), MAIN_FORKNUM, 0, page); RelationOpenSmgr(relation); PageSetChecksumInplace(page, 0); smgrextend(relation->rd_smgr, MAIN_FORKNUM, 0, (char *) page, true); pfree(page); smgrimmedsync(relation->rd_smgr, MAIN_FORKNUM); RelationCacheInvalidateEntry(relation->rd_id); }