Skip to content

Latest commit

 

History

History
1019 lines (862 loc) · 32.5 KB

operators.md

File metadata and controls

1019 lines (862 loc) · 32.5 KB

Operators

Operators are represented by special characters or keywords; they do not use function call syntax. An operator manipulates any number of data inputs, also called operands, and returns a result.

Common conventions:

  • Unless otherwise specified, all operators return NULL when one of the operands is NULL.
  • All operators will throw an error if the computation result overflows.
  • For all floating point operations, +/-inf and NaN may only be returned if one of the operands is +/-inf or NaN. In other cases, an error is returned.

The following table lists all ZetaSQL operators from highest to lowest precedence, i.e. the order in which they will be evaluated within a statement.

<tr>
  <td>&nbsp;</td>
  <td>||</td>
  <td>STRING, BYTES, or ARRAY&#60;T&#62;</td>
  <td>Concatenation operator</td>
  <td>Binary</td>
</tr>

<tr>
  <td>4</td>
  <td>+</td>
  <td>All numeric types<br>DATE and INT64</td>
  <td>Addition</td>
  <td>Binary</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>-</td>
  <td>All numeric types<br>DATE and INT64</td>
  <td>Subtraction</td>
  <td>Binary</td>
</tr>
<tr>
  <td>5</td>
  <td>&lt;&lt;</td>
  <td>Integer or BYTES</td>
  <td>Bitwise left-shift</td>
  <td>Binary</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>&gt;&gt;</td>
  <td>Integer or BYTES</td>
  <td>Bitwise right-shift</td>
  <td>Binary</td>
</tr>
<tr>
  <td>6</td>
  <td>&amp;</td>
  <td>Integer or BYTES</td>
  <td>Bitwise and</td>
  <td>Binary</td>
</tr>
<tr>
  <td>7</td>
  <td>^</td>
  <td>Integer or BYTES</td>
  <td>Bitwise xor</td>
  <td>Binary</td>
</tr>
<tr>
  <td>8</td>
  <td>|</td>
  <td>Integer or BYTES</td>
  <td>Bitwise or</td>
  <td>Binary</td>
</tr>
<tr>
  <td>9 (Comparison Operators)</td>
  <td>=</td>
  <td>Any comparable type. See

Data Types

  for a complete list.</td>
  <td>Equal</td>
  <td>Binary</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>&lt;</td>
  <td>Any comparable type. See

Data Types

  for a complete list.</td>
  <td>Less than</td>
  <td>Binary</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>&gt;</td>
  <td>Any comparable type. See

Data Types

  for a complete list.</td>
  <td>Greater than</td>
  <td>Binary</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>&lt;=</td>
  <td>Any comparable type. See

Data Types

  for a complete list.</td>
  <td>Less than or equal to</td>
  <td>Binary</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>&gt;=</td>
  <td>Any comparable type. See

Data Types

  for a complete list.</td>
  <td>Greater than or equal to</td>
  <td>Binary</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>!=, &lt;&gt;</td>
  <td>Any comparable type. See

Data Types

  for a complete list.</td>
  <td>Not equal</td>
  <td>Binary</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>[NOT] LIKE</td>
  <td>STRING and byte</td>
  <td>Value does [not] match the pattern specified</td>
  <td>Binary</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>[NOT] BETWEEN</td>
  <td>Any comparable types. See

Data Types

  for a complete list.</td>
  <td>Value is [not] within the range specified</td>
  <td>Binary</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>[NOT] IN</td>
  <td>Any comparable types. See

Data Types

  for a complete list.</td>
  <td>Value is [not] in the set of values specified</td>
  <td>Binary</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>IS [NOT] <code>NULL</code></td>
  <td>All</td>
  <td>Value is [not] <code>NULL</code></td>
  <td>Unary</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>IS [NOT] TRUE</td>
  <td>BOOL</td>
  <td>Value is [not] TRUE.</td>
  <td>Unary</td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td>IS [NOT] FALSE</td>
  <td>BOOL</td>
  <td>Value is [not] FALSE.</td>
  <td>Unary</td>
</tr>
<tr>
  <td>10</td>
  <td>NOT</td>
  <td>BOOL</td>
  <td>Logical NOT</td>
  <td>Unary</td>
</tr>
<tr>
  <td>11</td>
  <td>AND</td>
  <td>BOOL</td>
  <td>Logical AND</td>
  <td>Binary</td>
</tr>
<tr>
  <td>12</td>
  <td>OR</td>
  <td>BOOL</td>
  <td>Logical OR</td>
  <td>Binary</td>
</tr>
Order of Precedence Operator Input Data Types Name Operator Arity
1 . PROTO
STRUCT
Member field access operator Binary
  [ ] ARRAY Array position. Must be used with OFFSET or ORDINAL—see

Array Functions .

Binary
2 + All numeric types Unary plus Unary
  - All numeric types Unary minus Unary
  ~ Integer or BYTES Bitwise not Unary
3 * All numeric types Multiplication Binary
  / All numeric types Division Binary

Operators with the same precedence are left associative. This means that those operators are grouped together starting from the left and moving right. For example, the expression:

x AND y AND z

is interpreted as

( ( x AND y ) AND z )

The expression:

x * y / z

is interpreted as:

( ( x * y ) / z )

All comparison operators have the same priority, but comparison operators are not associative. Therefore, parentheses are required in order to resolve ambiguity. For example:

(x < y) IS FALSE

Element access operators

Operator Syntax Input Data Types Result Data Type Description
. expression.fieldname1... PROTO
STRUCT
Type T stored in fieldname1 Dot operator. Can be used to access nested fields, e.g.expression.fieldname1.fieldname2...
[ ] array_expression [position_keyword (int_expression ) ] See ARRAY Functions. Type T stored in ARRAY position_keyword is either OFFSET or ORDINAL. See

Array Functions

for the two functions that use this operator.

Arithmetic operators

All arithmetic operators accept input of numeric type T, and the result type has type T unless otherwise indicated in the description below:

Name Syntax
Addition X + Y
Subtraction X - Y
Multiplication X * Y
Division X / Y
Unary Plus + X
Unary Minus - X

NOTE: Divide by zero operations return an error. To return a different result, consider the IEEE_DIVIDE or SAFE_DIVIDE functions.

Result types for Addition and Multiplication:

INPUTINT32INT64UINT32UINT64NUMERICBIGNUMERICFLOATDOUBLE
INT32INT64INT64INT64ERRORNUMERICBIGNUMERICDOUBLEDOUBLE
INT64INT64INT64INT64ERRORNUMERICBIGNUMERICDOUBLEDOUBLE
UINT32INT64INT64UINT64UINT64NUMERICBIGNUMERICDOUBLEDOUBLE
UINT64ERRORERRORUINT64UINT64NUMERICBIGNUMERICDOUBLEDOUBLE
NUMERICNUMERICNUMERICNUMERICNUMERICNUMERICBIGNUMERICDOUBLEDOUBLE
BIGNUMERICBIGNUMERICBIGNUMERICBIGNUMERICBIGNUMERICBIGNUMERICBIGNUMERICDOUBLEDOUBLE
FLOATDOUBLEDOUBLEDOUBLEDOUBLEDOUBLEDOUBLEDOUBLEDOUBLE
DOUBLEDOUBLEDOUBLEDOUBLEDOUBLEDOUBLEDOUBLEDOUBLEDOUBLE

Result types for Subtraction:

INPUTINT32INT64UINT32UINT64NUMERICBIGNUMERICFLOATDOUBLE
INT32INT64INT64INT64ERRORNUMERICBIGNUMERICDOUBLEDOUBLE
INT64INT64INT64INT64ERRORNUMERICBIGNUMERICDOUBLEDOUBLE
UINT32INT64INT64INT64INT64NUMERICBIGNUMERICDOUBLEDOUBLE
UINT64ERRORERRORINT64INT64NUMERICBIGNUMERICDOUBLEDOUBLE
NUMERICNUMERICNUMERICNUMERICNUMERICNUMERICBIGNUMERICDOUBLEDOUBLE
BIGNUMERICBIGNUMERICBIGNUMERICBIGNUMERICBIGNUMERICBIGNUMERICBIGNUMERICDOUBLEDOUBLE
FLOATDOUBLEDOUBLEDOUBLEDOUBLEDOUBLEDOUBLEDOUBLEDOUBLE
DOUBLEDOUBLEDOUBLEDOUBLEDOUBLEDOUBLEDOUBLEDOUBLEDOUBLE

Result types for Division:

INPUTINT32INT64UINT32UINT64NUMERICBIGNUMERICFLOATDOUBLE
INT32DOUBLEDOUBLEDOUBLEDOUBLENUMERICBIGNUMERICDOUBLEDOUBLE
INT64DOUBLEDOUBLEDOUBLEDOUBLENUMERICBIGNUMERICDOUBLEDOUBLE
UINT32DOUBLEDOUBLEDOUBLEDOUBLENUMERICBIGNUMERICDOUBLEDOUBLE
UINT64DOUBLEDOUBLEDOUBLEDOUBLENUMERICBIGNUMERICDOUBLEDOUBLE
NUMERICNUMERICNUMERICNUMERICNUMERICNUMERICBIGNUMERICDOUBLEDOUBLE
BIGNUMERICBIGNUMERICBIGNUMERICBIGNUMERICBIGNUMERICBIGNUMERICBIGNUMERICDOUBLEDOUBLE
FLOATDOUBLEDOUBLEDOUBLEDOUBLEDOUBLEDOUBLEDOUBLEDOUBLE
DOUBLEDOUBLEDOUBLEDOUBLEDOUBLEDOUBLEDOUBLEDOUBLEDOUBLE

Result types for Unary Plus:

INPUTINT32INT64UINT32UINT64NUMERICBIGNUMERICFLOATDOUBLE
OUTPUTINT32INT64UINT32UINT64NUMERICBIGNUMERICFLOATDOUBLE

Result types for Unary Minus:

INPUTINT32INT64UINT32UINT64NUMERICBIGNUMERICFLOATDOUBLE
OUTPUTINT32INT64ERRORERRORNUMERICBIGNUMERICFLOATDOUBLE

Date arithmetics operators

Operators '+' and '-' can be used for arithmetic operations on dates.

date_expression + int64_expression
int64_expression + date_expression
date_expression - int64_expression

Description

Adds or subtracts int64_expression days to or from date_expression. This is equivalent to DATE_ADD or DATE_SUB functions, when interval is expressed in days.

Return Data Type

DATE

Example

SELECT DATE "2020-09-22" + 1 AS day_later, DATE "2020-09-22" - 7 AS week_ago

+------------+------------+
| day_later  | week_ago   |
+------------+------------+
| 2020-09-23 | 2020-09-15 |
+------------+------------+

Bitwise operators

All bitwise operators return the same type and the same length as the first operand.

Name Syntax Input Data Type Description
Bitwise not ~ X Integer or BYTES Performs logical negation on each bit, forming the ones' complement of the given binary value.
Bitwise or X | Y X: Integer or BYTES
Y: Same type as X
Takes two bit patterns of equal length and performs the logical inclusive OR operation on each pair of the corresponding bits. This operator throws an error if X and Y are BYTES of different lengths.
Bitwise xor X ^ Y X: Integer or BYTES
Y: Same type as X
Takes two bit patterns of equal length and performs the logical exclusive OR operation on each pair of the corresponding bits. This operator throws an error if X and Y are BYTES of different lengths.
Bitwise and X & Y X: Integer or BYTES
Y: Same type as X
Takes two bit patterns of equal length and performs the logical AND operation on each pair of the corresponding bits. This operator throws an error if X and Y are BYTES of different lengths.
Left shift X << Y X: Integer or BYTES
Y: INT64
Shifts the first operand X to the left. This operator returns 0 or a byte sequence of b'\x00' if the second operand Y is greater than or equal to

the bit length of the first operand X (for example, 64 if X has the type INT64).

This operator throws an error if Y is negative.

Right shift X >> Y X: Integer or BYTES
Y: INT64
Shifts the first operand X to the right. This operator does not do sign bit extension with a signed type (i.e. it fills vacant bits on the left with 0). This operator returns 0 or a byte sequence of b'\x00' if the second operand Y is greater than or equal to

the bit length of the first operand X (for example, 64 if X has the type INT64).

This operator throws an error if Y is negative.

Logical operators

ZetaSQL supports the AND, OR, and NOT logical operators. Logical operators allow only BOOL or NULL input and use three-valued logic to produce a result. The result can be TRUE, FALSE, or NULL:

x y x AND y x OR y
TRUE TRUE TRUE TRUE
TRUE FALSE FALSE TRUE
TRUE NULL NULL TRUE
FALSE TRUE FALSE TRUE
FALSE FALSE FALSE FALSE
FALSE NULL FALSE NULL
NULL TRUE NULL TRUE
NULL FALSE FALSE NULL
NULL NULL NULL NULL
x NOT x
TRUE FALSE
FALSE TRUE
NULL NULL

Examples

The examples in this section reference a table called entry_table:

+-------+
| entry |
+-------+
| a     |
| b     |
| c     |
| NULL  |
+-------+
SELECT 'a' FROM entry_table WHERE entry = 'a'

-- a => 'a' = 'a' => TRUE
-- b => 'b' = 'a' => FALSE
-- NULL => NULL = 'a' => NULL

+-------+
| entry |
+-------+
| a     |
+-------+
SELECT entry FROM entry_table WHERE NOT (entry = 'a')

-- a => NOT('a' = 'a') => NOT(TRUE) => FALSE
-- b => NOT('b' = 'a') => NOT(FALSE) => TRUE
-- NULL => NOT(NULL = 'a') => NOT(NULL) => NULL

+-------+
| entry |
+-------+
| b     |
| c     |
+-------+
SELECT entry FROM entry_table WHERE entry IS NULL

-- a => 'a' IS NULL => FALSE
-- b => 'b' IS NULL => FALSE
-- NULL => NULL IS NULL => TRUE

+-------+
| entry |
+-------+
| NULL  |
+-------+

Comparison operators

Comparisons always return BOOL. Comparisons generally require both operands to be of the same type. If operands are of different types, and if ZetaSQL can convert the values of those types to a common type without loss of precision, ZetaSQL will generally coerce them to that common type for the comparison; ZetaSQL will generally coerce literals to the type of non-literals, where present. Comparable data types are defined in Data Types.

NOTE: ZetaSQL allows comparisons between signed and unsigned integers.

STRUCTs support only 4 comparison operators: equal (=), not equal (!= and <>), and IN.

The following rules apply when comparing these data types:

  • Floating point: All comparisons with NaN return FALSE, except for != and <>, which return TRUE.
  • BOOL: FALSE is less than TRUE.
  • STRING: Strings are compared codepoint-by-codepoint, which means that canonically equivalent strings are only guaranteed to compare as equal if they have been normalized first.
  • NULL: The convention holds here: any operation with a NULL input returns NULL.
Name Syntax Description
Less Than X < Y Returns TRUE if X is less than Y.
Less Than or Equal To X <= Y Returns TRUE if X is less than or equal to Y.
Greater Than X > Y Returns TRUE if X is greater than Y.
Greater Than or Equal To X >= Y Returns TRUE if X is greater than or equal to Y.
Equal X = Y Returns TRUE if X is equal to Y.
Not Equal X != Y
X <> Y
Returns TRUE if X is not equal to Y.
BETWEEN X [NOT] BETWEEN Y AND Z Returns TRUE if X is [not] within the range specified. The result of "X BETWEEN Y AND Z" is equivalent to "Y <= X AND X <= Z" but X is evaluated only once in the former.
LIKE X [NOT] LIKE Y Checks if the STRING in the first operand X matches a pattern specified by the second operand Y. Expressions can contain these characters:
  • A percent sign "%" matches any number of characters or bytes
  • An underscore "_" matches a single character or byte
  • You can escape "\", "_", or "%" using two backslashes. For example, "\\%". If you are using raw strings, only a single backslash is required. For example, r"\%".
IN Multiple - see below Returns FALSE if the right operand is empty. Returns NULL if the left operand is NULL. Returns TRUE or NULL, never FALSE, if the right operand contains NULL. Arguments on either side of IN are general expressions. Neither operand is required to be a literal, although using a literal on the right is most common. X is evaluated only once.

When testing values that have a STRUCT data type for equality, it's possible that one or more fields are NULL. In such cases:

  • If all non-NULL field values are equal, the comparison returns NULL.
  • If any non-NULL field values are not equal, the comparison returns false.

The following table demonstrates how STRUCT data types are compared when they have fields that are NULL valued.

Struct1 Struct2 Struct1 = Struct2
STRUCT(1, NULL) STRUCT(1, NULL) NULL
STRUCT(1, NULL) STRUCT(2, NULL) FALSE
STRUCT(1,2) STRUCT(1, NULL) NULL

IN operators

The IN operator supports the following syntaxes:

x [NOT] IN (y, z, ... ) # Requires at least one element
x [NOT] IN (<subquery>)
x [NOT] IN UNNEST(<array expression>) # analysis error if the expression
                                      # does not return an ARRAY type.

Arguments on either side of the IN operator are general expressions. It is common to use literals on the right side expression; however, this is not required.

The semantics of:

x IN (y, z, ...)

are defined as equivalent to:

(x = y) OR (x = z) OR ...

and the subquery and array forms are defined similarly.

x NOT IN ...

is equivalent to:

NOT(x IN ...)

The UNNEST form treats an array scan like UNNEST in the FROM clause:

x [NOT] IN UNNEST(<array expression>)

This form is often used with ARRAY parameters. For example:

x IN UNNEST(@array_parameter)

Note: A NULL ARRAY will be treated equivalently to an empty ARRAY.

See the Arrays topic for more information on how to use this syntax.

When using the IN operator, the following semantics apply:

  • IN with an empty right side expression is always FALSE
  • IN with a NULL left side expression and a non-empty right side expression is always NULL
  • IN with a NULL in the IN-list can only return TRUE or NULL, never FALSE
  • NULL IN (NULL) returns NULL
  • IN UNNEST(<NULL array>) returns FALSE (not NULL)
  • NOT IN with a NULL in the IN-list can only return FALSE or NULL, never TRUE

IN can be used with multi-part keys by using the struct constructor syntax. For example:

(Key1, Key2) IN ( (12,34), (56,78) )
(Key1, Key2) IN ( SELECT (table.a, table.b) FROM table )

See the Struct Type section of the Data Types topic for more information on this syntax.

IS operators

IS operators return TRUE or FALSE for the condition they are testing. They never return NULL, even for NULL inputs, unlike the IS_INF and IS_NAN functions defined in Mathematical Functions. If NOT is present, the output BOOL value is inverted.

Function Syntax Input Data Type Result Data Type Description
X IS [NOT] NULL
Any value type BOOL Returns TRUE if the operand X evaluates to NULL, and returns FALSE otherwise.
X IS [NOT] TRUE
BOOL BOOL Returns TRUE if the BOOL operand evaluates to TRUE. Returns FALSE otherwise.
X IS [NOT] FALSE
BOOL BOOL Returns TRUE if the BOOL operand evaluates to FALSE. Returns FALSE otherwise.

Concatenation operator

The concatenation operator combines multiple values into one.

Function Syntax Input Data Type Result Data Type
STRING || STRING [ || ... ]
STRING STRING
BYTES || BYTES [ || ... ]
BYTES STRING
ARRAY<T> || ARRAY<T> [ || ... ]
ARRAY<T> ARRAY<T>