Special behavior of the and operator
To optimize performance when evaluating a query
where clause, the correlator evaluates each side of an
and operator as early as possible even if evaluation is not in left to right order. This behavior is different from the behavior outside a query. That is, outside a query, the left side of an
and operator is guaranteed to be evaluated first. See
Logical intersection (and).
For example, suppose you specify the following event pattern:
A as a -> B as b where a.x = 1 and b.y = 2
Consider what happens when the following events are added to their windows:
A(1), A(2), A(3), B(5), B(4), B(3)
The correlator can identify that
only the
a coassignment target is needed to evaluate the
a.x = 1 condition;
only the
b coassignment target is needed to evaluate the
b.y = 2 condition.
Because none of the B events cause the b.y = 2 condition to evaluate to true, the correlator does not evaluate the a.x = 1 condition.
In a where clause, because the right side of an and operator might be evaluated first, you should not specify conditions that have side effects. Side effects include, but are not limited to:
print or
log statements
route,
emit,
enqueue...to,
send...to statements
Modifying events, sequences, dictionaries, etc.
Causing a runtime error
Calling an action that has a side effect statement in it
Calling plug-ins that have side effects
If a where clause calls an action that has a side effect, you should not rely on when or whether the action is executed.
Whether the correlator can optimize evaluation of the where clause depends on how you specify the where clause conditions. For example, consider the following event definition:
event Util {
static action myWhereClause(A a, B b) returns boolean {
return a.x = 1 and b.y = 2;
}
}
Suppose you specify the following event pattern:
A as a -> B as b where Util.myWhereClause(a, b)
If the same A and B events listed above are added to their windows, the result is the same as the result of evaluating the following:
A as a -> B as b where a.x = 1 and b.y = 2
However, evaluation might take longer because the correlator cannot separate evaluation of b.y = 2 from evaluation of a.x = 1. The myWhereClause() action returns a.x = 1 and b.y = 2 as a single expression. Consequently, the correlator evaluates Util.myWhereClause(a, b) for each combination of a and b. Given the A and B events listed above, this is a total of 9 times.
While the correlator might evaluate some where clause conditions in a right-to-left order, the correlator always evaluates each where clause condition as soon as it is ready to be evaluated. When multiple conditions become ready to be evaluated at the same time then the correlator evaluates those conditions in the order they are written. For example, the typical pattern of checking whether a dictionary contains a key before operating on the value with that key continues to work reliably:
E as e -> F as f where e.dict.hasKey("k") and e.dict["k"] = f.x and f.y = 1
In this example, f.y = 1 might be evaluated before the other two conditions, but e.dict.hasKey("k") is always evaluated before e.dict["k"] = f.x, and the latter is not evaluated if the hasKey() method returns false.