The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Muldis::D::Ext::Relation - Muldis D extension adding more generic relational operators

VERSION

This document is Muldis::D::Ext::Relation version 0.90.0.

PREFACE

This document is part of the Muldis D language specification, whose root document is Muldis::D; you should read that root document before you read this one, which provides subservient details.

DESCRIPTION

Muldis D has a mandatory core set of system-defined (eternally available) entities, which is referred to as the Muldis D core or the core; they are the minimal entities that all Muldis D implementations need to provide; they are mutually self-describing and are used to bootstrap the language; any entities outside the core, called Muldis D extensions, are non-mandatory and are defined in terms of the core or each other, but the reverse isn't true.

This current Relation document describes the system-defined Muldis D Relation Extension, which consists of many generic relational operators (for generic relations), adding to the minimum few defined in the language core.

This current document does not describe the polymorphic operators that all types, or some types including core types, have defined over them; said operators are defined once for all types in Muldis::D::Core.

This documentation is pending.

SYSTEM-DEFINED GENERIC SINGLE INPUT RELATION FUNCTIONS

These functions are applicable to mainly relation types, but are generic in that they typically work with any relation types.

sys.std.Relation.d0c0

function sys.std.Relation.d0c0 (Relation <--)

This named_value selector function results in the only zero-attribute, zero-tuple Relation value, which is known by the special name Relation:d0c0, aka d0c0. Note that The Third Manifesto also refers to this value by the special shorthand name TABLE_DUM.

sys.std.Relation.d0c1

function sys.std.Relation.d0c1 (Relation <--)

This named_value selector function results in the only zero-attribute, single-tuple Relation value, which is known by the special name Relation:d0c1, aka d0c1. Note that The Third Manifesto also refers to this value by the special shorthand name TABLE_DEE.

sys.std.Relation.degree

function sys.std.Relation.degree (NNInt <-- Relation $topic)

This function results in the degree of its argument (that is, the count of attributes it has).

sys.std.Relation.is_nullary

function sys.std.Relation.is_nullary (Bool <-- Relation $topic)

This function results in Bool:true iff its argument has a degree of zero (that is, it has zero attributes), and Bool:false otherwise. By definition, the only 2 relation values for which this function would result in Bool:true are the values Relation:d0c[0|1].

sys.std.Relation.is_not_nullary

function sys.std.Relation.is_not_nullary (Bool <-- Relation $topic)

This function is exactly the same as sys.std.Relation.is_nullary except that it results in the opposite boolean value when given the same argument.

sys.std.Relation.has_attrs

function sys.std.Relation.has_attrs (Bool <-- Relation $topic, set_of.Name $attr_names)

This function results in Bool:true iff, for every one of the attribute names specified by its attr_names argument, its topic argument has an attribute with that name; otherwise it results in Bool:false. As a trivial case, this function's result is Bool:true if attr_names is empty.

sys.std.Relation.attr_names

function sys.std.Relation.attr_names (set_of.Name <-- Relation $topic)

This function results in the set of the names of the attributes of its argument.

sys.std.Relation.is_empty

function sys.std.Relation.is_empty (Bool <-- Relation $topic)

This function results in Bool:true iff its argument has a cardinality of zero (that is, it has zero tuples), and Bool:false otherwise. Note that if you are using a Maybe to represent a sparse data item, analagously to a SQL nullable context, then testing the Maybe with is_empty is analagous to testing a SQL nullable with is null.

sys.std.Relation.is_not_empty

function sys.std.Relation.is_not_empty (Bool <-- Relation $topic)

This function is exactly the same as sys.std.Relation.is_empty except that it results in the opposite boolean value when given the same argument. And following the analogy with is_empty, is_not_empty is analagous to SQL's is not null.

sys.std.Relation.has_key

function sys.std.Relation.has_key (Bool <-- Relation $topic, set_of.Name $attr_names)

This function results in Bool:true iff its topic argument has a (unique) key over the subset of its attributes whose names are specified by its attr_names argument; otherwise it results in Bool:false. This function will fail if topic does not have all of the attributes named by attr_names. As a trivial case, this function's result is Bool:true if topic is empty.

sys.std.Relation.empty

function sys.std.Relation.empty (Relation <-- Relation $topic)

This function results in the empty relation of the same heading of its argument, that is having the same degree and attribute names; it has zero tuples.

sys.std.Relation.power_set

function sys.std.Relation.power_set (set_of.Relation <-- Relation $topic)

This function results in the power set of its argument. The result is a Set whose sole attribute is Relation-typed (its type is nominally the same as that of the argument) and which has a tuple for every distinct subset of tuples in the argument. The cardinality of the result is equal to 2 raised to the power of the cardinality of the argument (which may easily lead to a very large result, so use this function with care). Note that the N-adic relational union of the power set of some relation is that relation; the N-adic intersection of any power set is the empty relation.

sys.std.Relation.tclose

function sys.std.Relation.tclose (Relation <-- Relation $topic)

This function results in the transitive closure of its argument. The argument must be a binary relation whose attributes are both of the same type, and the result is a relation having the same heading and a body which is a superset of the argument's tuples. Assuming that the argument represents all of the node pairs in a directed graph that have an arc between them, and so each argument tuple represents an arc, tclose will determine all of the node pairs in that graph which have a path between them (a recursive operation), so each tuple of the result represents a path. The result is a superset since all arcs are also complete paths. The tclose function is intended to support recursive queries, such as in connection with the "part explosion problem" (the problem of finding all components, at all levels, of some specified part).

sys.std.Relation.classification

function sys.std.Relation.classification (Relation <-- Relation $topic, ValMapFuncRef $func, Name $class_attr_name, Name $group_attr_name)

This function conceptually is to sys.std.Core.Relation.restriction what sys.std.Core.Relation.group is to sys.std.Core.Relation.semijoin. It classifies the tuples of topic into N groups using the value_map function named by func, such that any distinct tuples are in a common group if the function named by func results in the same value when given either of those tuples as its topic argument. This function conceptually is a short-hand for first extending topic with a new attribute whose name is given in class_attr_name, whose value per tuple is determined from topic using func, and then grouping that result relation on all of its original attributes, with the post-group RVA having the name given in group_attr_name; the result of classification is a binary relation whose 2 attributes have the names given in class_attr_name and group_attr_name. This function is intended for use when you want to partition a relation's tuples into an arbitrary number of groups using arbitrary criteria, in contrast with restriction where you are dividing into exactly 2 groups (and returning one) using arbitrary criteria.

sys.std.Relation.reduction

function sys.std.Relation.reduction (Tuple <-- Relation $topic, ValRedFuncRef $func, Tuple $identity)

This function is a generic reduction operator that recursively takes each pair of tuples in topic and applies an argument-specified tuple value-resulting value_reduction function (which is both commutative and associative) to the pair until just one input tuple is left, which is the result. The value_reduction function to apply is named in the func argument, and that function must have 2 parameters named v1 and v2, which take the 2 input tuples for an invocation. If topic has zero tuples, then reduction results in the tuple given in identity. Note that identity may be changed to take a function name rather than a value, for consistency with func. This function will fail|warn if the |declared headings of identity and topic aren't compatible.

sys.std.Relation.maybe_reduction

function sys.std.Relation.maybe_reduction (maybe_of.Tuple <-- Relation $topic, ValRedFuncRef $func)

This function is exactly the same as sys.std.Relation.reduction except that it does not take an identity argument, and it results in a Maybe of what is otherwise the result type, and that result has zero elements if the argument has zero elements.

sys.std.Relation.map

function sys.std.Relation.map (Relation <-- Relation $topic, set_of.Name $result_attr_names, ValMapFuncRef $func)

This function provides a convenient one-place generalization of per-tuple transformations that otherwise might require the chaining of up to a half-dozen other operators like projection, extension, and rename. This function results in a relation each of whose tuples is the result of applying, to each of the tuples of its topic argument, the Tuple-resulting value_map function named in its func argument. There is no restriction on what attributes the result tuple of func may have (except that all tuples from func must have compatible headings); this tuple from func would completely replace the original tuple from topic. The result relation has a cardinality that is the same as that of topic, unless the result of func was redundant tuples, in which case the result has appropriately fewer tuples. As a trivial case, if func is defined to unconditionally result in the same tuple as its own topic argument, then this function results simply in topic; or, if func is defined to have a static result, then this function's result will have just 0..1 tuples. Now, map requires the extra result_attr_names argument to prevent ambiguity in the general case where topic might have zero tuples, because in that situation, func would never be invoked, and the names of the attributes of the result are not known (we don't generally assume that map can reverse-engineer func to see what attributes it would have resulted in). This function will fail if topic has at least 1 tuple and the result of func does not have matching attribute names to those named by result_attr_names.

SYSTEM-DEFINED GENERIC MULTIPLE INPUT RELATION FUNCTIONS

These functions are applicable to mainly relation types, but are generic in that they typically work with any relation types.

sys.std.Relation.is_proper_subset

function sys.std.Relation.is_proper_subset (Bool <-- Relation $topic, Relation $other)

This function is exactly the same as sys.std.Core.Relation.is_subset except that it results in Bool:false if its 2 arguments are identical. Note that this operation is also known as .

sys.std.Relation.is_not_proper_subset

function sys.std.Relation.is_not_proper_subset (Bool <-- Relation $topic, Relation $other)

This function is exactly the same as sys.std.Relation.is_proper_subset except that it results in the opposite boolean value when given the same arguments. Note that this operation is also known as .

sys.std.Relation.is_proper_superset

function sys.std.Relation.is_proper_superset (Bool <-- Relation $topic, Relation $other)

This function is an alias for sys.std.Relation.is_proper_subset except that it transposes the topic and other arguments. This function is exactly the same as sys.std.Core.Relation.is_superset except that it results in Bool:false if its 2 arguments are identical. Note that this operation is also known as .

sys.std.Relation.is_not_proper_superset

function sys.std.Relation.is_not_proper_superset (Bool <-- Relation $topic, Relation $other)

This function is an alias for sys.std.Relation.is_not_proper_subset except that it transposes the topic and other arguments. This function is exactly the same as sys.std.Relation.is_proper_superset except that it results in the opposite boolean value when given the same arguments. Note that this operation is also known as .

sys.std.Relation.is_disjoint

function sys.std.Relation.is_disjoint (Bool <-- Relation $topic, Relation $other)

This symmetric function results in Bool:true iff the set of tuples comprising each of its 2 arguments are mutually disjoint, that is, iff the intersection of the 2 arguments is empty; it results in Bool:false otherwise.

sys.std.Relation.is_not_disjoint

function sys.std.Relation.is_not_disjoint (Bool <-- Relation $topic, Relation $other)

This symmetric function is exactly the same as sys.std.Relation.is_disjoint except that it results in the opposite boolean value when given the same arguments.

sys.std.Relation.exclusion

function sys.std.Relation.exclusion (Relation <-- bag_of.Relation $topic)

This function results in the relational exclusion/exclusive-or of the N element values of its argument; it is a reduction operator that recursively takes each pair of input values and relationally excludes (which is both commutative and associative) them together until just one is left, which is the result. The result relation has the same heading as all of its inputs, and its body contains every tuple that is in just an odd number of the input relations. Matters concerning a topic with zero values are as per sys.std.Core.Relation.union; this function will fail when given such, and the per-distinct-heading identity value for relational exclusion is the same as for relational union. Note that this operation is also known as symmetric difference or .

sys.std.Relation.symmetric_diff

function sys.std.Relation.symmetric_diff (Relation <-- bag_of.Relation $topic)

This function is an alias for sys.std.Relation.exclusion.

sys.std.Relation.composition

function sys.std.Relation.composition (Relation <-- Relation $topic, Relation $other)

This symmetric function results in the relational composition of its 2 arguments. It is conceptually a short-hand for first doing an ordinary relational join between its 2 arguments, and then performing a relational projection on all of the attributes that only one of the arguments has; that is, the result has all of and just the attributes that were not involved in matching the tuples of the 2 arguments. This function will fail|warn any time that join would fail|warn on the same 2 input relations.

sys.std.Relation.join_with_group

function sys.std.Relation.join_with_group (Relation <-- Relation $primary, Relation $secondary, Name $group_attr)

This function is a short-hand for first taking a (natural inner) join of its primary and secondary arguments, and then taking a group on all of the attributes that only the secondary argument had, such that the attribute resulting from the group has the name group_attr. The result has 1 tuple for every tuple of primary where at least 1 matching tuple exists in secondary. This function will fail if group_attr is the same name as any source attribute that wasn't grouped. This function is a convenient tool for gathering both parent and child records from a database using a single query while avoiding duplication of the parent record values.

SYSTEM-DEFINED RELATIONAL RANKING AND QUOTA FUNCTIONS

These additional functions are specific to supporting ranking and quotas.

sys.std.Relation.rank

function sys.std.Relation.rank (Relation <-- Relation $topic, Name $name, OrdDetFuncRef $ord_func, Bool $is_reverse_order?)

This function results in the relational extension of its topic argument by a single NNInt-typed attribute whose name is provided by the name argument, where the value of the new attribute for each tuple is the rank of that tuple as determined by the (total) order_determination function named in the ord_func argument when the latter function is curried by the is_reverse_order argument. The order_determination function compares tuples, with each invocation of it getting a topic tuple as each its topic and other arguments. The new attribute of rank's result has a value of zero for its ranked-first tuple, and each further consecutive ranked tuple has the next larger integer value. Note that rank provides the functionality of SQL's "RANK" feature but that the result of rank is always a total ordering (as per a (total) order_determination function) and so there is no "dense" / "not dense" distinction (however a partial ordering can be implemented over it). See also the sys.std.Array.Array_from_wrap function, which is the same as sys.std.Relation.rank but that it wraps the source tuples rather than just adding an attribute to them.

sys.std.Relation.rank_by_attr_names

function sys.std.Relation.rank_by_attr_names (Relation <-- Relation $topic, Name $name, array_of.OrderByName $order_by, Bool $is_reverse_order?)

This function is a short-hand for invoking rank with the function sys.std.Tuple.order_by_attr_names as its ord_func argument after the latter is curried with this function's order_by argument.

sys.std.Relation.limit

function sys.std.Relation.limit (Relation <-- Relation $topic, OrdDetFuncRef $ord_func, NNInt $min_rank, NNInt $max_rank, Bool $is_reverse_order?)

This function results in the relational restriction of its topic argument as determined by first ranking its tuples as per rank function (using ord_func and is_reverse_order) and then keeping just those tuples whose rank is within the inclusive range specified by the min_rank and max_rank arguments (rank's extra attribute is not kept). The limit function implements a certain kind of quota query where all the result tuples are consecutive in their ranks. This function will fail if max_rank is before min_rank. It is valid for min_rank or max_rank to be greater than the maximum rank of the source tuples; in the first case, the result has zero tuples; in the second case, the result has all remaining tuples starting at min_rank. If topic has any tuples and min_rank matches the rank of a source tuple, then the result will always have at least 1 tuple. Note that limit provides the functionality of SQL's "LIMIT/OFFSET" feature in combination with "ORDER BY" but that the result tuples of limit do not remain ordered (but see sys.std.Array.limit_of_Array_from_wrap for an alternative).

sys.std.Relation.limit_by_attr_names

function sys.std.Relation.limit_by_attr_names (Relation <-- Relation $topic, array_of.OrderByName $order_by, NNInt $min_rank, NNInt $max_rank, Bool $is_reverse_order?)

This function is to limit what rank_by_attr_names is to rank.

SYSTEM-DEFINED RELATIONAL SUBSTITUTION FUNCTIONS

These additional functions are specific to supporting substitutions.

sys.std.Relation.substitution

function sys.std.Relation.substitution (Relation <-- Relation $topic, set_of.Name $attr_names, ValMapFuncRef $func)

This function is similar to extension except that it substitutes values of existing relation attributes rather than adding new attributes. The result relation has the same heading as topic. The result tuple of the value_map function named in func must have a heading that is a subset of the heading of topic; corresponding values resulting from the function named in func will replace the values of the tuples of topic. The result relation has a cardinality that is the same as that of topic, unless the result of any substitutions was redundant tuples, in which case the result has appropriately fewer tuples. As a trivial case, if func is defined to unconditionally result in either the degree-zero tuple or in the same tuple as its own topic argument, then this function results simply in topic; or, if func is defined to have a static result and it replaces all attributes, then this function's result will have just 0..1 tuples. Now, strictly speaking, substitution could conceivably be implemented such that each result from func is allowed to specify replacement values for different subsets of topic attributes; however, to improve the function's predictability and ease of implementation over disparate foundations, substitution requires the extra attr_names argument so that users can specify a consistent subset that func will update (possibly to itself). This function will fail if topic has at least 1 tuple and the result of func does not have matching attribute names to those named by attr_names.

sys.std.Relation.static_subst

function sys.std.Relation.static_subst (Relation <-- Relation $topic, Tuple $attrs)

This function is a simpler-syntax alternative to sys.std.Relation.substitution in the typical scenario where every tuple of a relation, given in the topic argument, is updated with identical values for the same attributes; the new attribute values are given in the attrs argument.

sys.std.Relation.subst_in_restr

function sys.std.Relation.subst_in_restr (Relation <-- Relation $topic, ValFiltFuncRef $restr_func, set_of.Name $subst_attr_names, ValMapFuncRef $subst_func)

This function is like substitution except that it only transforms a subset of the tuples of topic rather than all of them. It is a short-hand for first separating the tuples of topic into 2 groups where those passed by a relational restriction (defined by restr_func) are then transformed (defined by subst_attr_names and subst_func), then the result of the substitution is unioned with the un-transformed group. See also the subst_in_semijoin function, which is a simpler-syntax alternative for subst_in_restr in its typical usage where restrictions are composed simply of anded or ored tests for attribute value equality.

sys.std.Relation.static_subst_in_restr

function sys.std.Relation.static_subst_in_restr (Relation <-- Relation $topic, ValFiltFuncRef $restr_func, Tuple $subst)

This function is to sys.std.Relation.subst_in_restr what sys.std.Relation.static_subst is to sys.std.Relation.substitution. See also the static_subst_in_semijoin function.

sys.std.Relation.subst_in_semijoin

function sys.std.Relation.subst_in_semijoin (Relation <-- Relation $topic, Relation $restr, set_of.Name $subst_attr_names, ValMapFuncRef $subst_func)

This function is like subst_in_restr except that the subset of the tuples of topic to be transformed is determined by those matched by a semijoin with restr rather than those that pass a generic relational restriction.

sys.std.Relation.static_subst_in_semijoin

function sys.std.Relation.static_subst_in_semijoin (Relation <-- Relation $topic, Relation $restr, Tuple $subst)

This function is to sys.std.Relation.subst_in_semijoin what sys.std.Relation.static_subst is to sys.std.Relation.substitution.

SYSTEM-DEFINED RELATIONAL OUTER-JOIN FUNCTIONS

These additional functions are specific to supporting outer-joins.

sys.std.Relation.outer_join_with_group

function sys.std.Relation.outer_join_with_group (Relation <-- Relation $primary, Relation $secondary, Name $group_attr)

This function is the same as sys.std.Relation.join_with_group except that it results in a half-outer natural join rather than an inner natural join; every tuple of primary has exactly 1 corresponding tuple in the result, but where there were no matching secondary tuples, the result attribute named by group_attr contains zero tuples rather than 1+.

sys.std.Relation.outer_join_with_maybes

function sys.std.Relation.outer_join_with_maybes (Relation <-- Relation $primary, Relation $secondary)

This function results in a plain half-outer natural join of its primary and secondary arguments where all the result attributes that come from just secondary are Maybe-typed; for result tuples from matched source tuples, each secondary attribute value is a Single; for result tuples from non-matched primary tuples, each secondary attribute value is nothing. The outer_join_with_maybes function is Muldis D's answer to the SQL LEFT OUTER JOIN where SQL NULL is implicitly used in result rows that were a non-match.

sys.std.Relation.outer_join_with_defaults

function sys.std.Relation.outer_join_with_defaults (Relation <-- Relation $primary, Relation $secondary, TypeRef $filler)

This function is the same as sys.std.Relation.outer_join_with_static_exten but that the filler tuple is the default value of the tuple data type whose name is given in the filler argument. This function is a short-hand for invoking outer_join_with_static_exten with the result from invoking sys.std.Core.Universal.default.

sys.std.Relation.outer_join_with_static_exten

function sys.std.Relation.outer_join_with_static_exten (Relation <-- Relation $primary, Relation $secondary, Tuple $filler)

This function is the same as sys.std.Relation.outer_join_with_maybes but that secondary-sourced result attributes are not converted to Maybe; rather, for result tuples from non-matches, the missing values are provided explicitly from the filler argument, which is a tuple whose heading matches the projection of secondary's attributes that aren't in common with primary, and whose body is the specific values to use for those missing attribute values.

sys.std.Relation.outer_join_with_exten

function sys.std.Relation.outer_join_with_exten (Relation <-- Relation $primary, Relation $secondary, ValMapFuncRef $exten_func)

This function is the same as sys.std.Relation.outer_join_with_static_exten but that the result tuples from non-matches are the result of performing a relational extension on the un-matched primary tuples such that each said result tuple is determined by applying the function named in exten_func to each said primary tuple.

SYSTEM-DEFINED GENERIC RELVAR UPDATERS

sys.std.Relation.assign_empty

updater sys.std.Relation.assign_empty (Relation &$topic)

This update operator is a short-hand for first invoking the sys.std.Relation.empty function with the same argument, and then assigning the result of that function to topic. This updater is analagous to the SQL "TRUNCATE" statement.

sys.std.Relation.assign_exclusion

updater sys.std.Relation.assign_exclusion (Relation &$topic, Relation $other)

This update operator is a short-hand for first invoking the sys.std.Relation.exclusion function such that it has 2 input relations from assign_exclusion's 2 arguments, and then assigning the result of that function to topic.

sys.std.Relation.assign_substitution

updater sys.std.Relation.assign_substitution (Relation &$topic, set_of.Name $attr_names, ValMapFuncRef $func)

This update operator is a short-hand for first invoking the sys.std.Core.Relation.substitution function with the same arguments, and then assigning the result of that function to topic. This updater is analagous to the general case of the unconditional SQL "UPDATE" statement.

sys.std.Relation.assign_static_subst

updater sys.std.Relation.assign_static_subst (Relation &$topic, Tuple $attrs)

This update operator is a short-hand for first invoking the sys.std.Core.Relation.static_subst function with the same arguments, and then assigning the result of that function to topic.

sys.std.Relation.assign_subst_in_restr

updater sys.std.Relation.assign_subst_in_restr (Relation &$topic, ValFiltFuncRef $restr_func, set_of.Name $subst_attr_names, ValMapFuncRef $subst_func)

This update operator is a short-hand for first invoking the sys.std.Core.Relation.subst_in_restr function with the same arguments, and then assigning the result of that function to topic. This updater is analagous to the general case of the conditional SQL "UPDATE" statement.

sys.std.Relation.assign_static_subst_in_restr

updater sys.std.Relation.assign_static_subst_in_restr (Relation &$topic, ValFiltFuncRef $restr_func, Tuple $subst)

This update operator is a short-hand for first invoking the sys.std.Core.Relation.static_subst_in_restr function with the same arguments, and then assigning the result of that function to topic.

sys.std.Relation.assign_subst_in_semijoin

updater sys.std.Relation.assign_subst_in_semijoin (Relation &$topic, Relation $restr, set_of.Name $subst_attr_names, ValMapFuncRef $subst_func)

This update operator is a short-hand for first invoking the sys.std.Core.Relation.subst_in_semijoin function with the same arguments, and then assigning the result of that function to topic. This updater is analagous to the common case of the conditional SQL "UPDATE" statement where the criteria is simply a set of and-ed and or-ed value equality tests.

sys.std.Relation.assign_static_subst_in_semijoin

updater sys.std.Relation.assign_static_subst_in_semijoin (Relation &$topic, Relation $restr, Tuple $subst)

This update operator is a short-hand for first invoking the sys.std.Core.Relation.static_subst_in_semijoin function with the same arguments, and then assigning the result of that function to topic.

SEE ALSO

Go to Muldis::D for the majority of distribution-internal references, and Muldis::D::SeeAlso for the majority of distribution-external references.

AUTHOR

Darren Duncan (perl@DarrenDuncan.net)

LICENSE AND COPYRIGHT

This file is part of the formal specification of the Muldis D language.

Muldis D is Copyright © 2002-2009, Muldis Data Systems, Inc.

See the LICENSE AND COPYRIGHT of Muldis::D for details.

TRADEMARK POLICY

The TRADEMARK POLICY in Muldis::D applies to this file too.

ACKNOWLEDGEMENTS

The ACKNOWLEDGEMENTS in Muldis::D apply to this file too.