Home

Resources
 
Listing Indexes, er Logical Files....

Ah, the ever present debate, when is a logical an index? I like to think that this could be a good Zen koan, but it is actually quite simple. You see, IBM has a system catalogue view in the library QSYS2 called SYSINDEXES that lists all of the indexes on your AS/400 system. The problem is the view only lists SQL INDEXES. See, a logical file only makes it into the list of indexes if the SQL CREATE INDEX statement created it. Since most AS/400 shops are dealing with legacy systems their logical files were created by DDS. Therefore, none of their logical files are in the SYSINDEXES view. However, most keyed logical files are indexes and can be consider for use by SQL in the resolution of a query. The problem is a semantic one; IBM chose to call a logical file an index only if the CREATE INDEX SQL statement created it.

A better way to look for indexes, (er logical files), which can be used in the resolution of a query is to look at the system catalogue tables in QSYS. QSYS has several physical files that have useful information on all of the database objects on your AS/400 system.

The first catalogue file to ponder is the QADBFDEP file. This physical file contains cross-reference information about what files are dependent on each other on your AS/400 system. The following query could be used to list the files that are dependent on the FOO table in the BAR library:

SELECT * FROM QSYS.QADBFDEP
WHERE DBFFIL = 'FOO' AND DBFLIB = 'BAR'

The DBFFIL field is the name of the target table, and the DBFLIB field is the name of the target library. The above query would list all of the files that are dependent on the FOO table and would include the name of the dependent table, its library, the type of dependency and its dependent files record format. Note that this is sort of like running the DSPDBR command against a table.

Another interesting table in QSYS is QADBXREF. This table contains information about all tables, physical files, indexes, logical files, source physical files and SQL views on your AS/400 system. It is like a subset of the information available from the DSPFD command. The following query joins the QADBFDEP table to the QADBXREF table in order to produce a listing of the files dependent on the OEPTOLY table in the HD1100PD library. The query also returns the type of dependent file, the short description of the file and whether the file is considered relational by the AS/400 system.

SELECT DBFLDP AS LIBRARY, DBFFDP AS FILENAME,
DBXOWN AS OWNER, DBXTXT AS SHORT_DESC,
DBXATR AS FILE_TYPE, DBXREL AS RELATIONAL,
DBXATS AS LAST_CHANGE
FROM QSYS.QADBFDEP LEFT JOIN QSYS.QADBXREF
ON (DBFFDP=DBXFIL AND DBXLDP=DBXLIB)
WHERE DBFFIL='OEPTOLY' AND DBFLIB='HD1100PD'

Now, the above query is much more useful than the output of DSPDBR because it includes the description of the file and they type of dependent file. Other information available in QADBXREF that you might want to include in the query is the number of fields in the file, the maximum record length and the number of key fields in the file.

Now, this begs the question about that relational field, what exactly does that mean. Well, as near as I can determine if the file type is a logical file and it is not a multi-format file it is considered relational by the AS/400 system. What this means to you is that you can name the file in the FROM clause of a query. I know this is not a good explanation, but we only have a limited amount of space this week so I need to move on. Suffice it to say, I will address the ‘relational’ nature of these files in a future article. However, I do want to point out that the relational attribute in QADBXREF is important to JDBC and ODBC programmers. In JDBC and ODBC, you can execute a query against your database connection to determine the indexes available against your physical file. This operation does not go against the SYSINDEXES view in QSYS2, but rather is a query against the relational=’Y’ logical files in QADBXREF that relate to your physical file. This is not an actual list of ALL of the logical files that might be considered in the resolution of your query. You see, DB2 might elect to use any of the logical files returned by my query above in resolution of a query against the physical file. In fact, if you check the query optimizer, you will see the DB2 looks at each of the logical files that are related to each of the physical files that are referenced in your query.

So, the short answer is to use the query above to get a list of indexes that might be used in resolution of an SQL query against a physical file. With a few changes, the query can even be used to return the names of the fields like the following:

SELECT DBFLDP AS LIBRARY,
DBFFDP AS FILENAME,
DBXTXT AS SHORT_DESC,
DBKPOS AS ORDINAL_POS,
DBKFLD AS KEY_FIELD,
DBXREL AS RELATIONAL
FROM QSYS.QADBFDEP
LEFT JOIN QSYS.QADBXREF
ON (dbffdp=dbxfil AND dbfldp=dbxlib)
LEFT JOIN QSYS.QADBKFLD
ON (DBFFDP=DBKFIL AND
DBFLDP = DBKLIB AND
DBFRDP = DBKFMT)
WHERE dbffil='OEPTOLY' AND dbflib='HD1100PD'
AND DBXATR='LF'
ORDER BY FILENAME, ORDINAL_POS

Note that the above query restricts itself to only files that have the LF, logical file, DBXATR so that we are only listing logical files that are related to the physical file. In addition, the query specifies that the information by returned order by the FILENAME and then by the ORDINAL_POS. ORDINAL_POS is the offset of the key in the logical file, where the 1st key would be ordinal position 1 and the second key would be ordinal position 2. Remember, with SQL you always want to specify the order that you want your result set returned in, otherwise you have no guanentees as to how the AS/400 will return the results of your query. The above query might be sutable for driving a report on the indexes available against a physical file, but by joining the query to the QADBIFLD file we can further enhance information about the keys in the logical file by returning the data type of the field and the fields short description. The next query returns most of the information you might want to know about a logical file by joining the QADBFDEP, QADBXREF, QADBKFLD and QADBIFLD files together.

SELECT DBFLDP AS LIBRARY,
DBFFDP AS FILENAME,
DBXTXT AS SHORT_DESC,
DBKPOS AS ORDINAL_POS,
DBKFLD AS KEY_FIELD,
DBITYP AS DATA_TYPE,
DBITXT AS FIELD_DESC,
DBICLN AS CHARACTER_LEN,
DBINLN AS NUMERIC_LEN,
DBINSC AS NUMERIC_SCALE,
DBXREL AS RELATIONAL
FROM QSYS.QADBFDEP
LEFT JOIN QSYS.QADBXREF
ON (dbffdp=dbxfil AND dbfldp=dbxlib)
LEFT JOIN QSYS.QADBKFLD
ON (DBFFDP=DBKFIL AND
DBFLDP = DBKLIB AND
DBFRDP = DBKFMT)
LEFT JOIN QSYS.QADBIFLD
ON (DBFFDP=DBIFIL AND
DBFLDP=DBILIB AND
DBFRDP=DBIFMT AND
DBKFLD=DBIFLD)
WHERE dbffil='OEPTOLY' AND dbflib='HD1100PD'
AND DBXATR='LF'
ORDER BY FILENAME, ORDINAL_POS

The system catalogue tables in QSYS are a wealth of information, spend some time looking at what is available to you and attempting to construct queries to explore your AS/400 and look for some updated pages on my web site, www.sqlthing.com , addressing these and other issues with indexes.