Add function of get_immv_def()

This function can reconstruct the underlying SELECT command for a
IMMV. (This is a decompiled reconstruction, not the original text
of the command)
This commit is contained in:
Takuma Hoshiai 2022-09-18 05:36:43 +09:00
parent 5bd2670002
commit 2d9abee78c
5 changed files with 48 additions and 15 deletions

View file

@ -16,11 +16,14 @@ NOTICE: created index "mv2_index" on immv "mv2"
SELECT create_immv('mv3', 'WITH d AS (DELETE FROM t RETURNING NULL) SELECT * FROM t'); SELECT create_immv('mv3', 'WITH d AS (DELETE FROM t RETURNING NULL) SELECT * FROM t');
ERROR: materialized views must not use data-modifying statements in WITH ERROR: materialized views must not use data-modifying statements in WITH
SELECT immvrelid FROM pg_ivm_immv ORDER BY 1; SELECT immvrelid, get_immv_def(immvrelid) FROM pg_ivm_immv ORDER BY 1;
immvrelid immvrelid | get_immv_def
----------- -----------+-----------------------
mv mv | SELECT i +
mv2 | FROM t
mv2 | SELECT i +
| FROM t +
| WHERE ((i % 2) = 0)
(2 rows) (2 rows)
DROP TABLE t; DROP TABLE t;
@ -29,16 +32,18 @@ DETAIL: table mv depends on table t
table mv2 depends on table t table mv2 depends on table t
HINT: Use DROP ... CASCADE to drop the dependent objects too. HINT: Use DROP ... CASCADE to drop the dependent objects too.
DROP TABLE mv; DROP TABLE mv;
SELECT immvrelid FROM pg_ivm_immv ORDER BY 1; SELECT immvrelid, get_immv_def(immvrelid) FROM pg_ivm_immv ORDER BY 1;
immvrelid immvrelid | get_immv_def
----------- -----------+-----------------------
mv2 mv2 | SELECT i +
| FROM t +
| WHERE ((i % 2) = 0)
(1 row) (1 row)
DROP TABLE mv2; DROP TABLE mv2;
SELECT immvrelid FROM pg_ivm_immv ORDER BY 1; SELECT immvrelid, get_immv_def(immvrelid) FROM pg_ivm_immv ORDER BY 1;
immvrelid immvrelid | get_immv_def
----------- -----------+--------------
(0 rows) (0 rows)
DROP TABLE t; DROP TABLE t;

View file

@ -5,3 +5,9 @@ RETURNS bool
STABLE STABLE
AS 'MODULE_PATHNAME', 'ivm_visible_in_prestate' AS 'MODULE_PATHNAME', 'ivm_visible_in_prestate'
LANGUAGE C; LANGUAGE C;
CREATE FUNCTION get_immv_def(IN immvrelid regclass)
RETURNS text
STRICT
AS 'MODULE_PATHNAME', 'get_immv_def'
LANGUAGE C;

View file

@ -11,6 +11,7 @@
*/ */
#include "postgres.h" #include "postgres.h"
#include "access/table.h"
#include "access/xact.h" #include "access/xact.h"
#include "catalog/dependency.h" #include "catalog/dependency.h"
#include "catalog/namespace.h" #include "catalog/namespace.h"
@ -45,6 +46,7 @@ static void parseNameAndColumns(const char *string, List **names, List **colName
PG_FUNCTION_INFO_V1(create_immv); PG_FUNCTION_INFO_V1(create_immv);
PG_FUNCTION_INFO_V1(refresh_immv); PG_FUNCTION_INFO_V1(refresh_immv);
PG_FUNCTION_INFO_V1(IVM_prevent_immv_change); PG_FUNCTION_INFO_V1(IVM_prevent_immv_change);
PG_FUNCTION_INFO_V1(get_immv_def);
/* /*
* Call back functions for cleaning up * Call back functions for cleaning up
@ -320,3 +322,22 @@ PgIvmImmvPrimaryKeyIndexId(void)
return pg_ivm_immv_pkey_id; return pg_ivm_immv_pkey_id;
} }
/*
* Return the SELECT part of a IMMV
*/
Datum
get_immv_def(PG_FUNCTION_ARGS)
{
Oid matviewOid = PG_GETARG_OID(0);
Relation matviewRel = NULL;
char * querystring = NULL;
matviewRel = table_open(matviewOid, AccessShareLock);
/* Make sure IMMV is a table. */
Assert(matviewRel->rd_rel->relkind == RELKIND_RELATION);
querystring = pg_ivm_get_querydef(get_immv_query(matviewRel), false);
table_close(matviewRel, NoLock);
PG_RETURN_TEXT_P(cstring_to_text(querystring));
}

View file

@ -43,6 +43,7 @@ extern void makeIvmAggColumn(ParseState *pstate, Aggref *aggref, char *resname,
/* matview.c */ /* matview.c */
extern Query *get_immv_query(Relation matviewRel);
extern ObjectAddress ExecRefreshImmv(const RangeVar *relation, bool skipData, extern ObjectAddress ExecRefreshImmv(const RangeVar *relation, bool skipData,
const char *queryString, QueryCompletion *qc); const char *queryString, QueryCompletion *qc);
extern bool ImmvIncrementalMaintenanceIsEnabled(void); extern bool ImmvIncrementalMaintenanceIsEnabled(void);

View file

@ -6,14 +6,14 @@ SELECT create_immv(' mv2 ( x ) ', 'SELECT * FROM t WHERE i%2 = 0');
SELECT create_immv('mv3', 'WITH d AS (DELETE FROM t RETURNING NULL) SELECT * FROM t'); SELECT create_immv('mv3', 'WITH d AS (DELETE FROM t RETURNING NULL) SELECT * FROM t');
SELECT immvrelid FROM pg_ivm_immv ORDER BY 1; SELECT immvrelid, get_immv_def(immvrelid) FROM pg_ivm_immv ORDER BY 1;
DROP TABLE t; DROP TABLE t;
DROP TABLE mv; DROP TABLE mv;
SELECT immvrelid FROM pg_ivm_immv ORDER BY 1; SELECT immvrelid, get_immv_def(immvrelid) FROM pg_ivm_immv ORDER BY 1;
DROP TABLE mv2; DROP TABLE mv2;
SELECT immvrelid FROM pg_ivm_immv ORDER BY 1; SELECT immvrelid, get_immv_def(immvrelid) FROM pg_ivm_immv ORDER BY 1;
DROP TABLE t; DROP TABLE t;