Declarative Objectivity (DO) Language : Schema Clauses : ALTER CLASS Clause
ALTER CLASS Clause
An ALTER CLASS clause enables you to add, delete, or rename attributes of an existing class in the schema of a federated database.   
Syntax 
alterClassClause : ALTER CLASS className attributeActions;
attributeActions : '{' attributeAction ( ',' attributeAction)* '}' ;
attributeAction : (ADD attributeStructure) | (RENAME name TO name) | (DROP name);
Used In 
UPDATE SCHEMA Statement
Quick Look 
Add three new attributes to the FleetData.Vehicle class:
UPDATE SCHEMA 
{
   ALTER CLASS FleetData.Vehicle 
   {
     ADD acquisitionDate : Date,
     ADD vehicleIdNumber : String,
     ADD serviceRecords : List {Element: String}
   }
};
Rename an attribute within the FleetData.RentalCompany class:
UPDATE SCHEMA
{
   ALTER CLASS FleetData.RentalCompany 
   {
      RENAME address TO corporateAddress
   }
};
Delete an attribute called temporary from the FleetData.RentalCompany class:
UPDATE SCHEMA
{
   ALTER CLASS FleetData.RentalCompany 
   {
      DROP temporary
   }
};
Change multiple attributes within a single class:
UPDATE SCHEMA
{
   ALTER CLASS FleetData.RentalCompany 
   {
     DROP temporary,
     ADD highVolumeDates: List {Element: Date},
     RENAME corporateName TO name
   }
};
Discussion 
An ALTER CLASS clause is an action clause of an UPDATE SCHEMA Statement. The clause:
Instructs UPDATE SCHEMA to modify the content of an existing schema class.
Identifies the class to be modified.
Specifies one or more comma-separated attribute actions. An attribute action may add, rename, or delete an attribute of the modified class.
You may include any number of attribute actions within a single ALTER CLASS clause. Each action is introduced by a keyword (ADD, RENAME, or DROP) specifying the kind of change to be made, and the name of the attribute to be changed. You enclose the list of attribute actions in curly braces. All of the attribute actions included within a particular ALTER CLASS clause apply to a single specified className.
You may include any number of ALTER CLASS clauses in a single UPDATE SCHEMA statement. However, you may not use a single UPDATE SCHEMA statement to both drop an attribute from a class and then add a new attribute with the same name to the same class. (These actions must be split into separate UPDATE SCHEMA statements.)
The ADD, RENAME, and DELETE attribute actions are the only kinds of changes you can make using a single ALTER CLASS clause. Other changes—such as modifying an attribute’s data type—require multiple ALTER CLASS clauses in separate UPDATE SCHEMA statements; see Changing the Data Type of Attributes.
The results of the specified attribute actions become available to concurrent database access when the enclosing UPDATE SCHEMA statement returns. No class is altered if the enclosing UPDATE SCHEMA statement returns an error.
Adding Attributes to a Class
You can use an ALTER CLASS clause to add one or more new attributes to an existing schema class. You specify each new attribute using the ADD keyword followed by an attribute structure describing the new attribute’s name and type characteristics.
   ALTER CLASS FleetData.Vehicle 
   {
     ADD acquisitionDate : Date
   }
If the altered class is the superclass of another class, the new attribute is added to the subclass, as well.
If the altered class has existing objects that were created under the original class description, space is added to each object to accommodate values of the new attributes. You can use an UPDATE statement with a SET clause to assign values to the new attributes.
Adding Bidirectional Relationships
You can add a bidirectional relationship that links two different classes. Recall that a bidirectional relationship is really a pair of reference attributes, where each attribute names the other as its inverse. You must add both of the new inverse attributes in the same operation, by including two ALTER CLASS clauses in the same UPDATE SCHEMA statement.
Example. The ALTER CLASS clauses in the following UPDATE SCHEMA statement add two new reference attributes—one in the RentalCompany class and one in the RentalContract class. Each new reference attribute names the other as its inverse.
UPDATE SCHEMA
{
   ALTER CLASS FleetData.RentalCompany {
      ADD contracts : Reference {
         Referenced : FleetData.RentalContract, 
         Inverse: company
      }
   }
 
   ALTER CLASS FleetData.RentalContract {
      ADD company : Reference {
         Referenced : FleetData.RentalCompany, 
         Inverse: contracts
      }
   }
};
Note:For clarity, this example includes the Inverse: setting explicitly in both attribute definitions. For convenience, you can omit this setting from one of them, and DO will automatically insert it.
Note:You can create a bidirectional relationship from an existing unidirectional relationship; see Changing a Unidirectional Relationship to Be Bidirectional. Besides adding a new inverse attribute, you must also change the data type of the existing reference attribute so that it specifies the inverse.
Renaming Attributes in a Class
You can use an ALTER CLASS clause to rename one or more existing attributes in an existing schema class. For each attribute to be renamed, you use the RENAME TO keyword to specify the attribute’s current name and its new name.
   ALTER CLASS FleetData.RentalCompany 
   {
      RENAME address TO corporateAddress
   }
If the altered class is the superclass of another class, the renamed attribute is renamed in the subclass, as well.
If the altered class has existing objects that were created under the original class description, no change is made to the size or content of those objects. When querying for the values of a renamed attribute, you must use attribute’s new name.
Renaming a Reference Attribute in a Bidirectional Relationship
You can rename an existing reference attribute that is part of a bidirectional relationship. Recall that a bidirectional relationship is really a pair of reference attributes, where each attribute names the other as its inverse. You can rename either of the reference attributes as you would any other attribute, by including an ALTER CLASS clause in an UPDATE SCHEMA statement. This operation automatically adjusts the name of the inverse within the description of other reference attribute.
Example. The RentalCompany has a contracts attribute that is the inverse of the company attribute in the RentalContracts class. The following UPDATE SCHEMA statement uses an ALTER CLASS clause to explicitly rename the contracts attribute of the RentalCompany class:
UPDATE SCHEMA
{
   ALTER CLASS FleetData.RentalCompany 
   {
      RENAME contracts TO rentalContracts 
   }
};
Besides performing the explicit rename, this operation also implicitly changes the name of the inverse specified by the company attribute of the RentalContract class. You can verify this by showing the updated definition of the RentalContract class:
SHOW CLASS FleetData.RentalContract;
 
CLASS FleetData.RentalContract {
...
   company: Reference { 
      Referenced: FleetData.RentalCompany, 
      Inverse: rentalContracts }
...
}
Deleting Attributes from a Class
You can use an ALTER CLASS clause to delete one or more existing attributes from an existing schema class. For each attribute to be deleted, you use the DROP keyword to specify the unwanted attribute’s name.
   ALTER CLASS FleetData.RentalCompany 
   {
      DROP temporary
   }
If the altered class is the superclass of another class, the dropped attribute is dropped from the subclass, as well.
Warning:If the altered class has existing objects that were created under the original class description, any value held by the dropped attribute is removed from each object and discarded.
Deleting Bidirectional Relationships
You can delete a bidirectional relationship that links two different classes. Recall that a bidirectional relationship is really a pair of reference attributes, where each attribute names the other as its inverse. You must delete both of the inverse attributes in the same operation, by including two ALTER CLASS clauses in the same UPDATE SCHEMA statement.
Example. The contracts attribute of the RentalCompany class and the company attribute of the RentalContracts class are inverses of each other. The following UPDATE SCHEMA statement uses two ALTER CLASS clauses to delete the inverse reference attributes from their respective classes.
UPDATE SCHEMA
{
   ALTER CLASS FleetData.RentalCompany {
      DROP contracts 
   }
   ALTER CLASS FleetData.RentalContract {
      DROP company 
   }
};
Note:You can create a unidirectional relationship from an existing bidirectional relationship; see Changing a Unidirectional Relationship to Be Bidirectional. Besides deleting one of the inverse attributes, you must also change the data type of the remaining attribute so that it is no longer an inverse.
Changing the Data Type of Attributes
An attribute’s data type is determined by the logical type and settings specified by the attribute structure with which the attribute was created. You can change an attribute’s data type by replacing an obsolete attribute with a new one that has the desired type characteristics.
The following table provides a sampling of the data-type characteristics you can change when you replace an attribute:
 
Type Characteristic to be Changed
Sample Uses
Encoding
Change a String attribute to hold Unicode UTF-16 strings instead of UTF-8 strings, or vice versa.
Change an Integer attribute to hold signed integers instead of unsigned, or vice versa.
Storage
Change a Real (floating-point) attribute from 32-bit storage to 64-bit storage, or vice versa
Change a String attribute from fixed length to variable length, or vice versa.
Referenced class or inverse
Change a Reference attribute so that it references the superclass class of the current referenced class.
Change a Reference attribute so that it represents a unidirectional relationship instead of a bidirectional relationship, or vice versa.
You replace an obsolete attribute using a multi-step procedure that executes several ALTER CLASS clauses in separate UPDATE SCHEMA statements. The specific replacement steps depend on whether you want to discard or preserve the values of the obsolete attribute in existing objects of the class.
Replacing an Obsolete Attribute and Discarding its Values
The ideal time for changing an attribute’s data type is when the attribute has no values that need to be preserved—for example:
Before any objects of the enclosing class have been created.
During early database development and testing, when objects of the enclosing class may exist, but hold dummy values that can be discarded.
To replace an attribute without preserving its values, you perform the following general steps:
1. Execute an UPDATE SCHEMA statement that drops the obsolete attribute.
2. Execute a separate UPDATE SCHEMA statement that adds a new attribute with the desired data type.
Example. Assume the RentalContract class has a trackingNumber attribute for holding 32-bit signed integers. After review, the design team decides that a tracking number should only be positive, and that 16-bit unsigned integers provide a more realistic range. You make this change by executing two UPDATE SCHEMA statements:
// Drop the original Integer attribute
UPDATE SCHEMA
{
   ALTER CLASS FleetData.RentalContract 
   {
      DROP trackingNumber
   }
};
 
// Add the new attribute with the desired encoding and storage settings
UPDATE SCHEMA
{
   ALTER CLASS FleetData.RentalContract 
   {
      ADD trackingNumber : Integer {Encoding : Unsigned, Storage : B16}
   }
};
Note: If RentalContract objects exist when this procedure is performed, then any trackingNumber values are discarded, and each object is adjusted to accommodate the new attribute size.
Replacing an Obsolete Attribute While Preserving its Values
Sometimes the data type of an attribute must be changed after objects of the enclosing class exist. In a production database, these objects normally contain values that must be preserved.
To replace an attribute and preserve its values in existing objects, you perform the following general steps:
1. Execute an UPDATE SCHEMA statement that adds a new attribute with the desired data type. Give it a temporary name.
2. Execute an UPDATE statement to process the existing objects of the class. Use a SET clause to obtain the value from the obsolete attribute in each object, and assign the value to the new attribute added in step 1.
3. Execute an UPDATE SCHEMA statement that drops the obsolete attribute and renames the new attribute.
Note:Depending on the nature of the data-type change, step 2 may be able to assign each value of the obsolete attribute directly to the corresponding new attribute, so that the value is converted to the new data type automatically. Or, step 2 may require additional UPDATE statements and operator expressions to transform values that are out-of-range or oversized for the new data type. See Assignment and Type Compatibility.
Example. Assume the RentalContract class has a trackingNumber attribute for holding 32-bit signed integers. The design team decides that each tracking number should be a 16-bit unsigned integer. RentalContract objects already exist with tracking numbers that need to be preserved. Because the range of the original data type is much larger (-2,147,483,648 to 2,147,483,647) than that of the new data type (0 to 32,767), a decision is made to set tracking numbers to 0 if they fall outside the new range. (Later, any RentalContract objects with a trackingNumber of 0 can be examined and assigned a valid tracking number.)
// Add the new attribute with the desired encoding and storage settings
UPDATE SCHEMA
{
   ALTER CLASS FleetData.RentalContract 
   {
      ADD trackingNumberTemp : Integer {Encoding : Unsigned, Storage : B16}
   }
};
 
// Set trackingNumber values to 0 if they fall outside the new range
UPDATE FleetData.RentalContract  WHERE (trackingNumber < 1) or (trackingNumber > 32767) SET trackingNumber TO 0;
 
// Copy values from the obsolete attribute to the new attribute
UPDATE FleetData.RentalContract SET trackingNumberTemp TO trackingNumber;
 
// Drop the obsolete attribute 
UPDATE SCHEMA
{
   ALTER CLASS FleetData.RentalContract 
   {
      DROP trackingNumber
   }
};
 
// Rename the new attribute
UPDATE SCHEMA
{
   ALTER CLASS FleetData.RentalContract 
   {
      RENAME trackingNumberTemp TO trackingNumber
   }
};
 
Changing a Unidirectional Relationship to Be Bidirectional
Example. Assume the Vehicle class has a reference attribute currentRental for holding unidirectional references to objects of the RentalContract class. The design team decides that the references should be bidirectional. Vehicle objects exist with references that need to be preserved.
// Add a pair of inverse bidirectional attributes to Vehicle and RentalContract
UPDATE SCHEMA
{
   ALTER CLASS FleetData.Vehicle 
   {
      ADD currentRentalTemp : Reference {Referenced : FleetData.RentalContract, Inverse : vehicle}
   }
   ALTER CLASS FleetData.RentalContract 
   {
      ADD vehicle : Reference {Referenced : FleetData.Vehicle, Inverse : currentRentalTemp}
   }
};
 
// Copy values from each Vehicle's unidirectional attribute to the new bidirectional attribute
UPDATE FleetData.Vehicle SET currentRentalTemp TO currentRental;
 
// Verify that the new inverse attributes are set in each RentalContract object
FROM FleetData.RentalContract RETURN vehicle;
 
// Drop the unidirectional attribute from Vehicle 
UPDATE SCHEMA
{
   ALTER CLASS FleetData.Vehicle 
   {
      DROP currentRental
   }
};
 
// Rename the new bidirectional attribute
UPDATE SCHEMA
{
   ALTER CLASS FleetData.Vehicle 
   {
      RENAME currentRentalTemp TO currentRental
   }
};
 
// Verify that the inverse is adjusted in the vehicle attribute of the RentalContract class
SHOW CLASS FleetData.RentalContract;
Changing a Bidirectional Relationship to Be Unidirectional
Example. Assume the Vehicle class has a reference attribute currentRental for holding bidirectional references to objects of the RentalContract class. The design team decides that the references should be unidirectional. Vehicle objects exist with references that need to be preserved.
// Add a unidirectional attribute to Vehicle 
UPDATE SCHEMA
{
   ALTER CLASS FleetData.Vehicle 
   {
      ADD currentRentalTemp : Reference {Referenced : FleetData.RentalContract}
   }
};
 
// Copy values from each Vehicle's original bidirectional attribute to the new unidirectional attribute
UPDATE FleetData.Vehicle SET currentRentalTemp TO currentRental;
 
// Drop the bidirectional attributes from Vehicle and from RentalContract
UPDATE SCHEMA
{
   ALTER CLASS FleetData.Vehicle 
   {
      DROP currentRental
   }
   ALTER CLASS FleetData.RentalContract 
   {
      DROP vehicle
   }
};
 
// Rename the new unidirectional attribute
UPDATE SCHEMA
{
   ALTER CLASS FleetData.Vehicle 
   {
      RENAME currentRentalTemp TO currentRental
   }
};