Reputation: 187499
I have the following postgres function
CREATE OR REPLACE FUNCTION refresh_materialized_view(name)
RETURNS integer AS
$BODY$
DECLARE
_table_name ALIAS FOR $1;
_entry materialized_views%ROWTYPE;
_result INT;
BEGIN
SELECT * INTO _entry FROM materialized_views WHERE table_name = _table_name;
BEGIN;
EXECUTE 'CREATE TEMP TABLE new_materialized_view_rows ON COMMIT DROP AS SELECT * FROM ' || _entry.view_name;
EXECUTE 'TRUNCATE TABLE ' || _table_name;
EXECUTE 'INSERT INTO ' || _table_name || ' SELECT * FROM new_materialized_view_rows';
UPDATE materialized_views
SET last_refresh = CURRENT_TIMESTAMP
WHERE table_name = _table_name;
COMMIT;
EXECUTE 'ANALYZE ' || table_name;
RETURN 1;
END
$BODY$
LANGUAGE plpgsql VOLATILE SECURITY DEFINER;
ALTER FUNCTION refresh_materialized_view(name) OWNER TO portal;
The function is called from a non-transactional context, so I've enclosed the statements that update data with
BEGIN;
COMMIT;
so that these statements execute atomically. However, when I execute the script above I get the following error:
ERROR: syntax error at or near ";"
LINE 16: BEGIN;
Upvotes: 0
Views: 231
Reputation:
A function is always part of the calling transaction. You cannot commit the transaction in a function. So you will need to do the following in the calling code:
begin;
select efresh_materialized_view('foobar');
commit;
"The function is called from a non-transactional context"
That is not possible. You cannot work without a transaction in PostgreSQL. You are probably referring to the "autocommit" mode which implicitely commits every statement - but that is still transactional.
Upvotes: 1
Reputation: 126970
You can't use COMMIT within a function. The function is transactional anyway, that's why you don't need the second BEGIN; as well. This is your bug as well, this is where it fails.
Upvotes: 0