Add get_immv_def func (#23)
get_immv_def reconstructs the underlying SELECT command for a IMMV. This is a decompiled reconstruction, not the original text of the command.
This commit is contained in:
parent
b6702f9a3a
commit
1d21409321
7 changed files with 80 additions and 15 deletions
|
|
@ -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 AS x +
|
||||||
|
| 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 AS x +
|
||||||
|
| 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;
|
||||||
|
|
|
||||||
|
|
@ -1043,6 +1043,24 @@ DELETE FROM mv_ivm_1;
|
||||||
ERROR: cannot change materialized view "mv_ivm_1"
|
ERROR: cannot change materialized view "mv_ivm_1"
|
||||||
TRUNCATE mv_ivm_1;
|
TRUNCATE mv_ivm_1;
|
||||||
ERROR: cannot change materialized view "mv_ivm_1"
|
ERROR: cannot change materialized view "mv_ivm_1"
|
||||||
|
-- get_immv_def function
|
||||||
|
SELECT immvrelid, get_immv_def(immvrelid) FROM pg_ivm_immv ORDER BY 1;
|
||||||
|
immvrelid | get_immv_def
|
||||||
|
-----------+----------------------------------
|
||||||
|
mv_ivm_1 | SELECT a.i, +
|
||||||
|
| a.j, +
|
||||||
|
| b.k +
|
||||||
|
| FROM (mv_base_a a +
|
||||||
|
| JOIN mv_base_b b USING (i))
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- mv_base_b is not immv
|
||||||
|
SELECT 'mv_base_b'::regclass, get_immv_def('mv_base_b');
|
||||||
|
regclass | get_immv_def
|
||||||
|
-----------+--------------
|
||||||
|
mv_base_b |
|
||||||
|
(1 row)
|
||||||
|
|
||||||
DROP TABLE mv_base_b CASCADE;
|
DROP TABLE mv_base_b CASCADE;
|
||||||
NOTICE: drop cascades to 3 other objects
|
NOTICE: drop cascades to 3 other objects
|
||||||
DETAIL: drop cascades to table mv_ivm_1
|
DETAIL: drop cascades to table mv_ivm_1
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
30
pg_ivm.c
30
pg_ivm.c
|
|
@ -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,31 @@ 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;
|
||||||
|
Query *query = NULL;
|
||||||
|
char *querystring = NULL;
|
||||||
|
|
||||||
|
/* Make sure IMMV is a table. */
|
||||||
|
if (get_rel_relkind(matviewOid) != RELKIND_RELATION)
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
|
matviewRel = table_open(matviewOid, AccessShareLock);
|
||||||
|
query = get_immv_query(matviewRel);
|
||||||
|
if (query == NULL)
|
||||||
|
{
|
||||||
|
table_close(matviewRel, NoLock);
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
}
|
||||||
|
|
||||||
|
querystring = pg_ivm_get_viewdef(matviewRel, false);
|
||||||
|
|
||||||
|
table_close(matviewRel, NoLock);
|
||||||
|
PG_RETURN_TEXT_P(cstring_to_text(querystring));
|
||||||
|
}
|
||||||
|
|
|
||||||
1
pg_ivm.h
1
pg_ivm.h
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -460,5 +460,10 @@ UPDATE mv_ivm_1 SET k = 1 WHERE i = 1;
|
||||||
DELETE FROM mv_ivm_1;
|
DELETE FROM mv_ivm_1;
|
||||||
TRUNCATE mv_ivm_1;
|
TRUNCATE mv_ivm_1;
|
||||||
|
|
||||||
|
-- get_immv_def function
|
||||||
|
SELECT immvrelid, get_immv_def(immvrelid) FROM pg_ivm_immv ORDER BY 1;
|
||||||
|
-- mv_base_b is not immv
|
||||||
|
SELECT 'mv_base_b'::regclass, get_immv_def('mv_base_b');
|
||||||
|
|
||||||
DROP TABLE mv_base_b CASCADE;
|
DROP TABLE mv_base_b CASCADE;
|
||||||
DROP TABLE mv_base_a CASCADE;
|
DROP TABLE mv_base_a CASCADE;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue