MainframeMaster

Building Composite Keys in INREC

A composite key is two or more fields concatenated into one contiguous block so that the sort (or a later step) can treat them as a single key. You might want to sort by region, then by date, then by id—you can do that with multiple sort keys in SORT FIELDS, or you can build one key that is region+date+id in that order at a known position (e.g. the start of the record) and sort by that one field. Building the composite in INREC is useful when key parts are scattered, need conversion (e.g. date to YYYYMMDD), or need padding so that character order matches the desired sort order. Because INREC runs before the sort, the sort sees the new record with the composite key at a fixed position. This page explains how to build composite keys with INREC BUILD (or FIELDS=), how to order and pad key parts, and when to use a composite key vs multiple SORT FIELDS keys.

INREC Processing
Progress0 of 0 lessons

Why Build a Composite Key?

You can sort by multiple keys by listing each key in SORT FIELDS=(pos1,len1,fmt1,dir1,pos2,len2,fmt2,dir2,...). Sometimes it is better to build one key that contains all key parts in order: (1) key parts may be in different places in the record and you want them in one block at the start; (2) key parts may need conversion (e.g. date to YYYYMMDD) or padding (e.g. leading zeros) so that a single character comparison gives the right order; (3) you want a simple SORT FIELDS=(1,keylen,CH,A) and possibly INCLUDE/OMIT on the same block. Building the composite in INREC creates a new record layout; the sort then runs on that layout, so the composite key drives the order.

INREC BUILD: Placing Key Parts in Order

In INREC BUILD= (or FIELDS=), you list items that make up the output record. Each item can be output_pos:input_start,length—copy length bytes from input at input_start to output starting at output_pos. To build a composite key, list the key parts in the order you want them, at consecutive output positions, usually starting at 1.

BUILD items for composite key
ItemMeaningExample
output_pos:input_start,lenCopy len bytes from input at input_start to output starting at output_pos1:10,5 → output 1–5 from input 10–14
ConstantsC'...' or X'...' insert literal bytes (e.g. padding, separator)C'0' or spaces for alignment
Order in BUILDOrder of items = order of key parts in the compositeRegion, then date, then id

So to build key = region (bytes 10–14) then date (bytes 20–27) then id (bytes 1–5), you could use BUILD=(1:10,5,6:20,8,14:1,5,...). Output 1–5 = region, 6–13 = date, 14–18 = id; total key length 18. Then SORT FIELDS=(1,18,CH,A) sorts by that 18-byte composite. The rest of the BUILD list can copy the remaining input fields so the full record is available after the sort.

Example: Region, Date, ID Composite Key

Input: region at 10–14 (5 bytes), date at 20–27 (8 bytes, YYYYMMDD), id at 1–5 (5 bytes). We want to sort by region, then date, then id. Build the composite at 1–18, then copy the rest of the record.

text
1
2
INREC BUILD=(1:10,5,6:20,8,14:1,5,19:28,62) SORT FIELDS=(1,18,CH,A)

Output positions 1–5 = region, 6–13 = date, 14–18 = id (composite key 18 bytes). Positions 19–80 = input 28–80 (62 bytes). So the reformatted record is 80 bytes: key at 1–18, then the rest. SORT FIELDS=(1,18,CH,A) sorts by the entire composite. Character comparison of the 18 bytes gives region order, then date within region, then id within date—assuming the date is already in YYYYMMDD so that character order is chronological.

Padding for Correct Character Sort Order

When you sort the composite as CH (character), DFSORT compares byte by byte. For numeric key parts to sort correctly, they must be padded so that character order matches numeric order. For example, 9 and 10: as two-byte character strings, "9" (followed by space) sorts after "10" because the first byte 9 > 1. So you need to right-justify with leading zeros: 009 and 010 so that 0 < 1 and 9 < 10. In INREC you can build such a field by copying a numeric field that is already stored with leading zeros, or by using conversion/editing (e.g. edit mask) to produce a fixed-width zero-padded value. If the key part is in PD or ZD and you want to avoid padding, you can instead use multiple sort keys (e.g. SORT FIELDS=(1,5,CH,A,6,4,PD,A)) so that the numeric part is compared as numeric, not character.

Including Converted or Edited Fields in the Key

The composite key can include converted or edited fields. For example, if the input has a date in MMDDYYYY at 50–57, you can convert it to YYYYMMDD in INREC and place it in the key (e.g. with date conversion operands). Then the character order of the key is chronological. Similarly, you can include a field that was edited with an edit mask (e.g. for a display amount) if you want to sort by that formatted value. The BUILD list is built in order: any conversion or edit produces bytes at the specified output position, and those bytes become part of the composite key.

Composite Key vs Multiple SORT FIELDS

Multiple keys: SORT FIELDS=(10,5,CH,A,20,8,CH,A,1,5,CH,A) sorts by three separate fields. No INREC needed if the key fields are already in the right format and order does not require a single contiguous key. Composite key: Build key at 1–18 in INREC, then SORT FIELDS=(1,18,CH,A). Use a composite when (1) you want the key in one block (e.g. for INCLUDE on the key), (2) key parts need conversion or padding for CH sort, or (3) you prefer a single key specification. Both approaches give the same logical sort order when the key parts and formats are equivalent.

Building the Key at Position 1

Putting the composite key at output position 1 is conventional: SORT FIELDS=(1,keylen,...) is simple, and INCLUDE/OMIT can reference the key with COND=(1,keylen,...). If you put the key elsewhere (e.g. 50–67), you must use that position in SORT FIELDS and in any conditions. So BUILD=(1:region_spec,2:date_spec,3:id_spec,...) with output positions 1, 2, 3, ... for each part keeps the key at the start.

Explain It Like I'm Five

Imagine you want to sort cards by color, then by number. One way is to tell the machine "first sort by color, then by number." Another way is to write a single label on each card that says "RED-005" or "BLUE-012"—color and number stuck together in order. Then the machine only has to sort by that one label. Building a composite key is like making that one label: we take the color and the number (and maybe more), put them in order, and write them at the top of the card. Then we sort by that one line. We do it before sorting (in INREC) so that when the sort looks at the card, it already sees the combined label.

Exercises

  1. Input has region at 1–4, amount (4-byte PD) at 20, and id at 30–35. You want to sort by region, then amount, then id. Should you build a composite key with CH sort for all three, or use multiple SORT FIELDS? Why?
  2. Write an INREC BUILD= that builds a 12-byte composite key: bytes 50–52 (3 bytes) at output 1–3, then bytes 10–18 (9 bytes) at output 4–12. Then copy input 1–80 to output 13–92. (Use output_pos:input_start,length syntax.)
  3. Why might you put a date conversion (e.g. to YYYYMMDD) inside the composite key built in INREC?
  4. If you build the composite key in OUTREC instead of INREC, will the sort order change? Explain.

Quiz

Test Your Knowledge

1. Why build a composite key in INREC instead of using multiple keys in SORT FIELDS?

  • You cannot use multiple keys
  • Sometimes the key parts are in different places or need to be normalized (e.g. padded, converted) so putting them in one contiguous block at a known position simplifies SORT FIELDS or enables a single key
  • INREC is faster
  • Only one key is allowed

2. What is a composite sort key?

  • A key made of one field
  • Two or more fields concatenated to form a single key (e.g. region then date then id) so that sort order is determined by the combined value
  • A key in PD format only
  • A key used in MERGE only

3. When building a composite key for character sort, why might you pad a numeric field?

  • Padding is never needed
  • So that character (byte) order matches numeric order—e.g. right-justify with leading zeros so that 5 sorts before 15 (005 vs 015)
  • Only for PD
  • To make the key longer

4. Can you build a composite key in OUTREC?

  • No
  • Yes—but then the sort runs on the original record, so the composite key in OUTREC would not affect sort order; use INREC when the key must drive the sort
  • OUTREC is the only place
  • Only with MERGE

5. In INREC BUILD=(1:50,5,6:20,8), what is the output layout?

  • Input unchanged
  • Output positions 1–5 = input 50–54; positions 6–13 = input 20–27
  • Only 5 bytes
  • Only 8 bytes