[
Table Of Contents
| Keyword Index
]
relvar(n) 0.8.5 ral "Relvar Operators"
relvar - Operators for Relation Variables
TABLE OF CONTENTS
SYNOPSIS
DESCRIPTION
RELVAR NAMES
CONSTRAINTS
COMMANDS
RELVAR TRACES
SEE ALSO
KEYWORDS
COPYRIGHT
package require ral ?0.8.5?
This manpage describes the relvar command.
The relvar command is part of the Tcl Relational Algebra Library
(ral) package.
TclRAL defines a variable space for relation variables.
Relation variables hold relation values and the subcommands of the
relvar command generally operate directly on the values storing
the results back into the relation variables.
For this reason, most of the relvar subcommands
take the name of a relation variable as an argument.
In the relational model as it applies to database management systems,
relation variables play the important role of
representing the persistent data base values.
Relation variables are the leaves of the
expression tree that perform the desired query and represent
the core data from which results may be computed.
That computation is usually expressed as a single, sometimes complex expression.
This allows for a non-procedural way of specifying the computation and
allows optimizers to find the most efficient manner of computing the result.
In the TclRAL implementation of the relational model,
relation variables serve a similar role although there
is no implicit persistence supplied by the library.
Relation values may be stored in Tcl variables like any other Tcl object.
This does abandon the non-procedural nature of relational expressions
as usually accomplished in the relational model, but is a better fit
to the Tcl way of doing things.
The namespace of relvar names follows the familiar Tcl method of naming
ordinary Tcl variables.
Thus relvars have Tcl namespace-like names.
For example, a relvar named Dog created at the global level
will be named ::Dog.
Thus it is possible and indeed encouraged to group related relvars
together in a namespace.
If an application uses only one set of relvars,
then the global namespace of relvars is most convenient.
Using several distinct sets of relvars is best accomplished if each
set is placed in their own relvar namespace.
Since it is possible to store a relation value in an ordinary Tcl variable
and since Tcl variables are convenient to use when formulating expressions,
creating a relvar also creates a corresponding Tcl variable by the same name.
The Tcl variable created is traced to prevent writing to it, since all
modifications to a relvar should come via the relvar commands.
So, creating a relvar name Dog at the global level creates a
relvar named ::Dog and a read-only Tcl variable named ::Dog.
TclRAL supports the notion of constraints as a means of
insuring integrity among a set of relvars.
There are many types of constraints that might be used to insure integrity,
but TclRAL supports three types of declarative constraints.
- Association
-
Association constraints define a referential association between two relvars.
In this context,
an association declares that a set of attributes in one relvar refers to
an identifier of another relvar.
Thus for all the tuples in a given relvar,
the given attribute values must match the corresponding attribute values
of the identifier of the associated relvar.
The association also declares the number of times that such matches may
occur and if it is allowed not to match at all.
- Partition
-
Partition constraints define a complete and disjoint
referential partitioning between one relvar,
known as the super set,
and a given set of relvars,
known as the sub sets.
This constraint declares that every tuple of the super set relvar is
referred to by exactly one tuple from among all the tuples in the
sub set relvars.
- Correlation
-
Correlation constraints define a referential association between two
relvars that is mediated by a third relvar.
The third relvar, the correlation relvar, contains attributes that
reference identifiers in the two associated relvars.
It is similar in some ways to two Association Constraints.
At the end of each ::ral::eval command (see below) or,
if outside of an eval command,
at the end of any command that modifies a relvar
that participates in a constraint,
all of the constraints defined for the modified relvars are evaluated.
If any of the constraints fail, the relvar modifications are discarded
and the relvar values are returned to the values they had before
the modifications.
Similarly,
during the creation of a constraint, the constraint is evaluated
on all the relvars associated with the constraint.
If the evaluation fails,
the constraint creation fails.
Like relvars, constraints have names.
Constraints names follow the same pattern as relvar names, i.e.
unresolved names are created in the current namespace.
Thus you are able to keep the relvars and their constraints organized
together in namespace-like groups.
- ::ral::relvar association name refrngRelvar refrngAttrList refToSpec refToRelvar refToAttrList refrngSpec
-
The association subcommand creates a referential association
between two relvars called name.
The return value of association is the empty string.
Associations declare that one relvar has attributes that refer to
an identifier of another relvar.
The referring relvar name is given by the refrngRelvar argument
and the referring attributes are given by refrngAttrList argument.
The referred to relvar name is given by refToRelvar and the
attributes that are referred to by refToAttrList. The referring
and referred to attribute lists are ordered and referring attributes
refer to the corresponding referred to attribute.
The set of attributes given by refToAttrList must constitute
an identifier for refToRelvar.
The refToSpec argument defines
the multiplicity and conditionality of the reference.
It can be one of:
- *
-
Each tuple in refToRelvar is referred to zero or more times by
the tuples in refrngRelvar.
- +
-
Each tuple in refToRelvar is referred to one or more times by
the tuples in refrngRelvar.
- 1
-
Each tuple in refToRelvar is referred to exactly once by
the tuples in refrngRelvar.
- ?
-
Each tuple in refToRelvar is referred to zero or one times by
the tuples in refrngRelvar.
Similarly refrngSpec defines the multiplicity and conditionality
associated with the references to refToRelvar.
Necessarily, refrngSpec may only be "1" or "?" implying:
- 1
-
Each tuple in refrngRelvar refers to exactly one tuple in
refToRelvar.
- ?
-
Each tuple in refrngRelvar refers to at most one tuple
(and possibly none at all) in refToRelvar.
The symbols for refrngSpec and refToSpec were chosen
by analogy to the use of those symbols in regular expression syntax.
|
% relvar association A1 OWNERSHIP OwnerName + OWNER OwnerName 1
% relvar association A2 OWNERSHIP DogName * DOG DogName 1
|
In this example,
A1 declares that for every tuple in OWNERSHIP,
the value of OWNERSHIP.OwnerName matches the value of OWNER.OwnerName
in exactly one tuple of OWNER and that for every tuple in OWNER the
value of OWNER.OwnerName matches the value of OWNERSHIP.OwnerName in
at least one tuple of OWNERSHIP and possibly more.
In the semantics of this example, the concepts of being an OWNER
and that of OWNERSHIP of a DOG are unconditionally associated since
no tuple of OWNER may exist without there being at least one associated
tuple of OWNERSHIP.
Also this constraint allows for OWNERS that may own more than one DOG.
Compare this to the case of A2.
A2 states that every tuple in OWNERSHIP must have a corresponding tuple
in DOG, but that tuples in DOG may not be referenced by any tuple in OWNERSHIP.
OWNERSHIP and DOG are conditionally associated
and in the semantics of this problem, it is possible to have dogs that
are not owned at all and to have dogs that are owned multiple times.
- ::ral::relvar constraint delete ?name1 name2 ...?
-
The constraint delete subcommand deletes all the
constraints given by the nameN arguments.
The return value is the empty string.
- ::ral::relvar constraint info name
-
The constraint info subcommand returns the detailed information
about the constraint named name.
The information returned is of the same format as the command used
to create the constraint minus the superfluous leading relvar command
word.
Additionally,
the relvar names and constraint names are returned in fully qualified form.
|
% relvar constraint info A1
association ::A1 ::OWNERSHIP OwnerName + ::OWNER OwnerName 1
% relvar constraint info ::P1
partition ::P1 ::Lamp SerialNo ::TableLamp SerialNo ::FloorLamp SerialNo
% relvar constraint info G
unknown constraint name, "G"
|
- ::ral::relvar constraint names ?pattern?
-
The constraint names subcommand returns a list of constraint names.
If the optional pattern is present,
then only those constraint names that match pattern are returned.
Name matching happens in the same manner as for the string match.
The returned names are fully qualified.
|
% relvar constraint names
::A1 ::A2
% relvar constraint names *2
::A2
|
- ::ral::relvar constraint member relvarName
-
The constraint member subcommand returns a list of constraint names
in which relvarName participates in some fashion.
The returned names are fully qualified.
|
% relvar constraint member OWNERSHIP
::A1 ::A2
|
- ::ral::relvar constraint path constraintName
-
The constraint path subcommand returns the fully qualified constraint
name of constraintName.
- ::ral::relvar correlation ?-complete? name correlRelvar correlAttrListA refToSpecA refToRelvarA refToAttrListA correlAttrListB refToSpecB refToRelvarB refToAttrListB
-
The correlation subcommand creates a referential correlation
called name.
The referential correlation is between a correlation relvar, correlRelvar,
and two other relvars, refToRelvarA and refToRelvarB.
The return value of correlation is the empty string.
Correlations declare that every tuple in correlRelvar refers to
exactly one tuple of refToRelvarA and exactly one tuple of
refToRelvarB.
The correlAttrListA attributes in correlRelvar refer to an
identifier of refToRelvarA that is given by the
attributes contained in the refToAttrListA list.
Similarly,
the correlAttrListB attributes in correlRelvar refer to an
identifier of refToRelvarB that is given by refToAttrListB.
Both refToAttrListA and refToAttrListB must constitute
an identifier for their corresponding relvars.
The refToSpecA and refToSpecB arguments can have the same values
as for the ::ral::relvar association command and specify
the multiplicity and conditionality of how refToRelvarA and
refToRelvarB are referred to by the tuples of correlRelvar.
If the ?-complete? option is given,
then every tuple of refToRelvarA must be correlated to every
tuple of refToRelvarB and vice versa.
That is, the cardinality of correlRelvar must equal the product
of the cardinality of refToRelvarA and refToRelvarB.
If the ?-complete? option is missing,
then correlRelvar is allowed to have a subset of the cartesian product
of the references.
Correlation constraints are often used to enforce the referential
constraints for relvars that are related in a many to many fashion.
However, they also arise in situations where the multiplicity is not
many-to-many but when the correlRelvar contains attributes that
apply to the association between refToRelvarA and refToRelvarB
themselves.
|
% relvar correlation C1 OWNERSHIP OwnerName + OWNER OwnerName DogName * DOG DogName
|
- ::ral::relvar create relvarName heading
-
The create subcommand creates a new relation variable whose name is given
by relvarName and that has the relation value heading given
by the heading argument.
The subcommand returns the relation value of the newly created relvar,
which necessarily will have cardinality of 0.
The heading argument is a valid relation value heading
as described for the ::ral::relation commands or
as returned from ::ral::relation heading.
If relvarName name begins with "::", then it is interpreted
as a fully resolved name and will be created in the given namespace.
Otherwize relvarName is interpreted as relative the to current namespace.
In either case,
an ordinary Tcl variable is also created by the same fully resolved
name as the relvar.
This implies that any namespaces referenced in relvarName
must already exist.
|
% relvar create OWNER {
> Relation
> {OwnerName string Age int City string}
> OwnerName
> }
Relation {OwnerName string Age int City string} OwnerName {}
% puts [relformat $::OWNER]
+=========+---+------+
|OwnerName|Age|City |
|string |int|string|
+=========+---+------+
+=========+---+------+
% relvar create DOG {
> Relation
> {DogName string Breed string}
> DogName
> }
Relation {DogName string Breed string} DogName {}
% relvar create OWNERSHIP {
> Relation
> {OwnerName string DogName string Acquired string}
> {{OwnerName DogName}}
> }
Relation {OwnerName string DogName string Acquired string} {{OwnerName DogName}} {}
|
- ::ral::relvar delete relvarName tupleVarName expression
-
The delete subcommands deletes tuples from the relation variable
given by the relvarName argument.
Each tuple in the body of relvarName is successively
assigned to the tuple variable named tupleVarName and
expression is evaluated.
If expression returns true, then that tuple is deleted, directly
modifying the value contained in relvarName.
The return value of the subcommand is the number of tuples deleted.
|
% puts [relformat $::OWNER "Before deleting Sue"]
+=========+---+-------------+
|OwnerName|Age|City |
|string |int|string |
+=========+---+-------------+
|Sue |24 |Cupertino |
|George |35 |Sunnyvale |
|Alice |30 |San Jose |
|Mike |50 |San Jose |
|Jim |42 |San Francisco|
+=========+---+-------------+
Before deleting Sue
-------------------
% relvar delete OWNER o {[tuple extract $o OwnerName] eq "Sue"}
1
% puts [relformat $::OWNER "After deleting Sue"]
+=========+---+-------------+
|OwnerName|Age|City |
|string |int|string |
+=========+---+-------------+
|George |35 |Sunnyvale |
|Alice |30 |San Jose |
|Mike |50 |San Jose |
|Jim |42 |San Francisco|
+=========+---+-------------+
After deleting Sue
------------------
|
- ::ral::relvar deleteone relvarName ?attr1 value1 attr2 value2 ...?
-
The deleteone subcommand deletes at most one tuple from the
relation variable given by the relvarName argument.
The attrN valueN arguments must be given in pairs
and are the attribute names and values that determine which tuple
is deleted from the relation value held in relvarName.
The set of attribute names in the attrN valueN arguments
must form one of the identifiers of relvarName.
If relvarName contains a tuple whose attribute values match those
in given then that tuple is deleted and relvarName
is modified in place.
Otherwise relvarName is unchanged.
This subcommand is useful in those contexts where the attribute values of an
identifier are known and evaluating an expression over all the tuples
in relvarName is superfluous.
The return value of the subcommand is the number of tuples deleted which will
necessarily be either 1 or 0.
|
% puts [relformat $::OWNER "Before deleting Mike"]
+=========+---+-------------+
|OwnerName|Age|City |
|string |int|string |
+=========+---+-------------+
|Sue |24 |Cupertino |
|George |35 |Sunnyvale |
|Alice |30 |San Jose |
|Mike |50 |San Jose |
|Jim |42 |San Francisco|
+=========+---+-------------+
Before deleting Mike
--------------------
% relvar deleteone OWNER OwnerName Mike
1
% puts [relformat $::OWNER "After deleting Mike"]
+=========+---+-------------+
|OwnerName|Age|City |
|string |int|string |
+=========+---+-------------+
|Sue |24 |Cupertino |
|George |35 |Sunnyvale |
|Alice |30 |San Jose |
|Jim |42 |San Francisco|
+=========+---+-------------+
After deleting Mike
-------------------
% relvar deleteone OWNER OwnerName Alfonse
0
% puts [relformat $::OWNER]
+=========+---+-------------+
|OwnerName|Age|City |
|string |int|string |
+=========+---+-------------+
|Sue |24 |Cupertino |
|George |35 |Sunnyvale |
|Alice |30 |San Jose |
|Jim |42 |San Francisco|
+=========+---+-------------+
|
- ::ral::relvar eval arg ?arg ...?
-
The eval subcommand concatenates it arguments together and evaluates
the resulting script as a relvar transaction.
The return value of eval is the return value of the last
command executed in the script.
At the end of the script,
the constraints associated with any relvar that was modified
by the script are evaluated.
If either the script generates an error or any of the constraints fail,
then the values of the modified relvars are returned to the values
they held before the eval command.
It is an error to attempt to create relvars or constraints in the
script executed by eval.
|
% puts [relformat $::OWNER]
+=========+---+-------------+
|OwnerName|Age|City |
|string |int|string |
+=========+---+-------------+
|Sue |24 |Cupertino |
|George |35 |Sunnyvale |
|Alice |30 |San Jose |
|Mike |50 |San Jose |
|Jim |42 |San Francisco|
+=========+---+-------------+
% relvar eval {
> relvar insert OWNER {OwnerName Tom Age 22 City Tulsa}
> }
for association ::A1(::OWNERSHIP [+] ==> [1] ::OWNER), in relvar ::OWNER
tuple {OwnerName Tom Age 22 City Tulsa} is not referenced by any tuple
% puts [relformat $::OWNER]
+=========+---+-------------+
|OwnerName|Age|City |
|string |int|string |
+=========+---+-------------+
|Sue |24 |Cupertino |
|George |35 |Sunnyvale |
|Alice |30 |San Jose |
|Mike |50 |San Jose |
|Jim |42 |San Francisco|
+=========+---+-------------+
% relvar eval {
> relvar insert OWNER {OwnerName Tom Age 22 City Tulsa}
> relvar insert OWNERSHIP {OwnerName Tom DogName Skippy Acquired 2006}
> }
for association ::A2(::OWNERSHIP [*] ==> [1] ::DOG), in relvar ::OWNERSHIP
tuple {OwnerName Tom DogName Skippy Acquired 2006} references no tuple
% puts [relformat $::OWNER]
+=========+---+-------------+
|OwnerName|Age|City |
|string |int|string |
+=========+---+-------------+
|Sue |24 |Cupertino |
|George |35 |Sunnyvale |
|Alice |30 |San Jose |
|Mike |50 |San Jose |
|Jim |42 |San Francisco|
+=========+---+-------------+
% relvar eval {
> relvar insert OWNER {OwnerName Tom Age 22 City Tulsa}
> relvar insert OWNERSHIP {OwnerName Tom DogName Jumper Acquired 2006}
> return
> }
% puts [relformat $::OWNER]
+=========+---+-------------+
|OwnerName|Age|City |
|string |int|string |
+=========+---+-------------+
|Sue |24 |Cupertino |
|George |35 |Sunnyvale |
|Alice |30 |San Jose |
|Mike |50 |San Jose |
|Jim |42 |San Francisco|
|Tom |22 |Tulsa |
+=========+---+-------------+
|
- ::ral::relvar insert relvarName ?name-value-list ...?
-
The insert subcommand inserts the tuples given by name-value-list
arguments into the value of the relation stored in relvarName.
The value of relvarName is modified in place.
The return value is a relation value with the same heading as the
value held in relvarName and whose body contains the tuples as they
were actually inserted.
This gives the caller access to any attributes that might have been modified
by a relvar trace.
It is an error to attempt to insert a duplicate tuple or a tuple whose
heading does not match the heading of the value held in relvarName.
The values of all attributes of the inserted tuples must be specified
with a valid value representation of the type associated with the attribute.
However, because of relvar tracing, the tuple values given in
name-value-list may not be the ones actually inserted into the relvar.
|
% relvar insert DOG {DogName Skippy Breed Dalmation}
Relation {DogName string Breed string} DogName {{DogName Fido Breed Poodle} {DogName Sam Breed Collie} {DogName Spot Breed Terrier} {DogName Rover Breed Retriever} {DogName Fred Breed Spaniel} {DogName Jumper Breed Mutt} {DogName Skippy Breed Dalmation}}
% relvar insert OWNER {OwnerName Tom Age 22 City Tulsa}
for association ::A1(::OWNERSHIP [+] ==> [1] ::OWNER), in relvar ::OWNER
tuple {OwnerName Tom Age 22 City Tulsa} is not referenced by any tuple
|
- ::ral::relvar intersect relvarName ?relationValue1 relationValue2 ...?
-
The intersect subcommand performs the relation intersection of the
relation value contained in relvarName with the given
relationValueN arguments and assigns the result back into
relvarName.
This command is shorthand for:
relvar set <relvarName> [relation intersect [relvar set <relvarName>]
<relationValue1> ...]
The headings of each relationValueN must match that of the value
contained in relvarName.
Since the intersect operation is commutative, the order of the
relationValueN arguments does not affect the result.
The return value of the command is the new relation value stored in
relvarName.
- ::ral::relvar minus relvarName relationValue
-
The minus subcommand performs the relation difference of the
relation value contained in relvarName with
the relationValue argument and assigns the result back into
relvarName.
This command is shorthand for:
relvar set <relvarName> [relation minus [relvar set <relvarName>]
<relationValue1>]
The headings of relationValue must match that of the value
contained in relvarName.
Note that this operation is not commutative.
The return value of the command is the new relation value stored in
relvarName.
- ::ral::relvar names ?pattern?
-
The names subcommand returns a list of the currently defined
relation variables.
If the pattern argument is specified then only those names matching
pattern are returned.
Name matching is performed as for the string match command.
The returned names are fully qualified.
|
% relvar names
::DOG ::OWNERSHIP ::OWNER
% relvar names ::D*
::DOG
|
- ::ral::relvar partition name super superAttrList sub1 sub1AttrList ?sub2 sub2AttrList sub3 sub3AttrList ...?
-
The partition subcommand defines a partition constraint named
name.
The relvar named super must have as one of its identifiers the
attributes named in the superAttrList argument.
The remaining arguments define the sub set relvars named subN
and the attributes in those relvars that reference the super set relvar
are given by the subNAttrList arguments.
A partition constraint declares that every tuple in the subN
relvars references exactly one tuple in the super relvar and that
every tuple in the super relvar is referred to by exactly one
tuple contained in one of the subN relvars.
This constraint implies that the tuples in the super relvar are
completely partitioned into the disjoint sub sets given by the the
subN relvars.
|
% relvar create Lamp {
> Relation
> {SerialNo string ModelNo string Make string}
> SerialNo
> }
Relation {SerialNo string ModelNo string Make string} SerialNo {}
% relvar create TableLamp {
> Relation
> {SerialNo string Shade string}
> SerialNo
> }
Relation {SerialNo string Shade string} SerialNo {}
% relvar create FloorLamp {
> Relation
> {SerialNo string Height int Sockets int}
> SerialNo
> }
Relation {SerialNo string Height int Sockets int} SerialNo {}
% relvar partition P1 Lamp SerialNo TableLamp SerialNo FloorLamp SerialNo
% relvar insert Lamp {SerialNo NF100 ModelNo FCN-22 Make Falcon}
for partition ::P1(::Lamp is partitioned [::TableLamp | ::FloorLamp]), in relvar ::Lamp
tuple {SerialNo NF100 ModelNo FCN-22 Make Falcon} is not referred to by any tuple
% relvar eval {
> relvar insert Lamp {SerialNo NF100 ModelNo FCN-22 Make Falcon}
> relvar insert TableLamp {SerialNo NF100 Shade Blue}
> return
> }
% relvar insert FloorLamp {SerialNo NF100 Height 72 Sockets 3}
for partition ::P1(::Lamp is partitioned [::TableLamp | ::FloorLamp]), in relvar ::Lamp
tuple {SerialNo NF100 ModelNo FCN-22 Make Falcon} is referred to by multiple tuples
% relvar insert FloorLamp {SerialNo NF101 Height 72 Sockets 3}
for partition ::P1(::Lamp is partitioned [::TableLamp | ::FloorLamp]), in relvar ::FloorLamp
tuple {SerialNo NF101 Height 72 Sockets 3} references no tuple
|
- ::ral::relvar path relvarName
-
The path subcommand returns the fully qualified relvar
name of relvarName.
- ::ral::relvar set relvarName ?relationValue?
-
The set subcommand replaces the current value held by the relation
variable named relvarName with the value given by
relationValue.
It is an error to attempt to assign a relation value to a relation variable
that is of a different type than the type of the value
that the variable currently holds.
In other words, it is not possible to change the type of a relvar
by assignment.
The return value of the subcommand is the current value
held by relvarName.
If the relationValue argument is missing, then no attempt is made to
change the value of relvarName.
This command operates in a manner analogous to the set command for
ordinary Tcl variables.
|
% relvar create PUPPY {
> Relation
> {PuppyName string Dame string Sire string}
> PuppyName
> }
Relation {PuppyName string Dame string Sire string} PuppyName {}
% relvar set PUPPY {
> Relation
> {PuppyName string Dame string Sire string}
> PuppyName
> {
> {PuppyName Bitsy Dame Spot Sire Jumper}
> }
> }
Relation {PuppyName string Dame string Sire string} PuppyName {{PuppyName Bitsy Dame Spot Sire Jumper}}
% relvar set PUPPY $::DOG
headings not equal, "Relation {DogName string Breed string} DogName"
|
- ::ral::relvar trace option type ?args?
-
- ::ral::relvar trace add variable relvarName traceops cmdPrefix
-
- ::ral::relvar trace remove variable relvarName traceops cmdPrefix
-
- ::ral::relvar trace info variable relvarName
-
- ::ral::relvar trace add eval cmdPrefix
-
- ::ral::relvar trace remove eval cmdPrefix
-
- ::ral::relvar trace info eval
-
The trace add variable subcommand adds a trace to relvarName.
The traceops argument is a list of one or more trace operation keywords
from the list:
- delete
-
- insert
-
- set
-
- unset
-
- update
-
The trace remove variable subcommand deletes any trace on
relvarName that matches traceops and command.
The trace info variable subcommand returns the trace information
for the relvar whose name is given by relvarName.
The trace information is a list each element of which describes one trace
on the relvar.
Each trace information element is in turn a list consisting of two elements,
the traceops and command, of the relvar trace.
It is an error to request any trace operation if relvarName does not
exist.
The trace add eval, trace remove eval and
trace info eval variations perform the corresponding
operation for tracing transactions via the relvar eval command.
See the RELVAR TRACES section below for further details.
- ::ral::relvar transaction option
-
- ::ral::relvar transaction begin
-
- ::ral::relvar transaction end
-
- ::ral::relvar transaction rollback
-
The transaction subcommand controls the evaluation of relvar
constraints.
Like relvar eval, relvar transaction demarcates the
boundaries of when relvar constraints are evaluated.
relvar transaction begin signals the beginning of a constraint
transaction.
When the matching relvar transaction end is executed,
all contraints for all relvars modified since the corresponding
relvar transaction begin command are evaluated.
Executing the relvar transaction rollback command, halts the
transaction and discards all the modifications, restoring the relvar
state to that which existed before the execution of
relvar transaction begin.
This command is complementary to relvar eval in that it provides
the same behavior but for those circumstances where accumulating the
relvar modifications into a single script is not convenient or possible.
The command returns the empty string.
If relvar modifications are such that the constraints are violated,
then relvar transaction end will throw an error.
- ::ral::relvar union relvarName ?relationValue1 relationValue2 ...?
-
The union subcommand performs the relation union of the
relation value contained in relvarName with the given
relationValueN arguments and assigns the result back into
relvarName.
This command is shorthand for:
relvar set <relvarName> [relation union [relvar set <relvarName>]
<relationValue1> ...]
The headings of each relationValueN must match that of the value
contained in relvarName.
Since the union operation is commutative, the order of the
relationValueN arguments does not affect the result.
The return value of the command is the new relation value stored in
relvarName.
- ::ral::relvar unset ?relvarName ...?
-
The unset subcommand deletes all the relation variables whose
names are given as the subcommand arguments.
The corresponding Tcl variables that were created when the relvar
was created are also unset.
This command operates in a manner analogous to the unset command for
ordinary Tcl variables.
It is an error to attempt to unset a relvar that is associated
with any constraints.
- ::ral::relvar update relvarName tupleVarName expression script
-
The update subcommand modifies the values of tuples in the relation
value contained in the relation variable given by relvarName.
Each tuple in relvarName is successively assigned to the tuple
variable given by tupleVarName and expression is evaluated.
If the result of the evaluation is true,
then script is evaluated.
The value of tupleVarName at the end of executing
script is then updated into relvarName.
Typically, script will invoke ::ral::tuple update
to modify the value of tupleVarName.
The return value of the subcommand
is a relation value with the same heading as the
value held in relvarName and whose body contains the tuples as they
were actually updated.
This gives the caller access to any attributes that might have been modified
by a relvar trace.
If the script throws an error or the modified value of a tuple cannot
be updated into relvarName, all changes to relvarName are
discarded and the value of relvarName is restored to its previous value.
Should script execute a break or return command,
then relvarName is updated (if possible) and the return code
is propagated to any surrounding command.
|
% puts [relformat $::OWNER]
+=========+---+-------------+
|OwnerName|Age|City |
|string |int|string |
+=========+---+-------------+
|Sue |24 |Cupertino |
|George |35 |Sunnyvale |
|Alice |30 |San Jose |
|Mike |50 |San Jose |
|Jim |42 |San Francisco|
+=========+---+-------------+
% relvar update OWNER o {[tuple extract $o OwnerName] eq "Sue"} {
> tuple update o Age [expr {[tuple extract $o Age] + 1}]
> }
1
% puts [relformat $::OWNER]
+=========+---+-------------+
|OwnerName|Age|City |
|string |int|string |
+=========+---+-------------+
|Sue |25 |Cupertino |
|George |35 |Sunnyvale |
|Alice |30 |San Jose |
|Mike |50 |San Jose |
|Jim |42 |San Francisco|
+=========+---+-------------+
% relvar update OWNER o {[tuple extract $o OwnerName] eq "George"} {
> tuple update o OwnerName Alfonse
> }
for association ::A1(::OWNERSHIP [+] ==> [1] ::OWNER), in relvar ::OWNER
tuple {OwnerName Alfonse Age 35 City Sunnyvale} is not referenced by any tuple
for association ::A1(::OWNERSHIP [+] ==> [1] ::OWNER), in relvar ::OWNERSHIP
tuple {OwnerName George DogName Fido Acquired 2001} references no tuple
tuple {OwnerName George DogName Sam Acquired 2000} references no tuple
% puts [relformat $::OWNER]
+=========+---+-------------+
|OwnerName|Age|City |
|string |int|string |
+=========+---+-------------+
|Sue |25 |Cupertino |
|George |35 |Sunnyvale |
|Alice |30 |San Jose |
|Mike |50 |San Jose |
|Jim |42 |San Francisco|
+=========+---+-------------+
|
- ::ral::relvar updateone relvarName tupleVarName id-name-value-list script
-
The updateone subcommand modifies at most one tuple from the
relation variable given by the relvarName argument.
The id-name-value-list must be list containing an even number of elements
which are attribute names alternating with attribute values.
The set of attribute names in id-name-value-list must form one of the
identifiers of relvarName.
If relvarName contains a tuple whose attribute values match those
in name-value-list then
that tuple is assigned to tupleVarName and script is executed.
After executing script the value contained in tupleVarName
replaces the original tuple, modifying relvarName in place.
Typically, script will invoke ::ral::tuple update
to modify the value of tupleVarName.
If no matching tuple is found, then relvarName is unchanged.
This subcommand is useful in those contexts where the attribute values of an
identifier are known and evaluating an expression over all the tuples
in relvarName is superfluous.
The return value is a relation value with the same heading as the
value held in relvarName and whose body contains either the single
tuple that was updated or is empty if no matching tuple was found.
This give the caller access to any attributes that might have been modified
by a relvar trace.
|
% puts [relformat $::OWNER]
+=========+---+-------------+
|OwnerName|Age|City |
|string |int|string |
+=========+---+-------------+
|Sue |24 |Cupertino |
|George |35 |Sunnyvale |
|Alice |30 |San Jose |
|Mike |50 |San Jose |
|Jim |42 |San Francisco|
+=========+---+-------------+
% relvar updateone OWNER o {OwnerName George} {
> tuple update o Age 37 City {New York}
> }
1
% puts [relformat $::OWNER]
+=========+---+-------------+
|OwnerName|Age|City |
|string |int|string |
+=========+---+-------------+
|Sue |24 |Cupertino |
|George |37 |New York |
|Alice |30 |San Jose |
|Mike |50 |San Jose |
|Jim |42 |San Francisco|
+=========+---+-------------+
|
By analogy to tracing ordinary variables in Tcl,
relvars can also be traced.
However, relvar tracing must account for the
operations that are applied to relvars.
There are five operations that may be traced on the relation values
held in relvars and one operation that allows tracing of transactions
on relvars.
For these operations, if a command prefix has been registered using
relvar trace add variable or relvar trace add eval
then that command prefix will have
additional arguments appended and will be invoked as described below.
Relvar traces operate in a very similar fashion as traces on ordinary
Tcl variables.
The trace command is invoked when the corresponding relvar operation
is invoked and is invoked in the context of the caller of the relvar operation,
which, in general, is different from the caller of the relvar trace add
command.
When executing a variable type trace for a relvar,
all other variable type tracing for that relvar is inhibited.
If multiple traces have been added to a relvar,
the traces are invoked in the order of most recent first to oldest last.
- delete
-
A delete trace is invoked for each tuple in a relvar that is deleted.
Tuples are deleted from relvars by invocations of relvar delete
or relvar deleteone.
The delete trace command is invoked as:
cmdPrefix delete relvarName tupleValue
where cmdPrefix is the command prefix of the trace as given
in relvar trace add variable,
the string delete indicates that a tuple is to be deleted from the relvar,
relvarName is the fully qualified name of the relvar
and tupleValue is the value of the tuple about to be deleted.
The trace command is invoked before the tuple is actually removed from
the relation value held in the relvar.
If cmdPrefix throws an error, then no other delete traces in the chain of
delete traces for the relvar are invoked and tupleValue is not removed
from the relvar value.
- insert
-
An insert trace is invoked for each tuple in a relvar that is inserted.
Tuples are inserted into relvars by invocations of relvar insert.
The insert trace command is invoked as:
cmdPrefix insert relvarName tupleValue
where cmdPrefix is the command prefix of the trace as given
in relvar trace add variable,
the string insert indicates that a tuple
is to be inserted into the relvar,
relvarName is the fully qualified name of the relvar
and tupleValue is the value of the tuple about to be inserted
The trace command is invoked before the tuple is actually inserted into
the relation value held in the relvar.
The cmdPrefix command must return a Tuple value.
The returned Tuple value is passed along to the next insert trace command.
The returned Tuple from the last trace command in the chain is then
inserted into the relvar.
Insert trace commands may choose to modify the value of tupleValue but
are required to return a value that can be coerced into a Tuple type and the
heading of the returned Tuple of the last trace command in the chain
must match that of the relvar if it is to be successfully inserted.
If cmdPrefix throws an error, then no other insert traces in the chain of
insert traces for the relvar are invoked and tupleValue is not inserted
into the relvar value.
- set
-
A set trace is invoked each time that the relation value held in a relvar
is assigned.
Relations values are assigned to relvars by invocation of the
relvar set,
relvar union,
relvar intersect
or
relvar minus
command.
The set trace command is invoked as:
cmdPrefix set relvarName relationValue
where cmdPrefix is the command prefix of the trace as given
in relvar trace add variable,
the string set indicates that a relation value
is to be assigned to the relvar,
relvarName is the fully qualified
name of the relvar
and relationValue is the relation value that is about to be assigned
to the relvar.
The trace command is invoked before the relation is actually assigned to the
relvar.
The cmdPrefix command must return a Relation value.
The returned Relation value is passed along to the next set trace command.
The returned Relation from the last trace command in the chain is then
assigned to the relvar.
Set trace commands may choose to modify the value of relationValue but
are required to return a value that can be coerced into a Relation type and the
heading of the returned Relation of the last trace command in the chain
must match that of the relvar if it is to be successfully assigned
If cmdPrefix throws an error, then no other set traces in the chain of
set traces for the relvar are invoked and relationValue is not assigned
to the relvar.
- unset
-
An unset trace is invoked each time a relvar is destroyed.
Relvars are destroyed by the invocation of the relvar unset command.
Note that due to a limitation of Tcl,
relvar unset traces are not invoked when an interpreter is deleted.
The unset trace command is invoked as:
cmdPrefix unset relvarName
where cmdPrefix is the command prefix of the trace as given
in relvar trace add variable,
the string unset indicates that the relvar
is being destroyed,
and relvarName is the fully qualified
name of the relvar.
The trace command is invoked before the relvar is actually destroyed so
the relation value stored in the relvar is still intact.
Any errors thown by cmdPrefix are ignored.
- update
-
An update trace is invoked for each tuple in a relvar that is updated.
Tuples are updated into relvars by invocations of relvar update
or relvar updateone.
The update trace command is invoked as:
cmdPrefix update relvarName oldTupleValue
newTupleValue
where cmdPrefix is the command prefix of the trace as given
in relvar trace add variable,
the string update indicates that a tuple
is to be updated in the relvar,
relvarName is the fully qualified name of the relvar,
oldTupleValue is the current value of the tuple in the relvar
and newTupleValue is the value that the tuple will have when
the update is performed.
The trace command is invoked before the tuple is actually updated in
the relation value held in the relvar.
The cmdPrefix command must return a Tuple value.
The returned Tuple value is passed along to the next update trace command.
The returned Tuple from the last trace command in the chain is then
updated into the relvar.
Update trace commands may choose to modify the value of newTupleValue but
are required to return a value that can be coerced into a Tuple type and the
heading of the returned Tuple of the last trace command in the chain
must match that of the relvar if it is to be successfully updated.
If cmdPrefix throws an error, then no other update traces in the chain of
update traces for the relvar are invoked and tupleValue is not updated
into the relvar value.
- eval
-
An eval trace is invoked each time that a relvar eval begins and
ends or when relvar transaction commands are invoked.
Eval traces are different from other relvar traces in that they provide a
means of determining the boundaries of a transaction rather than specific
operations on a relvar.
The eval trace command is invoked as:
cmdPrefix eval op level
where cmdPrefix is the command prefix of the trace as given
in relvar trace add eval,
the string eval indicates that the relvar transaction is in progress,
the op is either the string "begin" or "end" indicating whether
or not the relvar eval is just starting or is ending and
level is an integer greater than zero indicating the nesting depth
of the transaction.
The eval trace is invoked with the "begin" op before the script associated
with a relvar eval is executed and is invoked with the "end" op
after the script is executed but before the relvar constraints are evaluated
for the transaction.
Any errors thown by cmdPrefix are ignored.
relation , tuple
relation , variable
Copyright © 2004, 2005, 2006, 2007 by G. Andrew Mangogna