From 9ac5a2c42effeb7ac12f92c7ad8296b8ed7d78a7 Mon Sep 17 00:00:00 2001 From: Takuma Hoshiai Date: Thu, 15 Dec 2022 02:16:02 +0900 Subject: [PATCH] Fix segmentation fault in incorrect view def A segfault was occurred, if create_immv specify query other than SELECT. A query syntax checked, but did not check statement type. issue #37 --- expected/create_immv.out | 11 +++++++++++ pg_ivm.c | 4 ++++ sql/create_immv.sql | 7 +++++++ 3 files changed, 22 insertions(+) diff --git a/expected/create_immv.out b/expected/create_immv.out index 22e0e18..da9f95d 100644 --- a/expected/create_immv.out +++ b/expected/create_immv.out @@ -31,6 +31,17 @@ SELECT create_immv('mv_in_immv01', 'SELECT i FROM mv'); ERROR: including IMMV in definition is not supported on incrementally maintainable materialized view SELECT create_immv('mv_in_immv02', 'SELECT t.i FROM t INNER JOIN mv2 ON t.i = mv2.x'); ERROR: including IMMV in definition is not supported on incrementally maintainable materialized view +-- SQL other than SELECT +SELECT create_immv('mv_in_create', 'CREATE TABLE in_create(i int)'); +ERROR: view definition must specify SELECT statement +SELECT create_immv('mv_in_insert', 'INSERT INTO t VALUES(10)'); +ERROR: view definition must specify SELECT statement +SELECT create_immv('mv_in_update', 'UPDATE t SET i = 10'); +ERROR: view definition must specify SELECT statement +SELECT create_immv('mv_in_delete', 'DELETE FROM t'); +ERROR: view definition must specify SELECT statement +SELECT create_immv('mv_in_drop', 'DROP TABLE t'); +ERROR: view definition must specify SELECT statement DROP TABLE t; ERROR: cannot drop table t because other objects depend on it DETAIL: table mv depends on table t diff --git a/pg_ivm.c b/pg_ivm.c index b61967d..f96f952 100644 --- a/pg_ivm.c +++ b/pg_ivm.c @@ -197,6 +197,10 @@ create_immv(PG_FUNCTION_ARGS) parsetree = linitial_node(RawStmt, parsetree_list); + /* view definition should spcify SELECT query */ + if (!IsA(parsetree->stmt, SelectStmt)) + elog(ERROR, "view definition must specify SELECT statement"); + ctas = makeNode(CreateTableAsStmt); ctas->query = parsetree->stmt; #if defined(PG_VERSION_NUM) && (PG_VERSION_NUM >= 140000) diff --git a/sql/create_immv.sql b/sql/create_immv.sql index 8d1602e..c8d3415 100644 --- a/sql/create_immv.sql +++ b/sql/create_immv.sql @@ -12,6 +12,13 @@ SELECT immvrelid, get_immv_def(immvrelid) FROM pg_ivm_immv ORDER BY 1; SELECT create_immv('mv_in_immv01', 'SELECT i FROM mv'); SELECT create_immv('mv_in_immv02', 'SELECT t.i FROM t INNER JOIN mv2 ON t.i = mv2.x'); +-- SQL other than SELECT +SELECT create_immv('mv_in_create', 'CREATE TABLE in_create(i int)'); +SELECT create_immv('mv_in_insert', 'INSERT INTO t VALUES(10)'); +SELECT create_immv('mv_in_update', 'UPDATE t SET i = 10'); +SELECT create_immv('mv_in_delete', 'DELETE FROM t'); +SELECT create_immv('mv_in_drop', 'DROP TABLE t'); + DROP TABLE t; DROP TABLE mv;