The SIRA_PRISE command language |
The actual commands of the languageIn this section, the SIRA_PRISE commands are presented along with a detailed explanation of their operation. Any pertinent remarks regarding some syntactical category of the grammar will also be presented here. <SiraPriseCommand> := <Add>|<Delete>|<Update>|<Inquire>|<MultipleAssignment>+When communicating with a SIRA_PRISE server at the lowest possible level (i.e. without using packages such as the provided java client package), then commands must be sent to the server as a text string, formatted according to the rules of the grammar. Any command must be one of the categories mentioned in the formal grammar. These will be explained in detail in the pertinent sections below. All applicable constraints (= all database constraints that might possibly get violated as a consequence of carrying out the given command) are checked after all the insert/delete operations have been done. If a constraint violation is detected, the statement is completely undone. No automatic rollback is done for the entire transaction in which the statement was carried out. If (the detection of) a constraint violation must result in a rollback for the entire transaction, then it is up to the user to issue a rollback message to the server. <Add> := ASSERT|ADD|CREATE <RelvarName>,<RelationalExpression>
ADD will raise an exception if a tuple is added that is already present in the (body of the relation value currently held in the) updated relvar. The counterpart of ADD that does not raise an exception in that circumstance is ASSERT. In all other respects, ASSERT is identical to ADD. CREATE is a purely syntactical alias for ADD.
For relvars with at least one interval-typed attribute, this rule with respect to ADD is to be interpreted for each point of the interval individually. E.g. adding
If a relvar has interval-typed attributes, ADD will attempt to combine multiple tuples into one, whilst maintaining the same "informational value" within the database. In the above example, the result of the assertion would not be a relation of cardinality 2 in R, but instead the singleton
This rule is applied irrespective of the number of interval-typed attributes in the updated relvar
<Delete> := UNASSERT|DELETE|REMOVE <RelvarName>,<RelationalExpression>
DELETE will raise an exception if an attempt is made to remove a tuple from the (body of the relation value currently held in the) updated relvar, and that tuple is not there. The counterpart of DELETE that does not raise an exception in that situation is UNASSERT. In all other respects, UNASSERT is identical to DELETE. REMOVE is a purely syntactical alias for DELETE.
For relvars with at least one interval-typed attribute, this rule with respect to DELETE is to be interpreted for each point of the interval individually. E.g. deleting
Like with ADD, DELETE/UNASSERT will do the best it can to make the relation value after the update "as dense as possible". This is relevant in the case where the relvar has >1 interval-typed attribute. Using a somewhat more concise notation for the interval values, consider a relvar R with value
<Update> := UPDATE|MODIFY <RelvarName>,<RelationalExpression>,(<UpdateExpression>+)
<UpdateExpression> := <AttributeName>(<Expression>)
|
TYPE | DBMSFILE | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
This value selector selects a singleton relation value of degree two, with the two attributes named 'TYPE' and 'DBMSFILE'. Both attributes are relation-typed. The TYPE attribute has relation values of degree 1, with a single attribute named 'TYPENAME', the DBMSFILE attribute has relation values of degree two, with attributes 'FILENAME' and 'PAGESIZE'. The two attribute values in the singleton relation (the overall expression) are equal to the current value of the TYPE and DBMSFILE relvars of the database, this being achieved with relvar references as the expressions inside the tuple/attribute value selectors.
BTW : this example illustrates how a database can theoretically be seen, in its entirety, as a single tuple with as many relation-typed attributes as there are relvars in the database.
Relational operator invocations are invocations of one of the 19 operators supported by SIRA_PRISE.
JOIN is the 'natural join' operator on relations. The operator is associative, meaning that it is possible to give more than two relations as an argument. Theoretically, the syntax could also provide for monadic and niladic invocations of JOIN (i.e. joins on only one relation and joins on no relation at all), but SIRA_PRISE doesn't support that. The observation that for all R, JOIN(R) = R, and that JOIN() = TABLE_DEE should suffice as an explanation why. We prefer to spend our time trying to solve problems that are a bit more 'real', such as the following :
Allthough SIRA_PRISE is able to find the best evaluation strategy for joins between two arguments, it is not able to do so for joins that have >2 arguments. So the order in which the arguments are listed in an associative join invocation, can significantly impact performance. For good performance, the user is required to write the arguments that "join well" close to one another, and this, perhaps counterintuitively, AT THE END of the list of join arguments. Fortunately, this is about the only bad news there is to mention about (SIRA_PRISE's implementation of) JOIN.
For the formal details of the JOIN operator, please refer to The operator's javadoc.
For an introductory explanation and examples, please refer to the relevant section in the introduction to the relational algebra.
Like JOIN, UNION too is an associative operator. Once again, allthough it would be theoretically possible to support monadic and niladic invocations of this operator, SIRA_PRISE doesn't do that. For all R, UNION(R) = R and UNION() = RELATION(HEADING(...)BODY()) (i.e. the empty relation of the appropriate type).
For the formal details of the UNION operator, please refer to The operator's javadoc.
For an introductory explanation and examples, please refer to the relevant section in the introduction to the relational algebra.
For this associative operator, the same remark applies as for JOIN and UNION : monadic and niladic invocations of the operator are not supported. INTERSECT(R) = R for all R, and INTERSECT() =
RELATION(HEADING(...)BODY(TUPLE(...)...))
, with the relation body growing beyond any computer's memory capacity for all but the simplest relation types.
For the formal details of the INTERSECT operator, please refer to The operator's javadoc.
For an introductory explanation and examples, please refer to the relevant section in the introduction to the relational algebra.
For the formal details of the MINUS operator, please refer to The operator's javadoc.
For an introductory explanation and examples, please refer to the relevant section in the introduction to the relational algebra.
XMINUS is the operator that implements the operation known as 'symmetrical difference'. For the formal details of the XMINUS operator, please refer to The operator's javadoc.
It also happens to be the case that this operator is associative. Hence the same remark applies as for JOIN ,UNION and INTERSECT : monadic and niladic invocations of the operator are not supported. XMINUS(R) = R for all R, and XMINUS() =
RELATION(HEADING(...)BODY())
. However, unlike the other associative relational operators, it is also currently not possible to use XMINUS as the aggregation operator in an AGGREGATE invocation that aggregates over relation-valued attributes. This may be fixed in a future release, but we don't regard this issue as very pressing.
(Consider the "meaning" of some tuple appearing in the result of such an "associative" (i.e. >2 arguments) XMINUS invocation : it means that the tuple appeared in any odd number of the XMINUS arguments, but you don't know whether it appeared in 1 or 3 or ... of the arguments, and of course you don't know in
which of them. It doesn't seem like a very useful thing with a compelling need to support it.)
For an introductory explanation and examples, please refer to the relevant section in the introduction to the relational algebra.
In TTM, the name for the SEMIJOIN operator has recently changed to MATCHING. We prefer to stick with the old names, primarily because the new name for SEMIJOIN's counterpart, SEMIMINUS, includes the word 'NOT' in its new name, which we feel is a word that doesn't belong in names. No piece of furniture is called 'NOT TABLE', no photographer's monopod is called 'NOT TRIPOD', no president of the US is called 'NOT BUSH', no birdwatcher's telescope is called 'NOT BINOCULARS', the boolean value that means "not true" is not called 'NOT TRUE', etc. etc. Other than this psychological naming issue, there is no difference between SIRA_PRISE's SEMIJOIN and TTM's MATCHING.
For the formal details of the SEMIJOIN operator, please refer to The operator's javadoc.
For an introductory explanation and examples, please refer to the relevant section in the introduction to the relational algebra.
SEMIMINUS corresponds to TTM's NOT MATCHING operator. As already indicated, the word 'NOT' in that name is the reason why SIRA_PRISE doesn't follow TTM's recent rename of these operators.
For the formal details of the SEMIMINUS operator, please refer to The operator's javadoc.
For an introductory explanation and examples, please refer to the relevant section in the introduction to the relational algebra.
SIRA_PRISE also supports a LEFTJOIN operator. For the formal details of this LEFTJOIN operator, please refer to The operator's javadoc.
For an introductory explanation and examples, please refer to the relevant section in the introduction to the relational algebra.
SIRA_PRISE also supports TTM's RENAME operator. For the formal details of this RENAME operator, please refer to The operator's javadoc.
For an introductory explanation and examples, please refer to the relevant section in the introduction to the relational algebra.
SIRA_PRISE also supports the projection operator of the relational algebra. For the formal details of this PROJECT operator, please refer to The operator's javadoc.
For an introductory explanation and examples, please refer to the relevant section in the introduction to the relational algebra.
SIRA_PRISE also supports the EXTEND operator of the relational algebra defined in TTM. For the formal details of this EXTEND operator, please refer to The operator's javadoc.
For an introductory explanation and examples, please refer to the relevant section in the introduction to the relational algebra.
EXTEND(RESTRICT(TYPEPROPERTIES,ISSCALAR),(SIZERANGE(INTINTERVAL(BEGIN(MINIMUMSIZE)END(PLUS(MAXIMUMSIZE,INT(1)))))))
SIRA_PRISE supports an operator that combines the functionality of EXTEND, PROJECT and RENAME, called TRANSFORM. For the formal details of this operator, please refer to The operator's javadoc.
For an introductory explanation and examples, please refer to the relevant section in the introduction to the relational algebra.
SIRA_PRISE also supports the restriction operator of the relational algebra (in fact a slightly extended version of it). For the formal details of this RESTRICT operator, please refer to The operator's javadoc.
For an introductory explanation and examples, please refer to the relevant section in the introduction to the relational algebra.
SIRA_PRISE supports an operator that performs basic transitive closure. For the formal details of this TCLOSE operator, please refer to The operator's javadoc.
For an introductory explanation and examples, please refer to the relevant section in the introduction to the relational algebra.
From the syntax, observe in particular that the degenerate case of an "empty attribute matching list" is not supported.
SIRA_PRISE supports an operator that performs generalized transitive closure. For the formal details of this GTCLOSE operator, please refer to The operator's javadoc.
For an introductory explanation and examples, please refer to the relevant section in the introduction to the relational algebra.
As with "simple" TCLOSE, observe in particular that the degenerate case of an "empty attribute matching list" is not supported.
The process of generalized transitive closure involves matching two distinct tuples from a relation with each other, and when two tuples are matched, constructing a third tuple for inclusion in the result. This will involve evaluating the given expressions in the <GTcloseDef>. In many cases, the expressions
will need to reference the attribute values of both of the tuples that were matched. Using simply an attribute name isn't sufficient to make that distinction, since both tuples come from the same relation, thus they both have the same heading, thus they both have the same attributes, thus a simple attribute name
reference is ambiguous. A "special" syntactic device is used to make the needed distinction inside expressions that make up a <GTcloseDef> : when referencing the tuple whose "child" attributes matched (this is the tuple that has the "grandparent" for parent), prefix its attribute names with
__L__
, when referencing the tuple whose "parent" attributes matched (this is the tuple that has the "grandchild" for child), prefix its attribute names with
__R__
.
Example :
GTCLOSE(EXTEND(VIRTUALRELVARREFERENCES,EDGECNT(INT(1))),(RELVARNAME,REFERENCEDRELVARNAME),(EDGECNT(PLUS(__L__EDGECNT,__R__EDGECNT))))
For an explanation and examples of this operator, we refer to TTM.
SIRA_PRISE supports an operator that performs TTM's GROUPing operation. For the formal details of this GROUP operator, please refer to The operator's javadoc.
For an introductory explanation and examples, please refer to the relevant section in the introduction to the relational algebra.
SIRA_PRISE supports an operator that performs TTM's UNGROUPing operation. For the formal details of this UNGROUP operator, please refer to The operator's javadoc.
For an introductory explanation and examples, please refer to the relevant section in the introduction to the relational algebra.
The ungroup operator is, at present, restricted to the ungrouping of at most one relation-typed attribute. TTM is not entirely clear as to how ungroup should proceed in the event of multiple ungroup attributes under certain peculiar conditions (particularly in the event of name-clashes between the attributes of the relation-typed attributes to be ungrouped).
SIRA_PRISE supports a form of generic aggregations that are cast in a relational jacket, in the form of its AGGREGATE operator. For the formal details of this AGGREGATE operator, please refer to The operator's javadoc.
For an introductory explanation and examples, please refer to the relevant section in the introduction to the relational algebra.
SIRA_PRISE also supports a "more complicated" form of generic aggregations in the form of its SUMMARIZEBY operator. This SUMMARIZEBY operator is in fact identical to TTM's, but it may be a bit hard to see because of the great syntactic differences between SIRA_PRISE's expression language and TTM's (Tutorial D). Note that currently, there is no equivalent in SIRA_PRISE for TTM's SUMMARIZE operator (which has the additional PER construct). <RelationalExpression> is the relational expression to be summarized, the <AttributeName>s constitute the "grouping key" in the summary, and the <AggregationDef>s define which summaries are requested. For the formal details of this SUMMARIZEBY operator, please refer to The operator's javadoc.
For an introductory explanation and examples, please refer to the relevant section in the introduction to the relational algebra.
If relations involved interval-typed attributes, then previous SIRA_PRISE versions guaranteed that relations produced by relation value selectors, relational operator invocations, ... were always in some packed form. However, if >1 interval-typed attributes were involved, then there was no way to control which particular packed form was chosen. And because the result from PACKing first on X, then on Y will typically not be exactly the same relation as that produced by PACKing first on Y then X (refer to TDATRM/TaRT for further detail and examples), it meant certain relational operator invocations were arguably not fully 100% deterministic.
The now explicitly exposed PACK operator remedies this, by letting the user specify the exact ordering of the PACK attributes in the AttributeName List. All attributes named in the second argument must obviously be interval-typed.
Note that SIRA_PRISE does continue to always (with one exception, see next section) produce relation results that are in packed form. Moreover, the results produced in these cases has also been made deterministic by always taking lexicographical ordering for the PACK attributes.
For the formal details of this PACK operator, please refer to The operator's javadoc.
For an introductory explanation and examples, please refer to the relevant section in the introduction to the relational algebra.
For the formal details of the UNPACK operator, please refer to The operator's javadoc.
For an introductory explanation and examples, please refer to the relevant section in the introduction to the relational algebra.
Scalar expressions fall apart in the three categories indicated : scalar value selectors, invocations of scalar operators, and references to attribute names.
References to attribute names are obviously only valid if there is a scope in which those references can be resolved. Such scope is created by invocations of the relational operators RESTRICT, EXTEND, and AGGREGATE (which in turn implies that SUMMARIZEBY also creates scope, as SUMMARIZEBY builds on AGGREGATE).
INT(1)
), or else as a list of possrep component value specifications (e.g. DATE(D(...)M(...)Y(...))
). A Possrep component value specification is always introduced
by the possrep component name, followed by either a literal value (e.g. D(1)
) or else any scalar expression that evaluates to a value of the type of the named possrep component (e.g. D(INT(1))
or D(MAX(INT(1),SUB(X,5)))
).
Scalar operator expressions are introduced by the operator name, followed by the expressions denoting the operator invocation arguments.
The first six of these are names, and should obey the rules for valid SIRA_PRISE names :
The <LiteralValue> element is, obviously, subjected only to the rule that it must represent a valid value of the type of the value selector that it appears in.