We turn now to types that are obtained by invoking sometype generator. Abstractly, atype generatoris just a special kind of operator; it is special because (a) it returns a type instead of, e.g., a scalar value, and (b) the invocation occurs at compile time instead of run time. For example, we might write
VAR SALES ARRAY QTY (12) ;
quantities.1 In this example, the expression ARRAY QTY (12) can be regarded as an invocation of the ARRAY type generator, and it returns a specific array type. That specific array type is a generated type(a nonscalar generated type, as it happens, though scalar generated types are possible too). Points arising:
1. Type generators are known by many different names in the literature:type constructors, parameterized types, polymorphic types, type templates, generic types,possibly others too. 2. Generated types are indeed types, and can be used wherever ordinary (nongenerated) types
can be used. For example, we might define some relvar to have some attribute of type ARRAY QTY (12). By contrast, type generators as such arenottypes.
3. Like types, type generators can be either system or user defined, in general. In other words, the system might allow users to define their own type generators (though we do not requireD to support such functionality, andTutorial Din particular does not do so).
4. A generated type is system or user defined according as the corresponding type generator is system or user defined.
In general, generated types have possreps—or, at least, can be thought of as having possreps—that are derived in a fairly obvious way from (a) agenericpossrep that applies to the type generator in question and (b) the user-visible component(s) of the specific generated type in question. In the case of ARRAY QTY (12), for example:
■ There will be some generic possrep defined for one-dimensional arrays in general: probably as a sequence ofarray elementsthat can be identified by subscripts in the range fromlowerto
upper,wherelowerandupperare the applicable bounds (1 and 12, in our example). ■ The user-visible components are precisely the 12 array elements just mentioned.
In like manner, there will be operators that provide the required selector and THE_ operator functionality. For example, the expression (actually an array literal)
ARRAY QTY ( QTY( 2), QTY( 5), QTY( 9), QTY( 9), QTY(15), QTY(27), QTY(33), QTY(32),
QTY(25), QTY(19), QTY( 5), QTY( 1) )
might be used to specify a particular value of type ARRAY QTY (12) (“selector functionality”). Likewise, the expression
SALES (3)
might be used to access the third component (i.e., the third array element) of the array value that
1 The examples in this section are not formulated in terms of pureTutorial DbecauseTutorial Ddoes not support
general-purpose arrays—but arrays are such a familiar construct that it seemed a good idea to use them as a basis for this discussion.
happens to be the current value of the array variable SALES (“THE_ operator functionality”). It might also be used as a pseudovariable reference, as here:
SALES (3) := QTY(17) ;
Assignment and equality comparison operators also apply to values and variables of the generated type. For example, here is a valid assignment:
SALES := ARRAY QTY ( QTY( 2), QTY( 5), QTY( 9), QTY( 9), QTY(15), QTY(27), QTY(33), QTY(32),
QTY(25), QTY(19), QTY( 5), QTY( 1) ) ;
And here is a valid equality comparison:
SALES = ARRAY QTY ( QTY( 2), QTY( 5), QTY( 9), QTY( 9), QTY(15), QTY(27), QTY(33), QTY(32), QTY(25), QTY(19), QTY( 5), QTY( 1) )
Note: Any given type generator will also have a set of generic constraints and generic operators associated with it (generic in the sense that the constraints and operators in question will apply to every specific type obtained via invocation of the type generator in question). For
example, in the case of the ARRAY type generator:
■ There might be a generic constraint to the effect that the lower bound must not be greater than the upper bound.
■ There might be a generic “reverse” operator that takes an arbitrary one-dimensional array as input and returns as output another such array containing the elements of the given one in reverse order.
In fact, the “selectors,” “THE_ operators,” and assignment and equality comparison operators already discussed are also effectively derived from certain generic operators.
Of course, the type generators that are of particular interest in this book are TUPLE and (especially) RELATION. See Chapters 4-6 for further discussion.
CONCLUDING REMARKS
As noted in earlier, the material of this chapter is likely to be less familiar to many readers than that of Chapter 2 was. It is therefore worth summarizing the main points we have covered.
First of all, a type isa named, finite set of values:namely, the set of all values that satisfy a certaintype constraint,which is specified inTutorial D,in the case of scalar types specifically, by a POSSREP definition and its subordinate CONSTRAINT specification.1 Every type has an
associated set ofread-onlyandupdate operatorsfor operating on values and variables of the type in question. Values and variables are always typed; so also areattributes,(read-only)operators, parameters,and more generallyexpressionsof arbitrary complexity.
Types can be arbitrarily complex; thus, we can have types whose values are numbers, or strings, or dates, or times, or audio recordings, or maps, or video recordings, or XML documents, or geometric points (and so on). Typesconstrain operations,in that the operands to any given
operation are required to be of the types defined for that operation (strong typing). Strong typing is a good idea because it allows certain errors to be caught (preferably at compile time, otherwise at run time).
Types can besystemoruser defined;they can also bescalarornonscalar. A scalar type has no user-visible components. (The most importantnonscalar types in the relational model are
relation types, which were discussed in Chapter 2.) We distinguish betweentypesand theirphysical representation(types are amodelissue, physical representations are animplementationissue). However, we do require that user-defined scalar types in particular have at least one explicitly declaredpossiblerepresentation or “possrep.” Each such possrep causes automatic definition of oneselectoroperator and, for each component of that possrep, oneTHE_operator (also a corresponding THE_pseudovariable). We support explicittype conversionsbut no implicit
coercions. We also support the definition of any number of additional operators for scalar types, and we require thatequality comparison(“=”) andassignmentbe available for every type (with prescribed semantics).
We also discussedtype generators,which are compile-time operators that return types (ARRAY is a typical example, though not one that is supported inTutorial D). Generated types have possreps (of a kind), constraints, and operators that are derived from thegenericpossreps, constraints, and operators associated with the applicable type generator.
One final point (not mentioned explicitly in the body of the chapter): Recall from Chapter 1 that values—and hencesetsof values also—“have no location in time or space”; conceptually, those sets of values already exist, and always will exist (think of type INTEGER, for example). It follows in particular that the operation that defines a scalar type (the TYPE statement, inTutorial D) does not actually create the corresponding set of values; all it does is introduce anameby which that set of values can be referenced. Likewise, the operation that destroys a scalar type (DROP TYPE in Tutorial D) does not actually destroy the corresponding set of values, it merely drops the name that was introduced by the corresponding type definition.
EXERCISES
3.1 What is a type? 3.2 What is a literal?
3.3 State the rules regarding operand types for the assignment (“:=”) and equality comparison (“=”) operators.
3.4 Elaborate on the following logical differences: argument vs. parameter
generated type vs. nongenerated type physical representation vs. possible representation read-only operator vs. update operator
scalar vs. nonscalar
type vs. representation
user-defined type vs. system-defined type user-defined operator vs. system-defined operator
3.5 Why is it desirable to distinguish between read-only and update operators?
3.6 Explain the following in your own words: coercion; ordinal type; polymorphic operator; pseudovariable; selector; strong typing; THE_ operator; type generator.
3.7 Why are pseudovariables logically unnecessary?
3.8 Give some examples of polymorphic operators. Are the operators of the relational algebra polymorphic? What about aggregate operators such as SUM?
3.9 Define an operator that, given a rational number, returns the cube of that number.
3.10 Define a read-only operator that, given a point with cartesian coordinatesxandy,returns the point with cartesian coordinatesf(x) andg(y), wherefandgare predefined operators (of type RATIONAL in each case).
3.11 Repeat Exercise 3.10 but make the operator an update operator.
3.12 Give a type definition for a scalar type called CIRCLE whose values are circles in two- dimensional euclidean space. What selectors and THE_ operators apply to this type? Also: a. Define a set of read-only operators to compute the diameter, circumference, and area of
a given circle.
b. Define an update operator to double the radius of a given circle (more precisely, to update a given variable of type CIRCLE in such a way that its circle value is unchanged except that the radius is twice what it was before).
3.13 Give some examples of types for which it might be useful to define two or more distinct possreps. Can you think of an example where distinct possreps for the same type have different numbers of components?
3.14 Give an appropriate set of scalar type definitions for the suppliers-and-parts database. Do not attempt to write the relvar definitions.
3.15 We pointed out in the section “Selectors and THE_ Operators” in this chapter that it is strictly incorrect to say that (e.g.) the quantity for a certain shipment is 100 (“a quantity is a value of type QTY, not a value of type INTEGER”). As a consequence, Fig. 2.1 (in Chapter 2) is rather sloppy, inasmuch as it pretends that itiscorrect to think of, e.g., quantities as integers. Given your answer to Exercise 3.14, show the correct way of referring to the various scalar values in that figure.
3.16 Given your answer to Exercise 3.14, which of the following scalar expressions are valid? For those that are, state the type of the result; for the others, show an expression that will achieve what appears to be the desired effect.
a. CITY = 'London' b. SNAME || PNAME c. QTY * 100 d. QTY + 100 e. STATUS + 5 f. 'ABC' < CITY g. COLOR = CITY h. CITY || 'burg'
3.17 It is sometimes suggested that types are really variables, in a sense. For example, employee numbers might grow from three digits to four as a business expands, so we might need to update “the set of all possible employee numbers.” Discuss.
3.18 A type is a set of values, so (as noted in the introduction to this chapter) we can define an
emptytype to be a type where the set in question is empty. Can you think of any uses for such a type?
3.19 A possrep has a set of components, so we might define some type as having an empty possrep. What are the implications?
3.20 TheManifestorequires “=” to apply to every type; more specifically, it requiresv1=v2to evaluate to TRUE if and only ifv1andv2are the very same value. SQL, by contrast, does not require “=” to apply to every type, nor does it prescribe the semantics in all cases where it does apply. What are the implications of this state of affairs?
3.21 (For discussion) As noted in the body of the chapter, there are those who would claim that XML technology is destined to replace relational technology. There is an XML data model (actually several different ones, of which the most important is probablythe semistructured data model); there is an XML data definition language (actually at least two of them); there is an XML query language (at least three of them); and there are XML databases and XML DBMSs. What do you think is the true nature—the true technical nature, that is—of the relationship between these developments and relational technology? Note: A tutorial on XML from a database perspective can be found in Chapter 27 of reference [76].