rem rem $Header: maporder.sql 10-aug-99.14:34:29 hyeh Exp $ rem rem maporder.sql rem rem Copyright (c) 1996, 1999, Oracle Corporation. All rights reserved. rem rem NAME rem maporder.sql - Oracle 8 demo of map and order functions rem rem DESCRIPTION rem This demo features Oracle8's object extensions, specifically map and rem order functions of abstract data types rem rem NOTES rem rem MODIFIED (MM/DD/YY) rem hyeh 08/10/99 - use sqlplus syntax rem mjaeger 07/14/99 - bug 808870: OCCS: convert tabs, no long lines rem yaggarwa 08/06/98 - Add New syntax changes rem cchau 08/18/97 - enable dictionary protection rem mchien 05/29/97 - fix type syntax rem mchien 07/17/96 - rem mchien 07/16/96 - Created rem REMARK >>>> Set System Variables For Current SQLPlus Session <<<< SET FEEDBACK 1 SET NUMWIDTH 10 SET PAGESIZE 24 SET LINESIZE 80 SET TRIMSPOOL ON SET TAB OFF SET DEFINE '^' set echo on connect sys/knl_test7 as sysdba; grant connect, resource to mmo2 identified by mmo2; connect mmo2/mmo2 REM create type with MAP function with parameters should error! create type rational AS OBJECT ( numerator INTEGER, denominator INTEGER, MAP MEMBER FUNCTION rat_to_real (x number) RETURN REAL, PRAGMA RESTRICT_REFERENCES (rat_to_real, RNDS, WNDS, RNPS, WNPS) ); / show errors create or replace type rational AS OBJECT ( numerator INTEGER, denominator INTEGER, MAP MEMBER FUNCTION rat_to_real RETURN REAL, PRAGMA RESTRICT_REFERENCES (rat_to_real, RNDS, WNDS, RNPS, WNPS) ); / show errors REM create body with missing MAP specification in the body should error create type body rational AS MEMBER FUNCTION rat_to_real RETURN REAL IS BEGIN IF denominator = 0 THEN RETURN 0; ELSE RETURN numerator/denominator; END IF; --Unqualified attributes refer to the "self" object. END; END; / show errors REM create body with ORDER function instead of MAP as specified in type spec REM should error create or replace type body rational AS ORDER MEMBER FUNCTION rat_to_real RETURN REAL IS BEGIN IF denominator = 0 THEN RETURN 0; ELSE RETURN numerator/denominator; END IF; --Unqualified attributes refer to the "self" object. END; END; / show errors create or replace type body rational AS MAP MEMBER FUNCTION rat_to_real RETURN REAL IS BEGIN IF denominator = 0 THEN RETURN 0; ELSE RETURN numerator/denominator; END IF; --Unqualified attributes refer to the "self" object. END; END; / show errors create table tb1( c1 varchar2(10), c2 rational, c3 rational, c4 real); insert into tb1 values('row1', rational(9,10), rational(9,10), .9); insert into tb1 values('row2', rational(7,8), rational(7,8), .8); insert into tb1 values('row3', rational(5,6), rational(5,6), .7); insert into tb1 values('row4', rational(3,4), rational(3,4), .6); insert into tb1 values('row5', rational(1,2), rational(1,2), .5); insert into tb1 values('row6', rational(0,1), rational(0,1), .4); insert into tb1 values('bomb1', rational(1,0), rational(1,0), .3); insert into tb1 values('bomb2', rational(1,null), rational(1,null), null); insert into tb1 values('bomb3', rational(null,1), rational(null,1), null); insert into tb1 values('bomb4', rational(null,null), rational(null,null), null); insert into tb1 values('bomb5', null, null, null); select c1, sys_op_dump(c2), sys_op_dump(c3) from tb1 order by c2, c3; select c1, sys_op_dump(c2), sys_op_dump(c3) from tb1 order by c2, c3 desc; select c1, sys_op_dump(c3) from tb1 order by c3 desc; select c1, sys_op_dump(c2), sys_op_dump(c3) from tb1 order by c3, c2; select c1, sys_op_dump(c2), sys_op_dump(c3) from tb1 order by c3, c2 desc; select c1, sys_op_dump(c2) from tb1 order by c2 desc; update tb1 p set c4 = p.c2.rat_to_real(); select sys_op_dump(c2), c4 from tb1 order by c4; update tb1 p set c4 = p.c3.rat_to_real(); select sys_op_dump(c3), c4 from tb1 order by c4; select c1, sys_op_dump(c2-c3) from tb1 order by c2, c3; select c1 from tb1 where c2-c3 = 0 order by c1; select sys_op_dump(c2) from tb1 where c2 > c3 order by c2; select sys_op_dump(c2) from tb1 where c2 > rational(20,1); select sys_op_dump(c2) from tb1 where c2 = rational(9,10); select sys_op_dump(c3) from tb1 where c3 > rational(1,20) order by c3; select sys_op_dump(c3) from tb1 where c3 = rational(9,10); select sys_op_dump(c3) from tb1 where c3 in (rational(9,10), rational(1,2)) order by c3; REM Now test order function for rational numbers REM error case where order function does not have arguments! create type rat AS OBJECT ( numerator INTEGER, denominator INTEGER, ORDER MEMBER FUNCTION order_rat RETURN INTEGER, PRAGMA RESTRICT_REFERENCES (order_rat, RNDS, WNDS, RNPS, WNPS) ); / show errors create or replace type rat AS OBJECT ( numerator INTEGER, denominator INTEGER, ORDER MEMBER FUNCTION order_rat (rat1 rat) RETURN INTEGER, PRAGMA RESTRICT_REFERENCES (order_rat, RNDS, WNDS, RNPS, WNPS) ); / show errors create type body rat AS ORDER MEMBER FUNCTION order_rat(rat1 rat) RETURN INTEGER IS den1 INTEGER; den2 INTEGER; num1 INTEGER; num2 INTEGER; BEGIN den1 := nvl(self.denominator, 0); den2 := nvl(rat1.denominator, 0); num1 := nvl(self.numerator, 0); num2 := nvl(rat1.numerator, 0); if den1 = den2 then return num1 - num2; elsif (den1=0) then return 1; elsif (den2=0) then return -1; else return (num1*den2) - (den1*num2); END IF; END; END; / show errors create table tb2( c1 varchar2(10), c2 rat, c3 rat, c4 real); insert into tb2 values('row1', rat(9,10), rat(9,10), .9); insert into tb2 values('row2', rat(7,8), rat(7,8), .8); insert into tb2 values('row3', rat(5,6), rat(5,6), .7); insert into tb2 values('row4', rat(3,4), rat(3,4), .6); insert into tb2 values('row5', rat(1,2), rat(1,2), .5); insert into tb2 values('row6', rat(0,1), rat(0,1), .4); insert into tb2 values('bomb1', rat(1,0), rat(1,0), .3); insert into tb2 values('bomb2', rat(1,null), rat(1,null), null); insert into tb2 values('bomb3', rat(null,1), rat(null,1), null); insert into tb2 values('bomb4', rat(null,null), rat(null,null), null); insert into tb2 values('bomb5', null, null, null); select c1, sys_op_dump(c2), sys_op_dump(c3) from tb2 order by c2, c3; select c1, sys_op_dump(c2), sys_op_dump(c3) from tb2 order by c2, c3 desc; select c1, sys_op_dump(c3) from tb1 order by c3 desc; select c1, sys_op_dump(c2), sys_op_dump(c3) from tb2 order by c3, c2; select c1, sys_op_dump(c2), sys_op_dump(c3) from tb2 order by c3, c2 desc; select c1, sys_op_dump(c2) from tb1 order by c2 desc; update tb2 p set c4 = p.c2.order_rat(rat(3,10)); select sys_op_dump(c2), c4 from tb2 order by c4; update tb2 p set c4 = p.c2.order_rat(c3); select sys_op_dump(c2), sys_op_dump(c3), c4 from tb2 order by c4; select sys_op_dump(c2) from tb1 minus select sys_op_dump(c2) from tb2; select sys_op_dump(c2) from tb1 minus select sys_op_dump(c3) from tb2; select sys_op_dump(c3) from tb1 minus select sys_op_dump(c3) from tb2; select sys_op_dump(c2) from tb1 intersect select sys_op_dump(c2) from tb2; select sys_op_dump(c2) from tb1 intersect select sys_op_dump(c3) from tb2; select sys_op_dump(c3) from tb1 intersect select sys_op_dump(c3) from tb2; select sys_op_dump(c3) from tb2 where c2 in (select c2 from tb2) order by c3; select sys_op_dump(c3) from tb2 where c3 between rat(1,100) and rat(99,100) order by c3; select sys_op_dump(c2) from tb2 where c2 = ANY (SELECT c2 from tb2 where c3 = rat(9,10)); select sys_op_dump(c3) from tb2 where c2 >= ALL (rat(1,10), rat(9,10)); select c1 from tb2 where c2-c3 = 0 order by c1; REM #### test a recursive method REM method is the factorial function REM note: pragma for map method is not required! create or replace type tfact AS OBJECT (c1 int, map member function mfact return int, member function fact(a int) return int , PRAGMA RESTRICT_REFERENCES(fact,WNDS,RNDS,WNPS,RNPS) ); / show errors create or replace type body tfact AS member function fact(a int) return int is begin if a is null then return 0; elsif a = 0 then return 1; else return a*fact(a-1); end if; end; map member function mfact return int is begin return c1; end; END; / show errors CREATE TABLE tbfact (a tfact, b int, constraint aci check (a.c1 >= 0), constraint bci check (b >= 0)); INSERT INTO tbfact values(tfact(3), 4); INSERT INTO tbfact values(tfact(-1), 1); INSERT INTO tbfact values(tfact(1), -1); INSERT INTO tbfact values(tfact(0), 1); INSERT INTO tbfact values(tfact(null), 0); INSERT INTO tbfact values (null,0); INSERT INTO tbfact values(tfact(2), 3); SELECT p.a.c1 a, p.a.fact(p.a.c1) afact, b, p.a.fact(b) bfact FROM tbfact p WHERE a is not null ORDER by a; SELECT p.a.c1 a, p.a.fact(p.a.c1) afact, b, p.a.fact(b) bfact FROM tbfact p WHERE a is not null ORDER by a desc; drop type body rat; create or replace type body rat as ORDER MEMBER FUNCTION order_rat(rat1 rat) RETURN INTEGER IS BEGIN if self.denominator = rat1.denominator then return self.numerator - rat1.numerator; else return (self.numerator * rat1.denominator) - (self.denominator * rat1.numerator); END IF; END; END; / select c1, sys_op_dump(c2), sys_op_dump(c3) from tb2 order by c2, c3; select c1, sys_op_dump(c2), sys_op_dump(c3) from tb2 order by c2, c3 desc; select c1, sys_op_dump(c2), sys_op_dump(c3) from tb2 order by c3, c2; connect sys/knl_test7 as sysdba drop user mmo2 cascade;