Basics

Learn about the different parts that make up expressions.

Just as a sentence in English comprises words, phrases, and clauses, a CQL expression is composed of different parts that come together to form a complete expression.

In this section, we discuss the structure of expressions, explain key concepts such as precedence, and provide examples to demonstrate how these elements work together.

Introduction

CQL expressions follow a well-defined structure for writing valid queries. Similar to how individual words convey little meaning on their own, you must combine the various parts of an expression coherently to form a valid expression.

An expression can be as simple as a single value, like a literal or a variable, or even a combination of multiple sub-expressions.

Let's examine the following expression to see how it is structured:

user's score is greater than 90
Try in Playground

This expression is composed of the following parts:

  • user is a variable that refers to the current user.
  • score is an attribute of the user variable.
  • user's score is a property access expression that returns the user's score.
  • is greater than is a test that checks whether the left-hand side is greater than the right-hand side.
  • 90 is a literal value representing the score threshold.

As you can see, each element has a specific meaning and purpose within the expression. When combined, they form a complete expression that can be evaluated to produce a result.

Below is a brief description of the main parts that make up an expression:

ElementDescription
LiteralsValues directly written into the expression, such as true, "Croct" or [1, 2, 3].
VariablesNames that refer to values defined in the context, such as user or cart.
AccessorsExpressions that extract values from data structures, such as user's score or collection[0].
MacrosNatural language functions that take one or more parameters and return a value, such as sum of [1, 2, 3].
ModifiersNatural language functions that convert one value to another, such as "Croct" in upper case.
TestsNatural language conditions that test if value satisfies a predicate, such as user's age is greater than 18.
QuantifiersNatural language conditions that test if a collection satisfies a predicate, such as no items in cart satisfies item's name matches "smartphone".
OperationsOperations on one or more values, such as 1 plus 2 or 1 + 2.

Note that this is not an exhaustive list. Other expressions, such as durations and conditionals, are covered in later sections.

Basic expressions

These are some of the most basic expressions you will frequently use when writing CQL queries.

Grouping

You can use parentheses to group sub-expressions together and change the order in which they are evaluated:

(1 + 2) * 3 // 9
Try in Playground

In some cases, you need parentheses to disambiguate expressions. For example, when using quantifiers as part of a logical expression, you must use parentheses to explicitly define the scope of the quantifier predicate:

(no item in cart satisfies item's name matches "smartphone") and user is returning
Try in Playground

Without parentheses, the above expression would be evaluated as follows:

no item in cart satisfies (item's name matches "smartphone" and user is returning)
Try in Playground

As a result, the expression becomes illogical. It evaluates whether the user is a returning customer for each item added to the cart, despite these conditions being unrelated.

Variables

Variables are names that refer to values you define or values provided by the context. To use a variable, you simply type its name, such as user, cart or now.

Depending on the context in which your query is evaluated, you may have access to different variables and information. See the context reference for a complete list of variables available in each context.

Evaluation order

If you remember your math classes, you might recall that some operations take precedence over others. For example, multiplication comes before addition in arithmetic expressions.

To determine the order of operations, we follow the rules of precedence and associativity. These concepts are explained in more detail below.

Precedence

In CQL, as in mathematics, precedence dictates the order in which sub-expressions are evaluated. High-precedence operations, such as parentheses or multiplication, are performed before lower-precedence operations, like addition or logical operators.

For example, consider the following expression:

According to the precedence rules, the multiplication operation has higher precedence than the addition operation. Thus, the above expression is equivalent to 3 + (4 * 5), which equals 23.

Now, take a look at the following expression:

user's score is greater than 90 and user's plan is "premium"
Try in Playground

In this case, since the logical operator and has lower precedence than the test operations, the above expression is evaluated as follows:

(user's score is greater than 90) and (user's plan is "premium")
Try in Playground

To group sub-expressions together and override the default precedence, you can use parentheses. For example, the following expression evaluates the addition operation first:

The table below shows the precedence of the different expressions in CQL, from highest to lowest:

PrecedenceCategoryExamples
1Parenthesized expressions(1 + 2) * 3
2Unary operatorsnot - %
3Property accessuser.score user['score']
4Function callscalculate_score(user)
5Possessive expressionsproperty score of user
6Ownership expressionsuser's score
7Duration expressions1 day 2 weeks, 3 minutes
8Macrossum of average of
9Modifiersin upper case rounded
10Exponentiation** to power of
11Multiplicative expressions* times / mod
12Additive expressions+ plus - minus
13Range..
14Concatenation&
15Fallback?? or else, otherwise
16Order comparison< > <= >=
17Equality comparison== !=
18Test predicatesis matches contains
19Functions(x y) => x + y
20Quantifiersno every some at least at most
21Conditionalsif ?:
22Logical conjunction&& and
23Logical disjunction|| or

Associativity

Associativity is the tiebreaker determining the order in which expressions with the same precedence are evaluated.

Expressions can be left-associative, meaning they are evaluated from left to right, or right-associative, meaning they are evaluated from right to left. Non-associative expressions are those that cannot be chained together.

For example, consider the following expression:

Since the addition and subtraction operations have the same precedence, the associativity determines the order of evaluation. As both operations are left-associative, the above expression is equivalent to (1 + 2) - 3, which equals 0.

Now look at this other example:

The exponentiation operation, on the other hand, is right-associative. That is, the above expression is semantically equivalent to 3 ** (2 ** 1), which results in 9.

The following table shows the associativity of expressions in CQL:

CategoryAssociativityExample
ConditionalsRighta ? true : c ? false : true
Unary operatorsRightnot not true
FallbackLefta ?? b ?? c
ConcatenationLefta & b & c
Equality comparisonLefttrue == true == true
ExponentiationRight2 ** 3 ** 4
Multiplicative expressionsLeft2 * 3 / 4 mod 5
Additive expressionsLeft2 + 3 - 4 + 5
Logical conjunctionLefttrue and true and true
Logical disjunctionLefttrue or true or true