Assignment compatibility in EGL

Assignment-compatibility rules apply in the following situations:
Assignment compatibility is based on the following type classification:
The assignment-compatibility rules are as follows:
Note: A different set of rules is in effect in the following cases:

For details on those cases, see Reference compatibility in EGL.

The situation when passing data to a program is as follows:
  • An EGL called program accepts a series of bytes without validation, except that the received data is truncated or padded in accordance with the parameter type and length
  • Any errors occurs if an EGL statement attempts to use data whose format is not valid in the context of the attempted use

Assignment across numeric types

A value of any of the numeric types (including NUMC and PACF) can be assigned to a field of any numeric type and size, and EGL does the conversions necessary to retain the value in the target format.

Non-significant zeros are added or truncated as needed. (Initial zeros in the integer part of a value are non-significant, as are trailing digits in the fraction part of a value.)

For any of the numeric types, you can use the system variable sysVar.overflowIndicator to test whether an assignment or arithmetic calculation resulted in an arithmetic overflow, and you can set the system variable VGVar.handleOverflow to specify the consequence of such an overflow.

If an arithmetic overflow occurs, the value in the target field is unchanged. If an arithmetic overflow does not occur, the value assigned to the target field is aligned in accordance with the declaration of the target field.

Let's assume that you are copying a field of type NUM to another and that the runtime value of the source field is 108.314:
  • If the target field allows seven digits with one decimal place, the target field receives the value 000108.3, and a numeric overflow is not detected. (A loss of precision in a fractional value is not considered an overflow.)
  • If the target field allows four digits with two decimal places, a numeric overflow is detected, and the value in the target field is unchanged

When you assign a floating-point value (type FLOAT or SMALLFLOAT) to a field of a fixed-point type, the target value is truncated if necessary. If a source value is 108.357 and the fixed-point target has one decimal place, for example, the target receives 108.3.

Other cross-type assignments

Details on other cross-type assignments are as follows:
  • The assignment of a value of type NUM to a target of type CHAR is valid only if the source declaration has no decimal places. This operation is equivalent to a CHAR-to-CHAR assignment.
    If the source length is 4 and value is 21, for example, the content is equivalent to "0021", and a length mismatch does not cause an error condition:
    • If the length of the target is 5, the value is stored as "0021 " (a single-byte space was added on the right)
    • If the length of the target is 3, the value is stored as "002" (a digit was truncated on the right)

    If the value of type NUM is negative and assigned to a value of type CHAR, the last byte copied into the field is an unprintable character.

  • The assignment of a value of type CHAR to a target of type NUM is valid only in the following case:
    • The source (a field or text expression) has digits with no other characters
    • The target declaration has no decimal place

    This operation is equivalent to a NUM-to-NUM assignment.

    If the source length is 4 and value is "0021", for example, the content is equivalent to a numeric 21, and the effect of a length mismatch is shown in these examples:
    • If the length of the target is 5, the value is stored as 00021 (a numeric zero was padded on the left)
    • If the length of the target is 3, the value is stored as 021 (a non-significant digit was truncated)
    • If the length of the target is 1, the value is stored as 1
  • The assignment of a value of type NUMC to a target of type CHAR is possible in two steps, which eliminates the sign if the value is positive:
    1. Assign the NUMC value to a target of type NUM
    2. Assign the NUM value to a target of type CHAR

    If the value of the target of type NUMC is negative, the last byte copied into the target of type CHAR is an unprintable character.

  • The assignment of a value of type CHAR to a target of type HEX is valid only if the characters in the source are within the range of hexadecimal digits (0-9, A-F, a-f).
  • The assignment of a value of type HEX to a target of type CHAR stores digits and uppercase letters (A-F) in the target.
  • The assignment of a value of type MONEY to a target of type CHAR is not valid. The best practice for converting from MONEY to CHAR is to use the system function strLib.formatNumber.
  • The assignment of a value of type NUM or CHAR to a target of type DATE is valid only if the source value is a valid date in accordance with the mask yyyyMMdd; for details, see the topic DATE.
  • The assignment of a value of type NUM or CHAR to a target of type TIME is valid only if the source value is a valid time in accordance with the mask hhmmss; for details, see the topic TIME.
  • The assignment of a value of type CHAR to a target of type TIMESTAMP is valid only if the source value is a valid timestamp in accordance with the mask of the TIMESTAMP field. An example is as follows:
       // NOT valid because February 30 is not a valid date
       myTS timestamp("yyyyMMdd"); 
       myTS = "20050230";
    If characters at the beginning of a full mask are missing (for example, if the mask is "dd"), EGL assumes that the higher-level characters ("yyyyMM", in this case) represent the current moment, in accordance with the machine clock. The following statements cause a runtime error in February:
       // NOT valid if run in February
       myTS timestamp("dd"); 
       myTS = "30";
  • The assignment of a value of type TIME or DATE to a target of type NUM is equivalent to a NUM-to-NUM assignment.
  • The assignment of a value of type TIME, DATE, or TIMESTAMP to a target of type CHAR is equivalent to a CHAR-to-CHAR assignment.

Padding and truncation with character types

If the target is of a non-STRING character type (including DBCHAR and HEX) and has more space than is required to store a source value, EGL pads data on the right:
  • Uses single-byte blanks to pad a target of type CHAR or MBCHAR
  • Uses double-byte blanks to pad a target of type DBCHAR
  • Uses Unicode double-byte blanks to pad a target of type UNICODE
  • Uses binary zeros to pad a target of type HEX, which means (for example) that a source value "0A" is stored in a two-byte target as "0A00" rather than as "000A"

EGL truncates values on the right if the target of a character type has insufficient space to store the source value. No error is signaled.

If the target is a limited-length string, the following rules apply:
  • If more characters are in the source than are valid in the target, EGL runtime truncates the copied content to fit the available length.
  • If fewer characters are in the source than are valid in the target, EGL runtime pads the copied content with blanks, to the length of the target string. However, any trailing blanks in a limited-length string are ignored in a comparison.
A special case can occur in the following situation:
  • The runtime platform supports the EBCDIC character set
  • The assignment statement copies a literal of type MBCHAR or an item of type MBCHAR to a shorter item of type MBCHAR
  • A byte-by-byte truncation would remove a final shift-in character or split a DBCHAR character

In this situation, EGL truncates characters as needed to ensure that the target item contains a valid string of type MBCHAR, then adds (if necessary) terminating single-byte blanks.

Assignment between timestamps

If you assign an item of type TIMESTAMP to another field of type TIMESTAMP, the following rules apply:
  • If the mask of the source field is missing relatively high-level entries that are required by the target field, those target entries are assigned in accordance with the clock on the machine at the time of the assignment, as shown by these examples:
    •   sourceTimeStamp timestamp ("MMdd");
      	 targetTimeStamp timestamp ("yyyyMMdd");
      	
      	 sourceTimeStamp = "1201";
      
        // if this code runs in 2004, the next statement
        // assigns 20041201 to targetTimeStamp
      	 targetTimeStamp = sourceTimeStamp; 
    •   sourceTimeStamp02 timestamp ("ssff");
        targetTimeStamp02 timestamp ("mmssff");
      	
      	 sourceTimeStamp02 = "3201";
      
        // the next assignment includes the minute
        // that is current when the assignment statement runs
        targetTimeStamp02 = sourceTimeStamp02;
    • If the mask of the source item is missing relatively low-level entries that are required by the target field, those target entries are assigned the lowest valid values, as shown by these examples:
      • sourceTimeStamp timestamp ("yyyyMM");
        targetTimeStamp timestamp ("yyyyMMdd");
        
        sourceTimeStamp = "200412";
        
        // regardless of the day, the next statement
        // assigns 20041201 to targetTimeStamp
        targetTimeStamp = sourceTimeStamp; 
      • sourceTimeStamp02 timestamp ("hh");
        targetTimeStamp02 timestamp ("hhmm");
        
        sourceTimeStamp02 = "11";
        
        // regardless of the minute, the next statement
        // assigns 1100 to targetTimeStamp02
        targetTimeStamp02 = sourceTimeStamp02;

Assignment to or from substructured fields in fixed structures

You can assign a substructured field to a non-substructured field or the reverse, and you can assign values between two substructured fields. Assume, for example, that variables named myNum and myRecord are based on the following parts:

  DataItem myNumPart
    NUM(12)
  end

  Record myRecordPart type basicRecord
    10 topMost CHAR(4);
      20 next01 HEX(4);
      20 next02 HEX(4);
  end

The assignment of a value of type HEX to an item of type NUM is not valid outside of the mathematical system variables; but an assignment of the form myNum = topMost is valid because topMost is of type CHAR. In general terms, the primitive types of the fields in the assignment statement guide the assignment, and the primitive types of subordinate items are not taken into account.

The primitive type of a substructured item is CHAR by default. If you assign data to or from a substructured field and do not specify a different primitive type at declaration time, the rules described earlier for fields of type CHAR are in effect during the assignment.

Assignment of a fixed record

An assignment of one fixed record to another is equivalent to assigning one substructured item of type CHAR to another. A mismatch in length adds single-byte blanks to the right of the received value or removes single-byte characters from the right of the received value. The assignment does not consider the primitive types of subordinate structure fields.

The following exceptions apply:
  • The content of a record can be assigned to a record or to a field of type CHAR, HEX, or MBCHAR, but not to a field of any other type
  • A record can receive data from a record or from a string literal or from a field of type CHAR, HEX, or MBCHAR, but not from a numeric literal or from a field of a type other than CHAR, HEX, or MBCHAR

Finally, if you assign an SQL record to or from a record of a different type, you must ensure that the non-SQL record has space for the four-byte area that precedes each structure field.

Related concepts
PageHandler

Feedback
(C) Copyright IBM Corporation 2000, 2005. All Rights Reserved.