Thank you.  That's it.

I wanted to move calculation into $PIECE which was the root of my troubles.

Interestingly, when I pass empty path value ("") it is recognized as NULL on SQL side and

CASE :path
WHEN NULL 

does not work (never gets hit probably because it compares using equals and not is).

So it's either:

SELECT DISTINCT
    CASE nvl(:path,'')
    WHEN '' THEN $PIECE(Name, '.')
    ELSE $PIECE(Name, '.', 1, $LENGTH(:path, '.') + 1) END Name
FROM %Dictionary.ClassDefinitionQuery_SubclassOf('Ens.BusinessProcessBPL')
WHERE Name %STARTSWITH :path

or:

SELECT DISTINCT
    CASE
    WHEN :path IS NULL THEN $PIECE(Name, '.')
    ELSE $PIECE(Name, '.', 1, $LENGTH(:path, '.') + 1) END Name
FROM %Dictionary.ClassDefinitionQuery_SubclassOf('Ens.BusinessProcessBPL')
WHERE Name %STARTSWITH :path

It raises the question of how to pass empty string to SQL and avoid it being recognized as NULL, but it's irrelevant for my original inquiry.

For me the main acceptable case of foreach iteration is business objects - for example we receive array of results and must process them. In that case we, of course, must iterate over them, no way around it.

Everything static: constraints, enums, dictionaries, etc... should be (and usually could be) used without foreach iteration.

I agree that there are cases where we need to do something over each element of the collection.

But you said:

constants, static arrays in algorithms, e.g. arbitrary dictionaries

Which implies that foreach iteration is not desired here.

Anyways, in that case what does matter is size.

If you're sure that it would be less than $$$MaxStringLength then you can use $lb, otherwise use locals (which can be converted to ppg/globals easily).

1. Before we iterate over rows we need to determine column type, the example is about that.

Here's an example of what I'm talking about.

2. You want to avoid full scan as much as possible. Two techniques for that are:

  • knowing position
  • knowing key

And that determines the type of structure used.

If you don't know either you need to think about possible algorithm improvements.