An INSERT statement, unlike a SELECT statement, must specify a single target class. OPM-QL supports two distinct kinds of insert: a regular insert which, if successful, will always create a new object with a new oid, and INSERT AS statements, which extend an existing object to a new subclass.
A regular INSERT statement expresses the insertion of an instance into a class, and can specify values for all non-derived attributes of the class (including values for inherited attributes). An INSERT is required to specify values for any non-null attributes of a class.
If an INSERT statement inserts an object with oid x into a
class
, then it will also automatically insert objects with oid
x into any superclasses
of
. If such an insert causes any
integrity constraints to be violated then the insert will be rolled
back and fails. For example, if class
inherits a key attribute a
from class
, and we attempt to insert an object x into
,
where
already contains an object y with the same value as x
on the attribute a, then the insert would fail.
The value of an abstract attribute is represented by a class name together with values for an identifying set of attributes (a key). Multiple values assigned to a set or list valued attribute are enclosed within { }. Tuple attribute values are enclosed within ( ).
For example consider the classes SEQUENCE, PROJECT, ENTRY, and GEL_LANE of the OPM schema in Appendix A. The following INSERT statements inserts a new sequence into SEQUENCE and two entries into ENTRY:
INSERT SEQUENCE (
sequence_id = 101,
generated_by = PROJECT [project_id = 12],
length = 150,
entries = { ENTRY [entry_id = 1011], ENTRY [entry_id = 1012] },
gel_analysis = GEL_LANE [anal_tp = 'xxx']
);
INSERT ENTRY (
entry_id = 1011,
from_sequence = SEQUENCE [sequence_id = 101],
(begin_pos, end_pos) = (1, 100)
);
INSERT ENTRY (
entry_id = 1012,
from_sequence = SEQUENCE [sequence_id = 101],
(begin_pos, end_pos) = (101, 150)
);
Unlike a regular INSERT statement, an INSERT AS statement does not create a new object identity. Instead it inserts an object into its target class with the same oid as an object already present in a superclass. An INSERT AS statement must specify values for any required local attributes, and values for key attributes which are sufficient to identify an object of a superclass from which the object inserted can inherit. A INSERT AS statement may specify values for inherited attributes, but, in order for the insert to be valid, each value specified for an inherited attribute must agree with the existing values of the attributes for the object, unless the existing values of the attributes are Null .
For example suppose an object with oid x were in a class
and
an { INSERT AS statement was adding x to a class
, a
subclass of
. If
has an attribute a and the INSERT
AS statement specifies a value v for the (inherited) attribute a,
then the value of the a attribute of x in
must either be
Null or be v already in order for this insert to be valid.
Further an INSERT AS statement is required to specify values
for any required, inherited attributes that are not already determined
by existing instances of the object being inserted. For example
suppose
is a subclass of classes
and
, that x
is an object of class
which is not in
(or
), and that
has a required local attribute a. Then an INSERT AS
statement adding x to class
is required to specify a value for
the inherited attribute a as well as for any local required
attributes of
.
<INSERT query> ::= INSERT <class name> '(' <assign values> ')' ';'
| INSERT <class name> '(' <assign values> ')'
AS <an id value> ';'
;
<assign values> ::= <assign attribute values>
| <assign values> ',' <assign attribute values>
;
<assign attribute values> ::= <simple single assignment>
| <simple multi assignment>
| <tuple single assignment>
| <tuple multi assignment>
;
<simple single assignment> ::= <attribute name> '=' <attr value>
| <attribute name> '=' NULL
;
<id assignment> ::= <attribute name> '=' <a primitive value>
;
<attr value> ::= <a primitive value> | <an id value>
;
<a primitive value> ::= <integer> | <string> | <real>
;
<an id value> ::= <class name> '[' <id values> ']'
;
<id values> ::= <id assignment> | <id values> ',' <id assignment>
;
<simple multi assignment> ::= <attribute name> '='
'{' <multiple assignments> '}'
;
<multiple assignments> ::= <attr value>
| <multiple assignments> ',' <attr value>
;
<tuple single assignment> ::= '(' <component names> ')' '='
'(' <multiple assignments> ')'
| '(' <component names> ')' '=' NULL
;
<tuple multi assignment> ::= '(' <component names> ')' '='
'{' <multi comp assignments> '}'
;
<multi comp assignment> ::= '(' <multiple assignments> ')'
| <multi comp assignments> ','
'(' <multiple assignments> ')'
;
<component names> ::= <attribute name>
| <component names> ',' <attribute name>
;