Revision 14642
Added by Aaron Marcuse-Kubitza about 10 years ago
util.sql | ||
---|---|---|
4962 | 4962 |
-- |
4963 | 4963 |
|
4964 | 4964 |
CREATE FUNCTION rematerialize_view(table_esc text, view_ regclass, table_mod_sql text DEFAULT ''::text, repopulate boolean DEFAULT true) RETURNS void |
4965 |
LANGUAGE sql |
|
4966 |
AS $_$ |
|
4967 |
SELECT util.recreate($$ |
|
4968 |
SELECT util.drop_table($$||util.quote_typed($1)||$$); |
|
4969 |
SELECT util.copy_struct($$||util.quote_typed($2)||$$, $$|| |
|
4970 |
util.quote_typed($1)||$$); |
|
4971 |
$$||table_mod_sql -- no blank line before b/c table_mod_sql has preceding \n |
|
4972 |
); |
|
4965 |
LANGUAGE plpgsql |
|
4966 |
AS $$ |
|
4967 |
DECLARE |
|
4968 |
temp_table_esc text = util.concat_esc(table_esc, '__new'); |
|
4969 |
-- _ not . to avoid requiring "" around name |
|
4970 |
temp_table regclass; |
|
4971 |
temp_table_mod_sql text = util.identifier_replace(table_esc, temp_table_esc, |
|
4972 |
table_mod_sql); |
|
4973 |
BEGIN |
|
4974 |
IF repopulate THEN |
|
4975 |
/* test if recreate() can successfully re-create the dependent views, to |
|
4976 |
avoid populating the entire table (which for some views can take hours) |
|
4977 |
only to have the changes rolled back by a failing dependent view */ |
|
4978 |
BEGIN |
|
4979 |
PERFORM util.rematerialize_view(table_esc, view_, table_mod_sql, |
|
4980 |
repopulate := false); |
|
4981 |
|
|
4982 |
-- roll back DB changes |
|
4983 |
PERFORM util.raise('ROLBK', 'sandbox block finished and rolled back'); |
|
4984 |
EXCEPTION |
|
4985 |
WHEN SQLSTATE 'ROLBK' THEN NULL; |
|
4986 |
END; |
|
4987 |
END IF; |
|
4988 |
|
|
4989 |
-- create new table, without blocking original table |
|
4990 |
PERFORM util.copy_struct(view_, temp_table_esc); |
|
4991 |
temp_table = temp_table_esc::regclass; -- once it exists |
|
4992 |
PERFORM util.eval(temp_table_mod_sql); |
|
4993 |
PERFORM CASE WHEN repopulate THEN util.copy_data(view_, temp_table) END; |
|
4994 |
|
|
4995 |
-- move new table into place (fast operation) |
|
4996 |
PERFORM util.relation_replace(table_esc, temp_table); |
|
4997 |
END; |
|
4998 |
$$; |
|
4973 | 4999 |
|
4974 |
/* don't populate unless recreate() can successfully recreate the dependent |
|
4975 |
views, to avoid populating the entire table (which for some views can take |
|
4976 |
hours) only to have the changes rolled back by a failing dependent view */ |
|
4977 |
SELECT CASE WHEN repopulate THEN util.copy_data($2, $1) END; |
|
4978 |
$_$; |
|
4979 | 5000 |
|
4980 |
|
|
4981 | 5001 |
-- |
4982 | 5002 |
-- Name: FUNCTION rematerialize_view(table_esc text, view_ regclass, table_mod_sql text, repopulate boolean); Type: COMMENT; Schema: util; Owner: - |
4983 | 5003 |
-- |
... | ... | |
4989 | 5009 |
-- ... |
4990 | 5010 |
$$); |
4991 | 5011 |
|
5012 |
non-blocking: allows full access to original materialized table during operation |
|
5013 |
|
|
4992 | 5014 |
idempotent, but repeats action each time |
4993 | 5015 |
'; |
4994 | 5016 |
|
Also available in: Unified diff
schemas/util.sql: rematerialize_view(): made it non-blocking, so that it would allow full access to the original materialized table during the operation