Casting in expressions
SYNTAX:
primary = literal | ( [ cast ] qualifiable_factor { qualifier } ) .
cast = ?{? simple_types | entity_id | type_id ?}? .
Expressions may be cast to a specific data type by using a cast operator. To do this, the expression is preceded by the casting operator, i.e. the cast data type in braces. The following defines the legal cases for casting:
Cast to simple data types:
The value to be casted must be a specialization or a generalization of the cast data type.
Casting to a defined data type:
Untyping of typed data:
Typed data may be casted to unptyped by means of the XPXUNTYPED keyword, e.g. untypedValue := {XPXUNTYPED}typedValue;
Casting to a defined data type is only possible when a function with the same name as the cast data type is defined in the same mapping schema, i.e., casting to a defined type is done by means of an implicit call to a function. This function should perform the actual data conversion specified by the cast operator. Moreover, this function must have one formal parameter that is type compatible with the data type to be cast, and the function value must be compatible with the cast type.
Casting to entity types:
Casting to entity types implies implicit map call. Casting is only possible if there exist a MAP declaration in the same mapping schema that has exactly one map entity defined and exactly one extended entity reference in the FROM clause. The map entity type must be exactly the same type as the cast type. The extended entity reference in the FROM clause must be exactly the same type as the type to be cast, or be a subtype in case the extended entity reference in the FROM clause is preceded by the SUBTYPE keyword.
When the called map has already been executed with the instance given as argument in the implicit map call, i.e. the instance to be cast, then the map call is returning the map instance created in the first invocation of the map with the same source instance. This feature will avoid duplicated map instances from the same source instance.
If more than one MAP declaration matches the same cast operation, then an error message is issued.
Â
Example on casting:
Â
SCHEMA cast_source;
TYPE SEX = ENUMERATION OF Â Â Â Â Â (male,female);
END_TYPE;
Â
ENTITY anEntity;
 AnInt   : INTEGER;
 ANumber  : NUMBER;
 AReal   : REAL;
 ABoolean : BOOLEAN;
 AString  : STRING;
 ALogical : LOGICAL;
END_ENTITY;
Â
ENTITY adult;
 person : person;
END_ENTITY;
Â
ENTITY person;
 Sex    : sex;
 surname   : string;
 given_name  : string;
 birthday  : string;
END_ENTITY;
Â
ENTITY man
 SUBTYPE OF (person);
 wife : OPTIONAL woman;
END_ENTITY;
Â
ENTITY woman
 SUBTYPE OF (person);
 husband : OPTIONAL man;
END_ENTITY;
END_SCHEMA;
Â
Â
SCHEMA cast_target;
TYPE SEX = ENUMERATION OFÂ (male,female);
END_TYPE;
Â
ENTITY anEntity;
 AnInt   : INTEGER;
 aNumber  : NUMBER;
 aReal   : REAL;
 aBoolean : BOOLEAN;
 aString  : STRING;
 aLogical : LOGICAL;
END_ENTITY;
Â
ENTITY human_being;
 Man  : OPTIONAL man;
 woman : OPTIONAL woman;
END_ENTITY;
ENTITY man;
 Sex    : sex;
 surname   : string;
 given_name  : string;
 birthday  : string;
 wife    : OPTIONAL woman;
END_ENTITY;
ENTITY woman;
 Sex    : sex;
 surname   : string;
 given_name  : string;
 birthday  : string;
 husband   : OPTIONAL man;
END_ENTITY;
END_SCHEMA;
Â
Â
Â
Â
(* Example of CAST and MAP Calls *)
SCHEMA_MAP Casting;
Â
GLOBAL
 DECLARE ss INSTANCE OF SOURCE_SCHEMA cast_source;
 DECLARE ds INSTANCE OF TARGET_SCHEMA cast_target;
END_GLOBAL;
Â
CONSTANT
 Real_Constant : REAL := 3.14;
END_CONSTANT;
Â
MAP One FOR v:ds::AnEntity;
FROM (b:ss::AnEntity)
WHEN (TRUE);
BEGIN_MAP
 anInt := {Integer} b.anInt;         (* Simple Cast *)
 anInt := {Integer} b.aNumber;        (* Simple Cast *)
 anInt := {Integer} b.aReal;         (* Simple Cast *)
 anInt := {Integer} Real_Constant;       (* Simple Cast *)
 anInt := {Integer} b.anInt + {Integer} b.aReal; (* Simple Cast *)
 aReal := {Real} b.anInt;          (* Simple Cast *)
 anInt := 2 * {Integer} aReal;        (* Simple Cast *)
END_MAP;
Â
MAP Human_Being_From_Adult FOR v:ds::Human_Being;
FROM (b:ss::Adult)
WHEN (TRUE);
BEGIN_MAP
 IF b.Person.Sex = MALE THEN
  v.Man := {Man} b.Person;       (* Implicit MAP Call *)
  v.Man := Man_From_Person(b.Person);   (* Explicit MAP Call *)
 ELSE
  v.Woman := {Woman} b.person;      (* Implicit MAP Call *)
  v.Woman := Woman_From_Person(b.Person); (* Explicit MAP Call *)
 END_IF;
END_MAP;
Â
MAP Man_From_Person FOR v:ds::Man;
FROM (b:ss::Person)
WHEN (b.Sex = MALE);
BEGIN_MAP
 v.Sex    := MALE;
 Surname   := Surname;
 Given_Name  := Given_Name;
 Birthday  := Birthday;
END_MAP;
Â
MAP Woman_From_Person FOR v:ds::Woman;
FROM (b:ss::Person)
WHEN (b.sex = FEMALE);
BEGIN_MAP
(* Type Cast, calling Function named Sex *)
 v.Sex    := {Sex} FEMALE;
 Surname   := Surname;
 Given_Name  := Given_Name;
 Birthday  := Birthday;
END_MAP;
Â
FUNCTION Sex (EnumElement : ss::Sex) : ds::Sex;
 Return(EnumElement);
END_FUNCTION;
Â
END_SCHEMA_MAP;