expression | An INDEX filter condition. |
OPT | Only generate An INDEX filter condition. |
field | A single field in an INDEX. |
The KEYED and WILD keywords are valid only for filters on INDEX attributes (which also qualifies as part of the joincondition for a "half-keyed" JOIN). They indicate to the compiler which of the leading index fields are used as filters (KEYED) or wildcarded (WILD) so that the compiler can warn you if you've gotten it wrong. Trailing fields not used in the filter are ignored (always treated as wildcards).
Prior to version 7.0, KEYED(expression) on a disk read filter would give a compile-time error if the field being filtered was not fixed size. In version 7.0 and later versions, it won't.
The rules for their use are as follows (the term "segmonitor" refers to an internal object created to represent the possible match conditions for a single keyable field):
1. KEYED generates a segmonitor. The segmonitor may be a wild one if the expression can never be false, such as:
KEYED(inputval = '' OR field = inputval)
2. WILD generates a wild segmonitor, unless there is also a KEYED() filter on the same field.
3. KEYED, OPT generates a non-wild segmonitor only if the preceding field did.
4. Any field that is both KEYED and KEYED OPT creates a compile time error.
5. If WILD or KEYED are not specified for any fields, segmonitors are generated for all keyable conditions.
6. An INDEX filter condition with no KEYED specified generates a wild segmonitor (except as specified by 5).
7. KEYED limits are based upon all non-wild segmonitors.
8. Conditions that do not generate segmonitors are post-filtered.
Example:
ds := DATASET('~LR::person',
{ STRING15 f1, STRING15 f2, STRING15 f3, STRING15 f4,
UNSIGNED8 filepos{VIRTUAL(fileposition)} }, FLAT);
ix := INDEX(ds, { ds },'\\lexis\\person.name_first.key');
/*** Valid examples ****/
COUNT(ix(KEYED(f1='Kevin1')));
// legal because only f1 is used.
COUNT(ix(KEYED(f1='Kevin2' and f2='Halliday')));
// legal because both f1 and f2 are used
COUNT(ix(KEYED(f2='Kevin3') and WILD(f1)));
// keyed f2, but ok because f1 is marked as wild.
COUNT(ix(f2='Halliday'));
// ok - if keyed isn't used then it doesn't have to have
// a wild on f1
COUNT(ix(KEYED(f1='Kevin3') and KEYED(f2='Kevin4') and WILD(f1)));
// it is ok to mark as wild and keyed otherwise you can get
// in a mess with compound queries.
COUNT(ix(f1='Kevin3' and KEYED(f2='Kevin4') and WILD(f1)));
// can also be wild and a general expression.
/***Error examples ***/
COUNT(ix(KEYED(f3='Kevin3' and f2='Halliday')));
// missing WILD(f1) before keyed
COUNT(ix(KEYED(f3='Kevin3') and f2='Halliday'));
// missing WILD(f1) before keyed after valid field
COUNT(ix(KEYED(f3='Kevin3') and WILD(f2)));
// missing WILD(f1) before a wild
COUNT(ix(WILD(f3) and f2='Halliday'));
// missing WILD(f1) before wild after valid field
COUNT(ds(KEYED(f1='Kevin')));
//KEYED not valid in DATASET filters