SELECT ceil(price) FROM items, the expression ceil(price) computes the rounded-up value of the values from the price column.
Scalar expressions produce values suitable to store in a single table cell (one column of one row). They can be contrasted with and , which produce results structured as a table.
The following sections describe how to construct scalar expressions.
Constants
Constant expressions represent a simple value that doesn’t change. They are described further in section .Column references
An expression in a query can refer to columns in the current data source in two ways:- The name of the column, e.g.,
priceinSELECT price FROM items.- If the name of a column is also a , the name must be appropriately quoted. For example:
SELECT "Default" FROM configuration. - If the name is ambiguous (e.g., when joining across multiple tables), it is possible to disambiguate by prefixing the column name by the table name. For example,
SELECT items.price FROM items.
- If the name of a column is also a , the name must be appropriately quoted. For example:
- The ordinal position of the column. For example,
SELECT @1 FROM itemsselects the first column initems.
This is a CockroachDB SQL extension.
Use ordinal references with care in production code. During schema updates, column ordinal positions can change and invalidate existing queries that use ordinal positions based on a previous version of the schema.
Unary and binary operations
An expression prefixed by a unary operator, or two expressions separated by a binary operator, form a new expression. For a full list of CockroachDB operators, with details about their order of precedence and which data types are valid operands for each operator, see .Value comparisons
The standard operators< (less than), > (greater than), <= (less than or equal to), >= (greater than or equal to), = (equals), <> and != (not equal to), IS (identical to), and IS NOT (not identical to) can be applied to any pair of values from a single data type, as well as some pairs of values from different data types.
See also .
The following special rules apply:
NULLis always ordered smaller than every other value, even itself.NULLis never equal to anything via=, evenNULL. To check whether a value isNULL, use theISoperator or the conditional expressionIFNULL(...).
Typing rule
All comparisons accept any combination of argument types and result in typeBOOL.
Comparison with NaN
CockroachDB recognizes the special value NaN (Not-a-Number) for scalars of type or .
As per the IEEE 754 standard, NaN is considered to be different from every other numeric value in comparisons.
There are two exceptions however, made for compatibility with PostgreSQL:
NaNis considered to be equal with itself in comparisons. IEEE 754 specifies thatNaNis different from itself.NaNis considered to be less than every other value, including-INFINITY. IEEE 754 specifies thatNaNdoes not order with any other value, i.e.,x <= NaNandx >= NaNare both false for every value ofxincluding infinities.
NaN can be used in WHERE clauses and indexes.
For example:
Multi-valued comparisons
Syntax:<, >, =, <=, >=, <> and !=, as well as the pattern matching operators [NOT] LIKE and [NOT] ILIKE, can be applied to compare a single value on the left to multiple values on the right.
This is done by combining the operator using the keywords ANY/SOME or ALL.
The right operand can be either an array, a tuple or .
The result of the comparison is true if and only if:
- For
ANY/SOME, the comparison of the left value is true for any element on the right. - For
ALL, the comparison of the left value is true for every element on the right.
Typing rule
The comparison between the type on the left and the element type of the right operand must be possible.Set membership
Syntax:TRUE if and only if the value of the left operand is part of the result of evaluating the right operand. In the subquery form, any can be used.
For example:
See for more details and performance best practices.
Typing rule
IN requires its right operand to be a homogeneous tuple type and its left operand to match the tuple element type. The result has type BOOL.
String pattern matching
Syntax:TRUE if a match is found or FALSE otherwise, or the inverted value for the NOT variants.
Patterns can contain _ to match any single character, or % to match any sequence of zero or more characters. ILIKE causes the match to be tested case-insensitively.
For example:
Typing rule
The operands must be either bothSTRING or both BYTES. The result has type BOOL.
String matching using POSIX regular expressions
Syntax:TRUE if a match is found or FALSE otherwise, or the inverted value for the ! variants.
The variants with an asterisk * use case-insensitive matching; otherwise the matching is case-sensitive.
The pattern is expressed using POSIX regular expression syntax. Unlike LIKE patterns, a regular expression is allowed to match anywhere inside a string, not only at the beginning.
For example:
Typing rule
The operands must be either bothSTRING or both BYTES. The result has type BOOL.
String matching using SQL regular expressions
Syntax:TRUE if a match is found or FALSE otherwise, or the inverted value for the NOT variant.
The pattern is expressed using the SQL standard’s definition of a regular expression. This is a mix of SQL LIKE patterns and POSIX regular expressions:
_and%denote any character or any string, respectively..matches specifically the period character, unlike in POSIX where it is a wildcard.- Most of the other POSIX syntax applies as usual.
- The pattern matches the entire string (as in
LIKE, unlike POSIX regular expressions).
Typing rule
The operands must be either bothSTRING or both BYTES. The result has type BOOL.
Function calls and SQL special forms
General syntax:| Special form | Equivalent to |
|---|---|
AT TIME ZONE | timezone() |
CURRENT\_CATALOG | current\_catalog() |
COLLATION FOR | pg\_collation\_for() |
CURRENT\_DATE | current\_date() |
CURRENT\_ROLE | current\_user() |
CURRENT\_SCHEMA | current\_schema() |
CURRENT\_TIMESTAMP | current\_timestamp() |
CURRENT\_TIME | current\_time() |
CURRENT\_USER | current\_user() |
EXTRACT( FROM ) | extract("", ) |
EXTRACT\_DURATION( FROM ) | extract\_duration("", ) |
OVERLAY( PLACING FROM FOR ) | overlay(, , , ) |
OVERLAY( PLACING FROM ) | overlay(, , ) |
POSITION( IN ) | strpos(, ) |
SESSION\_USER | current\_user() |
SUBSTRING( FOR FROM ) | substring(, , ) |
SUBSTRING( FOR ) | substring(, 1, ) |
SUBSTRING( FROM FOR ) | substring(, , ) |
SUBSTRING( FROM ) | substring(, ) |
TRIM( FROM ) | btrim(, ) |
TRIM(, ) | btrim(, ) |
TRIM(FROM ) | btrim() |
TRIM(LEADING FROM ) | ltrim(, ) |
TRIM(LEADING FROM ) | ltrim() |
TRIM(TRAILING FROM ) | rtrim(, ) |
TRIM(TRAILING FROM ) | rtrim() |
USER | current\_user() |
Typing rule
In general, a function call requires the arguments to be of the types accepted by the function, and returns a value of the type determined by the function. However, the typing of function calls is complicated by the fact SQL supports function overloading. See Revisiting SQL Typing in CockroachDB for more details.Subscripted expressions
You can use the[… ] operator to access one item in an or value. For example:
- If the name
arefers to anARRAYof 10 values,a[3]will retrieve the third value.ARRAYvalues use 1-based indexing, so the first value has index1. - If the name
jrefers to aJSONBarray of 10 values,j[3]will retrieve the fourth value.JSONBarrays use zero-based indexing, so the first value has index0. - If the name
jrefers to a JSON object{"a": {"b":1}}, thenj['a']will access keyaand retrieve{"b":1}.j['a']['b']will access keyband retrieve1.
NULL if:
- The index is smaller than or equal to
0, or larger than the size of the array. - The key or key path does not exist in the JSON object.
Typing rule
The subscripted expression must have an array type; the index expression must have typeINT. The result has the element type of the subscripted expression.
Conditional expressions
Expressions can test a conditional expression and, depending on whether or which condition is satisfied, evaluate to one or more additional operands. These expression formats share the following property: some of their operands are only evaluated if a condition is true. This matters especially when an operand would be invalid otherwise. For example,IF(a=0, 0, x/a) returns 0 if a is 0, and x/a otherwise.
IF expressions
Syntax:
<cond, then evaluates <expr1 if the condition is true, or <expr2 otherwise.
In most cases, the expression corresponding to the case when the condition is false is not evaluated. The exception is when the expression is a subquery, which is eagerly evaluated when execution of the query begins.
Typing rule
The condition must have typeBOOL, and the two remaining expressions must have the same type. The result has the same type as the expression that was evaluated.
Simple CASE expressions
Syntax:
<cond, then picks the WHEN branch where <condval is equal to <cond, then evaluates and returns the corresponding THEN expression. If no WHEN branch matches, the ELSE expression is evaluated and returned, if any. Otherwise, NULL is returned.
In most cases, conditions and result expressions after the first match are not evaluated. The exception is subqueries, which are eagerly evaluated when execution of the query begins.
Typing rule
The condition and theWHEN expressions must have the same type. The THEN expressions and the ELSE expression, if any, must have the same type. The result has the same type as the THEN/ELSE expressions.
Searched CASE expressions
Syntax:
<cond expression; at the first <cond expression that evaluates to TRUE, returns the result of evaluating the corresponding THEN expression. If none of the <cond expressions evaluates to true, then evaluates and returns the value of the ELSE expression, if any, or NULL otherwise.
In most cases, conditions and result expressions after the first match are not evaluated. The exception is subqueries, which are eagerly evaluated when execution of the query begins.
Typing rule
All theWHEN expressions must have type BOOL. The THEN expressions and the ELSE expression, if any, must have the same type. The result has the same type as the THEN/ELSE expressions.
NULLIF expressions
Syntax:
IF ( <expr1> = <expr2>, NULL, <expr1> )
Typing rule
Both operands must have the same type, which is also the type of the result.COALESCE and IFNULL expressions
Syntax:
COALESCE evaluates the first expression first. If its value is not NULL, its value is returned directly. Otherwise, it returns the result of applying COALESCE on the remaining expressions. If all the expressions are NULL, NULL is returned.
In most cases, arguments to the right of the first non-null argument are not evaluated. The exception is subqueries, which are eagerly evaluated when execution of the query begins.
IFNULL(a, b) is equivalent to COALESCE(a, b).
Typing rule
The operands must have the same type, which is also the type of the result.Logical operators
The Boolean operatorsAND, OR and NOT are available.
Syntax:
AND and OR are commutative. Moreover, the input to AND and OR is not evaluated in any particular order. Some operand may not even be evaluated at all if the result can be fully ascertained using only the other operand.
This is different from the left-to-right “short-circuit logic” found in other programming languages. When it is essential to force evaluation order, use a conditional expression.
Typing rule
The operands must have typeBOOL. The result has type BOOL.
Aggregate expressions
An aggregate expression has the same syntax as a function call, with a special case forCOUNT:
Typing rule
The operand and return types are determined like for regular function calls.Window function calls
A window function call has the syntax of a function call followed by anOVER clause:
Typing rule
The operand and return types are determined like for regular function calls.Explicit type coercions
Syntax:CAST(now() AS DATE)
Note that in many cases a type annotation is preferable to a type coercion. See type annotations for more details.
Typing rule
The operand can have any type. The result has the type specified in theCAST expression.
As a special case, if the operand is a literal, a constant expression or a placeholder, the CAST type is used to guide the typing of the operand. See Revisiting SQL Typing in CockroachDB for more details.
Collation expressions
Syntax:'a' COLLATE de
Typing rule
The operand must have typeSTRING. The result has type COLLATEDSTRING.
Array constructors
Syntax:NULL, then the type of the array must be specified explicitly using a type annotation. For example:
ARRAY(...) instead.
Typing rule
The operands must all have the same type. The result has the array type with the operand type as element type.Tuple constructors
Syntax:Nth element in a tuple as a single table cell using the syntax (...).@N. For example:
(<tuple).* notation. This notation works as the inverse of the tuple-creating notation (.*). For example:
Typing rule
The operands can have any type. The result has a tuple type whose item types are the types of the operands.Explicitly typed expressions
Syntax:now()::DATE converts the current timestamp to a date value (and discards the current time), whereas now():::DATE triggers an error message (that now() does not have type DATE).
See Revisiting SQL Typing in CockroachDB for more information about context-dependent typing.
Typing rule
The operand must be implicitly coercible to the given type. The result has the given type.Subquery expressions
See for more details and performance best practices. You can use any as subquery.Scalar subqueries
Syntax:TRUE if there are more rows in table users than in table admins:
Typing rule
The operand must have a table type with only one column. The result has the type of that single column.Existence test on the result of subqueries
Syntax:TRUE or FALSE depending on whether the subquery returned any row (for EXISTS) or didn’t return any row (for NOT EXISTS).
Typing rule
The operand can have any table type. The result has typeBOOL.
Conversion of subquery results to an array
Syntax:ARRAY[...] instead.

