Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/sraoss/pg_ivm into main
Browse files Browse the repository at this point in the history
  • Loading branch information
yugo-n committed Sep 30, 2022
2 parents 5e69211 + 78b8ac2 commit 6eddcd2
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 0 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ refresh_immv(immv_name text, with_data bool) RETURNS bigint

The with_data flag is corresponding to `WITH [NO] DATA` option of REFRESH MATERIALIZED VIEW` command. If with_data is true, the backing query is executed to provide the new data, and if the IMMV is unpopulated, triggers for maintaining the view are created. Also, a unique index is created for IMMV if it is possible and the view doesn't have that yet. If with_data is false, no new data is generated and the IMMV become unpopulated, and the triggers are dropped from the IMMV. Note that unpopulated IMMV is still scannable although the result is empty. This behaviour may be changed in future to raise an error when an unpopulated IMMV is scanned.

#### get_immv_def

`get_immv_def` reconstructs the underlying SELECT command for an IMMV. (This is a decompiled reconstruction, not the original text of the command.)
```
get_immv_def(immv regclass) RETURNS text
```

### IMMV metadata catalog

Expand Down
5 changes: 5 additions & 0 deletions pg_ivm--1.2--1.3.sql
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@ RETURNS text
STRICT
AS 'MODULE_PATHNAME', 'get_immv_def'
LANGUAGE C;

-- event trigger

DROP EVENT TRIGGER pg_ivm_sql_drop_trigger;
DROP FUNCTION pg_ivm_sql_drop_trigger_func;
46 changes: 46 additions & 0 deletions pg_ivm.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@
*/
#include "postgres.h"

#include "access/genam.h"
#include "access/table.h"
#include "access/xact.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_namespace_d.h"
#include "catalog/pg_trigger_d.h"
#include "commands/trigger.h"
Expand All @@ -23,6 +26,7 @@
#include "parser/scansup.h"
#include "tcop/tcopprot.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
#include "utils/regproc.h"
#include "utils/rel.h"
Expand All @@ -35,13 +39,18 @@ PG_MODULE_MAGIC;
static Oid pg_ivm_immv_id = InvalidOid;
static Oid pg_ivm_immv_pkey_id = InvalidOid;

static object_access_hook_type PrevObjectAccessHook = NULL;

void _PG_init(void);

static void IvmXactCallback(XactEvent event, void *arg);
static void IvmSubXactCallback(SubXactEvent event, SubTransactionId mySubid,
SubTransactionId parentSubid, void *arg);
static void parseNameAndColumns(const char *string, List **names, List **colNames);

static void PgIvmObjectAccessHook(ObjectAccessType access, Oid classId,
Oid objectId, int subId, void *arg);

/* SQL callable functions */
PG_FUNCTION_INFO_V1(create_immv);
PG_FUNCTION_INFO_V1(refresh_immv);
Expand Down Expand Up @@ -75,6 +84,9 @@ _PG_init(void)
{
RegisterXactCallback(IvmXactCallback, NULL);
RegisterSubXactCallback(IvmSubXactCallback, NULL);

PrevObjectAccessHook = object_access_hook;
object_access_hook = PgIvmObjectAccessHook;
}

/*
Expand Down Expand Up @@ -350,3 +362,37 @@ get_immv_def(PG_FUNCTION_ARGS)
table_close(matviewRel, NoLock);
PG_RETURN_TEXT_P(cstring_to_text(querystring));
}

/*
* object_access_hook function for dropping an IMMV
*/
static void
PgIvmObjectAccessHook(ObjectAccessType access, Oid classId,
Oid objectId, int subId, void *arg)
{
if (PrevObjectAccessHook)
PrevObjectAccessHook(access, classId, objectId, subId, arg);

if (access == OAT_DROP && classId == RelationRelationId && !OidIsValid(subId))
{
Relation pgIvmImmv = table_open(PgIvmImmvRelationId(), AccessShareLock);
SysScanDesc scan;
ScanKeyData key;
HeapTuple tup;

ScanKeyInit(&key,
Anum_pg_ivm_immv_immvrelid,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(objectId));
scan = systable_beginscan(pgIvmImmv, PgIvmImmvPrimaryKeyIndexId(),
true, NULL, 1, &key);

tup = systable_getnext(scan);

if (HeapTupleIsValid(tup))
CatalogTupleDelete(pgIvmImmv, &tup->t_self);

systable_endscan(scan);
table_close(pgIvmImmv, NoLock);
}
}

0 comments on commit 6eddcd2

Please sign in to comment.