Header And Logo

PostgreSQL
| The world's most advanced open source database.

Functions

matview.h File Reference

#include "nodes/params.h"
#include "nodes/parsenodes.h"
#include "tcop/dest.h"
#include "utils/relcache.h"
Include dependency graph for matview.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void SetMatViewToPopulated (Relation relation)
void ExecRefreshMatView (RefreshMatViewStmt *stmt, const char *queryString, ParamListInfo params, char *completionTag)
DestReceiverCreateTransientRelDestReceiver (Oid oid)

Function Documentation

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  )