blob: ba72bb081c88ee0c178e23cf917ea98bc2ee4723 [file] [log] [blame]
-- Tests exception handling of GPDB PL/PgSQL UDF
-- It exercises:
-- 1. PROTOCOL or SQL type of dtm_action_target
-- 2. Various levels of sub-transactions
-- 3. dtm_action_protocol(PROTOCOL): subtransaction_begin, subtransaction_rollback or subtransaction_release
-- 4. dtm_action: fail_begin_command, fail_end_command or panic_begin_comand
--
-- debug_dtm_action: Using this can specify what action to be
-- triggered/simulated and at what point like error / panic / delay
-- and at start or end command after receiving by the segment.
-- debug_dtm_action_segment: Using this can specify segment number to
-- trigger the specified dtm_action.
-- debug_dtm_action_target: Allows to set target for specified
-- dtm_action should it be DTM protocol command or SQL command from
-- master to segment.
-- debug_dtm_action_protocol: Allows to specify sub-type of DTM
-- protocol for which to perform specified dtm_action (like prepare,
-- abort_no_prepared, commit_prepared, abort_prepared,
-- subtransaction_begin, subtransaction_release,
-- subtransaction_rollback, etc...
--
-- debug_dtm_action_sql_command_tag: If debug_dtm_action_target is sql
-- then this parameter can be used to set the type of sql that should
-- trigger the exeception. Ex: 'MPPEXEC UPDATE'
-- debug_dtm_action_nestinglevel: This allows to optional specify at
-- which specific depth level in transaction to take the specified
-- dtm_action. This apples only to target with protocol and not SQL.
--
--
-- start_matchsubs
-- s/\s+\(.*\.[ch]:\d+\)/ (SOMEFILE:SOMEFUNC)/
-- m/ /
-- m/transaction \d+/
-- s/transaction \d+/transaction /
-- m/transaction -\d+/
-- s/transaction -\d+/transaction/
-- end_matchsubs
-- skip FTS probes always
SELECT gp_inject_fault_infinite('fts_probe', 'skip', 1);
SELECT gp_request_fts_probe_scan();
CREATE OR REPLACE FUNCTION test_excep (arg INTEGER) RETURNS INTEGER
AS $$
DECLARE res INTEGER; /* in func */
BEGIN /* in func */
res := 100 / arg; /* in func */
RETURN res; /* in func */
EXCEPTION /* in func */
WHEN division_by_zero /* in func */
THEN RETURN 999; /* in func */
END; /* in func */
$$
LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION test_protocol_allseg(mid int, mshop int, mgender character) RETURNS VOID AS
$$
DECLARE tfactor int default 0; /* in func */
BEGIN /* in func */
BEGIN /* in func */
CREATE TABLE employees(id int, shop_id int, gender character) DISTRIBUTED BY (id); /* in func */
INSERT INTO employees VALUES (0, 1, 'm'); /* in func */
END; /* in func */
BEGIN /* in func */
BEGIN /* in func */
IF EXISTS (select 1 from employees where id = mid) THEN /* in func */
RAISE EXCEPTION 'Duplicate employee id'; /* in func */
ELSE /* in func */
IF NOT (mshop between 1 AND 2) THEN /* in func */
RAISE EXCEPTION 'Invalid shop id' ; /* in func */
END IF; /* in func */
END IF; /* in func */
SELECT * INTO tfactor FROM test_excep(0); /* in func */
BEGIN /* in func */
INSERT INTO employees VALUES (mid, mshop, mgender); /* in func */
EXCEPTION /* in func */
WHEN OTHERS THEN /* in func */
BEGIN /* in func */
RAISE NOTICE 'catching the exception ...3'; /* in func */
END; /* in func */
END; /* in func */
EXCEPTION /* in func */
WHEN OTHERS THEN /* in func */
RAISE NOTICE 'catching the exception ...2'; /* in func */
END; /* in func */
EXCEPTION /* in func */
WHEN OTHERS THEN /* in func */
RAISE NOTICE 'catching the exception ...1'; /* in func */
END; /* in func */
END; /* in func */
$$
LANGUAGE plpgsql;
SELECT role, preferred_role, content, status FROM gp_segment_configuration;
SET debug_dtm_action_segment=0;
SET debug_dtm_action_target=protocol;
SET debug_dtm_action_protocol=subtransaction_begin;
SET debug_dtm_action=panic_begin_command;
SET debug_dtm_action_nestinglevel=0;
DROP TABLE IF EXISTS employees;
select test_protocol_allseg(1, 2,'f');
-- make sure segment recovery is complete after panic.
0U: select 1;
0Uq:
select * from employees;
--
--
SET debug_dtm_action_segment=0;
SET debug_dtm_action_target=protocol;
SET debug_dtm_action_protocol=subtransaction_release;
SET debug_dtm_action=panic_begin_command;
SET debug_dtm_action_nestinglevel=0;
DROP TABLE IF EXISTS employees;
select test_protocol_allseg(1, 2,'f');
-- make sure segment recovery is complete after panic.
0U: select 1;
0Uq:
select * from employees;
--
--
SET debug_dtm_action_segment=0;
SET debug_dtm_action_target=protocol;
SET debug_dtm_action_protocol=subtransaction_release;
SET debug_dtm_action=panic_begin_command;
SET debug_dtm_action_nestinglevel=4;
DROP TABLE IF EXISTS employees;
select test_protocol_allseg(1, 2,'f');
-- make sure segment recovery is complete after panic.
0U: select 1;
0Uq:
select * from employees;
--
--
SET debug_dtm_action_segment=0;
SET debug_dtm_action_target=protocol;
SET debug_dtm_action_protocol=subtransaction_rollback;
SET debug_dtm_action=panic_begin_command;
SET debug_dtm_action_nestinglevel=3;
DROP TABLE IF EXISTS employees;
select test_protocol_allseg(1, 2,'f');
-- make sure segment recovery is complete after panic.
0U: select 1;
0Uq:
select * from employees;
--
--
SET debug_dtm_action_segment=0;
SET debug_dtm_action_target=protocol;
SET debug_dtm_action_protocol=subtransaction_rollback;
SET debug_dtm_action=panic_begin_command;
SET debug_dtm_action_nestinglevel=0;
DROP TABLE IF EXISTS employees;
select test_protocol_allseg(1, 2,'f');
-- make sure segment recovery is complete after panic.
0U: select 1;
0Uq:
select * from employees;
--
--
SET debug_dtm_action_segment=0;
SET debug_dtm_action_target=protocol;
SET debug_dtm_action_protocol=subtransaction_begin;
SET debug_dtm_action=panic_begin_command;
SET debug_dtm_action_nestinglevel=3;
DROP TABLE IF EXISTS employees;
select test_protocol_allseg(1, 2,'f');
-- make sure segment recovery is complete after panic.
0U: select 1;
0Uq:
select * from employees;
SELECT gp_inject_fault('fts_probe', 'reset', 1);