-- @@@ START COPYRIGHT @@@
--
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements.  See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership.  The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License.  You may obtain a copy of the License at
--
--   http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing,
-- software distributed under the License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-- KIND, either express or implied.  See the License for the
-- specific language governing permissions and limitations
-- under the License.
--
-- @@@ END COPYRIGHT @@@
-- HL_R2_Triggers_Spec.doc: SPJ enhancements to Triggers
-- AFTER trigger with a compound statement as a triggered action
-- (Compound statement with Insert, Update, Delete, Signal, an IF
-- statements.)
-- Result: Success

obey TEST_SPJC_STX_010(clean_up);
obey TEST_SPJC_STX_010(set_up);
LOG LOG_SPJC_STX_010 clear;
obey TEST_SPJC_STX_010(tests);
LOG;
obey TEST_SPJC_STX_010(clean_up);
exit;

?section clean_up
set schema CAT1.SCHM;


drop trigger TRIG01_SPJC_STX_010;

drop table TAB01_SPJC_STX_010;
drop table TAB02_SPJC_STX_010;

?section set_up
set schema CAT1.SCHM;

SET ENVVAR ALLOW_CS_IN_SQLCI 1;
CONTROL QUERY DEFAULT POS 'OFF';

create table TAB01_SPJC_STX_010(a int, b int, c int, d int);
create table TAB02_SPJC_STX_010(a int, b int, c int, d int);

INSERT INTO TAB01_SPJC_STX_010 VALUES
						(1, 2, 3, 4),
						(8, 6, 4, 2),
						(3, 6, 9, 12);

INSERT INTO TAB02_SPJC_STX_010 VALUES
						(2, 0, 0, 0),
						(7, 10, 10, 10),
						(9, 20, 20, 20);


?section tests

------------------------------------------------------------------
-- TEST CASE 01: AFTER trigger with a compound statement as a triggered
-- action (Compound statement with Insert, Update, Delete, Signal,
-- an IF statements.)
-- Result: Success
------------------------------------------------------------------

CREATE TRIGGER TRIG01_SPJC_STX_010 AFTER UPDATE ON
TAB01_SPJC_STX_010
REFERENCING OLD ROW AS O, NEW ROW AS N
FOR EACH ROW
BEGIN ATOMIC
	IF (N.A IS NULL) THEN
		SIGNAL SQLSTATE 'S0000' ('Error');
	ELSEIF (N.A = O.B) THEN
		DELETE FROM TAB02_SPJC_STX_010 WHERE A = N.A;
	ELSEIF (N.A > O.B) THEN
		UPDATE TAB02_SPJC_STX_010 SET D = N.A WHERE A = N.A;
	ELSEIF (N.A < O.B) THEN
		INSERT INTO TAB02_SPJC_STX_010 VALUES (N.A, N.B, N.C, N.D);
	END IF;
END;


UPDATE TAB01_SPJC_STX_010 SET A = A + 1;

-- Result: TAB01_SPJC_STX_010 has three rows with A = {2, 9, 4} and
--			TAB02_SPJC_STX_010 has
-- A            B            C            D          
-- -----------  -----------  -----------  -----------
-- 
--           7           10           10           10
--           9           20           20            9
--           4            6            9           12

select * from TAB01_SPJC_STX_010;

select * from TAB02_SPJC_STX_010;
------------------------------------------------------------------
