12
Tue, Nov
5 New Articles

Best of Cozzi: Qualified Data Structures

RPG
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

(Editor's note: Bob is on vacation this week, so he offers this "best of" article in case you missed it the first time.)

When OS/400 V5R1 was announced, it included what I would consider the most significant enhancement to RPG IV data structure support in history: qualified names.

Qualified data structure names allow you to refer to the subfields of a data structure by qualifying them to the data structure name itself. This means that within the calculation specifications (or C specs), you refer to a subfield name by typing the name of the data structure, then a period, and then the subfield name, something like this:

Eval MyStruct.MySubfield = 'ABCDEFG'

The period qualifies the data structure subfield named MYSUBFIELD to its parent data structure, named MYSTRUCT.

Qualified data structures provide a unique benefit; you may use the same subfield name in more than one data structure. And the names do not have to have the same attributes (as you might think). They are distinct fields. In fact, when a data structure is a qualified data structure, the subfield names must be referred to using the qualified syntax only.

To identify a data structure as a qualified data structure, the new QUALIFIED keyword is used. Specify this keyword on a data structure definition, and it becomes a qualified data structure.

If you use the QUALIFIED keyword, you may only refer to the subfields in that data structure by using qualified syntax. This is what allows duplicate field names to be assigned. Since the subfields of a qualified data structure must be qualified when they are used, the subfields are scoped to the data structure. For example, the three data structures listed in Figure 1 are perfectly valid in RPG IV.

     D Customer        DS                  Qualified Inz
     D  CustNo                        7P 0
     D  Contact                      30A
     D  Addr1                        20A
     D  Addr2                        20A
     D  City                         20A
     D  Phone                        11P 0
     D  Ext                           6A

     D undo_Buffer     DS                  Qualified Inz Occurs(10)
     D  CustNo                        7P 0
     D  Contact                      30A
     D  Addr1                        20A
     D  Addr2                        20A
     D  City                         20A
     D  Phone                        11P 0
     D  Ext                           6A

     D SaveCust        DS                  Inz
     D  CustNo                        5P 0
     D  Contact                      30A
     D  Addr1                        30A
     D  Addr2                        30A
     D  City                         30A
     D  Phone                        10S 0
     D  Ext                           5A

Figure 1: Here are three examples of qualified data structure declarations.

The first data structure, CUSTOMER, is a qualified data structure, so the subfields of that data structure may only be referred to by using the qualified syntax. This also allows the subfield names to be reused elsewhere in the source member, which is exactly what I did in the second data structure, UNDO_BUFFER. This data structure is a multiple-occurrence data structure and is qualified. Note that it contains the same set of subfield names as the CUSTOMER data structure. This data structure might be used to provide some level of "undo" capability in an application. Simply move CUSTOMER to an occurrence of UNDO_BUFFER and then increment the UNDO_BUFFER's occurrence. Again, since the UNDO_BUFFER is qualified, each subfield must be referred using the qualified syntax. The following are valid references to subfields in the CUSTOMER data structure:

  • Customer.Custno
  • Customer.Contact
  • Customer.Addr1
  • Customer.Phone

The following are valid references to the subfields of the UNDO_BUFFER data structure:

  • Undo_Buffer.Custno
  • Undo_Buffer.Contact
  • Undo_Buffer.Addr1
  • Undo_Buffer.Phone

The QUALIFIED keyword finally gives us the ability to use the same subfield name in more than one data structure. This is because the data structure is qualified and the subfields may only be referred to using qualified syntax. Because of this, the compiler can distinguish between the subfield names from different data structures. That is, CUSTOMER.CUSTNO is different from UNDO_BUFFER.CUSTNO.

But what about the third data structure listed in Figure 1? SAVECUST is a traditional data structure that does not contain the QUALIFIED keyword, so its subfields cannot be referred to using the qualified syntax. They have to be referenced in the traditional method by just specifying the subfield name itself.

If a source member were to contain all three data structures from Figure 1, there would be three definitions for the various subfields. Of course, this is due to the fact that, for example purposes only, I used the same subfield names in all three data structures. In the source member, you would have three definitions for the CUSTNO field, as follows:

  • Customer.Custno Packed(7,0)
  • Undo_Buffer.Custno Packed(7,0)
  • CustNo Packed(5,0)

Each subfield is individual; one has absolutely nothing to do with one another. The QUALFIED keyword gives us the ability to reuse field names. The name of any subfield of a qualified data structure may be use elsewhere in the source member without consequences. Of course, it is up to you to keep things organized.

Data Structure Templates

It might seem like qualified data structures would be enough of an enhancement, but IBM didn't stop there. IBM also provided us with the ability to create templates. Templates are data structures that are used like format-file objects, but rather than create record formats with them, you can declare other data structures by using the format of an existing data structure.

You can use the new LIKEDS keyword to declare a data structure with the same subfields as an existing data structure. Normally, this would create a conflict with subfield names, but when the LIKEDS keyword is used, the QUALIFIED keyword is implied.

Other languages have had this capability for decades. RPG IV joins the rest of the programming language community with its first step toward user-defined data types.

By declaring a data structure, you create a structure whose content is based on the needs at hand. Formerly, it was difficult in RPG to reuse the structure without creating unique subfield names. The PREFIX keyword offered some relief in that each subfield could be renamed by adding a specified prefix set of characters to the field name. Figure 2 shows an example.

     D Customer      E DS                  Extname(Custmast) PREFIX(CM_)
     D SaveCust      E DS                  Extname(Custmast) PREFIX(SAVE_)

Figure 2: The PREFIX keyword offers another way to use externally described data structures.

This example would declare two data structures with similar formats. I say "similar" because, while the subfield definitions would be identical in each structure, the subfield names themselves would be different. The first data structure, CUSTOMER, would have its subfield names prefixed with CM_, and the SAVECUST data structure would have its subfield names prefixed with SAVE_. In Figure 3, these data structures are expanded to illustrate their subfield names.

     D Customer      E DS                  Extname(Custmast) PREFIX(CM_)
     D  CM_CustNo                          EXTFLD(CUSTNO)
     D  CM_Contact                         EXTFLD(CONTACT)
     D  CM_ADDR1                           EXTFLD(ADDR1)
     D  CM_Addr2                           EXTFLD(ADDR2)
     D  CM_City                            EXTFLD(CITY)
     D  CM_Phone                           EXTFLD(PHONE)
     D  CM_Ext                             EXTFLD(EXT)

     D SaveCust      E DS                  Extname(Custmast) PREFIX(SAVE_)
     D  SAVE_CustNo                        EXTFLD(CUSTNO)
     D  SAVE_Contact                       EXTFLD(CONTACT)
     D  SAVE_ADDR1                         EXTFLD(ADDR1)
     D  SAVE_Addr2                         EXTFLD(ADDR2)
     D  SAVE_City                          EXTFLD(CITY)
     D  SAVE_Phone                         EXTFLD(PHONE)
     D  SAVE_Ext                           EXTFLD(EXT)

Figure 3: Here's an example of expanded externally described data structures with PREFIX keyword.

While this is similar to qualified data structures, it is not the same. With the LIKEDS keyword, you can avoid the PREFIX keyword altogether, as follows in Figure 4:

D Customer E DS Extname(CustMast)
D SaveCust DS LIKEDS(CUSTOMER)

Figure 4: With the LIKEDS keyword, you don't need the PREFIX keyword at all.

In this case, the CUSTOMER data structure is still externally described, but it does not include the PREFIX keyword, so its subfield names will be the same as those in the CUSTMAST database file. The format of the SAVECUST data structure is based on the CUSTOMER data structure. The SAVECUST data structure contains the LIKEDS keyword but does not contain the PREFIX keyword. It will have the same subfield names as the CUSTOMER data structure. This is possible because LIKEDS implies QUALIFIED. In fact, you can't even hard code the QUALIFIED keyword when LIKEDS is present; it is redundant, and the compiler will complain.

LIKEDS can be used to create one data structure like another. In using it, you may clone a data structure. There an enhanced way to use LIKEDS--with a template. The word template is loosely applied to a method of declaring a data structure and then basing that data structure on a pointer. When a data structure--or any field for that matter--is based on a pointer, no storage is allocated for the variable. So a data structure that contains the BASED keyword uses no physical storage at runtime. Instead, it uses the storage at the address assigned to its based pointer.

In the context of the LIKEDS keyword, a data structure could be declared and then include the BASED(@) keyword. The "at" symbol (@) is customarily used when you do not assign a value to a pointer--that is, when you are declaring a template, not a structure for storing data. Think of it as declaring an object in your RPG program that's like a format file.

For example, in Figure 5, a data structure named TP_CUSTOMER is declared. It contains the BASED(@) keyword. This causes no storage to be declared for the TP_CUSTOMER data structure, so it doesn't consume any valuable resources in your program.

     D tp_Customer     DS                  BASED(@)
     D  CustNo                        7P 0
     D  Contact                      30A
     D  Addr1                        20A
     D  Addr2                        20A
     D  City                         20A
     D  Phone                        11P 0
     D  Ext                           6A

Figure 5: Declare a data structure as a template.

The letters tp and the underscore in front of the data structure name are a convention that I used for this article; they are not standards, nor are they in any way required. To use this structure in your code, you would declare another data structure and use the LIKEDS keyword, as follows:

     D Customer        DS                  LIKEDS(tp_Customer)

The CUSTOMER data structure will contain all the subfields from the tp_CUSTOMER data structure and also will contain the QUALIFIED keyword. No other attributes are inherited. That is, the BASED keyword is not applied to the CUSTOMER data structure. In addition, the LIKEDS keyword does not inherit the initial values of the based data structure. So, if CUSTOMER should be initialized, you will have to initialize it using one of the following methods:

  1. Specify the INZ keyword on the CUSTOMER data structure definition.
  2. Use the CLEAR operation code in the calculation specifications, such as in the *INZSR subroutine.

There is a problem when using the BASED keyword in this context. The subfields of the original data structure (the one containing the BASED keyword) may not include the INZ keyword. If a data structure is based, it contains no storage, so no storage can be initialized. Therefore, INZ is not permitted on the based-on data structure. Consequently, creating a storageless template will only work in some circumstances.

There are actually three choices for initializing a derived data structure, however. The third choice is a new option on the INZ keyword. The *LIKEDS option of the INZ keyword can be used to initialize a data structure like the original data structure. The original data structure's initial values may be inherited by using the INZ(*LIKEDS) keyword on the derived data structure's declaration. Figure 6 illustrates this concept.

     D QualName        DS                             
     D   Object                      10A
     D   Library                     10A   Inz('*CURLIB')

     D FileName        DS                  LIKEDS(QUALNAME) Inz(*LIKEDS)

Figure 6: Another way to initialize a derived data structure is to use LIKEDS with INZ(*LIKEDS).

In Figure 6, the data structure QUALNAME is a traditional RPG data structure. It contains two subfields, OBJECT and LIBRARY. OBJECT is initialized to blank, and LIBRARY is initialized to '*CURLIB'.

The data structure named FILENAME is declared with the LIKEDS(QUALNAME) keyword. The FILENAME will contain both the OBJECT and the LIBRARY subfields. In order to cause the derived data structure to have the same initial values as the original data structure, the INZ(*LIKEDS) keyword is used. This causes FILENAME to inherit the initial values of the QUALNAME data structure.

Most other values of the original data structure are not inherited when the LIKEDS keyword is used, so there's more to duplicating a data structure than just adding the LIKEDS keyword. Listed in Figure 7 are an original data structure and a derived data structure. Note the added keywords needed to fully duplicate the original data structure's attributes.

     D ITEM            DS                  Occurs(15) Inz
     D  Catagory                      3A   Inz('THX')                           
     D  SeqNbr                        5S 0 Inz(100)
     D  Postfix                       2S 0 Inz(0)                          
     
     D ItemNo          DS                  LikeDS(ITEM) OCCURS(%ELEM(ITEM))
     D                                     INZ(*LIKEDS)

Figure 7: Duplicate a data structure and its attributes.

The LIKEDS keyword and the INZ(*LIKEDS) option along with the QUALIFIED keyword introduce a level of simplicity in coding data structures that has been long overdue. Before you implement qualified data structures, remember the following:

  • These enhancements are in V5R1 and later.
  • When the QUALIFIED keyword is used, the subfields of the data structure must be referenced using qualified syntax (e.g., dsname.subfield).
  • The LIKEDS keyword may be used to declare one data structure like another. The new data structure is referred to as a derived data structure; the original data structure is referred to as the based on data structure or the parent data structure.
  • When the LIKEDS keyword is used, the QUALIFIED keyword is implied.
  • Use the *LIKEDS option of the INZ keyword in conjunction with the LIKEDS keyword to inherit the initialization attributes of the parent data structure.

 

Bob Cozzi is author of the best-selling The Modern RPG IV Language, Fourth Edition as well as RPG TNT: 101 Dynamite Tips 'n Techniques with RPG IV and is host of the i5 Podcast Network, which provides free video and audio podcasts to the i5 community. You can also see him in person at RPG World in May 2007.

BOB COZZI

Bob Cozzi is a programmer/consultant, writer/author, and software developer. His popular RPG xTools add-on subprocedure library for RPG IV is fast becoming a standard with RPG developers. His book The Modern RPG Language has been the most widely used RPG programming book for more than a decade. He, along with others, speaks at and produces the highly popular RPG World conference for RPG programmers.


MC Press books written by Robert Cozzi available now on the MC Press Bookstore.

RPG TnT RPG TnT
Get this jam-packed resource of quick, easy-to-implement RPG tips!
List Price $65.00

Now On Sale

The Modern RPG IV Language The Modern RPG IV Language
Cozzi on everything RPG! What more could you want?
List Price $99.95

Now On Sale

BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$

Book Reviews

Resource Center

  • SB Profound WC 5536 Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. You can find Part 1 here. In Part 2 of our free Node.js Webinar Series, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Brian will briefly discuss the different tools available, and demonstrate his preferred setup for Node development on IBM i or any platform. Attend this webinar to learn:

  • SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation. Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects. The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the company are not aligned with the current IT environment.

  • SB HelpSystems ROBOT Generic IBM announced the E1080 servers using the latest Power10 processor in September 2021. The most powerful processor from IBM to date, Power10 is designed to handle the demands of doing business in today’s high-tech atmosphere, including running cloud applications, supporting big data, and managing AI workloads. But what does Power10 mean for your data center? In this recorded webinar, IBMers Dan Sundt and Dylan Boday join IBM Power Champion Tom Huntington for a discussion on why Power10 technology is the right strategic investment if you run IBM i, AIX, or Linux. In this action-packed hour, Tom will share trends from the IBM i and AIX user communities while Dan and Dylan dive into the tech specs for key hardware, including:

  • Magic MarkTRY the one package that solves all your document design and printing challenges on all your platforms. Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product. Make sure your data survives when catastrophe hits. Request your trial now!  Request Now.

  • SB HelpSystems ROBOT GenericForms of ransomware has been around for over 30 years, and with more and more organizations suffering attacks each year, it continues to endure. What has made ransomware such a durable threat and what is the best way to combat it? In order to prevent ransomware, organizations must first understand how it works.

  • SB HelpSystems ROBOT GenericIT security is a top priority for businesses around the world, but most IBM i pros don’t know where to begin—and most cybersecurity experts don’t know IBM i. In this session, Robin Tatam explores the business impact of lax IBM i security, the top vulnerabilities putting IBM i at risk, and the steps you can take to protect your organization. If you’re looking to avoid unexpected downtime or corrupted data, you don’t want to miss this session.

  • SB HelpSystems ROBOT GenericCan you trust all of your users all of the time? A typical end user receives 16 malicious emails each month, but only 17 percent of these phishing campaigns are reported to IT. Once an attack is underway, most organizations won’t discover the breach until six months later. A staggering amount of damage can occur in that time. Despite these risks, 93 percent of organizations are leaving their IBM i systems vulnerable to cybercrime. In this on-demand webinar, IBM i security experts Robin Tatam and Sandi Moore will reveal:

  • FORTRA Disaster protection is vital to every business. Yet, it often consists of patched together procedures that are prone to error. From automatic backups to data encryption to media management, Robot automates the routine (yet often complex) tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:

  • FORTRAManaging messages on your IBM i can be more than a full-time job if you have to do it manually. Messages need a response and resources must be monitored—often over multiple systems and across platforms. How can you be sure you won’t miss important system events? Automate your message center with the Robot Message Management Solution. Key features include:

  • FORTRAThe thought of printing, distributing, and storing iSeries reports manually may reduce you to tears. Paper and labor costs associated with report generation can spiral out of control. Mountains of paper threaten to swamp your files. Robot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing. Manage your reports with the Robot Report Management Solution. Key features include:

  • FORTRAFor over 30 years, Robot has been a leader in systems management for IBM i. With batch job creation and scheduling at its core, the Robot Job Scheduling Solution reduces the opportunity for human error and helps you maintain service levels, automating even the biggest, most complex runbooks. Manage your job schedule with the Robot Job Scheduling Solution. Key features include:

  • LANSA Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.

  • LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed. Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

  • LANSASupply Chain is becoming increasingly complex and unpredictable. From raw materials for manufacturing to food supply chains, the journey from source to production to delivery to consumers is marred with inefficiencies, manual processes, shortages, recalls, counterfeits, and scandals. In this webinar, we discuss how:

  • The MC Resource Centers bring you the widest selection of white papers, trial software, and on-demand webcasts for you to choose from. >> Review the list of White Papers, Trial Software or On-Demand Webcast at the MC Press Resource Center. >> Add the items to yru Cart and complet he checkout process and submit

  • Profound Logic Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application.

  • SB Profound WC 5536Join us for this hour-long webcast that will explore:

  • Fortra IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn: