BOOLEAN Expression Syntax
The Boolean expression must conform to the following syntax:
nwmsol
The Boolean expression must conform to the following syntax:
expression:=term[ ORterm… ]term:=factor[ ANDfactor… ]factor:= [ NOT … ]exp2exp2 := (expression) |testtest:= [ IGNORE { TRUE | FALSE } ] [ANY| ALL ]loperand[ ,loperand,… ]operator[ ANY | ALL ]roperand[ ,roperand,… ]loperand:=operandoperator:= = == ¬= ¬== < << > >> <= <<= >= >>= CONTAINS LIKE IS [ NOT ]roperand:= (For all operators except IS [ NOT ]):operand[ GENERIC | :operand] [ { CHARACTER | NUMERIC | FOLD | NOFOLD } …] [ , … ] (For the IS [ NOT ]operators):type-name| &variable[ , … ]type-name:= 'constant' | “constant” | &variable|numberoperand:= ALPHA ALPHANUM ALPHANUMNAT BITLIST16 DATE1 DATE2 DATE3 DATE4 DATE5 DATE6 DATE7 DATE8 DATE9 DATE10 DOMAIN DSN HEX MIXED MSGLVL N NAME NAME12 NAME256 NULL NUM REAL ROUTCDE SIGNNUM TIME1 TIME2 TIME3 Y
Notes:
- Tests can be connected using AND (&), OR (|), NOT (¬), and parentheses (). If the ampersand (&) is a variable substitution character (as set by the SUBCHAR operand), use of an ampersand (&) for AND requires a trailing blank if a word (such as NOT) follows it.
- The expression or the nesting of parentheses can be of any complexity.
- IGNORE allows a test to be ignored and treated as if it were true (return code 1) or false (return code 0).
- The ANY and ALL prefixes allow you to override the default processing of lists of operands on the left and right of an operator.The left default is ANY, meaning that if any left-operand passes the test, then the test is true (evaluation stops once this is satisfied). ALL means that all left-operands must pass the test for the test to be true (any operand that fails causes evaluation to stop).The right default depends on the operator. For =, ==, CONTAINS, LIKE, and IS, the default is ANY. For all others, the default is ALL. If ANY is specified or defaulted, then any operator and right-operand that result in a true result for a left operand results in a true result for that operand. If ALL is specified or defaulted, then any given left-operand must pass all combinations of operator and right-operand to pass a test.
- You can have constants on both sides of any operator. In this case, the expression can be always true or false. The constants can be there if you use substitution before evaluation. However, if mixed constant types are found, for example, '123' = 123, then a syntax error is raised.The IS and IS NOT operators do not support constants to the left of them.
- Constant values must be quoted if they are non-numeric, or if they are numeric but a character comparison is wanted. Numbers must always be unquoted.Quoted constants can use either single quotes (') or double quotes (”). Use two adjacent quote characters to represent a quote character in the value. Alternatively, use the alternate quote character to surround the value.Numbers are recognized and validated based on the current &CONTROL INTEGER/REAL setting.
- The GENERIC modifier is only permitted with a quoted constant or variable to the right of an operator, and only for the equal (=) and not equal (¬=) operators. The modifier implies a CHARACTER test.
- The RANGE test (:) is permitted with the equal and not equal operators only. Both sides of the range must be the same type, that is, you cannot sayconstant:number, ornumber:constant. If one side of the range is numeric and the other is a variable, then the variable must have a numeric value. Otherwise, BAD is returned.If the from and to range values are reversed, they are reversed before making the test, rather than raising an error.
- If a variable is compared to a number and the variable value is null or not numeric, then BAD is returned.
- The CHARACTER modifier forces a character compare and is only required when comparing a variable to another variable. This modifier avoids the default action of testing both sides for numerics and performing a compare based on the result.Similarly, the NUMERIC modifier forces a numeric compare. If either variable is not numeric, BAD is returned. The NUMERIC modifier is invalid with the GENERIC modifier.
- The FOLD and NOFOLD modifiers force uppercasing (FOLD) or prevent uppercasing (NOFOLD) of character values. The modifiers override the following settings:
- Default for the operator
- As set by the FOLD= operand on the &BOOLEXPR invocation
- Default based on the &CONTROL IFCASE setting
- The operators are:
- = (equal) -- Standard equality test
- ¬= (not equal) -- Standard inequality test
- < (less than) -- Standard less than test
- > (greater than) -- Standard greater than test
- <= (less than or equal) -- Standard less than or equal test
- >= (greater than or equal) -- Standard greater than or equal testThe standard operators strip both leading and trailing blanks, except for equal and not equal, when used with the GENERIC modifier. The comparison then pads with trailing blanks if necessary.When variables are on both sides of the operator, the standard operators, by default, type check both variables. If both are numeric, the operators perform a numeric compare. Otherwise, a character compare is performed. Specification of the GENERIC or CHARACTER modifiers overrides this test to force a character compare. Specification of the NUMERIC operator forces a numeric compare. In this case, the operands must be valid numbers as determined by the current &CONTROL INTEGER or REAL setting.For character compares, these operators honor the setting of &CONTROL IFCASE by default. The FOLD and NOFOLD modifiers override this setting, as does the FOLD=YES or NO operand. If variable uppercase translation is performed automatically on assignment, the effect of the &CONTROL UCASE option can override the intended effect of IFCASE.
- == (strictly equal to)
- ¬== (strictly not equal to)
- << (strictly less than)
- >> (strictly greater than)
- <<= (strictly less than or equal to)
- >>= (strictly greater than or equal to)The strict operators always perform a character compare. No blank stripping or padding is performed. Numeric constants are invalid with these operands. If one value is physically shorter than another value, but equal for the shortest length, then the shorter value is regarded as logically less than the longer value. By default, values are not uppercased, although the FOLD and NOFOLD modifiers, and the FOLD= operand can override this default. The setting of &CONTROL IFCASE is ignored for these operators.
- CONTAINSThe CONTAINS operator searches the left operands for the right-hand values. Variable values on the left have one leading and one trailing blank added to their value before to the search. CONTAINS honors &CONTROL IFCASE for folding, by default, which can be overridden as for the standard operators.
- LIKEThe LIKE operator performs a pattern-match, as for the ANSI SQL LIKE operator. The standard wildcard characters are used. (They are: the per cent sign (%) which matches 0 or more characters, and the underscore character (_) which matches one character.) LIKE honors &CONTROL IFCASE for folding, by default, which can be overridden as for the standard operators.
- IS and IS NOTThe IS and IS NOT operators perform a type check on the nominated variables. Only variables are specified to the left of these operators. The listed types are verified, as for &TYPECHK.If a variable is specified in the type list, then during expression evaluation it must contain a list of type names, separated by blanks or commas. If it is null, it is treated as if it contained types that the left variables all passed. If it contains invalid data, then the expression returns a BAD result.Use of these operators can prevent BAD checks on non-numeric variables.
Examples: &BOOLEXPR
This example shows how you can use &BOOLEXPR to evaluate a complex condition that is beyond the capabilities of the &IF or &DOWHILE/&DOUNTIL NCL statements:
&R = &BOOLEXPR SUBCHAR=% DATA=+ %NAME = 'FRED SMITH' AND + %DOB < 700101 AND + (ANY %SKILL1, %SKILL2, %SKILL3, %SKILL4 = 'PROGRAMMER' + OR + %RELATIVES CONTAINS 'ManagingDirector') &IF &R = 1 &THEN &DO : &DOEND
This example shows how a dynamic expression is validated for syntactical correctness. The expression is contained in the NCL variables &EXPR1 to &EXPR10.
&R = &BOOLEXPR SUBCHAR=% EVAL=NO VARS=EXPR* + RANGE=(1,10) &IF &R = INVALID &THEN &DO : &DOEND
This example shows how the dynamic expression of the last example is processed at a later time. The result is checked for the BAD value in case a non-numeric variable value or nonvalid type list variable was encountered. Otherwise, whether the result is true is checked.
&R = &BOOLEXPR SUBCHAR=% EVAL=YES VARS=EXPR* + RANGE=(1,10) &IF &R = BAD &THEN &DO : &DOEND &ELSE &IF &R = 1 &THEN &DO : &DOEND
Return Codes:
The &BOOLEXPR function typically returns a value that is assigned to the target variable on the assignment statement.
Syntax errors in the various operands, such as SUBCHAR or FOLD, result in the NCL process being abnormally terminated. Syntax errors in the Boolean expression or data validity errors never result in process termination.
The following return values are possible when using EVAL=YES (the default):
- INVALID
- The Boolean expression is not valid. &SYSMSG contains a descriptive message.
- BAD
- The Boolean expression is valid, but a variable referred to in the expression contained data that is not valid for the operator. Only the following conditions can return this value:
- Non-numeric data or null value when a numeric value is required (such as when a test has &variable=number)
- A variable is expected to contain a list of valid type names
- 0
- The Boolean expression is valid and evaluated to false.
- 1
- The Boolean expression is valid and evaluated to true.
The following return values are possible when using EVAL=NO:
- INVALID
- The Boolean expression is not valid. &SYSMSG contains a message with additional information.
- VALID
- The Boolean expression is valid. If EVAL=YES had been specified, evaluation would have been attempted.
No other values are returned.
Notes:
&BOOLEXPR processes in the following order:
- First, the operands of the &BOOLEXPR function itself are verified.That is, the EVAL, FOLD, SUBCHAR, VARS, RANGE, and DATA operands. Errors in these operands result in the NCL process being terminated.
- If the VARS/RANGE operands are used, the nominated variables are retrieved. Their values are concatenated together with blanks between them to form the source of the Boolean expression.
- The Boolean expression is then compiled into a parse tree. Errors during compilation result in the INVALID return value.
- If EVAL=NO was specified, execution is complete and the return value is VALID.
- If EVAL=YES was specified, the parse tree is interpreted. Variables are retrieved and tests are performed.Invalid variable values (numeric or type lists) result in the interpretation being terminated with a BAD return value.Evaluation of AND and OR lists is from left to right. The first false (for AND) or true (for OR) test will short-circuit the rest of the tests at that level.This left-to-right order means that you can specify, for example:%VAR IS SIGNNUM AND %VAR = 1:10This expression does not return a BAD value. Only if the value in &VAR is both numeric and 1 through 10, is the value 1 (true) returned. In all other cases, the value 0 (false) is returned.ANY/ALL evaluations are processed left-to-right, with the list entries on the right being performed for each list entry on the left in order.Use of &variableswith DATA= can cause too-early evaluation of variable contents, leading to syntax errors in the expression.