Page History
...
No | Type | Req/ Opt | Description | Min Len | Max Len | Min Dec | Max Dec |
|---|---|---|---|---|---|---|---|
1 | A | Req | Type of indexed space operation to be performed. Pass as one of: INSERT Unconditionally insert a new entry into an indexed space. PUT Insert a new or update an existing entry in an indexed space. GET Get an entry from an indexed space. FIRST Get the first entry in an indexed space. NEXT Get the next entry in an indexed space. DESTROY Destroy an indexed space and free associated system resources. Note that this Built-In Function only validates and acts upon the first character of the requested index space operation (i.e. C,I,P,G,F,N,D) but to maximize RDML function readability it is recommended that you use the full words CREATE, INSERT, PUT, GET, FIRST, NEXT and DESTROY. | 1 | 50 | ||
2 | A | Req | Definition string or indexed space, identifier (or handle). An identifier (or handle) is the value returned to you in argument 2 when you create a new indexed space that uniquely identifies the indexed space. When Arg 1 is Pass Pass this argument as: CREATE The indexed space definition string. See the following information for details of definition strings. any other The identifier (or handle) of the indexed space that is to be used by the requested operation (the identifier or handle is the value returned in return value 2 when a new index space is created. It uniquely identifies the indexed space which you wish to use). | 1 | 256 | ||
3 | A | Opt | Definition string continuation. Only valid for CREATE operations, ignored for other operations. | 1 | 256 | ||
4 | A | Opt | Definition string continuation. Only valid for CREATE operations, ignored for other operations. | 1 | 256 | ||
5 | A | Opt | Definition string continuation. Only valid for CREATE operations, ignored for other operations. | 1 | 256 | ||
6 | A | Opt | Definition string continuation. Only valid for CREATE operations, ignored for other operations. | 1 | 256 | ||
7 | A | Opt | Definition string continuation. Only valid for CREATE operations, ignored for other operations. | 1 | 256 | ||
8 | A | Opt | Definition string continuation. Only valid for CREATE operations, ignored for other operations. | 1 | 256 | ||
9 | A | Opt | Definition string continuation. Only valid for CREATE operations, ignored for other operations. | 1 | 256 | ||
10 | A | Opt | Definition string continuation. Only valid for CREATE operations, ignored for other operations. | 1 | 256 | ||
11 | A | Opt | Definition string continuation. Only valid for CREATE operations, ignored for other operations. | 1 | 256 |
...
No | Type | Req/ Opt | Description | Min Len | Max Len | Min Dec | Max Dec |
1 | A | Req | Standard Return Code | 2 | 2 | ||
2 | A | Opt | Returned indexed space identifier or handle. | 10 | 10 |
...
"name" is the name of a valid RDML field that is defined in, or referenced by, the the RDML function that is creating the list.
"keyword" specifies the use of the field specified in "name". It may be one of KEY, DATA, AVG, MAX, MIN, COUNT and SUM. If a keyword is not specified then DATA is is assumed as a default keyword.
"value" specifies the name of a valid RDML field that is defined in, or referenced by, the RDML function defining the list. It is used to specify, for certain keyword values only, the field upon which the keyword activity should take place. Thus ".., A SUM(B), .." defines defines that indexed space field A is to contain the SUM (or total) of field B. Likewise, the the string ".., X AVG(Y), .." defines that indexed space field X is to contain the average average of field Y.
The "keywords" AVG, MAX, MIN and SUM require associated "values" and thus must be formatted as AVG(value), MAX(value), MIN(value) and SUM(value) where value is the name of a field defined in the invoking RDML function.
...
An indexed space must have at least one key field/column defined.
An indexed space can have at most 20 key fields/columns defined.
An indexed space must have at least one non-key field/column defined.
An index space can have at most 100 non-key fields/columns defined.
The aggregate byte length of all key fields/columns in an indexed space definition cannot exceed 16K. Note that if you are coming even remotely close to this limit then you should consult your product vendor about application design.
The aggregate byte length of all non-key fields/columns in an indexed space definition entry cannot exceed 16K. Note that if you are coming even remotely close to this limit then you should consult your product vendor about application design.
The significance of defined keys decreases with the order of their definition. Thus the definition string "aaa key(), bbb key(), ccc key(), xxx data(), yyy data()" defines "aaa" as the most significant key and "ccc" as the least significant key.
Key definitions can take place at any point in the definition string, but it is customary to place them at the beginning.
There is no effective limit to how many entries can be place into an indexed space, but you must REMEMBER AT ALL TIMES that indexed spaces use allocated system memory. The more entries that exist in an index space the more overhead you are placing on the consumption of a system resource. References in this section to "no effective limit" actually mean that you are effectively constrained by how much memory your system can viably allocate and use.
The operations FIRST and NEXT support sequential key order access, however they can only be used with indexed spaces where there are less than 63KB / 6 (for Windows 3.1) or 32MB / 6 6 (other environments) entries in the indexed space. This is because the storage of the indexed entry's key always takes 6 bytes (regardless of the actual aggregate length of the key fields).
If you try to use FIRST/NEXT sequential processing on an indexed space that is too large to support it you will receive a specific error message and your application will be aborted. GET, PUT and INSERT operations are not subjected to this limitation and can be used with no effective limit on the number of entries in the indexed space.An indexed space can only be used by the function that creates it. Although you can easily pass the identifier (or handle) of an indexed space to another function, any attempt by the other function to access the index space may lead to application failure and or unpredictable results. Do not attempt to do this. It will not work because when you CREATE an indexed space, a unique access plan to data fields stored in the creating function is formed. This access plan is unique to the creating function and cannot be effectively used by any other RDML function.
You should use the DESTROY operation in your functions. However, all indexed spaces created by an RDML function are automatically destroyed when it terminates.
If you are using multiple definition strings with a CREATE operation please remember that trailing blanks are ignored. Therefore:
...
FUNCTION OPTIONS(*LIGHTUSAGE *DIRECT)
********** COMMENT(Departmental Summary definitions)
DEFINE FIELD(#OVTDEPSAL) TYPE(*DEC) LENGTH(15) DECIMALS(2) COLHDG('Total' 'Salary' 'Expenditure') EDIT_CODE(3)
DEFINE FIELD(#OVXDEPSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Maximum' 'Salary') EDIT_CODE(3)
DEFINE FIELD(#OVNDEPSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Minimum' 'Salary') EDIT_CODE(3)
DEFINE FIELD(#OVADEPSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Average' 'Salary') EDIT_CODE(3)
DEFINE FIELD(#OVCDEPSAL) TYPE(*DEC) LENGTH(7) DECIMALS(0) COLHDG('Total' 'Employees') EDIT_CODE(3)
DEFINE FIELD(#OVFDEPSAL) TYPE(*CHAR) LENGTH(256) DECIMALS(0) COLHDG('Indexed' 'Space' 'Definition')
CHANGE FIELD(#OVFDEPSAL) TO('deptment key(), ovtdepsal sum(salary), ovxdepsal max(salary), ovndepsal min(salary), ovadepsal avg(salary), ovcdepsal count()')
DEFINE FIELD(#OVHDEPSAL) TYPE(*CHAR) LENGTH(10) LABEL('Space Handle')
DEF_LIST NAME(#OVSDEPSAL) FIELDS(#DEPTMENT #OVTDEPSAL #OVCDEPSAL #OVXDEPSAL #OVNDEPSAL #OVADEPSAL)
**********
DEFINE FIELD(#OV_RC) TYPE(*CHAR) LENGTH(2) LABEL('Return Code')
********** COMMENT(Create the indexed space)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(CREATE #OVFDEPSAL) TO_GET(#OV_RC #OVHDEPSAL)
********** COMMENT((Pass over the data and update the summary details')
SELECT FIELDS(#DEPTMENT #SALARY) FROM_FILE(PSLMST)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(PUT #OVHDEPSAL) TO_GET(#OV_RC)
ENDSELECT
********** COMMENT(Now load/show a browse list with the results)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(FIRST #OVHDEPSAL) TO_GET(#OV_RC)
DOWHILE COND('#OV_RC = OK')
ADD_ENTRY TO_LIST(#OVSDEPSAL)
USE USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(NEXT #OVHDEPSAL) TO_GET(#OV_RC)
ENDWHILE
DISPLAY BROWSELIST(#OVSDEPSAL)
********** COMMENT(Destroy the indexed space)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(DESTROY #OVHDEPSAL) TO_GET(#OV_RC)
The following sample RDML function is identical to the previous one except that it uses a second indexed space to aggregate information for all departments and then adds the "grand" aggregates to the end of the aggregate list that is displayed to the user. This demonstrates how indexed spaces can be used to perform multiple level totaling by using multiple indexed spaces:
FUNCTION OPTIONS(*LIGHTUSAGE *DIRECT)
********** COMMENT(Departmental Summary definitions)
DEFINE FIELD(#OVTDEPSAL) TYPE(*DEC) LENGTH(15) DECIMALS(2) COLHDG('Total' 'Salary' 'Expenditure') EDIT_CODE(3)
DEFINE FIELD(#OVXDEPSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Maximum' 'Salary') EDIT_CODE(3)
DEFINE FIELD(#OVNDEPSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Minimum' 'Salary') EDIT_CODE(3)
DEFINE FIELD(#OVADEPSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Average' 'Salary') EDIT_CODE(3)
DEFINE FIELD(#OVCDEPSAL) TYPE(*DEC) LENGTH(7) DECIMALS(0) COLHDG('Total' 'Employees') EDIT_CODE(3)
DEFINE FIELD(#OVFDEPSAL) TYPE(*CHAR) LENGTH(256) DECIMALS(0) COLHDG('Indexed' 'Space' 'Definition')
CHANGE FIELD(#OVFDEPSAL) TO('deptment key(), ovtdepsal sum(salary), ovxdepsal max(salary), ovndepsal min(salary), ovadepsal avg(salary), ovcdepsal count()')
DEFINE FIELD(#OVHDEPSAL) TYPE(*CHAR) LENGTH(10) LABEL('Space Handle')
DEF_LIST NAME(#OVSDEPSAL) FIELDS(#DEPTMENT #OVTDEPSAL #OVCDEPSAL #OVXDEPSAL #OVNDEPSAL #OVADEPSAL)
**********
DEFINE FIELD(#OVFGRAND) TYPE(*CHAR) LENGTH(256) DECIMALS(0) COLHDG('Indexed' 'Space' 'Definition')
CHANGE FIELD(#OVFGRAND) TO('ovkgrand key(), ovtdepsal sum(salary), ovxdepsal max(salary), ovndepsal min(salary), ovadepsal avg(salary), ovcdepsal count()')
DEFINE FIELD(#OVHGRAND) TYPE(*CHAR) LENGTH(10) LABEL('Space Handle')
DEFINE FIELD(#OVKGRAND) REFFLD(#DEPTMENT) LABEL('Invariant Key') DEFAULT('''*ALL''')
**********
DEFINE FIELD(#OV_RC) TYPE(*CHAR) LENGTH(2) LABEL('Return Code')
********** COMMENT(Create the indexed spaces)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(CREATE #OVFDEPSAL) TO_GET(#OV_RC #OVHDEPSAL)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(CREATE #OVFGRAND) TO_GET(#OV_RC #OVHGRAND)
********** COMMENT((Pass over the data and create the summary indexes')
SELECT FIELDS(#DEPTMENT #SALARY) FROM_FILE(PSLMST)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(PUT #OVHDEPSAL) TO_GET(#OV_RC)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(PUT #OVHGRAND) TO_GET(#OV_RC)
...
ENDSELECT
********** COMMENT(Now load/show a browse list with the results)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(FIRST #OVHDEPSAL) TO_GET(#OV_RC)
DOWHILE COND('#OV_RC = OK')
ADD_ENTRY TO_LIST(#OVSDEPSAL)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(NEXT #OVHDEPSAL) TO_GET(#OV_RC)
ENDWHILE
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(GET #OVHGRAND) TO_GET(#OV_RC)
CHANGE FIELD(#DEPTMENT) TO(#OVKGRAND)
ADD_ENTRY TO_LIST(#OVSDEPSAL)
********** COMMENT(Display the results)
DISPLAY BROWSELIST(#OVSDEPSAL)
********** COMMENT(Destroy the indexed space)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(DESTROY #OVHDEPSAL) TO_GET(#OV_RC)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(DESTROY #OVHGRAND) TO_GET(#OV_RC)
The following example RDML function is again very similar to the previous two, except that it produces two additional aggregation lists by using two additional indexed spaces. The second is by department/section and the third is by salary (i.e., a distribution of how many employees earn a particular salary value) :
FUNCTION OPTIONS(*LIGHTUSAGE *DIRECT)
********** COMMENT(Departmental Summary definitions)
DEFINE FIELD(#OVTDEPSAL) TYPE(*DEC) LENGTH(15) DECIMALS(2) COLHDG('Total' 'Salary' 'Expenditure') EDIT_CODE(3)
DEFINE FIELD(#OVXDEPSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Maximum' 'Salary') EDIT_CODE(3)
DEFINE FIELD(#OVNDEPSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Minimum' 'Salary') EDIT_CODE(3)
DEFINE FIELD(#OVADEPSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Average' 'Salary') EDIT_CODE(3)
DEFINE FIELD(#OVCDEPSAL) TYPE(*DEC) LENGTH(7) DECIMALS(0) COLHDG('Total' 'Employees') EDIT_CODE(3)
DEFINE FIELD(#OVFDEPSAL) TYPE(*CHAR) LENGTH(256) DECIMALS(0) COLHDG('Indexed' 'Space' 'Definition')
CHANGE FIELD(#OVFDEPSAL) TO('deptment key(), ovtdepsal sum(salary), ovxdepsal max(salary), ovndepsal min(salary), ovadepsal avg(salary), ovcdepsal count()')
DEFINE FIELD(#OVHDEPSAL) TYPE(*CHAR) LENGTH(10) LABEL('Space Handle')
DEF_LIST NAME(#OVSDEPSAL) FIELDS(#DEPTMENT #OVTDEPSAL #OVCDEPSAL #OVXDEPSAL #OVNDEPSAL #OVADEPSAL)
********** COMMENT(Section Summary definitions)
DEFINE FIELD(#OVTSECSAL) TYPE(*DEC) LENGTH(15) DECIMALS(2) COLHDG('Total' 'Salary' 'Expenditure') EDIT_CODE(3)
DEFINE FIELD(#OVXSECSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Maximum' 'Salary') EDIT_CODE(3)
DEFINE FIELD(#OVNSECSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Minimum' 'Salary') EDIT_CODE(3)
...
DEFINE FIELD(#OVASECSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Average' 'Salary') EDIT_CODE(3)
DEFINE FIELD(#OVCSECSAL) TYPE(*DEC) LENGTH(7) DECIMALS(0) COLHDG('Total' 'Employees') EDIT_CODE(3)
DEFINE FIELD(#OVFSECSAL) TYPE(*CHAR) LENGTH(256) DECIMALS(0) COLHDG('Indexed' 'Space' 'Definition')
CHANGE FIELD(#OVFSECSAL) TO('deptment key(), section key(), ovtdepsal sum(salary), ovxdepsal max(salary), ovndepsal min(salary), ovadepsal avg(salary), ovcdepsal count()')
DEFINE FIELD(#OVHSECSAL) TYPE(*CHAR) LENGTH(10) LABEL('Space Handle')
DEF_LIST NAME(#OVSSECSAL) FIELDS(#DEPTMENT #SECTION #OVTDEPSAL #OVCDEPSAL #OVXDEPSAL #OVNDEPSAL #OVADEPSAL)
********** COMMENT(Salary Distribution Definitions)
DEFINE FIELD(#OVCSALSAL) TYPE(*DEC) LENGTH(7) DECIMALS(0) COLHDG('Total' 'Employees') EDIT_CODE(3)
DEFINE FIELD(#OVFSALSAL) TYPE(*CHAR) LENGTH(256) DECIMALS(0) COLHDG('Indexed' 'Space' 'Definition')
CHANGE FIELD(#OVFSALSAL) TO('salary key(), ovcsalsal count()')
DEFINE FIELD(#OVHSALSAL) TYPE(*CHAR) LENGTH(10) LABEL('Space Handle')
DEF_LIST NAME(#OVSSALSAL) FIELDS(#SALARY #OVCSALSAL)
**********
DEFINE FIELD(#OV_RC) TYPE(*CHAR) LENGTH(2) LABEL('Return Code')
********** COMMENT(Create the indexed space)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(CREATE #OVFDEPSAL) TO_GET(#OV_RC #OVHDEPSAL)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(CREATE #OVFSECSAL) TO_GET(#OV_RC #OVHSECSAL)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(CREATE #OVFSALSAL) TO_GET(#OV_RC #OVHSALSAL)
********** COMMENT((Pass over the data and create the summary indexes')
SELECT FIELDS(#DEPTMENT #SECTION #SALARY) FROM_FILE(PSLMST)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(PUT #OVHDEPSAL) TO_GET(#OV_RC)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(PUT #OVHSECSAL) TO_GET(#OV_RC)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(PUT #OVHSALSAL) TO_GET(#OV_RC)
ENDSELECT
********** COMMENT(Now load/show a browse list with the results)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(FIRST #OVHDEPSAL) TO_GET(#OV_RC)
DOWHILE COND('#OV_RC = OK')
ADD_ENTRY TO_LIST(#OVSDEPSAL)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(NEXT #OVHDEPSAL) TO_GET(#OV_RC)
ENDWHILE
DISPLAY BROWSELIST(#OVSDEPSAL)
********** COMMENT(Now load/show a browse list with the results)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(FIRST #OVHSECSAL) TO_GET(#OV_RC)
DOWHILE COND('#OV_RC = OK')
ADD_ENTRY TO_LIST(#OVSSECSAL)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(NEXT #OVHSECSAL) TO_GET(#OV_RC)
ENDWHILE
DISPLAY BROWSELIST(#OVSSECSAL)
********** COMMENT(Now load/show a browse list with the results)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(FIRST #OVHSALSAL) TO_GET(#OV_RC)
DOWHILE COND('#OV_RC = OK')
ADD_ENTRY TO_LIST(#OVSSALSAL)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(NEXT #OVHSALSAL) TO_GET(#OV_RC)
ENDWHILE
DISPLAY BROWSELIST(#OVSSALSAL)
********** COMMENT(Destroy the indexed spaces)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(DESTROY #OVHDEPSAL) TO_GET(#OV_RC)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(DESTROY #OVHSECSAL) TO_GET(#OV_RC)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(DESTROY #OVHSALSAL) TO_GET(#OV_RC)
The following sample RDML function is designed to demonstrate how indexed lists can be used to improve application performance in "batch" style jobs processing large amounts of information.
Logically, the "engine" loop of this function is like this:
...
BEGIN_LOOP TO(#OV_ITER)
...
SELECT FIELDS(#EMPNO #SURNAME #GIVENAME #DEPTMENT #SECTION) FROM_FILE(PSLMST)
...
FETCH FIELDS(#DEPTDESC) FROM_FILE(DEPTAB) WITH_KEY(#DEPTMENT)
...
FETCH FIELDS(#SECDESC) FROM_FILE(SECTAB) WITH_KEY(#DEPTMENT #SECTION)
...
ENDSELECT
...
END_LOOP
This loop selects all the employees in the standard shipped demonstration table PSLMST (repeated for a specified number of iterations). It does this to attempt to emulate the processing of a large number of records typically found in a "batch" job.
...
However, the "engine" loop has actually been coded as:
...
BEGIN_LOOP TO(#OV_ITER)
...
SELECT FIELDS(#EMPNO #SURNAME #GIVENAME #DEPTMENT #SECTION) FROM_FILE(PSLMST)
...
IF COND(*USEINDEX)
...
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(GET #OV_DEPTAB) TO_GET(#OV_RC)
...
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(GET #OV_SECTAB) TO_GET(#OV_RC)
ELSE
...
FETCH FIELDS(#DEPTDESC) FROM_FILE(DEPTAB) WITH_KEY(#DEPTMENT)
...
FETCH FIELDS(#SECDESC) FROM_FILE(SECTAB) WITH_KEY(#DEPTMENT #SECTION)
...
ENDIF
...
ENDSELECT
...
END_LOOP
which allows you to run the engine loop using either the DBMS (i.e., the FETCH commands) or an indexed space (i.e., the USE OV_INDEXED_SPACE commands) to get the department and section descriptions. By doing this you will be able to see the speed advantage that an indexed space provides over performing a full DBMS access to find information.
...
Notice that you can run the "engine" loop through 1 -> 20 iterations using either the DBMS (specify D) or an indexed space (specify I) to fetch the department and section description details. All department and section descriptions are loaded into their associated indexed spaces at the beginning of the function:
FUNCTION OPTIONS(*LIGHTUSAGE *DIRECT)
********** COMMENT(Define and load the department indexed space)
DEFINE FIELD(#OV_DEPDEF) TYPE(*CHAR) LENGTH(50) LABEL('Dept Index')
CHANGE FIELD(#OV_DEPDEF) TO('deptment key(), deptdesc')
DEFINE FIELD(#OV_DEPTAB) TYPE(*CHAR) LENGTH(10) LABEL('Index Handle')
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(CREATE #OV_DEPDEF) TO_GET(#OV_RC #OV_DEPTAB)
SELECT FIELDS(#DEPTMENT #DEPTDESC) FROM_FILE(DEPTAB)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(INSERT #OV_DEPTAB) TO_GET(#OV_RC)
ENDSELECT
********** COMMENT(Define and load the section indexed space)
DEFINE FIELD(#OV_SECDEF) TYPE(*CHAR) LENGTH(50) LABEL(' Section Index')
CHANGE FIELD(#OV_SECDEF) TO('deptment key(), section key(), secdesc')
DEFINE FIELD(#OV_SECTAB) TYPE(*CHAR) LENGTH(10) LABEL('Index Handle')
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(CREATE #OV_SECDEF) TO_GET(#OV_RC #OV_SECTAB)
SELECT FIELDS(#DEPTMENT #SECTION #SECDESC) FROM_FILE(SECTAB)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(INSERT #OV_SECTAB) TO_GET(#OV_RC)
ENDSELECT
********** COMMENT(Define other variables)
OVERRIDE FIELD(#GIVENAME) LENGTH(10)
DEFINE FIELD(#OV_RC) TYPE(*CHAR) LENGTH(2) LABEL('Return Code')
...
DEFINE FIELD(#OV_MODE) TYPE(*CHAR) LENGTH(1) LABEL('Mode (D/I)') DEFAULT(D)
DEFINE FIELD(#OV_ITER) TYPE(*DEC) LENGTH(3) DECIMALS(0) LABEL('Iterations') EDIT_CODE(3) DEFAULT(5)
DEFINE FIELD(#OV_TOTAL) TYPE(*DEC) LENGTH(7) DECIMALS(0) LABEL('PSLMST Accesses') EDIT_CODE(3)
DEF_COND NAME(*USEINDEX) COND('#OV_MODE = I')
DEF_LIST NAME(#OV_LIST) FIELDS(#SURNAME #GIVENAME #DEPTDESC #SECDESC) COUNTER(#OV_TOTAL)
********** COMMENT(Repeat testing until cancelled)
BEGIN_LOOP
********** COMMENT(Request and validate testing details)
POP_UP FIELDS((#OV_MODE *IN) (#OV_ITER *IN)) EXIT_KEY(*NO) PROMPT_KEY(*NO)
BEGINCHECK
VALUECHECK FIELD(#OV_MODE) WITH_LIST(D I) MSGTXT('Mode must be D (use DBMS) or I (use indexed space)')
RANGECHECK FIELD(#OV_ITER) RANGE((1 20)) MSGTXT(('Number of iterations must be in range 1 to 20'))
ENDCHECK
********** COMMENT(Repeat the test for the number of iterations)
CLR_LIST NAMED(#OV_LIST)
BEGIN_LOOP TO(#OV_ITER)
...
SELECT FIELDS(#EMPNO #SURNAME #GIVENAME #DEPTMENT #SECTION) FROM_FILE(PSLMST)
IF COND(*USEINDEX)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(GET #OV_DEPTAB) TO_GET(#OV_RC)
USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(GET #OV_SECTAB) TO_GET(#OV_RC)
ELSE
FETCH FIELDS(#DEPTDESC) FROM_FILE(DEPTAB) WITH_KEY(#DEPTMENT)
FETCH FIELDS(#SECDESC) FROM_FILE(SECTAB) WITH_KEY(#DEPTMENT #SECTION)
ENDIF
ADD_ENTRY TO_LIST(#OV_LIST)
ENDSELECT
END_LOOP
********** COMMENT(display the results)
DISPLAY FIELDS(#OV_TOTAL) BROWSELIST(#OV_LIST) EXIT_KEY(*NO) MENU_KEY(*NO) PROMPT_KEY(*NO)
END_LOOP