Fast/Unload with Model 204 fieldgroups

From m204wiki
Revision as of 15:08, 3 April 2015 by JAL (talk | contribs) (→‎Handling of missing AT-MOST-ONE fields: remove NOUNLOAD and NOUNLOADC)
Jump to navigation Jump to search

Model 204 processing for multiply occurring fields was enhanced in version 7.5 to support physical field groups which let you view and process groups of fields as a logical entity. Fast/Unload supports physical fieldgroups as of its version 4.6.

Since you can define a physical field group only for files with the FILEORG X'100' setting, the documentation for Fast/Unload support of FILEORG X'100' files is presented as part of the Fast/Unload support for fieldgroups.

Support for FILEORG X'100' files

As of version 4.6, Fast/Unload supports files whose FILEORG setting includes the X'100' bit, which were introduced in version 7.2 of Model 204. The various aspects of this support are:

UAI UAI FUEL programs may be used to unload FILEORG X'100' files, for reloading with Fast/Reload.
PAI The PAI statement in FUEL supports FILEORG X'100' files; see PAI.
FSTATS The field statistics produced by the FSTATS option or statement include information about fields and fieldgroups in a FILEORG X'100' file, including the new field attributes. See FSTATS for FILEORG X'100' files.
FOR FIELDGROUP blocks New FUEL statements are provided to establish a fieldgroup context for processing members of the fieldgroup. An overview of these statements is provided in FOR FIELDGROUP blocks.
Other references to fieldgroups In addition to FOR FIELDGROUP blocks, you can refer to fieldgroups by name (always preceded by the FIELDGROUP keyword) in the following FUEL constructs:
Reference to the number of occurrences of a fieldgroup Corresponding to references to the number of occurrences of a field as an entity in a FUEL program, you can also refer to the number of occurrences of a fieldgroup, by coding the FIELDGROUP keyword, followed by the fieldgroup name, followed by the number token (#) in parentheses:

FOR I FROM 1 TO FIELDGROUP PAYMENT.INFO(#)

[NO]UNLOAD[C] FIELDGROUP The ability to unload a single field, as performed by the UNLOAD fieldname[(occ)] statement, has been extended to allow unloading a fieldgroup occurrence, as described in [NO]UNLOAD[C] FIELDGROUP.
#IF FIELDGROUP
fieldgroup DEFINED
The #IF preprocessor statement has been extended to allow testing for the presence in the file being unloaded (or any of the files in a group being unloaded), of a fieldgroup.

For example:

#IF FIELDGROUP PAYMENT.INFO DEFINED

Occurrences of EXACTLY-ONE and AT-MOST-ONE fieldgroup members You may refer to occurrences of non-nested, non-FG *, non-REPEATABLE fields without an enclosing FOR FIELDGROUP block. This facility is explained in References to fieldgroup members not in fieldgroup context.
EXACTLY-ONE fields EXACTLY-ONE fields are new in V7.2. Their handling in FUEL is explained in EXACTLY-ONE fields.
Handling of DEFAULT-VALUE fields This is explained in Handling of DEFAULT-VALUE fields. Also, for PUT of an AT-MOST-ONE DEFAULT-VALUE field which is MISSING, see Handling of missing AT-MOST-ONE fields.
Handling of missing AT-MOST-ONE fields This is explained in Handling of missing AT-MOST-ONE fields.

There are many other field attributes introduced in FILEORG X'100' files, and they do not have any impact on version 4.6 of Fast/Unload. For example, Fast/Unload does not enforce the DATETIME format restriction in the ADD or CHANGE statement.

Record structure in FILEORG X'100' files, context and other fieldgroup concepts

A record in a Model 204 file with the FILEORG X'100' bit consists of a sequence of field and/or fieldgroup occurrences. These occurrences are called outer occurrences. A fieldgroup occurrence consists of a seqence of field and/or fieldgroup occurrences. These occurrences are called member occurrences. Each fieldgroup occurrence has a numeric ID that is different from all other fieldgroup occurrence IDs in the same record.

A fieldgroup is defined in a file by using the DEFINE FIELDGROUP command.

Note: This is different from the FIELDGROUP attribute, which can be specified on either the DEFINE FIELD or DEFINE FIELDGROUP command. The FIELDGROUP attribute can be abbreviated as FG, as is typically the case in this document.

The DEFINE command for a field or fieldgroup can specify that it is a member of a specific fieldgroup by using the FG attribute with the name of the fieldgroup. When a field or fieldgroup is defined as a member of a specific fieldgroup, that field or fieldgroup can only occur as a member within some occurrence of the fieldgroup named in its FG attribute.

Fields and fieldgroups defined without the FG attribute cannot occur within a fieldgroup, so when they occur in a record, they occur as outer occurrences.

These features are powerful and enable definition of a straightforward approach to repeating field groups, as shown in this example:

DEFINE FIELD OUTFLD DEFINE FIELDGROUP GRP DEFINE FIELD EXOMEM WITH FG GRP DEFINE FIELD EXOMEM2 WITH FG GRP DEFINE FIELD REPMEM WITH REPEATABLE FG GRP

An example PAI of a record in a file with these definitions is:

OUTFLD = OUT01 OUTFLD = OUT02 \GRP = 20 EXOMEM = MEM01 EXOMEM2 = MEM02 /GRP = 20 OUTFLD = OUT03 \GRP = 5 EXOMEM = MEM03 EXOMEM2 = REPMEM = REPMEM01 /GRP = 5 OUTFLD = OUT07

Notes:

  • The order of fieldgroup IDs, as in this example (20 and 5), need not correspond to the order of the fieldgroups in the record. The ID of a fieldgroup is assigned when it is added to the record, and is equal to one more than the highest fieldgroup ID which had been used in the record (even if the fieldgroup with that ID has been deleted).
  • The default repeatability for (non-FG *) fieldgroup member fields is EXACTLY-ONE. In the second occurrence of GRP above, whether or not EXOMEM2 has been stored cannot be determined; it is treated in all respects as if it had been stored with a value of the null string.

In order for Fast/Unload to operate on an occurrence of a fieldgroup member, the fieldgroup containing the member must be identified. This is obtained in either of two ways:

  • By referring to the member of the fieldgroup within a FOR FIELDGROUP block that identifies an occurrence of the fieldgroup — this fieldgroup occurrence is the fieldgroup context for the fieldgroup member.
  • For an AT-MOST-ONE or EXACTLY-ONE non-FG * field member of a non-nested fieldgroup, a reference outside the context of the fieldgroup implicitly identifies the fieldgroup occurrence; see References to fieldgroup members not in fieldgroup context.

The following FUEL program explains both cases of fieldgroup member reference, assuming that the record shown in the above PAI output is the current record:

FOR EACH RECORD FOR FIELDGROUP GRP(1) PUT EXOMEM /* In context of GRP(1): MEM01 END FOR FOR FIELDGROUP GRP(2) PUT EXOMEM /* In context of GRP(2): MEM03 PUT REPMEM /* In context of GRP(2): REPMEM01 END FOR PUT EXOMEM(1) /* Out of context: MEM01 PUT EXOMEM(2) /* Out of context: MEM03 * REPMEM illegal here; it requires a fieldgroup context END FOR

In addition to fieldgroup context:

  • Record context is always available for fields and fieldgroups defined without the FG attribute.

Nested fieldgroups and FG *

Two advanced aspects of the fieldgroup feature, not explored in Record structure in FILEORG X'100' files, context and other fieldgroup concepts, are:

  • The DEFINE FIELDGROUP command allows the FG attribute, which indicates that an occurrence (or more, if AT-MOST-ONE is not specfied) of the fieldgroup being defined may be contained within an occurrence of the fieldgroup specified in the FG attribute. A fieldgroup occurrence contained within another fieldgroup is called a nested fieldgroup occurrence.
  • The FG attribute of the DEFINE FIELD or DEFINE FIELDGROUP command can specify FG *. This indicates that the field or fieldgroup can occur either or both as an outer occurrence or as a member of any occurrence of any fieldgroup in a record. A field or fieldgroup defined with the FG * attribute is called an FG * field or fieldgroup, respectively.

Here is a contrived example illustrating the possibilities using the FG attribute:

DEFINE FIELD OUTFLD DEFINE FIELD STARFLD WITH FG * DEFINE FIELDGROUP STARGRP WITH FG * DEFINE FIELD INSTAR WITH FG STARGRP DEFINE FIELDGROUP GRP DEFINE FIELD INGRP WITH FG GRP DEFINE FIELDGROUP NEST WITH FG GRP

An example PAI of a record in a file with these definitions is:

OUTFLD = OUT01 OUTFLD = OUT02 STARFLD = STAROUT01 STARFLD = STAROUT02 \STARGRP = 15 INSTAR = INSTAR01 STARFLD = STARMEM01 STARFLD = STARMEM02 \STARGRP = 30 INSTAR = STARFLD = STARMEM03 STARFLD = STARMEM04 /STARGRP = 30 /STARGRP = 15 STARFLD = STAROUT03 OUTFLD = OUT03 \GRP = 20 INGRP = MEM01 STARFLD = STARMEM05 \STARGRP = 35 INSTAR = STARFLD = STARMEM06 STARFLD = STARMEM07 /STARGRP = 35 /GRP = 20 \GRP = 5 INGRP = MEM02 /GRP = 5

Since FG * fields and fieldgroups can exist as both outer and member occurrences, a reference to fstar, where fstar is defined with FG *, is to either:

  • The occurrence of fstar within the fieldgroup occurrence established by the closest containing FOR FIELDGROUP block.
  • The outer occurrence of fstar, if there is no enclosing FOR FIELDGROUP block.

For example, if the current record is the one described by the above PAI output:

FOR EACH RECORD PUT STARFLD /* In record context: STAROUT01 FOR FIELDGROUP GRP /* In record context: ID=20 PUT STARFLD /* In fieldgroup context: STARMEM05 FOR FIELDGROUP STARGRP /* In fieldgroup context: ID=35 PUT STARFLD /* In fieldgroup context: STARMEM06 END FOR END FOR END FOR

See Nested fieldgroups for futher discussion of nested fieldgroups.

FOR FIELDGROUP blocks

Three statements added in version 4.6 of Fast/Unload, all with syntax "FOR ... FIELDGROUP ...", create FOR FIELDGROUP blocks, which are terminated by END FOR. Within each block, a fieldgroup occurrence (one for each iteration, in the case of FOR EACH FIELDGROUP) is used as the context for references to its members. These statements are described in the following sections:

In addition, within any of the above blocks there is a version 4.6 statement for terminating execution of the block (LEAVE FIELDGROUP), a version 4.6 special variable for obtaining the fieldgroup ID of a fieldgroup occurrence (#FIELDGROUPID), and a version 4.6 special variable for obtaining the occurrence number of a fieldgroup occurrence (#FIELDGROUPOCCURRENCE).

In addition to this syntax for referencing fieldgroup members, some fieldgroup members can also be referenced outside FOR FIELDGROUP blocks in certain circumstances, as described in References to fieldgroup members not in fieldgroup context.

Statements that cannot reference fieldgroup members

For a field in the context of an occurrence of its fieldgroup (established by a containing FOR FIELDGROUP block), or for a fieldgroup member that can be used outside its fieldgroup context (as described in References to fieldgroup members not in fieldgroup context), that field can be used in any FUEL statement, except in the following:

  • The UNLOAD[C] field or NOUNLOAD field statement
  • The DELETE[C] field statement
  • The sort or hash specification of the SORT or UAI statement

References to fieldgroup members not in fieldgroup context

A fieldgroup member can always be referenced within the context of an occurrence of its fieldgroup established by a FOR FIELDGROUP block, as described in FOR FIELDGROUP blocks (although, as listed in Statements that cannot reference fieldgroup members, certain statements may not reference fieldgroup members).

In addition to the fieldgroup context established by FOR FIELDGROUP blocks, you may make references to certain fieldgroup members without a containing context. A fieldgroup member can only be referenced outside its fieldgroup context if it is EXACTLY-ONE or AT-MOST-ONE, and it is non-FG *, and its containing fieldgroup is not nested.

Stated another way, the following references are only allowed within fieldgroup context for fieldgroup members or, for non-fieldgroup members, within record context:

  • REPEATABLE member of fieldgroup
  • FG * field
  • Field in nested fieldgroup
  • Nested fieldgroup

For fieldgroup members that allow it, an "out of context" reference to an occurrence is actually a reference to occurrence number 1 of that field within the specified occurrence of its containing fieldgroup. For example, consider the following field definitions and FUEL program:

DEFINE FIELDGROUP GRP DEFINE FIELD FOO WITH FG GRP ... //FUNIN DD * OPEN ... FOR EACH RECORD PUT FOO(10) OUTPUT END FOR

In the above example, FOO(10) is a reference to occurrence number 1 of FOO within occurrence number 10 of fieldgroup GRP.

Further, an "out of context" reference to the occurrence count of an EXACTLY-ONE (or AT-MOST-ONE, as well) member is actually a reference to the occurrence count of its containing fieldgroup. For example (assuming the same definitions as above), consider the following FUEL fragment:

FOR I FROM 1 TO FOO(#) ... END FOR

In the above fragment, the FOR loop is a executed as many times as the occurrence count of fieldgroup GRP.

First occurrence

In many discussions of EXACTLY-ONE and AT-MOST-ONE fields, the term first occurrence is used. This refers to any of the following:

  • Occurrence number 1 of an outer EXACTLY-ONE or AT-MOST-ONE field.
  • Occurrence number 1 of an EXACTLY-ONE or AT-MOST-ONE fieldgroup member, in the context of the containing fieldgroup.
  • Any occurrence n of an EXACTLY-ONE or AT-MOST-ONE fieldgroup member, not in the context of the containing fieldgroup, if occurrence n of the fieldgroup exists.

Hence, given the following definitions within a file:

DEFINE FIELD OUTER WITH AT-MOST-ONE DEFINE FIELDGROUP GRP DEFINE FIELD INNER WITH AT-MOST-ONE FG GRP DEFINE FIELD BOTH WITH AT-MOST-ONE FG *

Then the following FUEL program contains comments illustrating which references are to the first occurrence (all of the comments are also true if any AT-MOST-ONE above is changed to EXACTLY-ONE):

FOR EACH RECORD PUT OUTER /* This is first occurrence PUT OUTER(3) /* This is NOT first occurrence PUT BOTH /* This is first occurrence PUT BOTH(3) /* This is NOT first occurrence PUT INNER /* This is first occurrence, if fieldgroup /* GRP has at least one occurrence PUT INNER(3) /* This is first occurrence, if fieldgroup /* GRP has at least three occurrences FOR FIELDGROUP GRP PUT BOTH /* This is first occurrence PUT BOTH(3) /* This is NOT first occurrence PUT INNER /* This is first occurrence PUT INNER(3) /* This is NOT first occurrence END FOR END FOR

Nested FOR FIELDGROUP blocks

A FOR FIELDGROUP block may contain other FOR FIELDGROUP blocks, and the context established by a containing block "remains active" within a contained block (unless the fieldgroup specified on the contained block is the same as that specified in a containing block).

For example, given the following definitions:

DEFINE FIELDGROUP PERSON DEFINE FIELD NAME WITH FG PERSON DEFINE FIELD PERSON.SOCSECNUM WITH FG PERSON DEFINE FIELDGROUP BANKACCT DEFINE FIELD BALANCE WITH FG BANKACCT DEFINE FIELD ACCT.SOCSECNUM WITH FG BANKACCT

The following FUEL program aggregates each person's bank balances:

FOR EACH RECORD FOR EACH FIELDGROUP PERSON %BAL = 0 FOR EACH FIELDGROUP BANKACCT IF ACCT.SOCSECNUM EQ PERSON.SOCSECNUM THEN %BAL = %BAL + BALANCE END IF END FOR PUT NAME PUT ' balance=' PUT %BAL OUTPUT END FOR /* EACH FIELDGROUP PERSON END FOR

Notice that IF ACCT.SOCSECNUM EQ PERSON.SOCSECNUM references field ACCT.SOCSECNUM in the inner (BANKACCT) block and references field PERSON.SOCSECNUM in the outer (PERSON) block.

In the above example, and in many applications, nested FIELDGROUP blocks are not processing nested fieldgroups, but whenever processing nested fieldgroups, nested FOR FIELDGROUP blocks are required, as shown in Nested fieldgroups.

Nested fieldgroups

A nested fieldgroup is a fieldgroup which is itself defined to be a member of another fieldgroup. For example:

DEFINE FIELDGROUP PERSON DEFINE FIELD NAME WITH FG PERSON DEFINE FIELDGROUP MEDICALEXAM WITH FG PERSON DEFINE FIELD EXAM.DATE WITH FG MEDICALEXAM

In the above example, fieldgroup MEDICALEXAM is nested within, that is, it is a member of, fieldgroup PERSON.

To access occurrences of nested fieldgroups, you must use nested fieldgroups. For example:

FOR EACH RECORD FOR EACH FIELDGROUP PERSON PUT NAME %NEED_EXAM = '(no exams)' FOR EACH FIELDGROUP MEDICALEXAM PUT EXAM.DATE AT 30 OUTPUT %NEED_EXAM = '' END FOR IF %NEED_EXAM NE '' THEN PUT %NEED_EXAM AT 30 OUTPUT END FOR END FOR /* EACH FIELDGROUP PERSON END FOR

Handling of particular field attributes

EXACTLY-ONE fields

The EXACTLY-ONE "repeatability" attribute mandates one and only one occurrence of the field, either within its containing fieldgroup occurrence or within the record:

  • An EXACTLY-ONE field that is a fieldgroup member occurs exactly once in every occurrence of that fieldgroup.
  • An EXACTLY-ONE field that is not a fieldgroup member (that is, an outer field) occurs exactly once in every record in the file.

EXACTLY-ONE is the default repeatability attribute for a field defined as a member of a (specific) fieldgroup. EXACTLY-ONE is not allowed in combination with FG *, nor is it allowed on the DEFINE FIELDGROUP command.

The other repeatability attributes are REPEATABLE, AT-MOST-ONE, and OCCURS. For fieldgroups, fields that are not fieldgroup members, and FG * fields, REPEATABLE is the default repeatability attribute.

Fast/Unload handling of EXACTLY-ONE fields is straightforward:

  • The DELETE statement is not allowed with an EXACTLY-ONE field.
  • The ADD statement is not allowed with an EXACTLY-ONE field.
    The analogous constraint for AT-MOST-ONE fields, which is enforced in SOUL, is not enforced in FUEL.
  • The first occurrence (see First occurrence) of an EXACTLY-ONE field is never MISSING — that is, on the PUT statement, the SORT clause of the UAI statement, or on the IF and ELSEIF statements — and it always EXISTS on IF and ELSEIF.
  • Within its context, the occurrence count of an EXACTLY-ONE field is always one.
  • See References to fieldgroup members not in fieldgroup context for a discussion of an EXACTLY-ONE fieldgroup member outside its context.

In the above items, the context is either:

  • The context of an occurrence of its fieldgroup, for fieldgroup members.
  • Record context, for outer fields.

DEFAULT-VALUE fields

The DEFAULT-VALUE attribute, allowed in FILEORG X'100' files, specifies the value of the first occurrence (see First occurrence) of an EXACTLY-ONE or AT-MOST-ONE field if it has not been stored.

For an EXACTLY-ONE field, the result of this in FUEL is that any reference to the value of the first occurrence of the field, if it has not been stored, results in the DEFAULT-VALUE (and, note that there is no way in SOUL nor in FUEL to determine whether or not the field has been stored).

For an AT-MOST-ONE DEFAULT-VALUE field, any reference to the value of the first occurrence of the field, if it has not been stored, also generally results in the DEFAULT-VALUE but, since the field occurrence may also be MISSING, the PUT statement result may be something other than the DEFAULT-VALUE, as explained in Handling of missing AT-MOST-ONE fields.

The DEFAULT-VALUE of a field (AT-MOST-ONE or EXACTLY-ONE) has no effect on references to field occurrences other than the first.

Handling of missing AT-MOST-ONE fields

Missing field processing is done for:

  • The MISSING/EXISTS clauses on the IF/ELSEIF statements
  • The PUT statement
  • The #ERROR special variable
  • Retrieving a value
  • The UAI SORT statement
  • Some #function arguments, for example, the first argument of #N2DATE

In addition, all of the above processing is performed for a %variable to which a field occurrence has been assigned.

Prior to the introduction of FILEORG X'100' files, the handling of all missing field occurrences was the same. However, when the DEFAULT-VALUE attribute is used with an AT-MOST-ONE field, if the first occurrence (see First occurrence) of the field is missing, it still has a value (the value of the DEFAULT-VALUE attribute).

When an AT-MOST-ONE field has a DEFAULT-VALUE, and that field is missing, then the following take place when the first occurrence of the field is referenced:

  1. The IS FIXED and IS FLOAT tests for the missing first occurrence are true if the DEFAULT-VALUE is convertible to a fixed or float representation, respectively.
  2. When the missing first occurrence is used in a PUT statement that does not contain the MISSING clause other than MISSING *:
    • If the DEFAULT-VALUE is convertible to the PUT AS format (a DEFAULT-VALUE longer than the length of a PUT AS STRING statement is not convertible), then the DEFAULT-VALUE is output.
    • Otherwise, an ERROR condition occurs (in additon to the MISSING condition). See MISSING and ERROR clauses for a description of the ERROR clause in the PUT statement.
  3. After a PUT of the missing first occurrence, #ERROR is 1 or, if the DEFAULT-VALUE is not convertible to the output format as just described, it is 3.
  4. If the missing first occurrence of the field is used in the SORT clause of the UAI statement:
    • If the MISSING clause is present, the value specified there is used in the sort key.
    • Otherwise, the DEFAULT-VALUE is used in the sort key. If the DEFAULT-VALUE is not convertible to the type specified, then a missing first occurrence will terminate Fast/Unload.
  5. The value used for the missing first occurrence (for example, in a comparison, on the right hand side of an assignment, as a #function argument) is the DEFAULT-VALUE.

The above behavior will also take place for a %variable, if the %variable has been assigned from the missing first occurrence of an AT-MOST-ONE DEFAULT-VALUE field.

Other contexts in which the first occurrence of an AT-MOST-ONE field is missing is not affected by whether the field has the DEFAULT-VALUE attribute:

  • The IF/ELSEIF statement's MISSING test for the missing first occurrence is true.
  • The missing first occurrence may not be used with a DELETE or UNLOAD statement (DELETEC and UNLOADC can be used), nor may it be used on the left side of a CHANGE statement.

The DEFAULT-VALUE of a field (AT-MOST-ONE or EXACTLY-ONE) has no effect on references to occurrences other than the first.

Fieldgroup-specific FUEL statements

These statements, added or changed in version 4.6 of Fast/Unload, support fieldgroups in FILEORG X'100' files.

FOR FIELDGROUP fgrpName[(occ)]

The following block creates a context within which references to fieldgroup members and #FIELDGROUPID use the given fieldgroup occurrence:

FOR FIELDGROUP fgrpName[(occ)] . . . statements that use fgrpName[(occ)] as the . . . fieldgroup context END FOR

The fgrpName clause in the statement can be replaced by the name of any fieldgroup defined in the file.

The (occ) clause in the statement is optional and specifies the occurrence number of the fieldgroup being used as the context. Just as with the occurrence number of a regular field in FUEL, occ may be a positive integer count, a loop control variable, or a %variable. If it is a %variable, the value of the %variable must be a number greater than or equal to 1; any fractional part is dropped.

The given occurrence of the specified fieldgroup, within the current context, is the context for any members of that fieldgroup. If the (occ) clause is omitted, the first occurrence of the fieldgroup is used. If the occurrence of the fieldgroup does not exist within the current context, the entire block is skipped.

For example, assuming the following field definitions:

DEFINE FIELD FIELDA (FG GRP) DEFINE FIELD FIELDB (FG GRP)

The following statements put, on the output stream, the values of the fields in the second occurrence of fieldgroup GRP:

FOR FIELDGROUP GRP(2) PUT FIELDA PUT FIELDB OUTPUT END FOR

Note: If GRP is not nested, and each of FIELDA and FIELDB is either EXACTLY-ONE, or is AT-MOST-ONE and not FG *, the following statements are equivalent to the above:

PUT FIELDA(2) PUT FIELDB(2) OUTPUT

There is no significant difference in processing time between the above two approaches.

FOR FIELDGROUP fgrpName = id

The following block creates a context within which references to fieldgroup members and #FIELDGROUPID use the fieldgroup occurrence whose ID is specified:

FOR FIELDGROUP fgrpName = id . . . statements which use fgrpName with the . . . specified id as the fieldgroup context END FOR

The fgrpName clause in the statement can be replaced by the name of any fieldgroup defined in the file.

The id clause in the statement specifies the fieldgroup ID to be matched for the fieldgroup being used as the context. It may be a positive integer count, a loop control variable, a special variable, or a %variable. If it is a special variable or a %variable, its value must be a number greater than or equal to 1; any fractional part is dropped.

The occurrence of the specified fieldgroup, within the current context, whose fieldgroup ID is equal to the specified id, is the context for any members of that fieldgroup. If an occurrence of the fieldgroup does not exist with the specified id within the current context, the entire block is skipped.

For example, assuming the following field definitions:

DEFINE FIELD FIELDA (FG GRP) DEFINE FIELD FIELDB (FG GRP)

The following statements put on the output stream the values of the fields in the occurrence of fieldgroup GRP that has the ID 4:

FOR FIELDGROUP GRP = 4 PUT FIELDA PUT FIELDB OUTPUT END FOR

Note that if both the fieldgroup ID and fieldgroup occurrence number are available, it is faster to access a fieldgroup occurrence using FOR FIELDGROUP fgrpName(occ) than to access it using FOR FIELDGROUP fgrpName = id.

FOR EACH FIELDGROUP fgrpName

The following block loops over all occurrences of a fieldgroup in the current context. Within the block, it creates a context within which references to fieldgroup members and #FIELDGROUPID use, in order, each of the occurrences of the fieldgroup within the current context:

FOR EACH FIELDGROUP fgrpName . . . statements that use consecutive occurrences of . . . fgrpName as the fieldgroup context END FOR

The fgrpName clause in the statement can be replaced by the name of any fieldgroup defined in the file.

FUEL's FOR EACH FIELDGROUP statement is identical to the SOUL FOR EACH OCCURRENCE OF FIELDGROUP statement.

Within the current context, each occurrence of the specified fieldgroup is the context for any members of that fieldgroup.

For example, assuming the following field definitions:

DEFINE FIELD FIELDA (FG GRP) DEFINE FIELD FIELDB (FG GRP)

The following statements put on the output stream the values of the fields in all occurrences of fieldgroup GRP:

FOR EACH FIELDGROUP GRP PUT FIELDA PUT FIELDB OUTPUT END FOR

Note: If GRP is not nested, and each of FIELDA and FIELDB is either EXACTLY-ONE or is AT-MOST-ONE, and is not FG *, the following statements are equivalent to the above (except for the use of the loop control variable I):

FOR I FROM 1 TO FIELDA(#) PUT FIELDA(I) PUT FIELDB(I) OUTPUT END FOR

There is no significant difference in processing time between the above two approaches.

Also note that the following FUEL statements:

FOR EACH FIELDGROUP GRP ... body END FOR

are processed, for all intents and purposes (for example, with the same performance) the same as the following:

FOR I FROM 1 TO FIELDGROUP GRP(#) FOR FIELDGROUP GRP(I) ... body END FOR END FOR

The latter approach may be better in your FUEL program if you need to access the occurrence number (I, in this example) of the fieldgroup, although that is also available in the FOR EACH FIELDGROUP example above via the #FIELDGROUPOCCURRENCE special variable (see #FIELDGROUPOCCURRENCE).

LEAVE FIELDGROUP

This statement will terminate execution of the current FOR FIELDGROUP block, causing execution to resume at the statement after the end of its matching END FOR.

[NO]UNLOAD[C] FIELDGROUP

The UNLOAD[C] FIELDGROUP statement allows the unloading of one outer occurrence, or all outer occurrences, of a fieldgroup.

The syntax is:

UNLOAD[C] FIELDGROUP [fldgrpName [qualifier]]

Where:

UNLOAD FIELDGROUP This statement unloads the specified occurrence(s); if a single occurrence is specified or implied, the occurrence must be present; if it is not present, the Fast/Unload job is cancelled. It can also be used without specifying any fieldgroup name.
UNLOADC FIELDGROUP This statement unloads the specified occurrence(s). If a single occurrence is specified or implied, and the occurrence is not present, no action is performed. It can also be used without specifying any fieldgroup name.
fldgrpName The name of the fieldgroup, whose occurrence(s) are to be unloaded. It must either be a non-nested fieldgroup, or it must be a FG * fieldgroup and be referenced outside any FOR FIELDGROUP block. The resulting outer occurrence(s) of the fieldgroup are unloaded.

If fldgrpName is omitted, the current occurrence of the fieldgroup specified on the containing FOR FIELDGROUP block is unloaded. The fieldgroup specified on that block must either be a non-nested fieldgroup, or it must be a FG * fieldgroup and be referenced outside any FOR FIELDGROUP block.

qualifier A specification of which occurence(s) of the fieldgroup named fldgrpName to be unloaded, of one of the following forms:
(occ) The occurrence number to be unloaded, enclosed in parentheses. occ may be an integer constant, a %variable, or a loop control variable.
(*) Unload all occurrences of the fieldgroup; if there are none, no action is taken.
= id The ID of the fieldgroup to be unloaded.

qualifier is optional. If it is omitted, the first occurrence of the named fieldgroup is unloaded.

The NOUNLOAD FIELDGROUP statement allows one outer occurrence, or all outer occurrences, of a fieldgroup to be marked to not be unloaded as part of a subsequent blanket UNLOAD statement for the record. The syntax is:

NOUNLOAD FIELDGROUP [fldgrpName [qualifier]]

Where:

fldgrpName The name of the fieldgroup, whose occurrence(s) are to be marked to not be unloaded. It must either be a non-nested fieldgroup, or it must be a FG * fieldgroup and be referenced outside any FOR FIELDGROUP block. The resulting outer occurrence(s) of the fieldgroup are marked to not be unloaded.

If fldgrpName is omitted, the current occurrence of the fieldgroup specified on the containing FOR FIELDGROUP block is marked to not be unloaded. The fieldgroup specified on that block must either be a non-nested fieldgroup, or it must be a FG * fieldgroup and be referenced outside any FOR FIELDGROUP block.

qualifier A specification of which occurence(s) of the fieldgroup named fldgrpName are to be marked to not be unloaded, of one of the following forms:
(occ) The occurrence number to be marked, enclosed in parentheses. occ may be an integer constant, a %variable, or a loop control variable.
(*) Mark all occurrences of the fieldgroup.
= id The ID of the fieldgroup to be marked.

qualifier is optional; if omitted, the first occurrence of the named fieldgroup is marked.

PAI

The PAI statement in FUEL supports FILEORG X'100' files, providing the same information that PAI CTOFIELDS in SOUL provides. There are no operands of the FUEL PAI statement, to control display of automatic fields or LOB fields, as there are in the SOUL PAI statement.

Fieldgroups are displayed with a fieldgroup name = ID line at the start and end of the fieldgroup. For example, repeating the example PAI output shown in Record structure in FILEORG X'100' files, context and other fieldgroup concepts:

OUTFLD = OUT01 OUTFLD = OUT02 \GRP = 20 EXOMEM = MEM01 EXOMEM2 = MEM02 /GRP = 20 OUTFLD = OUT03 \GRP = 5 EXOMEM = MEM03 EXOMEM2 = REPMEM = REPMEM01 /GRP = 5 OUTFLD = OUT07

Fieldgroup-specific special variables

These special variables were introduced in version 4.6 of Fast/Unload.

#FIELDGROUPID

This special variable returns the fieldgroup ID of the current occurrence of the fieldgroup specified on the containing FOR FIELDGROUP block.

#FIELDGROUPID is not usable in a SORT FIELDS shorthand. These shorthands are discussed in Using SORT FIELDS.

#FIELDGROUPOCCURRENCE

This special variable returns the occurrence number of the current occurrence of the fieldgroup specified on the containing FOR FIELDGROUP block.

#FIELDGROUPOCCURRENCE is not usable in a SORT FIELDS shorthand. These shorthands are discussed in Using SORT FIELDS.

FSTATS for FILEORG X'100' files

Field and fieldgroup statistics are produced for FILEORG X'100' files as follows:

  • Occurrence counts for fieldgroup members are shown per fieldgroup, as opposed to per record, for non-fieldgroup members.
  • Occurrence counts for EXACTLY-ONE fields refer to physically stored occurrences.
  • The length calculated for a fieldgroup is based on the actual length (including the fieldgroup header) of physical fieldgroup items stored in table B or X. The length of each fieldgroup item never exceeds 511.

    For example, if the total length of the fields physically stored in a fieldgroup is 700, the fieldgroup occurrence will be split into multiple fieldgroup items, and the combined lengths of these items is used as the length of the fieldgroup occurrence in the fieldgroup's length statistics.

  • The occurrence count calculated for a fieldgroup is based on "logical" fieldgroup occurrences. For example, if the total length of the fields physically stored in a fieldgroup is 700, even though this is physically stored as multiple fieldgroup items, this is treated as one fieldgroup occurrence.
  • To help highlight fieldgroups distinctly from fields, a fieldgroup will contain three asterisks (***) in the field sequence number column.
  • The new field attributes in FILEORG X'100' files are only displayed for FSTATS AVGTOT.
  • Since the default for STORE-NULL differs for EXACTLY-ONE fields, FSTATS for it may differ from the output of the DISPLAY FIELD command:
    • If the STORE-NULL attribute is NONE or ALL, it is displayed (for any field).
    • The STORE-NULL attribute is always displayed for an EXACTLY-ONE field.
    • Otherwise, STORE-NULL is not displayed (and by inference, if STORE-NULL is allowed, it is LIT).
  • Since the STORE-DEFAULT attribute is only allowed for a field with the DEFAULT-VALUE attribute, it is always displayed for such a field. This may differ from the output of the DISPLAY FIELD command.
  • A CONCATENATED field is simply shown with CAT. The fields that are concatenated as the value are not shown.
  • A COUNT-OCCURRENCES-OF field is simply shown with CTO. The field that is counted as the value is not shown.

See also