Types
Objects are classified into types making each object an instance of one or several types. The set of all instances of a type is called the extent of the type. The types are organized in a supertype/subtype hierarchy. If an object is an instance of a type, then it is also an instance of all the supertypes of that type; conversely, the extent of a type is a subset of all extents of the supertypes of that type.
System types​
The following picture shows the type hierarchy for built-in system types:
The most general type in named Object
. All other types are below
Object
in the hierarchy. The arrows connecting two types in the
diagram should be read is a.
Literal types​
Literal objects are self-described system maintained objects that
are implicitly created or deleted by the system when needed. Literals
types such as numbers (type Number
), strings (type Charstring
),
Booleans (type Boolean
) or time stamps (Timeval
) are below type
Literal
in the type hierarchy. The type Number
can represent both
integers (type Integer
) and floating point numbers (type Real
).
The function typesig(o)
can be used to inspect the type signature
of object o
as a string specifying the type of o
. The following
expression exemplify type signatures of various kinds of literal objects:
typesig(123);
typesig(1.2);
typesig(-2.4e-21);
typesig(+inf);
typesig('Hello World');
typesig(|2023-09-21T09:45:44.086Z|);
typesig(true);
typesig(false);
typesig(null);
Collection types​
Collections (type Collection
) are objects containing collections
of other objects as elements. As literals, collections are
implicitly created and deleted by the system when needed. The
following kinds of collections are supported:
Collections of type
Bag
contain unordered sets of objects where duplicates are allowed. A set query return a bag as result.Type
Json
represent JSON collections that, more specifically:Collections of type
Vector
contain ordered sequences of objects of any kind. A vector query returns an collection of typeVector
as result.Collections of type
Record
represents key/value pairs.
Collections of type
Array
represent tensors and contain numerical values organized as a cube of arbitrary dimensionality. An array query returns an object of typeArray
as result.Type
Stream
represents a possibly infinite and growing sequence of objects, e.g. to represent continuous readings of sensor measurements. A stream query returns a stream as result.
Examples of collections:
bag(1,2,3);
[1,2,3];
[[1,2],[3,4]];
{"id":1,"name":"Kalle","age":32};
array([1,2,3]);
array([1.1,2.2,3.3]);
The type signatures of collections are often parameterized types with
format "type of
other type", for example:
typesig(bag(1,2,3));
typesig([1,2,3]);
typesig([[1,2],[3,4]]);
typesig({"id":1,"name":"Kalle","age":32});
typesig(array([1,2,3]));
typesig(array([1.1,2.2,3.3]));
Surrogate types​
Each instance of a surrogate type has an associated object identifier (OID). The surrogate objects are explicitly created or deleted by the user or the system. Examples of surrogate objects are objects representing real-world entities such as sensors, system objects such as functions, or even objects representing other SA Engine peers.
The types Type
, Function
, Userobject
and their subtypes are all
surrogate types.
The type
Userobject
is a place holder for user defined types used for organizing data in the local database. All user defined types are subtypes of typeUsertype
.The system type named
Type
represents the types themselves, such as their names, their supertypes, etc.The system type
Function
represents functions and their properties.
User defined types​
The create type
statement creates a new user defined type.
For examples:
create type Person;
create type Student under Person;
create type Teacher under Person;
The result of a create type
statement is a
surrogate
object
representing the so created type.
Type names are not case sensitive and the type names are always internally upper-cased. For clarity all type names used in examples in this manual have the first letter capitalized. Type names must be unique in the database.
The new type will be a subtype of all the supertypes in the under
clause.
If no supertypes are specified the new type becomes a subtype of the
system type named Userobject
.
After the type definitions above the type hierarchy around type
Userobject
will look like this:
Multiple inheritance is defined by specifying more than one supertype, for example:
create type TA under Student, Teacher;
Defining properties​
Properties of a type are defined as functions. The simplest kind of
functions are stored
functions,
which are tables stored in the local database. Let us add the
properties name
and income
to type Person
as stored functions:
create function name(Person p) -> Charstring
as stored;
create function income(Person p) -> Real
as stored;
Once types and functions are defined the database can be populated by creating new objects, for example:
create Person (name, income) instances
:venus ("Venus", 3500),
:serena ("Serena",3900)
The statement above
creates two new objects
of type Person
and binds the session
variables
:venus
and :serena
to those objects. It thereby sets values of
the stored functions name
and income
to the names and incomes of
:venus
and :serena
, respectively.
When the database is populated we can make simple queries by calling the new stored property functions, for example:
name(:venus);
income(:serena)
Deleting types​
The delete type
statement deletes a type and all its subtypes.
Example:
delete type Person;
If the deleted type has subtypes they will be deleted as well. In this
case Student
, Teacher
, and TA
and all theirs properties and
objects are deleted.