SQL scripts generated from the class model defined in the section called “Database mapping requirements”:

class Person : public iopc::OidObject {
public:
	EShort age;
	EString name;
};

class Employee : public Person {
public:
	EInt salary;
};

class Student : public Person {
public:
	EString studcardid;
};

class PhdStudent : public Student {
public:
	short int scholarship;
};

Class mapping uses the following settings. For the format definition see the section called “Class metadata”

Person and Employee use vertical mapping, Student uses horizontal mapping, PhdStudent uses filtered mapping. Its attributes are inserted into Student.

::Person[db.mapping.type];string;vertical
::Student[db.mapping.type];string;horizontal
::PhdStudent[db.mapping.type];string;filtered
::PhdStudent[db.mapping.insertto];string;::Student
::Employee[db.mapping.type];string;vertical
iopc::EString[db.type.length];int;50
CREATE SEQUENCE OIDSEQ MINVALUE 1 START WITH 1 INCREMENT BY 1 CACHE 20 NOCYCLE;
CREATE SEQUENCE SERIALSEQ MINVALUE 1 START WITH 1 INCREMENT BY 1 CACHE 20 NOCYCLE;

CREATE TABLE OidObject ( 
	CLASSNAME VARCHAR2(1000), OID NUMBER(10), SERIALID NUMBER(10), 
	CONSTRAINT OidObject_pk  PRIMARY KEY (OID))
CREATE INDEX OidObject_idxcn ON OidObject (CLASSNAME);

CREATE TABLE Person ( 
	age NUMBER(5), name VARCHAR2(50), OID NUMBER(10), 
	CONSTRAINT Person_OID_fk FOREIGN KEY (OID) REFERENCES OidObject(OID), 
	CONSTRAINT Person_pk  PRIMARY KEY (OID));
	
CREATE TABLE Student ( 
	studcardid VARCHAR2(50), age NUMBER(5), name VARCHAR2(50), scholarship NUMBER(5), OID NUMBER(10), 
	CONSTRAINT Student_OID_fk FOREIGN KEY (OID) REFERENCES OidObject(OID), 
	CONSTRAINT Student_pk  PRIMARY KEY (OID));
	
CREATE TABLE Employee ( 
	salary NUMBER(10), OID NUMBER(10), 
	CONSTRAINT Employee_OID_fk FOREIGN KEY (OID) REFERENCES OidObject(OID), 
	CONSTRAINT Employee_pk  PRIMARY KEY (OID));
	
CREATE VIEW OidObject_SV AS (
SELECT
	OidObject.CLASSNAME AS CLASSNAME, OidObject.OID AS OID, OidObject.SERIALID AS SERIALID 
	FROM OidObject 
	WHERE OidObject.CLASSNAME = 'iopc::OidObject');
	
CREATE VIEW Person_SV AS (
SELECT 
	Person.age AS Person_age, Person.name AS Person_name, 
	OidObject.CLASSNAME AS CLASSNAME, OidObject.OID AS OID, OidObject.SERIALID AS SERIALID 
FROM Person INNER JOIN OidObject ON (Person.OID = OidObject.OID) 
WHERE OidObject.CLASSNAME = '::Person');

CREATE VIEW Student_SV AS (
SELECT 
	Student.studcardid AS Student_studcardid, 
	Student.age AS Person_age, Student.name AS Person_name, 
	OidObject.CLASSNAME AS CLASSNAME, OidObject.OID AS OID, OidObject.SERIALID AS SERIALID 
FROM Student INNER JOIN OidObject ON (Student.OID = OidObject.OID) 
WHERE OidObject.CLASSNAME = '::Student');

CREATE VIEW PhdStudent_SV AS (
SELECT 
	Student.studcardid AS Student_studcardid, 
	Student.age AS Person_age, Student.name AS Person_name, 
	Student.scholarship AS PhdStudent_scholarship, 
	OidObject.CLASSNAME AS CLASSNAME, OidObject.OID AS OID, OidObject.SERIALID AS SERIALID 
FROM Student INNER JOIN OidObject ON (Student.OID = OidObject.OID) 
WHERE OidObject.CLASSNAME = '::PhdStudent');

CREATE VIEW Employee_SV AS (
SELECT 
	Employee.salary AS Employee_salary, 
	Person.age AS Person_age, Person.name AS Person_name, 
	OidObject.CLASSNAME AS CLASSNAME, OidObject.OID AS OID, OidObject.SERIALID AS SERIALID 
FROM Employee INNER JOIN 
	Person ON (Employee.OID = Person.OID) INNER JOIN 
	OidObject ON (Employee.OID = OidObject.OID) 
WHERE OidObject.CLASSNAME = '::Employee');

CREATE VIEW Employee_PV AS (
SELECT 
	Employee.salary AS Employee_salary, 
	Person.age AS Person_age, Person.name AS Person_name, 
	OidObject.CLASSNAME AS CLASSNAME, OidObject.OID AS OID, OidObject.SERIALID AS SERIALID 
FROM Employee INNER JOIN 
	Person ON (Employee.OID = Person.OID) INNER JOIN 
	OidObject ON (Employee.OID = OidObject.OID));
	
CREATE VIEW PhdStudent_PV AS (
SELECT 
	Student.studcardid AS Student_studcardid, 
	Student.age AS Person_age, Student.name AS Person_name, 
	Student.scholarship AS PhdStudent_scholarship, 
	OidObject.CLASSNAME AS CLASSNAME, OidObject.OID AS OID, OidObject.SERIALID AS SERIALID 
FROM Student INNER JOIN OidObject ON (Student.OID = OidObject.OID) 
WHERE OidObject.CLASSNAME IN ('::PhdStudent'));

CREATE VIEW Student_PV AS (
SELECT 
	Student.studcardid AS Student_studcardid, 
	Student.age AS Person_age, Student.name AS Person_name, 
	OidObject.CLASSNAME AS CLASSNAME, OidObject.OID AS OID, OidObject.SERIALID AS SERIALID 
FROM Student INNER JOIN OidObject ON (Student.OID = OidObject.OID));

CREATE VIEW Person_PV AS (
SELECT 
	Person.age AS Person_age, Person.name AS Person_name, 
	OidObject.CLASSNAME AS CLASSNAME, OidObject.OID AS OID, OidObject.SERIALID AS SERIALID 
FROM Person INNER JOIN OidObject ON (Person.OID = OidObject.OID) 
UNION ALL 
SELECT 
	Student.age AS Person_age, Student.name AS Person_name, 
	OidObject.CLASSNAME AS CLASSNAME, OidObject.OID AS OID, OidObject.SERIALID AS SERIALID 
FROM Student INNER JOIN OidObject ON (Student.OID = OidObject.OID));

CREATE VIEW OidObject_PV AS (SELECT * FROM OidObject);

ADT mapping is set on all classes. ADT hierarchy root is OidObject.

iopc::OidObject[db.mapping.type];string;object
::Person[db.mapping.type];string;object
::Student[db.mapping.type];string;object
::PhdStudent[db.mapping.type];string;object
::Employee[db.mapping.type];string;object
iopc::EString[db.type.length];int;50
CREATE SEQUENCE OIDSEQ MINVALUE 1 START WITH 1 INCREMENT BY 1 CACHE 20 NOCYCLE;
CREATE SEQUENCE SERIALSEQ MINVALUE 1 START WITH 1 INCREMENT BY 1 CACHE 20 NOCYCLE;

CREATE OR REPLACE TYPE tOidObject AS OBJECT ( 
	OID NUMBER(10), CLASSNAME VARCHAR2(1000), SERIALID NUMBER(10), 
	STATIC PROCEDURE insert_object(p_OID NUMBER, p_CLASSNAME VARCHAR2, p_SERIALID NUMBER), 
	STATIC PROCEDURE update_object(p_OID NUMBER, p_CLASSNAME VARCHAR2, p_SERIALID NUMBER), 
	STATIC PROCEDURE delete_object(p_OID NUMBER) ) NOT FINAL;

CREATE TABLE OidObject OF tOidObject ( 
  CONSTRAINT OidObject_pk  PRIMARY KEY (OID) );

CREATE OR REPLACE TYPE BODY tOidObject AS 
	STATIC PROCEDURE insert_object(p_OID NUMBER, p_CLASSNAME VARCHAR2, p_SERIALID NUMBER) IS 
		BEGIN INSERT INTO OidObject VALUES(tOidObject(p_OID, p_CLASSNAME, p_SERIALID)); END; 
	STATIC PROCEDURE update_object(p_OID NUMBER, p_CLASSNAME VARCHAR2, p_SERIALID NUMBER) IS 
		BEGIN UPDATE OidObject X SET VALUE(X) = NEW tOidObject(p_OID, p_CLASSNAME, p_SERIALID) WHERE X.OID = p_OID; END; 
	STATIC PROCEDURE delete_object(p_OID NUMBER) IS 
		BEGIN DELETE FROM OidObject WHERE OID = p_OID; END; END;

CREATE INDEX OidObject_idxcn ON OidObject (CLASSNAME);

CREATE OR REPLACE TYPE tPerson UNDER tOidObject ( 
	age NUMBER(5), name VARCHAR2(50), 
	STATIC PROCEDURE insert_object(p_OID NUMBER, p_CLASSNAME VARCHAR2, p_SERIALID NUMBER, p_age NUMBER, p_name VARCHAR2), 
	STATIC PROCEDURE update_object(p_OID NUMBER, p_CLASSNAME VARCHAR2, p_SERIALID NUMBER, p_age NUMBER, p_name VARCHAR2), 
	STATIC PROCEDURE delete_object(p_OID NUMBER) ) NOT FINAL;
	
CREATE OR REPLACE TYPE BODY tPerson AS 
	STATIC PROCEDURE insert_object(p_OID NUMBER, p_CLASSNAME VARCHAR2, p_SERIALID NUMBER, p_age NUMBER, p_name VARCHAR2) IS BEGIN 
		INSERT INTO OidObject VALUES(tPerson(p_OID, p_CLASSNAME, p_SERIALID, p_age, p_name)); END; 
	STATIC PROCEDURE update_object(p_OID NUMBER, p_CLASSNAME VARCHAR2, p_SERIALID NUMBER, p_age NUMBER, p_name VARCHAR2) IS BEGIN 
		UPDATE OidObject X SET VALUE(X) = NEW tPerson(p_OID, p_CLASSNAME, p_SERIALID, p_age, p_name) WHERE X.OID = p_OID; END; 
	STATIC PROCEDURE delete_object(p_OID NUMBER) IS BEGIN 
		DELETE FROM OidObject WHERE OID = p_OID; END; END;
		
CREATE OR REPLACE TYPE tStudent UNDER tPerson ( studcardid VARCHAR2(50), 
	STATIC PROCEDURE insert_object(p_OID NUMBER, p_CLASSNAME VARCHAR2, p_SERIALID NUMBER, p_age NUMBER, p_name VARCHAR2, p_studcardid VARCHAR2), 
	STATIC PROCEDURE update_object(p_OID NUMBER, p_CLASSNAME VARCHAR2, p_SERIALID NUMBER, p_age NUMBER, p_name VARCHAR2, p_studcardid VARCHAR2), 
	STATIC PROCEDURE delete_object(p_OID NUMBER) ) NOT FINAL;
	
CREATE OR REPLACE TYPE BODY tStudent AS 
	STATIC PROCEDURE insert_object(p_OID NUMBER, p_CLASSNAME VARCHAR2, p_SERIALID NUMBER, p_age NUMBER, p_name VARCHAR2, p_studcardid VARCHAR2) IS BEGIN 
		INSERT INTO OidObject VALUES(tStudent(p_OID, p_CLASSNAME, p_SERIALID, p_age, p_name, p_studcardid)); END; 
	STATIC PROCEDURE update_object(p_OID NUMBER, p_CLASSNAME VARCHAR2, p_SERIALID NUMBER, p_age NUMBER, p_name VARCHAR2, p_studcardid VARCHAR2) IS BEGIN 
		UPDATE OidObject X SET VALUE(X) = NEW tStudent(p_OID, p_CLASSNAME, p_SERIALID, p_age, p_name, p_studcardid) WHERE X.OID = p_OID; END; 
	STATIC PROCEDURE delete_object(p_OID NUMBER) IS BEGIN 
		DELETE FROM OidObject WHERE OID = p_OID; END; END;
		
CREATE OR REPLACE TYPE tPhdStudent UNDER tStudent ( scholarship NUMBER(5), 
	STATIC PROCEDURE insert_object(p_OID NUMBER, p_CLASSNAME VARCHAR2, p_SERIALID NUMBER, p_age NUMBER, p_name VARCHAR2, p_studcardid VARCHAR2, p_scholarship NUMBER), 
	STATIC PROCEDURE update_object(p_OID NUMBER, p_CLASSNAME VARCHAR2, p_SERIALID NUMBER, p_age NUMBER, p_name VARCHAR2, p_studcardid VARCHAR2, p_scholarship NUMBER), 
	STATIC PROCEDURE delete_object(p_OID NUMBER) ) NOT FINAL;
	
CREATE OR REPLACE TYPE BODY tPhdStudent AS 
	STATIC PROCEDURE insert_object(p_OID NUMBER, p_CLASSNAME VARCHAR2, p_SERIALID NUMBER, p_age NUMBER, p_name VARCHAR2, p_studcardid VARCHAR2, p_scholarship NUMBER) IS BEGIN 
		INSERT INTO OidObject VALUES(tPhdStudent(p_OID, p_CLASSNAME, p_SERIALID, p_age, p_name, p_studcardid, p_scholarship)); END; 
	STATIC PROCEDURE update_object(p_OID NUMBER, p_CLASSNAME VARCHAR2, p_SERIALID NUMBER, p_age NUMBER, p_name VARCHAR2, p_studcardid VARCHAR2, p_scholarship NUMBER) IS BEGIN 
		UPDATE OidObject X SET VALUE(X) = NEW tPhdStudent(p_OID, p_CLASSNAME, p_SERIALID, p_age, p_name, p_studcardid, p_scholarship) WHERE X.OID = p_OID; END; 
	STATIC PROCEDURE delete_object(p_OID NUMBER) IS BEGIN 
		DELETE FROM OidObject WHERE OID = p_OID; END; END;
		
CREATE OR REPLACE TYPE tEmployee UNDER tPerson ( salary NUMBER(10), 
	STATIC PROCEDURE insert_object(p_OID NUMBER, p_CLASSNAME VARCHAR2, p_SERIALID NUMBER, p_age NUMBER, p_name VARCHAR2, p_salary NUMBER), 
	STATIC PROCEDURE update_object(p_OID NUMBER, p_CLASSNAME VARCHAR2, p_SERIALID NUMBER, p_age NUMBER, p_name VARCHAR2, p_salary NUMBER), 
	STATIC PROCEDURE delete_object(p_OID NUMBER) ) NOT FINAL;
	
CREATE OR REPLACE TYPE BODY tEmployee AS 
	STATIC PROCEDURE insert_object(p_OID NUMBER, p_CLASSNAME VARCHAR2, p_SERIALID NUMBER, p_age NUMBER, p_name VARCHAR2, p_salary NUMBER) IS BEGIN 
		INSERT INTO OidObject VALUES(tEmployee(p_OID, p_CLASSNAME, p_SERIALID, p_age, p_name, p_salary)); END; 
	STATIC PROCEDURE update_object(p_OID NUMBER, p_CLASSNAME VARCHAR2, p_SERIALID NUMBER, p_age NUMBER, p_name VARCHAR2, p_salary NUMBER) IS BEGIN 
		UPDATE OidObject X SET VALUE(X) = NEW tEmployee(p_OID, p_CLASSNAME, p_SERIALID, p_age, p_name, p_salary) WHERE X.OID = p_OID; END; 
	STATIC PROCEDURE delete_object(p_OID NUMBER) IS BEGIN 
		DELETE FROM OidObject WHERE OID = p_OID; END; END;
		
CREATE VIEW OidObject_SV AS (
SELECT 
	TREAT(VALUE(X) AS tOidObject).OID AS OID, TREAT(VALUE(X) AS tOidObject).CLASSNAME AS CLASSNAME, TREAT(VALUE(X) AS tOidObject).SERIALID AS SERIALID 
FROM OidObject X 
WHERE X.CLASSNAME = 'iopc::OidObject');

CREATE VIEW Person_SV AS (
SELECT 
	TREAT(VALUE(X) AS tPerson).OID AS OID, 
	TREAT(VALUE(X) AS tPerson).age AS Person_age, TREAT(VALUE(X) AS tPerson).name AS Person_name, 
	TREAT(VALUE(X) AS tPerson).CLASSNAME AS CLASSNAME, TREAT(VALUE(X) AS tPerson).SERIALID AS SERIALID 
FROM OidObject X WHERE X.CLASSNAME = '::Person');

CREATE VIEW Student_SV AS (
SELECT 
	TREAT(VALUE(X) AS tStudent).OID AS OID, 
	TREAT(VALUE(X) AS tStudent).studcardid AS Student_studcardid, TREAT(VALUE(X) AS tStudent).age AS Person_age, TREAT(VALUE(X) AS tStudent).name AS Person_name, 
	TREAT(VALUE(X) AS tStudent).CLASSNAME AS CLASSNAME, TREAT(VALUE(X) AS tStudent).SERIALID AS SERIALID 
FROM OidObject X WHERE X.CLASSNAME = '::Student');

CREATE VIEW PhdStudent_SV AS (
SELECT 
	TREAT(VALUE(X) AS tPhdStudent).OID AS OID, 
	TREAT(VALUE(X) AS tPhdStudent).scholarship AS PhdStudent_scholarship, 
	TREAT(VALUE(X) AS tPhdStudent).studcardid AS Student_studcardid, TREAT(VALUE(X) AS tPhdStudent).age AS Person_age, TREAT(VALUE(X) AS tPhdStudent).name AS Person_name, 
	TREAT(VALUE(X) AS tPhdStudent).CLASSNAME AS CLASSNAME, TREAT(VALUE(X) AS tPhdStudent).SERIALID AS SERIALID 
FROM OidObject X WHERE X.CLASSNAME = '::PhdStudent');

CREATE VIEW Employee_SV AS (
SELECT 
	TREAT(VALUE(X) AS tEmployee).OID AS OID, 
	TREAT(VALUE(X) AS tEmployee).salary AS Employee_salary, 
	TREAT(VALUE(X) AS tEmployee).age AS Person_age, TREAT(VALUE(X) AS tEmployee).name AS Person_name, 
	TREAT(VALUE(X) AS tEmployee).CLASSNAME AS CLASSNAME, TREAT(VALUE(X) AS tEmployee).SERIALID AS SERIALID 
FROM OidObject X WHERE X.CLASSNAME = '::Employee');

CREATE VIEW Employee_PV AS (
SELECT 
	TREAT(VALUE(X) AS tEmployee).OID AS OID, 
	TREAT(VALUE(X) AS tEmployee).salary AS Employee_salary, 
	TREAT(VALUE(X) AS tEmployee).age AS Person_age, TREAT(VALUE(X) AS tEmployee).name AS Person_name, 
	TREAT(VALUE(X) AS tEmployee).CLASSNAME AS CLASSNAME, TREAT(VALUE(X) AS tEmployee).SERIALID AS SERIALID 
FROM OidObject X WHERE VALUE(X) IS OF (tEmployee));

CREATE VIEW PhdStudent_PV AS (
SELECT 
	TREAT(VALUE(X) AS tPhdStudent).OID AS OID, 
	TREAT(VALUE(X) AS tPhdStudent).scholarship AS PhdStudent_scholarship, 
	TREAT(VALUE(X) AS tPhdStudent).studcardid AS Student_studcardid, TREAT(VALUE(X) AS tPhdStudent).age AS Person_age, TREAT(VALUE(X) AS tPhdStudent).name AS Person_name, 
	TREAT(VALUE(X) AS tPhdStudent).CLASSNAME AS CLASSNAME, TREAT(VALUE(X) AS tPhdStudent).SERIALID AS SERIALID 
FROM OidObject X WHERE VALUE(X) IS OF (tPhdStudent));

CREATE VIEW Student_PV AS (
	SELECT TREAT(VALUE(X) AS tStudent).OID AS OID, 
	TREAT(VALUE(X) AS tStudent).studcardid AS Student_studcardid, TREAT(VALUE(X) AS tStudent).age AS Person_age, TREAT(VALUE(X) AS tStudent).name AS Person_name, 
	TREAT(VALUE(X) AS tStudent).CLASSNAME AS CLASSNAME, TREAT(VALUE(X) AS tStudent).SERIALID AS SERIALID 
FROM OidObject X WHERE VALUE(X) IS OF (tStudent));

CREATE VIEW Person_PV AS (
	SELECT TREAT(VALUE(X) AS tPerson).OID AS OID, 
	TREAT(VALUE(X) AS tPerson).age AS Person_age, TREAT(VALUE(X) AS tPerson).name AS Person_name, 
	TREAT(VALUE(X) AS tPerson).CLASSNAME AS CLASSNAME, TREAT(VALUE(X) AS tPerson).SERIALID AS SERIALID 
FROM OidObject X WHERE VALUE(X) IS OF (tPerson));

CREATE VIEW OidObject_PV AS (SELECT * FROM OidObject);

There is a problem in Oracle 10g in execution of porymorphic views belonging to classes that use ADT mapping. In some scenarios the predicate WHERE VALUE(X) IS OF (tType) AND (X.Property_of_Type_tType oper Value) is evaluated incorrectly and no rows are returned from those queries regardless if part of the query is hidden in the view or not. For this reason the following global setting can be used:

globals[db.oracle.workaround.10gOO];bool;true

When the workaround is enabled, the WHERE clause in Polymorphic views is generated in the following way:

WHERE X.OID IN (SELECT Y.OID FROM OidObject Y WHERE VALUE(Y) IS OF(tType))

The problem is fixed in Oracle 11g.