Expressions¶
One expression language serves every place that reads values from features:
- Select By Attributes, Definition Query, display filters, label classes, attribute
constraints and reports use an expression as a condition (a
WHEREclause): a feature matches when the expression is true. - Calculate Field and calculation attribute rules use an expression as a value, stored in the field after conversion to the field's type.
- Symbols by expression take a value per feature: a marker's size, the fill and outline colours, the outline width and a marker's angle.
pop_est > 100000000 AND continent = 'Asia'
name LIKE 'S%' OR iso_a3 IN ('FRA', 'DEU', 'ITA')
"name" || ' (' || to_string(round(pop_est / 1e6)) || ' M)'
CASE WHEN pop_est > 1e8 THEN 'large' WHEN pop_est > 1e7 THEN 'medium' ELSE 'small' END
scale_linear(pop_est, 0, 1e9, 2, 12)
Grammar¶
Keywords and function names are not case sensitive. Rules are listed from the loosest binding
to the tightest; [ x ] is optional, { x } repeats zero or more times, | separates choices.
expression = or ;
or = and { "OR" and } ;
and = not { "AND" not } ;
not = "NOT" not | comparison ;
comparison = concat [ compare_op concat
| "IS" [ "NOT" ] "NULL"
| [ "NOT" ] ( "LIKE" | "ILIKE" ) concat
| [ "NOT" ] "IN" "(" expression { "," expression } ")"
| [ "NOT" ] "BETWEEN" concat "AND" concat ] ;
compare_op = "=" | "==" | "<>" | "!=" | "<" | "<=" | ">" | ">=" ;
concat = sum { "||" sum } ;
sum = product { ( "+" | "-" ) product } ;
product = unary { ( "*" | "/" | "%" ) unary } ;
unary = ( "-" | "+" ) unary | power ;
power = primary [ "^" unary ] ;
primary = number | text | "TRUE" | "FALSE" | "NULL"
| field | variable | call | case | "(" expression ")" ;
call = name "(" [ expression { "," expression } ] ")" ;
case = "CASE" [ expression ]
"WHEN" expression "THEN" expression
{ "WHEN" expression "THEN" expression }
[ "ELSE" expression ] "END" ;
number = digits [ "." digits ] [ exponent ] | "." digits [ exponent ] ;
exponent = ( "e" | "E" ) [ "+" | "-" ] digits ;
text = "'" { character | "''" } "'" ;
field = name | '"' { character | '""' } '"' | "!" { character } "!" ;
variable = "@" name | "$" name ;
name = ( letter | digit | "_" ) { letter | digit | "_" } ; (* not starting with a digit *)
So a OR b AND c is a OR (b AND c), NOT a = b is NOT (a = b), 1 + 2 * 3 is 7,
-2 ^ 2 is −4 and 2 ^ 3 ^ 2 is 512 (^ groups from the right). A comparison takes one
operator: write a < b AND b < c, not a < b < c.
Values¶
| Write | Meaning |
|---|---|
42, 3.5, 1e6, .5 |
Numbers; whole numbers are integers |
'text', 'it''s' |
Text in single quotes; two quotes stand for one |
TRUE, FALSE, NULL |
Booleans and the missing value |
pop_est, "Pop Est", !Pop Est! |
A field, by name, ignoring letter case; quote a name with spaces, punctuation or the name of a keyword ("OR", "null") |
@map_scale, $scale |
The scale denominator of the map being drawn: set in symbols by expression, null in queries and Calculate Field |
@row_number |
The feature's position in the layer, from 1 |
$id |
The feature's id |
An unknown field, variable or function is an error that names it.
Operators¶
| Operator | Result |
|---|---|
+ - * / |
Arithmetic; / always divides exactly (7 / 2 is 3.5) |
% |
Remainder |
^ |
Power |
\|\| |
Joins the two values as text; null when either is null |
= <> < <= > >= |
Comparison; == and != are also accepted |
LIKE, ILIKE |
Text pattern: % matches any run of characters, _ one character |
IN (…) |
Equal to one of the values |
BETWEEN a AND b |
>= a AND <= b |
IS NULL, IS NOT NULL |
Whether the value is missing |
AND OR NOT |
Logic |
Rules shared by all of them:
- Comparing numbers and text. A number and text that reads as a number compare as numbers
(
'12' = 12is true). Two texts compare as text, ignoring letter case, even when both read as numbers (name = 'paris'matchesParis;'10' < '9';LIKEignores case too). - Arithmetic reads text as a number when it is one (
'12' + 1is 13).+joins text that isn't (name + ' km');-,*,/on such text give null. - Nulls. Arithmetic with a null gives null. A comparison with a null is unknown: it
matches neither
pop > 100norNOT pop > 100;IS NULLtests for it.ANDis false when either side is false andORtrue when either side is true, whatever the other side is. - Errors give null: a division by zero, the square root of a negative number, a result too large to represent.
INcompares with each value as=does; aNULLin the list matches nothing, sox NOT IN (1, NULL)is true for 2.- As a condition, a value that isn't true or false counts as true when it is a non-zero number or non-empty text.
Functions¶
| Function | Result |
|---|---|
if(condition, a[, b]) |
a when the condition is true, otherwise b (or null) |
coalesce(a, b, …) |
The first value that isn't null |
nullif(a, b) |
Null when a equals b, otherwise a |
abs(x) |
Absolute value |
round(x[, places]) |
Rounded half away from zero to places decimals (0 by default; negative rounds to tens, hundreds…) |
floor(x), ceil(x) |
Rounded down, up |
sqrt(x), exp(x), ln(x), log10(x) |
Square root, eˣ, natural and base-10 logarithm |
pi() |
π |
min(a, b, …), max(a, b, …) |
The smallest, largest number; values that aren't numbers are skipped |
clamp(low, x, high) |
x kept within low…high; null when low is above high |
scale_linear(x, d0, d1, r0, r1) |
x mapped from the domain d0…d1 to the range r0…r1, clamped to the domain |
scale_exp(x, d0, d1, r0, r1, exponent) |
As scale_linear, along a curve: 0.5 grows fast then slowly, 2 slowly then fast |
to_string(x) |
x as text |
to_int(x), to_real(x) |
x as a whole number (cut toward zero), as a decimal number; null if it isn't a number |
length(s) |
Number of characters |
upper(s), lower(s), trim(s) |
Upper case, lower case, without surrounding spaces |
substr(s, start[, length]) |
Part of s from character start (1 is the first; negative counts from the end); a negative length leaves that many characters off the end |
left(s, n), right(s, n) |
The first, last n characters |
replace(s, find, with) |
Every find in s replaced by with |
concat(a, b, …) |
The values joined as text, nulls skipped |
color_rgb(r, g, b), color_rgba(r, g, b, a) |
A colour as the text 'r,g,b' or 'r,g,b,a', each channel 0–255 |
Limits¶
A number too large to represent (1e999) is an error. An expression is at most 10,000 characters and nests at most 64 levels: each parenthesis,
function call, NOT, sign before something other than a number, ^ and CASE counts (a
CASE two). One chain of AND, OR, ||, +/- or *///%, and the arms of one
CASE, take at most 256 terms; a function at most 32 arguments; an IN list as many as fit.
Text an expression makes is cut at 64 KiB, and a LIKE pattern longer than 10,000 characters
matches nothing. A LIKE that would take more than about 16 million steps to match (a very long
text against a pattern of many %s) is unknown.
Calculate Field¶
Calculate Field also takes the forms its earlier calculator took: a field name with spaces
written bare (Pop Est * 2) still works when the text isn't a valid expression, and on a layer
with a field named true, false or null such forms keep reading it as the field (in other
expressions, quote it: "null"). Text that starts and ends with a quote but holds more quotes
now reads as an expression: 'it''s' is it's and 'a' || 'b' is ab, where both were taken
as the text between the outer quotes.