TAA Tools
USRIDX          USER INDEX                             TAAIDXA

The User Index  tool provides an  interface to allow  reading, writing,
updating,  and  deleting entries  from  a user  index.   Several  other
tools  such as CRTUSRIDX also use  interfaces provided by USRIDX.  Only
keyed fixed  length  user indexes  are supported.    The maximum  entry
length is 2000 bytes including the key.

OPM and ILE  users may use a dynamic call to  TAAIDXAR5.  An externally
described  data  structure (TAAIDXAP)  is  the only  parameter  that is
passed which contains fields for  the operation requested and the  data
to be returned.

An  ILE  user  may also  use  a  bound  call.   A  service  program  is

User Index concepts

The system  supports a *USRIDX object.   Both keyed and non-keyed types
are supported (similar to *DTAQ objects)  and the entries may be  fixed
or variable length.   APIs are used to create, read,  write, and delete
entries in a user index.

In some  applications, a program  must read an unknown  amount of data,
place  it into an array,  possibly update some of  the values, and then
sort the array to allow processing in sequence.

If an unknown  amount of data exists,  a typical solution is  to define
an array with  a large number of entries (the RPG  OPM limit is 9,999).
This  can make  functions like RPG's  LOKUP very  slow if  a value does
not exist.  Sorting  an array in  RPG must be  done by placing the  key
in the high order position of each element.

A  *USRIDX object  can simplify  this  type of  processing by  allowing
keyed  operations.   The  data  can  be written  randomly  to  the user
index.  If  updating is required,  random updates may  be made by  key.
To output  the  entries in  sequence, the  program only  needs to  read
sequentially by key.

From an  external perspective, you can consider a  *USRIDX object to be
similar  to a simple data base  work file.  The  key to the entry makes
up the first n  bytes of an entry.   When a user index is  created, you
define the length of the entry and the length of the key.

The system supports a single command to operate on user indexes:

            DLTUSRIDX       Delete user index

The TAA support of *USRIDX objects allows the following commands:

            CRTUSRIDX       Create user index (only keyed fix length)
            CVTUSRIDX       Convert user index entries
            RTVUSRIDXA      Retrieve user index attributes
            DSPUSRIDXA      Display user index attributes
            DSPUSRIDX       Display user index entries
            CLRUSRIDX       Clear user index

Also supported  by TAA are programs  which allow you  to interface from
a  HLL program to cause operations  such as read, write,  etc to a user
index.   This allows  a  typical RPG  programmer to  use a  user  index
without knowledge of the APIs.

For dynamic calls from OPM or ILE, use the TAAIDXAR5 program.

For bound calls from ILE, use the TAAIDXA *SRVPGM.

The TAA support is  limited to keyed fix length  entries and supports a
maximum entry  length of 2000 bytes.  The maximum  size of a user index
may be 4GB.

Sample OPM program

Sample OPM  programs  are  provided  that will  create  a  user  index,
write, read, update, and delete entries.  To run the programs, enter:

             CALL        PGM(TAAIDXAC6)

A spooled file will be displayed with the results.

The TAAIDXAC6 CL program  creates the MYUSRIDX user index  (*USRIDX) in
QTEMP  and calls  the  TAAIDXAR6 RPG  program.   The  program  writes 3
entries  to the  user index,  retrieves them  in keyed  order, randomly
retrieves an  entry, updates it,  deletes a  different entry, and  then
retrieves the  entries in keyed  order.  A  listing occurs to  show the

After the programs run, you can try out the following commands:


An  externally described  data  structure is  used to  pass information
the supplied program.   You can  display the format  of the  externally
described data structure with the command:

             DSPFMT      FILE(TAAIDXAP)

To  understand how  you  use the  TAA interface  to  manipulate a  user
index,  the following TXTnn  entries refer to  the corresponding values
within the TAAIDXAR6 RPG OPM source  test program.  You can print  this
program out and  refer to it as you  go thru the discussion.   To print
the code, use:


  **   TXT010.    The externally  described  data structure  (TAAIDXAP)
       has  two  fields  which  are larger  than  the  RPG  OPM maximum
       length of 256  bytes.   These two fields  UIDATA and UIMSTX  are
       defined as  arrays to prevent compilation errors.   Using arrays
       requires  the use  of MOVEA when  the fields  are referenced (if
       using ILE  RPG, the arrays  would not  be needed  and the  MOVEA
       operations could be replaced with MOVEL).

  **   TXT020.  The  externally described data structure  (TAAIDXAP) is
       defined and given a name IDXDS.

  **   TXT030.   The sub program  described as USRIDX is  defined to be
       TAAIDXAR5.  This is the  TAA supplied program for programs  that
       will cause operations to  a user index by passing  an externally
       described data structure as the only parameter.

  **   TXT040.   The MSGDS  data structure of  512 bytes is  defined to
       allow use by the TAA Tool SNDDIAG.

  **   TXT050.   In the  TAAIDXAC6 CL program,  the MYUSRIDX user index
       object was created with a  length of 20 and a key length  of 10.
       If you  used the DSPUSRIDXA command  after the call to  the test
       program  (TAAIDXAC6)  you  would  see  this  information.    The
       definition means that each entry  will begin with a 10 byte  key
       and then  have 10 bytes  of data associated  with the key.   The
       MYDS data  structure is defined with  a key of 10  bytes in 1-10
       and data  in 11-20.   Thus  the key  is part  of  the entry  and
       always begins  in the  high order  for the  length defined  when
       the user index was created.

  **   TXT060.   The program moves the name of  the user index and user
       index   library  (MYUSRIDX  in  QTEMP)   to  fields  within  the
       TAAIDXAP  externally  described  data  structure.    The  *WRITE
       operation  code is  requested.   Each entry  to be  written then
       requires  a move of  a key  value and corresponding  data to the
       fields in  the MYDS  data structure.   The  WRITE subroutine  is
       used to write each entry to the user index.

  **   TXT070.   The  WRITE subroutine  moves  the data  from the  MYDS
       data structure  to the UIDATA field  in the externally described
       data structure.   This UIDATA field  is the entry  that will  be
       written to the user index.

       Note that  each time the  program writes to  the user index,  it
       moves  data from the  MYDS data  structure to the  UIDATA field.
       Similarly,  each time  a read occurs,  the returned  entry is in
       UIDATA and is moved  to the MYDS data structure  for processing.

       The  USRIDX program  (TAAIDXAR5) is  called and  the  IDXDS data
       structure  is  passed.   If an  error  occurs, the  UIMSID field
       will not  be  blank.    A  typical error  that  might  occur  is
       CPF3C74 meaning a duplicate key occurred.

  **   TXT080.   The  entries that  were written  will be  sequentially
       read and printed by the READ subroutine.

  **   TXT090.   The 'low value' is  placed into the key  field and the
       MYDS data structure is moved to UIDATA.

  **   TXT100.  The  operations are set  to *READ and  *GT.  Note  that
       you should  use a MOVEL  with padding when  placing data in  the
       UIOPCD and  UISCOD fields.  The call to  USRIDX ignores any data
       in  the data portion of UIDATA.   The key portion of UIDATA (now
       containing 'low  value')  is used  to  access the  first  record
       because *READ *GT was specified.

  **   TXT110.   The UIMSID field must  be checked after each  call.  A
       value  of TAA9891 means that  the entry was  not returned.  When
       a sequential read  is used, TAA9891 means  'end of entries'  and
       the program branches to the end of the subroutine.

       Any other error value causes the program to abort.

  **   TXT120.  If  the UIMSID field is  blank, it means that  an entry
       was placed  in the UIDATA field.  The data  is moved to the MYDS
       data structure for processing.

  **   TXT130.  After the  first entry is  returned, the program  loops
       back to  request the next  entry.  The  USRIDX program uses  the
       value in  the key portion  of the UIDATA field  to determine how
       to  request  the  next entry.    Since the  first  *READ request
       returns the  first  entry,  a request  for  *READ and  *GT  will
       cause the  second entry  by key  to be returned.   Each  time an
       entry is processed, this same loop occurs.

  **   TXT140.   A  random  request will  now be  made to  retrieve the
       '234'  key.   The  key  is  set  to  '234'  and  the  MYDS  data
       structure is moved to the UIDATA field.

  **   TXT150.  The  UIOPCD field is set  for *READ, and *EQ  is placed
       in  the UISCOD field requesting  an equal key.   Note that there
       is probably data  in bytes 11-20  of the UIDATA  field when  the
       call occurs.   This data will be  ignored by a *READ  request to
       the USRIDX program.

  **   TXT160.   The  UIMSID field is  checked for  errors.   Since the
       program  assumes the key  will exist, the  program will abort if
       the message field is non-blank.

  **   TXT170.   If  the UIMSID  field  is blank,  the entry  has  been
       placed  in the  UIDATA field.    It is  moved to  the MYDS  data
       structure for processing.

  **   TXT180.   The entry  that was just  read will be  changed in the
       data portion.   The new  value 'MILLER'  is moved  the the  DATA
       field and  the key ('234').   The  MYDS data structure  is moved
       to UIDATA.

  **   TXT190.   A  request is made  then for  *UPDATE of an  equal key

       Note that it  would not have  been necessary to  read the  entry
       first.  The update request requires that a key be named.

       Note there  is no  locking mechanism  to prevent  two jobs  from
       updating  the same  entry at  the same  time.   You  must ensure
       this  such as in  this example by  placing the user  index is in
       QTEMP.  You could  consider locking the user index  with ALCOBJ.

  **   TXT200.  A  check for errors occurs and if  UIMSID is not blank,
       the program will abort.

  **   TXT210.   A delete will now be requested  of key '456'.  The key
       is placed  in  MYDS  and the  data  structure is  moved  to  the
       UIDATA field.

  **   TXT220.  A request  for *DELETE with an *EQ key is  made and the
       USRIDX program  is called.  Note that  there is probably data in
       positions 11-20 of  the UIDATA  field, but this  is ignored  and
       only the key portion is used.

  **   TXT230.  A check  for errors occurs and if UIMSID  is not blank,
       the program will abort.

  **   TXT240.   The READ subroutine is used again  to list the entries
       in sequential order.

  **   TXT250.   The  USRIDX program  is kept  open after each  call to
       allow faster  processing.   To end  the  program with  LR on,  a
       *CLOSE request  is made and the  USRIDX program is  called.  The
       activation  group  used  for the  USRIDX  program  is destroyed.
       Any UIDATA value is  ignored and none is  passed back.  A  check
       for errors occurs  and if UIMSID is not blank,  the program will

  **   TXT260.   The SNDERR routine is used any  time there is an error
       in the UIMSID  field that is  not handled by the  program.   For
       example,  the program  considered  a  TAA9891 value  as  meaning
       'end of  entries' when a *READ was  used to process sequentially
       by key.

       To  provide  for  feedback  relating  to  error  conditions, the
       current contents  of IDXDS  (the  data structure  passed to  the
       USRIDX program)  is moved to  the MSGDS data structure  which is
       512  bytes in  length.   The  SNDDIAG TAA  program is  called to
       send the text as  a diagnostic message.   The message will  thus
       describe the  first 512  bytes of the  data structure  last sent
       to the USRIDX program.

       The  SNDDIAG program  is  used again  to send  the  message text
       that was returned  by the  USRIDX program in  the UIMSTX  field.
       The message  will begin  with the  message ID  received from  an
       API (or created by USRIDX) followed by the message text.

       The  program  then  calls  the  TAA  ABORT  program  which  will
       abnormally   terminate  the  program   with  an  escape  message

Format of TAAIDXAP Externally Described Data Structure

   UINM          The User Index name.  10 bytes in positions 1-10.

   UILIB         The User Index  library name.   10 bytes in  positions

   UIOPCD        The  Operation  code.   7  bytes  in positions  21-27.
                 The   following   are  valid   (some   operations  are
                 modified by the UISCOD field).

                      *READ - Reads one entry

                      *WRITE - Writes one entry

                      *UPDATE - Updates one entry

                      *DELETE - Deletes one entry

                      *CLEAR - Clears all entries

                      *CLOSE -  Closes the  processing program.    This
                      should be  used when  a program  calls TAAIXDAR5.
                      The    activation   group   for    TAAIXDAR5   is

   UISCOD        The Search code.   6  bytes in positions  28-33.   The
                 values  *EQ,  *GT,   *LT,  *GE,  *LE,   *FIRST  (first
                 entry),  and *LAST  (last entry)  are supported.   The
                 search  code is  used with  *READ, *ADD,  *UPDATE, and
                 *DELETE operations.

                 The value is ignored for *CLEAR and *CLOSE.

                 When *FIRST  or *LAST is  specified, the UIDATA  field
                 is ignored.

   UIDATA        The  entry data.    2000 bytes  in positions  34-2033.
                 The  length of the  key portion (high  order bytes) is
                 determined by  accessing the  attributes of  the  user
                 index.  The  length of the data  portion is determined
                 by  subtracting the length  of the key  from the entry
                 length defined for the user index.

                      For *READ  operations, only  the key  portion  is
                      used.   The  data  portion  is  ignored.   If  an
                      entry  is found, both  the key  and the  data are

                      For  *WRITE  operations,  both  the  key  and the
                      data portion are  used.  The  value of UIDATA  is
                      not changed.

                      For  *UPDATE operations,  both  the  key and  the
                      data  portion are used.   The value  of UIDATA is
                      not changed.   Note that it  is valid to  request
                      a  UISCOD value  such as  *GT in  which case  the
                      key  higher than  the  one specified  is updated.
                      The key  of the  entry that  was updated  is  not

                      For *DELETE operations,  only the key  portion is
                      used.  The value of UIDATA is not changed.

                      For  *CLEAR  operations,   the  UIDATA  value  is

                      For   *CLOSE  operations,  the  UIDATA  value  is

   UIMSID        The  message   ID  field.     7  bytes  in   positions
                 2034-2040.   This  field  must be  checked after  each
                 operation  to ensure  valid results.   The  user index
                 program does not return escape messages.

                 TAA9891 will be  returned if  no entry is  found on  a
                 *READ,  *UPDATE,  or  *DELETE operation.    Note  that
                 when  reading  sequentially,  TAA9891  means  no  more
                 entries exist ('end of entries').

                 Any error messages  sent from  the APIs  used will  be
                 returned.   For  example,  CPF3C74  is returned  if  a
                 duplicate key  is attempted to be written  by a *WRITE

   UIMSDT        The  message  data  field.    256  bytes  in positions
                 2041-2296.   Any  message data  for an  error  message
                 will be placed in this field.

                 For  a *CLEAR  operation, the  number of  entries that
                 were  cleared is  placed in  the first  10 bytes  as a
                 zoned value.

   UIMSTX        The message  text  field.    512  bytes  in  positions
                 2297-2808.   The complete  text of  the message  if an
                 error occurs.

Using an ILE bound program

The  TAAIDXAR98  and TAAIDXAR99  RPG  members contain  the  QUSEC error
data structure  and all  the  prototypes.   Use  CPYTAA as  follows  to
extract the source:

             CPYTAA       TAAARCMBR(TAAIDXAR98)
             CPYTAA       TAAARCMBR(TAAIDXAR99)

This places the source in the QATTRPG file in TAATOOL.

The following items should be in the users source.

       h bnddir('TAATOOL/TAADIXA')
       / copy taatool/qattrpg/TAAIDXAR98
       / copy taatool/qattrpg/TAAIDXAR99

All the  ILE functions are  provided by the  DoUsrIdxOp (do user  index
operation) subprocedure  using parameters for the  fields described for
the  TAAIDXAP data structure.   Note that you do  not need the TAAIDXAP
data structure.

Sample ILE  programs exist  that cause  3 entries  to be  written to  a
user index.  You may try these programs by:

             CALL     TAAIDXAC7

This  creates the  user  index object  and  calls the  RPG ILE  program
TAAIDXAR7.  The DSPUSRIDXA command is used to display the results.

You can review the code with the command:


Review and recommendations

  **   To  access by key,  you must place  the key in  the UIDATA field
       before doing a read.

  **   If  you  are  using  the  TAAIDXAP  externally   described  data
       structure in  either an  OPM or ILE  program, you  must remember
       to  move your  data (probably  a data  structure) to  the UIDATA
       field before  making  a write  request.   Conversely,  you  must
       remember to move  from the UIDATA  field to your  data (probably
       a data structure) after a successful read operation.

  **   If you  have decimal values,  you probably want to  keep them in
       zoned  format to simplify debugging.   This allows the DSPUSRIDX
       TAA command  to be used  normally without  requesting a  display
       by hex value.

  **   Assuming  you use  a data  structure for  your data,  it  can be
       helpful  to separate  the fields  by a  blank value  to simplify
       reviewing the data with DSPUSRIDX.

Escape messages you can monitor for


The call  to the  supplied programs  should  always complete  normally.
You  are responsible  for checking  the UIMSID  field.   If blank,  the
request was successful.

TAA9891  will be  returned  for a  *READ, *UPDATE,  or  *DELETE request
when the key does not  exist (such as no more  entries can be found  to
be read).

Other message IDs may be sent by the APIs used.


Only fixed  length  keyed user  indexes are  supported  with a  maximum
length of 2000 bytes.

The maximum supported size is 4GB.


The following TAA Tools must be on your system:

     ABORT           Abort
     CRTUSRIDX       Create user index
     DSPLSTSPLF      Display last spooled file
     DSPUSRIDXA      Display user index attributes
     SNDDIAG         Send diagnostic message
     SNDSTSMSG       Send status message


None, the tool is ready to use.

Objects used by the tool

   Object        Type    Attribute      Src member    Src file
   ------        ----    ---------      ----------    ----------

   TAAIDXAC6     *PGM       CLP         TAAIDXAC6     QATTCL
   TAAIDXAC7     *PGM       CLP         TAAIDXAC7     QATTCL
                            RPGLE       TAAIDXAR      QATTRPG
   TAAIDXAR6     *PGM       RPG         TAAIDXAR6     QATTRPG
   TAAIDXAR98                           TAAIDXAR98    QATTRPG
   TAAIDXAR99                           TAAIDXAR98    QATTRPG
   TAAIDXA       *SRVPGM                TAAIDXAR      QATTRPG

TAAIXDAR creates a module for the TAAIDXA *SRVPGM.

The  test  programs  TAAIDXAC6,  TAAIDXAC7,  TAAIDXAR6,  and  TAAIDXAR7
require  the tool  commands (CRTUSRIDX, RTVUSRIDXA,  and DSPUSRIDXA) to
exist.   An escape  message occurs  during the  create if  they do  not
exist stating that  CRTTAATOOL should be used for the  3 tools and then
USRIDX again.

Added to TAA Productivity tools June 15, 2004

Home Page Up to Top