Wednesday, December 23, 2020

More special options for RPG debugging

rpg debug special fields qrnu

Last week I wrote about a new way in debug of changing the value returned from a procedure in a RPG program. Having had some time to look around I have found some other of these special debug features. These others have been around for several releases, therefore, if you are not on IBM i 7.4 or 7.3 with the latest Technology Refreshes you might be able to use some or all of them.

These "special names for debugging" are:


_QRNU_NULL_name:  See or change null indicator for a variable

It has always bugged me that I cannot see the value of a null indicator for a variable or field when I am in debug. This special values allows me to do that, and to change it if I want too.

Example program:

01  **free
02  ctl-opt alwnull(*usrctl) ;

03  dcl-s wkVar char(3) inz('A') nullind ;

04  %nullind(wkVar) = *on ;

05  %nullind(wkVar) = *off ;

06  *inlr = *on ;

Line 1: My RPG is always free!

Line 2: As I am going to be playing with nulls I need this control option.

Line 3: My variable definition, I have defined it with its own null indicator using the NULLIND keyword.

Line 4: To make a variable null I turn on the null indicator.

Line 5: To change the variable to not be null I turn off the null indicator.

As I mentioned above these "special names" can only be used in debug. When I started debug with this program I added breakpoints at:

  1. Line 5
  2. Line 6

At line 5 even though the variable is null it contains the value I initialized it with:

ev wkvar

  WKVAR = 'A  '

The only way I can tell that the variable is null is by using _QRNU_NULL + the variable's name. For example:

ev _qrnu_null_wkvar

Onto the next breakpoint. Having made the variable not null it is no surprise that the "special value" tells me the variable is not null.

ev _qrnu_null_wkvar

I can even change the null indicator using the following:

ev _qrnu_null_wkvar = '1'
 _QRNU_NULL_WKVAR = '1' = '1'

What happens if I want to do this with a data structure:

01  **free
02  ctl-opt alwnull(*usrctl) ;

03  dcl-ds wkDS qualified ;
04    sf1 char(1) inz('1') nullind ;
05    sf2 char(1) inz('2') nullind ;
06  end-ds ;

07  %nullind(wkDS.sf1) = *on ;

08  *inlr = *on ;

Line 3 – 6: My data structure definition. Notice that both the subfields have been defined with null indicators.

Line 7: Turn on the null indicator for the first subfield.

I add the break point at line 8. I can see the null indicators for the subfields in the data structure that have null indicators:

ev qrnu_null_wkds

  EVAL _qrnu_null_wkds

Let me turn on the indicator for the second subfield:

ev qrnu_null_wkds.sf2 = '1'

  EVAL _qrnu_null_wkds.sf2 = '1'
  _QRNU_NULL_WKDS.SF2 = '1' = '1'

Now I can both the indicators are null:

ev qrnu_null_wkds

  EVAL _qrnu_null_wkds

This is very useful, I will be using this a lot.


_QRNU_TABI_name:  See or change the index of a RPG table

Another thing that is hard to find out in a RPG program what is the current index of a table, not a SQL table... you know the ones at the bottom of your RPG programs.

01  **free
02  dcl-s Table1 char(2) dim(5) ctdata ;

03  *inlr = *on ;

04  **
05  1
06  2
07  3
08  4
09  5

Line 2: Definition of my table.

Lines 4 – 9: The table.

The debug break point is at line 3.

If I do the following debug statement I am looking at the first table element as that is the default:

ev table1

  EVAL table1
  TABLE1 = '1 '

If I want to see what is in all of the table I would do this:

ev table1(1..5)

  EVAL table1(1..5)
  TABLE1(1) = '1 '
  TABLE1(2) = '2 '
  TABLE1(3) = '3 '
  TABLE1(4) = '4 '
  TABLE1(5) = '5 '

If I only wanted to see what was in the third element of the table I would:

ev table(3)

  EVAL table1(3)  
  TABLE1(3) = '3 '

The table's index is still set to the first table element. If want to change the index I would:

ev table1 = %index(3)

  EVAL TABLE1 = %index(3)
  TABLE1 = %INDEX(3) = 3

ev table1

  TABLE1 = '3 '

I can also see which table element the index is pointing at using:

ev _qrnu_tabi_table1
  EVAL _qrnu_tabi_table1

I could also change the index's position using:

ev _qrnu_tabi_table1 = 5
EVAL _qrnu_tabi_table1 = 5
_QRNU_TABI_TABLE1 = 5 = 5 

ev table1

  EVAL table1
  TABLE1 = '5 '

Another useful trick I will be using.


_QRNU_DSI_name:  See or change index of multiple occurrence data structures

Let me start by saying that you cannot code multiple occurrence data structures in free format RPG definitions. They have been superseded by data structure arrays. Therefore my example has to use fixed format definitions:

01  D wkMODS          DS                  occurs(10)

02     %occur(wkMODS) = 5 ;

03     *inlr = *on ;

Line 1: Definition for the MODS, Multiple Occurrence Data Structure.

Line 2: Set the data structure to the fifth occurrence.

The breakpoint is at line 3. I can see which occurrence the data structure is positioned to using:

ev _qrnu_dsi_wkmods


I can also change the occurrence:

ev _qrnu_dsi_wkmods = 3

  EVAL _qrnu_dsi_wkmods = 3

ev _qrnu_dsi_wkmods


Fortunately I do not encounter MODS that often so I might use this occasionally.


_QRNU_XMLSAX:  View names of the associated with the events for the XML-SAX operation code

As I have not written about the XML-SAX I do not want to turn this post into that article.

When I do write about it I will try to remember to include this.


You can learn more about this from the IBM website:


This article was written for IBM i 7.4, and should work for some earlier releases too.


  1. Thank you for

  2. Thanks very much! This is helpful.

  3. Just I was searching an error with an array and this timely article helped me. Thanks Simon


To prevent "comment spam" all comments are moderated.
Learn about this website's comments policy here.

Some people have reported that they cannot post a comment using certain computers and browsers. If this is you feel free to use the Contact Form to send me the comment and I will post it for you, please include the title of the post so I know which one to post the comment to.