[ Table Of Contents | Keyword Index ]

ralutil(n) 0.12.2 ral "Ralutil Package"

Name

ralutil - Commands for the ralutil package

Table Of Contents

Synopsis

Description

This manpage describes the ralutil package. The ralutil package is a supplementary package to the Tcl Relational Algebra Library (ral) package.

VARIABLES

The ralutil package defines two variables, DUM and DEE. These two relation values play a special role as identity and annihilator relations.

::ralutil::DUM

The ordinary Tcl variable ::ralutil::DUM contains a relation value whose heading is empty and whose body is empty.

::ralutil::DEE

The ordinary Tcl variable ::ralutil::DEE contains a relation value whose heading is empty and whose body contains a single tuple that is the empty tuple.

COMMANDS

::ralutil::pipe script ?varName? ?sep?

The pipe command provides a control structure to execute a sequence of commands feeding the output of one command as the input to the next one in the sequence. The script argument is a sequence of commands separated by a command separator character (by default "|"). The script is rewritten and executed such that the return value of the first command in the sequence is used as an argument to the next and so on for all the commands in script. The return value of a preceding command is inserted into the succeeding command to replace the special argument substitution character (default "~"). If no argument substitution character is found in a command, then the value is made the last argument of the command. If the varName argument is present and not the empty string, then the rewritten script is not executed but rather is stored in the Tcl variable given by varName. This is useful in loops where it is not necessary to recompute script reorganization each time. Executing eval of the contents of varName can be used to execute the rewritten script. If the sep argument is present it is interpreted as a two character string giving the command separator and argument place holder syntax characters in that order. By default these are "|" and "~" respectively, but different values may be specified if these characters are otherwise present in the script and would be misinterpreted in the script rewriting. It is frequently the case that relational expressions take the output of one command directly as the argument of another one. This is easily done in Tcl because command evaluation may be nested arbitrarily deep. However, deeply nested commands can be difficult to read and follow. The pipe command is a control structure that allows deeply nested commands to be written as a linear sequence. This command was inspired by code from the Tcl wiki http://wiki.tcl.tk/17419. The implementation is different than that found on the wiki, but the idea is the same. N.B. that here is nothing about the pipe command that is specific to relational algebra. It can be used to sequence any Tcl commands.

To obtain a list of the breeds of all dogs whose name starts with "S":

set sdogs [::ralutil::pipe {
    relvar set DOG |
    relation restrictwith ~ {[string match S* $DogName]} |
    relation project ~ Breed |
    relation list
}]

The same command in natural Tcl nesting order is:

set sdogs [relation list \ 
    [relation project \ 
        [[relation restrictwith \ 
            [relvar set DOG] \ 
        {[string match S* $DogName]}] \ 
    Breed]]]
::ralutil::crosstab relValue crossAttr ?attr1 attr2 ...?

Generate a cross tabulation of relValue for the crossAttr attribute against the optional attrN attributes. Cross tabulations are sometimes known as pivot tables. The result is relation value whose heading consists of the attrN attributes plus a new attribute for each distinct value of the crossAttr attribute. The value of the new cross tabulated attributes is the number of tuples in relValue that have the corresponding value of crossAttr.

% set tab [::ralutil::crosstab [relvar set OWNERSHIP] Acquired]
% puts [relformat $tab]
+----+----+----+----+-----+
|2000|2001|2002|2003|Total|
|int |int |int |int |int  |
+----+----+----+----+-----+
|2   |3   |1   |1   |7    |
+----+----+----+----+-----+
% set tab [::ralutil::crosstab [relvar set OWNERSHIP] Acquired DogName]
% puts [relformat $tab]
+-------+----+----+----+----+-----+
|DogName|2000|2001|2002|2003|Total|
|string |int |int |int |int |int  |
+-------+----+----+----+----+-----+
|Fido   |0   |2   |0   |0   |2    |
|Sam    |2   |0   |0   |0   |2    |
|Spot   |0   |1   |0   |0   |1    |
|Rover  |0   |0   |1   |0   |1    |
|Fred   |0   |0   |0   |1   |1    |
+-------+----+----+----+----+-----+
::ralutil::rvajoin rel1 rel2 newAttr ?attr1 attr2 ...?

The rvajoin command performs the relational equivalent to an outer join. The idea is to end up with a relation that contains a relation valued attribute which in turn contains the tuples that match in the join and is empty for those tuples in the relation that do not match across the join attributes (the "natural join" leaving such tuples out of the result altogether). rel1 is the first relation to join and rel2 is the second relation to join. newAttr the name of the new relation valued attribute. The remaining optional arguments are the attributes across which the join is to be made. If the no such arguments are given, then the join is performed across the attributes that have the same name. The result has the same heading as rel1 plus an attribute newAttr. The type of newAttr is Relation with a heading that matches rel2 minus the join attributes. N.B. that rvajoin is not commutative like the natural join. To show the difference between rvajoin and natural join i.e. relation join, consider the join of Dog to Ownership. In this data set, Jumper the Mutt is not owned by anyone. In the natural join, there is no tuple with Jumper. The RVA join has a tuple for Jumper and an empty relation valued attribute showing that Jumper is not owned. It is also instructive to consider the effect of the ungroup operation on the RVA join which gives the same result as the natural join.

% relformat [relation join $::DOG $::OWNERSHIP] "Natural Join"
+-------+---------+---------+--------+
|DogName|Breed    |OwnerName|Acquired|
|string |string   |string   |string  |
+-------+---------+---------+--------+
|Fido   |Poodle   |Sue      |2001    |
|Fido   |Poodle   |George   |2001    |
|Sam    |Collie   |Sue      |2000    |
|Sam    |Collie   |George   |2000    |
|Spot   |Terrier  |Alice    |2001    |
|Rover  |Retriever|Mike     |2002    |
|Fred   |Spaniel  |Jim      |2003    |
+-------+---------+---------+--------+
Natural Join
------------
% set j [rvajoin $::DOG $::OWNERSHIP OwnedBy]
% relformat $j "RVA Join"
+-------+---------+--------------------+
|DogName|Breed    |OwnedBy             |
|string |string   |Relation            |
+-------+---------+--------------------+
|Fido   |Poodle   |+---------+--------+|
|       |         ||OwnerName|Acquired||
|       |         ||string   |string  ||
|       |         |+---------+--------+|
|       |         ||Sue      |2001    ||
|       |         ||George   |2001    ||
|       |         |+---------+--------+|
|Sam    |Collie   |+---------+--------+|
|       |         ||OwnerName|Acquired||
|       |         ||string   |string  ||
|       |         |+---------+--------+|
|       |         ||Sue      |2000    ||
|       |         ||George   |2000    ||
|       |         |+---------+--------+|
|Spot   |Terrier  |+---------+--------+|
|       |         ||OwnerName|Acquired||
|       |         ||string   |string  ||
|       |         |+---------+--------+|
|       |         ||Alice    |2001    ||
|       |         |+---------+--------+|
|Rover  |Retriever|+---------+--------+|
|       |         ||OwnerName|Acquired||
|       |         ||string   |string  ||
|       |         |+---------+--------+|
|       |         ||Mike     |2002    ||
|       |         |+---------+--------+|
|Fred   |Spaniel  |+---------+--------+|
|       |         ||OwnerName|Acquired||
|       |         ||string   |string  ||
|       |         |+---------+--------+|
|       |         ||Jim      |2003    ||
|       |         |+---------+--------+|
|Jumper |Mutt     |+---------+--------+|
|       |         ||OwnerName|Acquired||
|       |         ||string   |string  ||
|       |         |+---------+--------+|
|       |         |+---------+--------+|
+-------+---------+--------------------+
RVA Join
--------
% relformat [relation ungroup $j OwnedBy] "Ungrouping the Owned By Attribute"
+-------+---------+---------+--------+
|DogName|Breed    |OwnerName|Acquired|
|string |string   |string   |string  |
+-------+---------+---------+--------+
|Fido   |Poodle   |Sue      |2001    |
|Fido   |Poodle   |George   |2001    |
|Sam    |Collie   |Sue      |2000    |
|Sam    |Collie   |George   |2000    |
|Spot   |Terrier  |Alice    |2001    |
|Rover  |Retriever|Mike     |2002    |
|Fred   |Spaniel  |Jim      |2003    |
+-------+---------+---------+--------+
Ungrouping the OwnedBy Attribute
--------------------------------
::ralutil::sysIdsInit

The sysIdsInit command initializes a scheme whereby attributes of relvars can be given system generated identifiers. This procedure should be invoked before requesting system generated identifiers via sysIdGenSystemId.

::ralutil::sysIdsGenSystemId relvarName attrName

The sysIdGenSystemId command requests that the attrName attribute of the relvar, relvarName, be assigned a system generated identifier. This procedure uses relvar tracing to assign a unique integer value to attrName when a tuple is inserted into relvarName.

::ralutil::attrConstraint relvarName attrExpr

The attrConstraint command provides a simpler interface to relvar tracing. It adds a variable trace for insert and update on the given relvarName. The trace evaluates attrExpr and if true, allows the insert or update to procede. The expression may contain references to attribute names of the form :<attr name>: (e.g. for an attribute called A1, "expr" may contain tokens of the form, :A1:). When the trace is evaluated, all of the attribute attribute name tokens are replaced by the value of the attribute. The intended use case is when you wish to constrain an attribute value to be within some subrange of the data type. For example, if an int typed attribute called, Status should be greater than 0 and less than 22, then

attrConstraint myRelvar {:Status: > 0 && :Status: < 22}

will install a variable trace on "myRelvar" to insure that each insert or update to it has a proper value for "Status".

See Also

relation, relvar

Keywords

relation, relvar, tuple