ECSql Operators
Bitwise operator
| Operator | Description | Example |
|---|---|---|
& |
Bitwise AND | (4&2 ) output 0 |
~ |
Bitwise NOT urinary | ( ~1 ) output -2 or 0xfffffffffffffffe |
| |
Bitwise OR | (3|4 ) output 7 |
<< |
Bitwise shift left | (1<<2) output 4 |
>> |
Bitwise shift right | (4>>1) output 2 |
Arithmetic operator
| Operator | Description | Example |
|---|---|---|
+ |
Add | (1 + 1) output 2 |
- |
Subtract | (2 - 1) output 1 |
* |
Multiply | (2 * 2) output 4 |
/ |
Divide | (4 / 2) output 2 |
% |
Modulo | (4 % 2) output 0 |
String operator
| Operator | Description | Example |
|---|---|---|
|| |
Concatenate | 'Hello'|| ',' || 'World' output Hello,World |
Boolean operator
| Operator | Description | Example |
|---|---|---|
= |
Equal | (1 = 3) output FALSE |
> |
Greater than | (1 > 3) output FALSE |
< |
Less than | (1 < 3) output TRUE |
>= |
Greater or equal to | (3 >= 3) output TRUE |
<= |
Less or equal to | (3 <= 5) output TRUE |
<> |
Not equal | (1 <> 3) output TRUE |
!= |
Not equal | (1 != 3) output TRUE |
IS |
Null-safe equal | (NULL IS NULL) output TRUE |
IS NOT |
Null-safe not equal | (1 IS NOT NULL) output TRUE |
OR |
OR op | (1=2 OR 1=1) output TRUE |
AND |
AND op | (1=1 AND 1=1) output TRUE |
NOT |
NOT unary op | NOT (1=1) output FALSE |
IS / IS NOT operator (null-safe comparison)
The IS and IS NOT operators compare two operands using null-safe semantics, mapping to SQLite's IS / IS NOT operators. Unlike = and <>, a NULL operand never makes the result unknown:
NULL IS NULLisTRUE(whereasNULL = NULLis unknown, so the row is filtered out).<value> IS NULLisFALSEwhen<value>is notNULL.
Each operand may be any value expression — a property, the NULL literal, a constant, a parameter, a function call, an arithmetic expression, and so on — and the NULL literal may appear on either side.
For multi-column operands such as Point2d/Point3d and navigation properties, the comparison is expanded column-wise (consistent with = and <>): IS joins the per-column comparisons with AND, while IS NOT joins them with OR.
Both operands must be type-compatible, following the same rules as = and <>: comparable primitive types (for example two strings, or numeric types compared with each other) or composite types of the same shape (Point2d with Point2d, a navigation property with a navigation property), with the NULL literal allowed against any type. Comparing unrelated types — for example a string against a Point3d — is rejected when the statement is prepared.
Note:
IS [NOT]is also used by the unrelated ECClass filter predicate (<classId> IS [NOT] (<class-name>, ...)) and by the boolean truth testsIS [NOT] TRUE/FALSE/UNKNOWN. These keep their original meaning and take precedence only when the right-hand operand matches their shape: a bareNULL/TRUE/FALSE/UNKNOWN, or a parenthesized qualified class name — optionally with anONLY/ALLprefix or written as a comma-separated list (for example(bis.Element),(ONLY bis.Element), or(bis.Element, bis.Model)). Any other parenthesized right-hand operand is a value expression: a parenthesized unqualified name such as(MyProperty)is read as that property (ECSQL class names must always be schema-qualified, so there is no ambiguity here), soprop1 IS (prop2)andx IS (y + 1)are null-safe value comparisons. A parenthesized qualified name that does not resolve to a known ECClass — for example(ts.Status.Active)— is likewise read as a value expression, soStatus IS (ts.Status.Active)is a null-safe comparison; if the qualified name does resolve to a class, the type-predicate reading takes precedence, e.g.ECClassId IS (bis.Element)stays a type predicate.
Last Updated: 03 September, 2026