> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kinetica.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Expressions

<a id="expressions" />

*Kinetica* has native API support for a variety of expressions, which are used
as inputs while querying data *(for supported SQL expressions, see*
[Queries (SQL)](/content/sql/query) *)*.  These native API expressions can involve one or
more constants (both numeric and string) and *table* columns. The expressions
follow certain constraints based on where they are used, but all the expressions
should follow the basic guidelines outlined below.

<Note>
  Use parentheses liberally to ensure correct order-of-operations.
</Note>

## Constants

| Type      | Details                                                                                                                                                                                                                                                                                                                         |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| String    | String constants must be enclosed in single quotes or double quotes, e.g., <br /> <br /> \* 'hello' <br /> \* "world"                                                                                                                                                                                                           |
| Numerical | Numerical constants can be expressed as: <br /> <br /> \* decimal integers (`31242`) <br /> \* hex integers (`0x3420123a`) <br /> \* doubles (`3.41e5`) <br /> \* floats (`3.1415F`)                                                                                                                                            |
| Date/Time | Supported date formats have optional leading zeros for months & days, while datetime optionally supports UTC format.  Examples of each date/time data type: <br /> <br /> \* date     (`2000-1-2`, `2020-01-02`) <br /> \* time     (`1:23:45`, `17:17:17`) <br /> \* datetime (`2000-1-2 1:23:45.678`, `2020-01-02T17:17:17Z`) |

## Operators

When these operators are applied to numeric columns, they will interpret
non-zero values as *true* and zero values as *false*, returning `1` for *true*
and `0` for *false*.

| Type         | Details                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Bitwise      | `&` `\|` `<<` `>>` `~` `^`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| Comparison   | `>` `<` `>=` `<=` `==` `=` `!=` `<>` `in`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| Logical      | `and`: Evaluates to *true* only if both sides of the expression are *true*; see [Short-Circuiting](/content/concepts/expressions#short-circuiting) for error-checking details <br /> <br /> `or`: Evaluates to *true* if either side of the expression is *true*; see [Short-Circuiting](/content/concepts/expressions#short-circuiting) for error-checking details <br /> <br /> `xor`: Evaluates to *true* only if one side of the expression is *true* and the other *false* <br /> <br /> `not`: Evaluates to *true* if the expression is *false*, and vice versa <br /> <br /> `!`: Synonym for `not` |
| Mathematical | `+` `-` `*` `/`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |

<a id="expression-functions" />

## Functions

<a id="expression-functions-array" />

### Array Functions

<a id="expression-functions-array-scalar" />

#### Scalar Functions

<AccordionGroup>
  <Accordion title="ARRAY_APPEND(array, value)" id="array_append-array-value" defaultOpen>
    Returns an array consisting of `array` with `value` appended to the end.
  </Accordion>

  <Accordion title="ARRAY_CONCAT(arr1, arr2)" id="array_concat-arr1-arr2" defaultOpen>
    Returns an array consisting of all the elements of array `arr1` followed by all of
    the elements of array `arr2`.
  </Accordion>

  <Accordion title="ARRAY_CONTAINS(array, value)" id="array_contains-array-value" defaultOpen>
    Returns true if `value` is present in `array`.
  </Accordion>

  <Accordion title="ARRAY_CONTAINS_ALL(arr1, arr2)" id="array_contains_all-arr1-arr2" defaultOpen>
    Returns true if every value in array `arr2` is present in array `arr1`; otherwise
    returns false.
  </Accordion>

  <Accordion title="ARRAY_CONTAINS_ANY(arr1, arr2)" id="array_contains_any-arr1-arr2" defaultOpen>
    Returns true if any value in array `arr2` is present in array `arr`; otherwise
    returns false.
  </Accordion>

  <Accordion title="ARRAY_DISTINCT(array)" id="array_distinct-array" defaultOpen>
    Returns an array consisting of `array` values with duplicates removed.
  </Accordion>

  <Accordion title="ARRAY_EMPTY(array)" id="array_empty-array" defaultOpen>
    Returns true if `array` is empty; otherwise returns false.
  </Accordion>

  <Accordion title="ARRAY_EXCEPT(arr1, arr2)" id="array_except-arr1-arr2" defaultOpen>
    Returns an array consisting of all of the elements of array `arr1` with the ones that
    also appear in array `arr2` removed.
  </Accordion>

  <Accordion title="ARRAY_INTERSECT(arr1, arr2)" id="array_intersect-arr1-arr2" defaultOpen>
    Returns an array consisting of all of the elements of array `arr1` that also appear
    in array `arr2`.
  </Accordion>

  <Accordion title="ARRAY_ITEM(array, pos)" id="array_item-array-pos" defaultOpen>
    Returns the item in `array` at the given 1-based `pos` position.

    See [examples](/content/concepts/array#array-func-ex-item).
  </Accordion>

  <Accordion title="ARRAY_LENGTH(array)" id="array_length-array" defaultOpen>
    Returns the number of items in the given `array` at the 1st dimension.

    See [examples](/content/concepts/array#array-func-ex-len).
  </Accordion>

  <Accordion title="ARRAY_LOWER(array, dim)" id="array_lower-array-dim" defaultOpen>
    Returns the lowest index of `array` in the given `dim` dimension; since all arrays
    are 1-dimensional, only specifying a dimension of `1` will return a value, and since
    array indices are 1-based, that value will always be `1`.
  </Accordion>

  <Accordion title="ARRAY_NDIMS(array)" id="array_ndims-array" defaultOpen>
    Returns the number of dimensions in the given `array`; since all arrays are
    1-dimensional, that number will always be `1`.
  </Accordion>

  <Accordion title="ARRAY_NOT_EMPTY(array)" id="array_not_empty-array" defaultOpen>
    Returns true if `array` is not empty; otherwise returns false.
  </Accordion>

  <Accordion title="ARRAY_SLICE(array, from, to)" id="array_slice-array-from-to" defaultOpen>
    Returns an array consisting of the values from `array` between the `from` index
    (inclusive) up to the `to` index (exclusive) using 0-based indexing. Negative indexes
    are treated as offsets from the end of the array.
  </Accordion>

  <Accordion title="ARRAY_TO_STRING(array, delim)" id="array_to_string-array-delim" defaultOpen>
    Converts the items of `array` into a string delimited by `delim`.

    See [examples](/content/concepts/array#array-func-ex-atos).
  </Accordion>

  <Accordion title="ARRAY_UPPER(array, dim)" id="array_upper-array-dim" defaultOpen>
    Returns the highest index of `array` in the given `dim` dimension; since all arrays
    are 1-dimensional, only specifying a dimension of `1` will return a value, and since
    array indices are 1-based, that value will always be equivalent to `ARRAY_LENGTH`.
  </Accordion>

  <Accordion title="MAKE_ARRAY(value)" id="make_array-value" defaultOpen>
    Returns an array consisting of the single `value` element.
  </Accordion>

  <Accordion title="STRING_TO_ARRAY(str, delim)" id="string_to_array-str-delim" defaultOpen>
    Converts the values in `str`, delimited by `delim`, into an array.

    See [examples](/content/concepts/array#array-func-ex-stoa).
  </Accordion>
</AccordionGroup>

<a id="expression-functions-array-agg" />

#### Aggregation/Transposition Functions

The following functions can be used on [array](/content/concepts/array)
columns within [aggregations](/content/concepts/expressions#aggregate-expressions-label).

These functions can be used to convert primitive column values into arrays of
those values (aggregation) or to convert array columns into columns of primitive
values (unnest).

<AccordionGroup>
  <Accordion title="ARRAY_AGG(expr)" id="array_agg-expr" defaultOpen>
    Combines column values within a group into a single *array* of those values.

    See [examples](/content/concepts/array#array-func-agg-ex-agg).
  </Accordion>

  <Accordion title="ARRAY_AGG_DISTINCT(expr)" id="array_agg_distinct-expr" defaultOpen>
    Combines column values within a group into a single *array* of those values, removing
    any duplicates.

    See [examples](/content/concepts/array#array-func-agg-ex-agg-dist).
  </Accordion>

  <Accordion title="UNNEST_JSON_ARRAY" id="unnest_json_array" defaultOpen>
    Transposes array values into columnar data.

    See [UNNEST\_JSON\_ARRAY](/content/concepts/array#array-func-unnest).
  </Accordion>
</AccordionGroup>

### Conditional Functions

<AccordionGroup>
  <Accordion title="CASE(expr, {<matches>}, {<values>}, value_if_no_match)" id="case-expr-<matches>-<values>-value_if_no_match" defaultOpen>
    Evaluates `expr`: returns the first value from the `values` list whose corresponding match
    from the `matches` list is equal to `expr`; returns `value_if_no_match` if `expr` is not
    equal to any of the matches in the `matches` list

    <Info>
      A *null* cannot be used for either a match or value, but `value_if_no_match` can be
      null.
    </Info>

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Parameter</th>
            <th>Description</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>expr</code></td>
            <td>any expression to match against the list of <code>matches</code></td>
          </tr>

          <tr>
            <td><code>matches</code></td>
            <td>a comma-delimited list of constants to match <code>expr</code> against; needs to be of the same data type as <code>expr</code> and have the same number of list items as the <code>values</code> list</td>
          </tr>

          <tr>
            <td><code>values</code></td>
            <td>a comma-delimited list of constants, one of which will be returned in the event that <code>expr</code> matches an item in the <code>matches</code> list; needs to be of the same data type as <code>value\_if\_no\_match</code> and have the same number of list items as the <code>matches</code> list</td>
          </tr>

          <tr>
            <td><code>value\_if\_no match</code></td>
            <td>any value to return in the event of a match; needs to be of the same data type as the list items in <code>values</code></td>
          </tr>
        </tbody>
      </table>
    </div>

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>CASE(0, \{1, 2, 3}, \{'A', 'B', 'C'}, 'D')</code></td>
            <td><code>D</code></td>
          </tr>

          <tr>
            <td><code>CASE(1, \{1, 2, 3}, \{'A', 'B', 'C'}, 'D')</code></td>
            <td><code>A</code></td>
          </tr>

          <tr>
            <td><code>CASE(2, \{1, 2, 3}, \{'A', 'B', 'C'}, 'D')</code></td>
            <td><code>B</code></td>
          </tr>

          <tr>
            <td><code>CASE(3, \{1, 2, 3}, \{'A', 'B', 'C'}, 'D')</code></td>
            <td><code>C</code></td>
          </tr>

          <tr>
            <td><code>CASE(4, \{1, 2, 3}, \{'A', 'B', 'C'}, 'D')</code></td>
            <td><code>D</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="IF(expr, value_if_true, value_if_false)" id="if-expr-value_if_true-value_if_false" defaultOpen>
    Evaluates `expr`: if *true*, returns `value_if_true`; otherwise, if *false* or *null*,
    returns `value_if_false`; see [Short-Circuiting](/content/concepts/expressions#short-circuiting) for error-checking details

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Parameter</th>
            <th>Description</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>expr</code></td>
            <td>any *true*/*false* condition <Note>When an integer column is used directly, this function will interpret non-zero values as *true* and zero values as *false*.</Note></td>
          </tr>

          <tr>
            <td><code>value\_if\_true</code></td>
            <td>any type; must be the same type as <code>value\_if\_false</code></td>
          </tr>

          <tr>
            <td><code>value\_if\_false</code></td>
            <td>any type; must be the same type as <code>value\_if\_true</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>
</AccordionGroup>

### Conversion Functions

For the `CAST()` and `CONVERT()` functions, valid destination types are:

| Numeric                                                                                                                                                  | Text                                                                                                                                                                                 | Date/Time                                                             | Geometry      |
| -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------- | ------------- |
| \* *bool* <br /> \* *int8* <br /> \* *int16* <br /> \* *int* <br /> \* *long* <br /> \* *ulong* <br /> \* *float* <br /> \* *double* <br /> \* *decimal* | \* *string* <br /> \* *char1* <br /> \* *char2* <br /> \* *char4* <br /> \* *char8* <br /> \* *char16* <br /> \* *char32* <br /> \* *char64* <br /> \* *char128* <br /> \* *char256* | \* *timestamp* <br /> \* *date* <br /> \* *time* <br /> \* *datetime* | \* *geometry* |

<AccordionGroup>
  <Accordion title="CAST (original value, destination type)" id="cast-original-value-destination-type" defaultOpen>
    Returns the equivalent of `original value` converted to the  `destination type`;
    useful for converting strings to numbers and numbers to strings
  </Accordion>

  <Accordion title="CHAR(expr)" id="char-expr" defaultOpen>
    Returns the character associated with the ASCII code in `expr`
  </Accordion>

  <Accordion title="CHAR1(expr)" id="char1-expr" defaultOpen>
    Converts the given `expr` to *char1* type
  </Accordion>

  <Accordion title="CHAR2(expr)" id="char2-expr" defaultOpen>
    Converts the given `expr` to *char2* type
  </Accordion>

  <Accordion title="CHAR4(expr)" id="char4-expr" defaultOpen>
    Converts the given `expr` to *char4* type
  </Accordion>

  <Accordion title="CHAR8(expr)" id="char8-expr" defaultOpen>
    Converts the given `expr` to *char8* type
  </Accordion>

  <Accordion title="CHAR16(expr)" id="char16-expr" defaultOpen>
    Converts the given `expr` to *char16* type
  </Accordion>

  <Accordion title="CHAR32(expr)" id="char32-expr" defaultOpen>
    Converts the given `expr` to *char32* type
  </Accordion>

  <Accordion title="CHAR64(expr)" id="char64-expr" defaultOpen>
    Converts the given `expr` to *char64* type
  </Accordion>

  <Accordion title="CHAR128(expr)" id="char128-expr" defaultOpen>
    Converts the given `expr` to *char128* type
  </Accordion>

  <Accordion title="CHAR256(expr)" id="char256-expr" defaultOpen>
    Converts the given `expr` to *char256* type
  </Accordion>

  <Accordion title="CONVERT (original value, destination type, style)" id="convert-original-value-destination-type-style" defaultOpen>
    Returns the equivalent of `original value` converted to the `destination type`. The
    `style` parameter is currently only applicable when the `destination type` is
    *string* and the `original value` is of *timestamp* or *datetime* type.

    Valid style codes include:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Style</th>
            <th>Format</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>0</code></td>
            <td><code>mon dd yyyy hh:mi\<AM|PM></code></td>
          </tr>

          <tr>
            <td><code>21</code> <code>121</code></td>
            <td><code>yyyy-mm-dd hh:mi:ss.mmm</code></td>
          </tr>
        </tbody>
      </table>
    </div>

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>CONVERT('0.1', double)</code></td>
            <td><code>0.1</code></td>
          </tr>

          <tr>
            <td><code>CONVERT(DATETIME('2000-10-10 12:34:56'), string, 0)</code></td>
            <td><code>Oct 10 2000 12:34PM</code></td>
          </tr>

          <tr>
            <td><code>CONVERT(DATETIME(971181296789), string, 21)</code></td>
            <td><code>2000-10-10 12:34:56.789</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="DATE(expr)" id="date-expr" defaultOpen>
    Converts `expr` to date (`YYYY-MM-DD`) format
  </Accordion>

  <Accordion title="DATETIME(expr)" id="datetime-expr" defaultOpen>
    Converts `expr` to datetime (`YYYY-MM-DD HH24:MI:SS.mmm`) format
  </Accordion>

  <Accordion title="DECIMAL(expr)" id="decimal-expr" defaultOpen>
    Converts the given `expr` to *decimal* type
  </Accordion>

  <Accordion title="DOUBLE(expr)" id="double-expr" defaultOpen>
    Converts the given `expr` to *double* type
  </Accordion>

  <Accordion title="FLOAT(expr)" id="float-expr" defaultOpen>
    Converts the given `expr` to *float* type
  </Accordion>

  <Accordion title="INT(expr)" id="int-expr" defaultOpen>
    Converts the given `expr` to *int* type
  </Accordion>

  <Accordion title="LONG(expr)" id="long-expr" defaultOpen>
    Converts the given `expr` to *long* type
  </Accordion>

  <Accordion title="STRING(expr)" id="string-expr" defaultOpen>
    Converts `expr` to a string format appropriate for the `expr` type
  </Accordion>

  <Accordion title="TIME(expr)" id="time-expr" defaultOpen>
    Converts `expr` to time (`HH:MI:SS.mmm`) format
  </Accordion>

  <Accordion title="TIMESTAMP(expr)" id="timestamp-expr" defaultOpen>
    Converts `expr` to the number of milliseconds since the epoch
  </Accordion>

  <Accordion title="TO_CHAR(expr, format)" id="to_char-expr-format" defaultOpen>
    Converts the given date/time `expr` to a string matching the given `format`.
    The returned string will be truncated at 32 characters.
    See [Date/Time Conversion Codes](/content/concepts/expressions#datetime-conversion-codes) for the list of format codes.

    Example:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <tbody>
          <tr>
            <td>**Function Call**</td>
            <td><code>TO\_CHAR(DATETIME(971181296000), '"Last login: "YYYY-MM-DD')</code></td>
          </tr>

          <tr>
            <td>**Return**</td>
            <td><code>Last login: 2000-10-10</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="TO_DATE(string, format)" id="to_date-string-format" defaultOpen>
    Converts the given string to a *date* type with the given format code.
    See [Date/Time Conversion Codes](/content/concepts/expressions#datetime-conversion-codes) for the list of format codes.

    Example:

    ```
    TO_DATE('2017-06-15', 'YYYY-MM-DD')
    ```
  </Accordion>

  <Accordion title="TO_DATETIME(string, format)" id="to_datetime-string-format" defaultOpen>
    Converts the given string to a *datetime* type with the given format code.
    See [Date/Time Conversion Codes](/content/concepts/expressions#datetime-conversion-codes) for the list of format codes.

    Example:

    ```
    TO_DATETIME('2017-06-15 10:37:30', 'YYYY-MM-DD HH:MI:SS')
    ```
  </Accordion>

  <Accordion title="TO_TIME(string, format)" id="to_time-string-format" defaultOpen>
    Converts the given string to a *time* type with the given format code.
    See [Date/Time Conversion Codes](/content/concepts/expressions#datetime-conversion-codes) for the list of format codes.

    Example:

    ```
    TO_TIME('10:37:30', 'HH:MI:SS')
    ```
  </Accordion>

  <Accordion title="TO_TIMESTAMP(string, format)" id="to_timestamp-string-format" defaultOpen>
    Converts the given string to a *timestamp* type with the given format code.
    See [Date/Time Conversion Codes](/content/concepts/expressions#datetime-conversion-codes) for the list of format codes.

    Example:

    ```
    TO_TIMESTAMP('2017-06-15 10:37:30', 'YYYY-MM-DD HH:MI:SS')
    ```
  </Accordion>

  <Accordion title="ULONG(expr)" id="ulong-expr" defaultOpen>
    Converts the given `expr` to *ulong* type
  </Accordion>

  <Accordion title="VECTOR(expr, len)" id="vector-expr-len" defaultOpen>
    Converts the given stringified array of `len` number of *float* values in `expr` to
    `VECTOR` type.

    Example:

    ```
    VECTOR('[1.1, 2.2, 3.3]', 3)
    ```
  </Accordion>
</AccordionGroup>

<a id="datetime-conversion-codes" />

#### Date/Time Conversion Codes

The following formatting codes can be used to convert date/time strings to
native date/time objects (with `TO_DATE`, `TO_DATETIME`, `TO_TIME` and `TO_TIMESTAMP`)
and for formatting date/time objects as strings (with `TO_CHAR`).

These characters are interpreted literally:  `-` `/` `,` `.` `;` `:`

Other characters need to be quoted in order to be interpreted literally.
For example, `MM-DD-YYYY` can be used to convert `01-02-2022` to a date,
while `"Today is "MM-DD-YYYY` is needed to convert `Today is 01-02-2022`.

In the following table, `Opt` in the Input column indicates that the field may be empty
when being read, and still be considered a valid input.  This can be useful when reading
data from a source that, for example, sometimes includes milliseconds in their time strings
and sometimes does not (e.g., the `MMM` code is `Opt`).  `Yes` in the Input column indicates
that some data must be present in the input string to be considered valid, unless it is after
a `$` character, in which case all input after the `$` is optional.

| Format Code | Input | Output | Description                                                                                                                                                                                                                                                                                                                      |
| ----------- | ----- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `_`         | Yes   |        | Any one character                                                                                                                                                                                                                                                                                                                |
| `?`         | Opt   |        | Zero or more non-digit characters                                                                                                                                                                                                                                                                                                |
| `$`         | Yes   |        | Everything after this is optional; e.g., `HH:MI$:SS` would accept `12:34` and `12:34:56`                                                                                                                                                                                                                                         |
| `AD`        |       | Yes    | Era indicator without periods                                                                                                                                                                                                                                                                                                    |
| `A.D.`      |       | Yes    | Era indicator with periods                                                                                                                                                                                                                                                                                                       |
| `AM`        | Yes   | Yes    | Meridian indicator without periods \[`AM`, `PM`]                                                                                                                                                                                                                                                                                 |
| `A.M.`      | Yes   | Yes    | Meridian indicator with periods \[`A.M.`, `P.M.`]                                                                                                                                                                                                                                                                                |
| `BC`        |       | Yes    | Era indicator without periods                                                                                                                                                                                                                                                                                                    |
| `B.C.`      |       | Yes    | Era indicator with periods                                                                                                                                                                                                                                                                                                       |
| `C`         | Yes   | Yes    | Number of day in calendar month, with optional leading zero \[`1` - `31`]                                                                                                                                                                                                                                                        |
| `CC`        |       | Yes    | Century (if last 2 digits of the 4-digit year are `00`, this is the first 2 digits; otherwise, this is first 2 digits + 1)                                                                                                                                                                                                       |
| `D`         | Yes   | Yes    | Day of week \[`1` - `7`] (*Sunday* - *Saturday*)                                                                                                                                                                                                                                                                                 |
| `DAY`       | Yes   | Yes    | Day of week \[`Sunday` - `Saturday`]                                                                                                                                                                                                                                                                                             |
| `DD`        | Yes   | Yes    | Number of day in month, with leading zero \[`01` - `31`]                                                                                                                                                                                                                                                                         |
| `DDD`       | Yes   | Yes    | Number of day of year \[`1` - `366`]                                                                                                                                                                                                                                                                                             |
| `DL`        | Yes   | Yes    | Date long format (`DAY, MONTH C, RRRR`)                                                                                                                                                                                                                                                                                          |
| `DS`        | Yes   | Yes    | Date short format (`M/C/RRRR`)                                                                                                                                                                                                                                                                                                   |
| `DY`        | Yes   | Yes    | Abbreviated day name (e.g., "Mon")                                                                                                                                                                                                                                                                                               |
| `FF[1-9]`   | Opt   | Yes    | Fractional seconds where the number of fractional second digits can be specified (default is 3 digits); when used for input, the string may contain an optional "." preceding the numbers                                                                                                                                        |
| `H`         | Yes   | Yes    | Alias for `H12`                                                                                                                                                                                                                                                                                                                  |
| `H12`       | Yes   | Yes    | Hour of day in 12-hour format, with optional leading zero \[`0` - `11`]                                                                                                                                                                                                                                                          |
| `H24`       | Yes   | Yes    | Hour of day in 24-hour format, with optional leading zero \[`0` - `23`]                                                                                                                                                                                                                                                          |
| `HH`        | Yes   | Yes    | Alias for `HH12`                                                                                                                                                                                                                                                                                                                 |
| `HH12`      | Yes   | Yes    | Hour of day in 12-hour format, with leading zero \[`00` - `11`]                                                                                                                                                                                                                                                                  |
| `HH24`      | Yes   | Yes    | Hour of day in 24-hour format, with leading zero \[`00` - `23`]                                                                                                                                                                                                                                                                  |
| `I`         | Yes   | Yes    | Last digit of ISO year                                                                                                                                                                                                                                                                                                           |
| `ID`        | Yes   | Yes    | ISO 8601 day of week \[`1` - `7`] (*Monday* - *Sunday*)                                                                                                                                                                                                                                                                          |
| `IDDD`      | Yes   | Yes    | ISO 8601 day of year \[`001` - `371`] (where `001` is the *Monday* of the 1st ISO week)                                                                                                                                                                                                                                          |
| `IW`        | Yes   | Yes    | ISO 8601 week of year \[`01` - `53`] (where `01` contains the first *Thursday* of the year)                                                                                                                                                                                                                                      |
| `IY`        | Yes   | Yes    | Last 2 digits of ISO year                                                                                                                                                                                                                                                                                                        |
| `IYY`       | Yes   | Yes    | Last 3 digits of ISO year                                                                                                                                                                                                                                                                                                        |
| `IYYY`      | Yes   | Yes    | Last 4 digits of ISO year                                                                                                                                                                                                                                                                                                        |
| `J`         | Yes   | Yes    | Julian day; the number of days since *January 1, 4712 BC*.  Number specified with `J` must be integers.                                                                                                                                                                                                                          |
| `LLL`       | Opt   | Yes    | Whole milliseconds (often positioned after a colon); e.g., `12:34:56:78` => *78 milliseconds*; when used for input, the string may contain an optional "." or ":" preceding the numbers; when "." is found, this code will act like the `MMM` code                                                                               |
| `M`         | Yes   | Yes    | Number of month in year, with optional leading zero \[`1` - `12`]                                                                                                                                                                                                                                                                |
| `MI`        | Yes   | Yes    | Minute of hour \[`00` - `59`]                                                                                                                                                                                                                                                                                                    |
| `MM`        | Yes   | Yes    | Number of month in year, with leading zero \[`01` - `12`]                                                                                                                                                                                                                                                                        |
| `MMM`       | Opt   | Yes    | Fractions of a second up to milliseconds; e.g., `12:34:56.78` => *780 milliseconds*; when used for input, the string may contain an optional "." or ":" preceding the numbers; when ":" is found, this code will act like the `LLL` code                                                                                         |
| `MON`       | Yes   | Yes    | 3-character abbreviation of month in title case \[`Jan` - `Dec`]                                                                                                                                                                                                                                                                 |
| `MONTH`     | Yes   | Yes    | Full name of month \[`January` - `December`]                                                                                                                                                                                                                                                                                     |
| `MS`        | Opt   | Yes    | Alias for `MMM`                                                                                                                                                                                                                                                                                                                  |
| `OF`        | Opt   | Yes    | Time-zone offset from UTC (`TZHTZM`)                                                                                                                                                                                                                                                                                             |
| `PM`        | Yes   | Yes    | Alias for `AM`                                                                                                                                                                                                                                                                                                                   |
| `P.M.`      | Yes   | Yes    | Alias for `A.M.`                                                                                                                                                                                                                                                                                                                 |
| `Q`         |       | Yes    | Quarter of the year \[`1` - `4`] (*January-March* - *October-December*)                                                                                                                                                                                                                                                          |
| `RM`        | Yes   | Yes    | Roman numeral month \[`I` - `XII`] (*January* - *December*)                                                                                                                                                                                                                                                                      |
| `RR`        | Yes   | Yes    | Rounded year.  Assume the given 2-digit year occurs in the present century, then: <br /> <br /> \* If the assumed date is greater than 50 years into the future, declare the date to be in the previous century <br /> \* If the assumed date is greater than 50 years into the past, declare the date to be in the next century |
| `RRRR`      | Yes   | Yes    | Either a 2-digit or 4-digit year; if 2-digit, equivalent to `RR`                                                                                                                                                                                                                                                                 |
| `SCC`       |       | Yes    | Same as `CC`                                                                                                                                                                                                                                                                                                                     |
| `SS`        | Yes   | Yes    | Second of minute \[`00` - `59`]                                                                                                                                                                                                                                                                                                  |
| `SSSS`      | Yes   | Yes    | Alias for `SSSSS`                                                                                                                                                                                                                                                                                                                |
| `SSSSS`     | Yes   | Yes    | Seconds past midnight \[`0` - `86399`]                                                                                                                                                                                                                                                                                           |
| `SYEAR`     |       | Yes    | Same as `YEAR`                                                                                                                                                                                                                                                                                                                   |
| `SYYYY`     | Yes   | Yes    | Same as `YYYY`                                                                                                                                                                                                                                                                                                                   |
| `TS`        | Yes   | Yes    | Time short format (`H24:MI:SS.MMM`)                                                                                                                                                                                                                                                                                              |
| `TZ`        | Opt   | Yes    | Time zone (`TZH`)                                                                                                                                                                                                                                                                                                                |
| `TZH`       | Opt   | Yes    | Time zone hour (ISO); "Z" or +/- followed by one or two digits (will always output "Z")                                                                                                                                                                                                                                          |
| `TZM`       | Opt   | Yes    | Time zone minute (ISO); colon followed by one or two digits; for input, an optional colon is allowed at the front; if present, two digits must follow it                                                                                                                                                                         |
| `US`        | Opt   | Yes    | Microseconds; when used for input, the string may contain an optional "." preceding the numbers                                                                                                                                                                                                                                  |
| `W`         | Yes   | Yes    | Week of month \[`1` - `5`], where week 1 starts on the first day of the month and ends on the seventh                                                                                                                                                                                                                            |
| `WW`        | Yes   | Yes    | Week of year \[`1` - `53`], where week 1 starts on the first day of the year and continues to the seventh day of the year                                                                                                                                                                                                        |
| `X`         | Yes   | Yes    | Local radix character (always `.`.  E.g., `HH:MI:SSXFF`)                                                                                                                                                                                                                                                                         |
| `Y`         | Yes   | Yes    | Last 1 digit of year                                                                                                                                                                                                                                                                                                             |
| `Y,YYY`     | Yes   | Yes    | Year with a comma after the thousands place                                                                                                                                                                                                                                                                                      |
| `YEAR`      |       | Yes    | Year spelled out (e.g., "Two Thousand Twenty Five")                                                                                                                                                                                                                                                                              |
| `YY`        | Yes   | Yes    | Last 2 digits of year                                                                                                                                                                                                                                                                                                            |
| `YYY`       | Yes   | Yes    | Last 3 digits of year                                                                                                                                                                                                                                                                                                            |
| `YYYY`      | Yes   | Yes    | 4-digit year                                                                                                                                                                                                                                                                                                                     |

<a id="expression-functions-datetime" />

### Date/Time Functions

This section comprises the following functions:

* [Date/Time Base Functions](/content/concepts/expressions#expression-functions-datetime-base), which can extract parts of
  date/time expressions, convert back and forth between data types, and return
  the current date/time
* [Date/Time Complex Conversion Functions](/content/concepts/expressions#expression-functions-datetime-complex), which can perform more complex
  date/type conversions

<a id="expression-functions-datetime-base" />

#### Date/Time Base Functions

<AccordionGroup>
  <Accordion title="CLOCK_TIMESTAMP()" id="clock_timestamp" defaultOpen>
    Returns the date & time as `YYYY-MM-DD HH24:MI:SS.mmm`

    <Info>
      `CLOCK_TIMESTAMP` may return different values each time it is called in the
      same query or SQL Procedure, which may lead to data getting out of sync across HA
      clusters.  Use `CURRENT_DATETIME` to avoid this issue.
    </Info>
  </Accordion>

  <Accordion title="CURRENT_DATE()" id="current_date" defaultOpen>
    Returns the date as `YYYY-MM-DD`
  </Accordion>

  <Accordion title="CURRENT_DATETIME()" id="current_datetime" defaultOpen>
    Returns the date & time as `YYYY-MM-DD HH24:MI:SS.mmm`

    <Info>
      `CURRENT_DATETIME` will return same values each time it is called in the
      same query or SQL Procedure, and should keep data in-sync across HA clusters.
      See `CLOCK_TIMESTAMP` to always get the actual time each time it is called.
    </Info>
  </Accordion>

  <Accordion title="CURRENT_TIME()" id="current_time" defaultOpen>
    Returns the time as `HH24:MI:SS.mmm`
  </Accordion>

  <Accordion title="CURRENT_TIMESTAMP()" id="current_timestamp" defaultOpen>
    Returns the date & time as the number of milliseconds since the epoch
  </Accordion>

  <Accordion title="DATEADD (unit, amount, expr)" id="dateadd-unit-amount-expr" defaultOpen>
    Adds the positive or negative integral `amount` of `unit` date/time intervals to the
    `date` or `datetime` value in `expr`

    The following date/time intervals are supported for `unit`:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Constant</th>
            <th>Description</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>YEAR</code></td>
            <td>Year is modified by interval amount (not affected by leap year, etc.) overflow/underflow occurs</td>
          </tr>

          <tr>
            <td><code>QUARTER</code></td>
            <td>Month is modified by three times the interval amount, irrespective of the number of days in the months between; day adjusting performed the same as the <code>MONTH</code> description, but only on final month (e.g., *Jan 31st* + *1 quarter* will be *Apr 30th*, not *Apr 28th* because of *February*)</td>
          </tr>

          <tr>
            <td><code>MONTH</code></td>
            <td>Month is modified by interval amount and date adjusted if overflow/underflow occurs; day adjusted to last day of calculated month if not a valid day for that month (e.g., *Apr 31st* -> *Apr 30th*)</td>
          </tr>

          <tr>
            <td><code>WEEK</code></td>
            <td>Day is modified by 7 times the interval amount (time not affected by daylight savings time, etc.); month & year are adjusted, if overflow/underflow occurs</td>
          </tr>

          <tr>
            <td><code>DAY</code></td>
            <td>Day is modified by interval amount (time not affected by daylight savings time, etc.); date is adjusted, if overflow/underflow occurs</td>
          </tr>

          <tr>
            <td><code>HOUR</code></td>
            <td>Hours are modified by interval amount (time not affected by daylight savings time, etc.); date is adjusted, if overflow/underflow occurs</td>
          </tr>

          <tr>
            <td><code>MINUTE</code></td>
            <td>Minutes are modified by interval amount; date/time are adjusted, if overflow/underflow occurs</td>
          </tr>

          <tr>
            <td><code>SECOND</code></td>
            <td>Seconds are modified by interval amount; date/time are adjusted, if overflow/underflow occurs</td>
          </tr>

          <tr>
            <td><code>MILLISECOND</code></td>
            <td>Milliseconds are modified by interval amount; date/time are adjusted, if overflow/underflow occurs</td>
          </tr>
        </tbody>
      </table>
    </div>

    <Info>
      Any of these `unit` types can have a `SQL_TSI_` prefix prepended to them;
      e.g., both `DAY` and `SQL_TSI_DAY` are valid `unit` types for specifying a day
      interval.  They may also be single-quoted or unquoted.
    </Info>

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result *(in string format)*</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>DATEADD(YEAR, 1, '2000-10-10')</code></td>
            <td><code>2001-10-10 00:00:00.000</code></td>
          </tr>

          <tr>
            <td><code>DATEADD(QUARTER, 1, '2000-11-30')</code></td>
            <td><code>2001-02-28 00:00:00.000</code></td>
          </tr>

          <tr>
            <td><code>DATEADD(MONTH, 1, '2000-01-31')</code></td>
            <td><code>2000-02-29 00:00:00.000</code></td>
          </tr>

          <tr>
            <td><code>DATEADD(WEEK, 53, '2000-01-01')</code></td>
            <td><code>2001-01-06 00:00:00.000</code></td>
          </tr>

          <tr>
            <td><code>DATEADD(DAY, 1, '2000-12-31')</code></td>
            <td><code>2001-01-01 00:00:00.000</code></td>
          </tr>

          <tr>
            <td><code>DATEADD(HOUR, 12, '2000-10-10 12:34:56')</code></td>
            <td><code>2000-10-11 00:34:56.000</code></td>
          </tr>

          <tr>
            <td><code>DATEADD(MINUTE, 1, '2000-10-10 12:34:56')</code></td>
            <td><code>2000-10-10 12:35:56.000</code></td>
          </tr>

          <tr>
            <td><code>DATEADD(SECOND, 1, '2000-12-31 23:59:59')</code></td>
            <td><code>2001-01-01 00:00:00.000</code></td>
          </tr>

          <tr>
            <td><code>DATEADD(MILLISECOND, 1, '2000-10-10 12:34:56')</code></td>
            <td><code>2000-10-10 12:34:56.001</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="DATE_BUCKET (width, ds[, offset[, base]])" id="date_bucket-width-ds-offset-base" defaultOpen>
    Calculates the date range in which a given date `ds` falls, based on a set of
    fixed-width "buckets" with the given `width`, start-aligned `base` date, and
    `offset` from that `base` date

    The `width` is the number of days each bucket should span.

    The `offset` is the number of days after (positive `offset`) or number of days before
    (negative `offset`) the `base` date to which the buckets should be aligned.  The
    default is no offset.

    The default `base` is `2000-01-03`.

    For example, given the following call:

    ```
    DATE_BUCKET(7, ds, -3, '2023-02-21')
    ```

    The call will be processed as follows:

    * The given date `ds` will be slotted into a date bucket
    * The bucket will span a range of `7` days
    * The baseline bucket will start at `2023-02-18` (`2023-02-21` offset by `-3` days)
      and continue through `2023-02-24` (`7` days, including `2023-02-18`)
    * Buckets will extend before & after the baseline bucket in contiguous, non-overlapping
      fashion
    * The result record will show the date at the beginning of the bucket's date range
  </Accordion>

  <Accordion title="DATEDIFF ([unit,] begin, end)" id="datediff-unit-begin-end" defaultOpen>
    Calculates the difference between two date/time expressions, returning the result as an
    integral difference in the units specified; more precisely, how many whole date/time
    intervals of type `unit` need to be added to (or subtracted from) `begin` to equal
    `end` (or get as close as possible **without** going past it) using the unit types and
    the rules specified in `TIMESTAMPADD`.

    The default `unit` is `DAY`.

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>DATEDIFF('2000-10-10', '2000-12-31')</code></td>
            <td><code>82</code></td>
          </tr>

          <tr>
            <td><code>DATEDIFF('2000-03-31', '2000-04-30')</code></td>
            <td><code>30</code></td>
          </tr>

          <tr>
            <td><code>DATEDIFF('2000-12-31', '2000-10-10')</code></td>
            <td><code>-82</code></td>
          </tr>

          <tr>
            <td><code>DATEDIFF('2000-10-10 12:34:56.789', 978222896678)</code></td>
            <td><code>81</code></td>
          </tr>

          <tr>
            <td><code>DATEDIFF(MONTH, '2000-10-10', '2000-12-31')</code></td>
            <td><code>2</code></td>
          </tr>

          <tr>
            <td><code>DATEDIFF(MONTH, '2000-03-31', '2000-04-30')</code></td>
            <td><code>0</code></td>
          </tr>

          <tr>
            <td><code>DATEDIFF(MONTH, '2000-12-31', '2000-10-10')</code></td>
            <td><code>-2</code></td>
          </tr>

          <tr>
            <td><code>DATEDIFF(HOUR, '2000-10-10 12:34:56.789', 978222896678)</code></td>
            <td><code>1955</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="DATEPART(part, expr)" id="datepart-part-expr" defaultOpen>
    Returns the requested `part` of the date/time `expr`.  The `part` may be any of
    those specified in `DATE_TRUNC(part, expr)`, plus the following:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Constant</th>
            <th>Description</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>SECS\_SINCE\_EPOCH</code></td>
            <td>Return the number of seconds since the epoch (1970-01-01).</td>
          </tr>

          <tr>
            <td><code>MSECS\_SINCE\_EPOCH</code></td>
            <td>Return the number of milliseconds since the epoch.</td>
          </tr>
        </tbody>
      </table>
    </div>

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>DATEPART(YEAR, '2000-12-31')</code></td>
            <td><code>2000</code></td>
          </tr>

          <tr>
            <td><code>DATEPART(MONTH, '2000-03-31 12:34:56.000')</code></td>
            <td><code>3</code></td>
          </tr>

          <tr>
            <td><code>DATEPART(DAY, '2000-03-31 12:34:56.000')</code></td>
            <td><code>31</code></td>
          </tr>

          <tr>
            <td><code>DATEPART(SECOND, '2000-03-31 12:34:56.220')</code></td>
            <td><code>56</code></td>
          </tr>

          <tr>
            <td><code>DATEPART(MSECS\_SINCE\_EPOCH, '2000-03-31 12:34:56.220')</code></td>
            <td><code>954506096220</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="DATE_TRUNC(part, expr)" id="date_trunc-part-expr" defaultOpen>
    Returns the date/time `expr` after truncating it beyond the given date/time `part`.
    The following date/time constants are supported for `part`:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Constant</th>
            <th>Description</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>YEAR</code></td>
            <td>Return the first day of the year in which <code>expr</code> occurs</td>
          </tr>

          <tr>
            <td><code>QUARTER</code></td>
            <td>Return the first day of the quarter in which <code>expr</code> occurs</td>
          </tr>

          <tr>
            <td><code>MONTH</code></td>
            <td>Return the first day of the month in which <code>expr</code> occurs</td>
          </tr>

          <tr>
            <td><code>WEEK</code></td>
            <td>Return the first day of the week in which <code>expr</code> occurs</td>
          </tr>

          <tr>
            <td><code>DAY</code></td>
            <td>Return the date (at midnight) on which <code>expr</code> occurs</td>
          </tr>

          <tr>
            <td><code>HOUR</code></td>
            <td>Return the timestamp up to the hour in which <code>expr</code> occurs</td>
          </tr>

          <tr>
            <td><code>MINUTE</code></td>
            <td>Return the timestamp up to the minute in which <code>expr</code> occurs</td>
          </tr>

          <tr>
            <td><code>SECOND</code></td>
            <td>Return the timestamp up to the second in which <code>expr</code> occurs</td>
          </tr>

          <tr>
            <td><code>MILLISECOND</code></td>
            <td>Return the timestamp up to the millisecond in which <code>expr</code> occurs</td>
          </tr>
        </tbody>
      </table>
    </div>

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>DATE\_TRUNC(YEAR, '2008-09-10 12:34:56.789')</code></td>
            <td><code>2008-01-01 00:00:00.000</code></td>
          </tr>

          <tr>
            <td><code>DATE\_TRUNC(QUARTER, '2008-09-10 12:34:56.789')</code></td>
            <td><code>2008-07-01 00:00:00.000</code></td>
          </tr>

          <tr>
            <td><code>DATE\_TRUNC(MONTH, '2008-09-10 12:34:56.789')</code></td>
            <td><code>2008-09-01 00:00:00.000</code></td>
          </tr>

          <tr>
            <td><code>DATE\_TRUNC(WEEK, '2008-09-10 12:34:56.789')</code></td>
            <td><code>2008-09-07 00:00:00.000</code></td>
          </tr>

          <tr>
            <td><code>DATE\_TRUNC(DAY, '2008-09-10 12:34:56.789')</code></td>
            <td><code>2008-09-10 00:00:00.000</code></td>
          </tr>

          <tr>
            <td><code>DATE\_TRUNC(HOUR, '2008-09-10 12:34:56.789')</code></td>
            <td><code>2008-09-10 12:00:00.000</code></td>
          </tr>

          <tr>
            <td><code>DATE\_TRUNC(MINUTE, '2008-09-10 12:34:56.789')</code></td>
            <td><code>2008-09-10 12:34:00.000</code></td>
          </tr>

          <tr>
            <td><code>DATE\_TRUNC(SECOND, '2008-09-10 12:34:56.789')</code></td>
            <td><code>2008-09-10 12:34:56.000</code></td>
          </tr>

          <tr>
            <td><code>DATE\_TRUNC(MILLISECOND, '2008-09-10 12:34:56.789')</code></td>
            <td><code>2008-09-10 12:34:56.789</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="DAY(expr)" id="day-expr" defaultOpen>
    Alias for `DAYOFMONTH(expr)`
  </Accordion>

  <Accordion title="DAYNAME(expr)" id="dayname-expr" defaultOpen>
    Extracts the day of the week from `expr` and converts it to the corresponding day name
    \[`Sunday` - `Saturday` ]
  </Accordion>

  <Accordion title="DAYOFMONTH(expr)" id="dayofmonth-expr" defaultOpen>
    Extracts the day of the month from `expr` \[`1` - `31`]
  </Accordion>

  <Accordion title="DAYOFWEEK(expr)" id="dayofweek-expr" defaultOpen>
    Extracts the day of the week from `expr` \[`1` - `7`]

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Expression Value</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td>Date on *Sunday*</td>
            <td><code>1</code></td>
          </tr>

          <tr>
            <td>Date on *Monday*</td>
            <td><code>2</code></td>
          </tr>

          <tr>
            <td>Date on *Tuesday*</td>
            <td><code>3</code></td>
          </tr>

          <tr>
            <td>Date on *Wednesday*</td>
            <td><code>4</code></td>
          </tr>

          <tr>
            <td>Date on *Thursday*</td>
            <td><code>5</code></td>
          </tr>

          <tr>
            <td>Date on *Friday*</td>
            <td><code>6</code></td>
          </tr>

          <tr>
            <td>Date on *Saturday*</td>
            <td><code>7</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="DAY_OF_WEEK(expr)" id="day_of_week-expr" defaultOpen>
    Alias for `DAYOFWEEK(expr)`
  </Accordion>

  <Accordion title="DAYOFYEAR(expr)" id="dayofyear-expr" defaultOpen>
    Extracts the day of the year from `expr` \[`1` - `366`]
  </Accordion>

  <Accordion title="DAY_OF_YEAR(expr)" id="day_of_year-expr" defaultOpen>
    Alias for `DAYOFYEAR(expr)`
  </Accordion>

  <Accordion title="EPOCH_MSECS_TO_DATETIME(expr)" id="epoch_msecs_to_datetime-expr" defaultOpen>
    Converts `expr` milliseconds since the epoch to a date/time

    Example:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <tbody>
          <tr>
            <td>**Function Call**</td>
            <td><code>EPOCH\_MSECS\_TO\_DATETIME(971181296789)</code></td>
          </tr>

          <tr>
            <td>**Return**</td>
            <td><code>2000-10-10 12:34:56.789</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="EPOCH_SECS_TO_DATETIME(expr)" id="epoch_secs_to_datetime-expr" defaultOpen>
    Converts `expr` seconds since the epoch to a date/time

    Example:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <tbody>
          <tr>
            <td>**Function Call**</td>
            <td><code>EPOCH\_SECS\_TO\_DATETIME(971181296)</code></td>
          </tr>

          <tr>
            <td>**Return**</td>
            <td><code>2000-10-10 12:34:56.000</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="HOUR(expr)" id="hour-expr" defaultOpen>
    Extracts the hour of the day from `expr` \[`0` - `23`]
  </Accordion>

  <Accordion title="LAST_DAY(expr)" id="last_day-expr" defaultOpen>
    Returns the date of the last day of the month in the given `expr`
  </Accordion>

  <Accordion title="MINUTE(expr)" id="minute-expr" defaultOpen>
    Extracts the minute of the day from `expr` \[`0` - `59`]
  </Accordion>

  <Accordion title="MONTH(expr)" id="month-expr" defaultOpen>
    Extracts the month of the year from `expr` \[`1` - `12`]
  </Accordion>

  <Accordion title="MONTHNAME(expr)" id="monthname-expr" defaultOpen>
    Extracts the month of the year from `expr` and converts it to the corresponding month
    name \[ `January` - `December`]
  </Accordion>

  <Accordion title="MSEC(expr)" id="msec-expr" defaultOpen>
    Extracts the millisecond of the second from `expr` \[`0` - `999`]
  </Accordion>

  <Accordion title="MSECS_SINCE_EPOCH(expr)" id="msecs_since_epoch-expr" defaultOpen>
    Converts `expr` date/time to the number of milliseconds since the epoch

    Example:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <tbody>
          <tr>
            <td>**Function Call**</td>
            <td><code>MSECS\_SINCE\_EPOCH('2000-10-10 12:34:56.789')</code></td>
          </tr>

          <tr>
            <td>**Return**</td>
            <td><code>971181296789</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="NEXT_DAY(date, expr)" id="next_day-date-expr" defaultOpen>
    Returns the date of the next day of the week, provided as a day name in `expr`, that
    occurs after the given `date`

    Some examples, given that *2000-10-10* is a *Tuesday*:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>NEXT\_DAY('2000-10-10', 'Wednesday')</code></td>
            <td><code>2000-10-11</code></td>
          </tr>

          <tr>
            <td><code>NEXT\_DAY('2000-10-10', 'Friday')</code></td>
            <td><code>2000-10-13</code></td>
          </tr>

          <tr>
            <td><code>NEXT\_DAY('2000-10-10', 'Tuesday')</code></td>
            <td><code>2000-10-17</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="NOW()" id="now" defaultOpen>
    Alias for `CURRENT_DATETIME()`
  </Accordion>

  <Accordion title="QUARTER(expr)" id="quarter-expr" defaultOpen>
    Extracts the quarter of the year from `expr` \[`1` - `4`]

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Expression Value</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td>Date in *January*, *February*, or *March*</td>
            <td><code>1</code></td>
          </tr>

          <tr>
            <td>Date in *April*, *May*, or *June*</td>
            <td><code>2</code></td>
          </tr>

          <tr>
            <td>Date in *July*, *August*, or *September*</td>
            <td><code>3</code></td>
          </tr>

          <tr>
            <td>Date in *October*, *November*, or *December*</td>
            <td><code>4</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="SEC(expr)" id="sec-expr" defaultOpen>
    Alias for `SECOND(expr)`
  </Accordion>

  <Accordion title="SECOND(expr)" id="second-expr" defaultOpen>
    Extracts the seconds of the minute from `expr` \[ `0` - `59` ]
  </Accordion>

  <Accordion title="SECS_SINCE_EPOCH(expr)" id="secs_since_epoch-expr" defaultOpen>
    Converts `expr` date/time to the number of seconds since the epoch

    Example:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <tbody>
          <tr>
            <td>**Function Call**</td>
            <td><code>SECS\_SINCE\_EPOCH('2000-10-10 12:34:56')</code></td>
          </tr>

          <tr>
            <td>**Return**</td>
            <td><code>971181296</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="SLEEP(expr)" id="sleep-expr" defaultOpen>
    Pause execution for at least `expr` seconds, though system load may delay the return
    from this call for longer than the specified amount.  Use a decimal for `expr` to pause
    for less than a second; e.g., `SLEEP(0.001)` will pause for at least 1 millisecond.
    `SLEEP` should be invoked without a table reference in the call to avoid being called
    for every record in a result set; e.g., in Python:

    ```
    db.get_records_by_column('', 'SLEEP(0.001)')
    ```
  </Accordion>

  <Accordion title="TIMEBOUNDARYDIFF (unit, begin, end)" id="timeboundarydiff-unit-begin-end" defaultOpen>
    Calculates the difference between two date/time expressions, returning the result as an
    integral difference in the units specified; more precisely, how many whole date/time
    intervals of type `unit` need to be added to (or subtracted from) `begin` to equal
    `end` *up to the precision of the* `unit` *specified*, using the unit types and rules
    specified in `TIMESTAMPADD`.

    For example, if `unit` were `MONTH`, only the year & month of `begin` and `end`
    would be used in the calculation; if `unit` were `DAY`, any time portion from
    `begin` & `end` would be dropped, and so on.  This is unlike `TIMESTAMPDIFF`, which
    will consider the entirety of both `begin` & `end` in the calculation.

    <Info>
      This *is* symmetric with `TIMESTAMPADD` in all cases, as adding *1* `MONTH`
      to *Mar 31st* results in *Apr 30th*, and the `TIMEBOUNDARYDIFF` in `MONTH` units
      between those two dates is *1*.
    </Info>

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>TIMEBOUNDARYDIFF(MONTH, DATE('2000-10-10'), DATE('2000-12-31'))</code></td>
            <td><code>2</code></td>
          </tr>

          <tr>
            <td><code>TIMEBOUNDARYDIFF(MONTH, DATE('2000-03-31'), DATE('2000-04-30'))</code></td>
            <td><code>1</code></td>
          </tr>

          <tr>
            <td><code>TIMEBOUNDARYDIFF(MONTH, DATE('2000-12-31'), DATE('2000-10-10'))</code></td>
            <td><code>-2</code></td>
          </tr>

          <tr>
            <td><code>TIMEBOUNDARYDIFF(HOUR, 978222896000, DATETIME('2000-10-10 12:34:56'))</code></td>
            <td><code>-1956</code></td>
          </tr>
        </tbody>
      </table>
    </div>

    <Note>
      This function does not work with string literal date stamps
      (e.g., `2000-12-31 12:34:56`); to use string literals in this function, first cast
      them to the appropriate date/time type (e.g., `DATETIME('YYYY-MM-DD HH24:MI:SS')`)
    </Note>
  </Accordion>

  <Accordion title="TIME_BUCKET (width, ts[, offset[, base]])" id="time_bucket-width-ts-offset-base" defaultOpen>
    Calculates the date/time range in which a given timestamp `ts` falls, based on a set of
    fixed-width "buckets" with the given `width`, start-aligned `base` date/time, and
    `offset` from that `base` date/time

    The `width` is the number of milliseconds each bucket should span.

    The `offset` is the number of milliseconds after (positive `offset`) or number of
    milliseconds before (negative `offset`) the `base` date/time to which the buckets
    should be aligned.  The default is no offset.

    The default `base` is `2000-01-03 00:00:00`.

    For example, given the following call:

    ```
    TIME_BUCKET(5 * 60 * 1000, ts, -2.5 * 60 * 1000, '2023-02-28')
    ```

    The call will be processed as follows:

    * The given timestamp `ts` will be slotted into a date/time bucket
    * The bucket will span a range of `5` minutes
    * The baseline bucket will start at `2023-02-27 23:57:30` (`2023-02-28` offset by
      `-2.5` minutes) and continue through `2023-02-28 00:02:30` (`5` minutes from
      `2023-02-27 23:57:30`)
    * Buckets will extend before & after the baseline bucket in contiguous, non-overlapping
      fashion
    * The result record will show the timestamp at the beginning of the bucket's range
  </Accordion>

  <Accordion title="TIMESTAMPADD (unit, amount, expr)" id="timestampadd-unit-amount-expr" defaultOpen>
    Adds the positive or negative integral `amount` of `unit` date/time intervals to the
    `date`, `datetime`, or `time` value in `expr`

    The following date/time intervals are supported for `unit`:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Constant</th>
            <th>Description</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>YEAR</code></td>
            <td>Year is modified by interval amount (not affected by leap year, etc.) overflow/underflow occurs</td>
          </tr>

          <tr>
            <td><code>QUARTER</code></td>
            <td>Month is modified by three times the interval amount, irrespective of the number of days in the months between; day adjusting performed the same as the <code>MONTH</code> description, but only on final month (e.g., *Jan 31st* + *1 quarter* will be *Apr 30th*, not *Apr 28th* because of *February*)</td>
          </tr>

          <tr>
            <td><code>MONTH</code></td>
            <td>Month is modified by interval amount and date adjusted if overflow/underflow occurs; day adjusted to last day of calculated month if not a valid day for that month (e.g., *Apr 31st* -> *Apr 30th*)</td>
          </tr>

          <tr>
            <td><code>WEEK</code></td>
            <td>Day is modified by 7 times the interval amount (time not affected by daylight savings time, etc.); month & year are adjusted, if overflow/underflow occurs</td>
          </tr>

          <tr>
            <td><code>DAY</code></td>
            <td>Day is modified by interval amount (time not affected by daylight savings time, etc.); date is adjusted, if overflow/underflow occurs</td>
          </tr>

          <tr>
            <td><code>HOUR</code></td>
            <td>Hours are modified by interval amount (time not affected by daylight savings time, etc.); date is adjusted, if overflow/underflow occurs</td>
          </tr>

          <tr>
            <td><code>MINUTE</code></td>
            <td>Minutes are modified by interval amount; date/time are adjusted, if overflow/underflow occurs</td>
          </tr>

          <tr>
            <td><code>SECOND</code></td>
            <td>Seconds are modified by interval amount; date/time are adjusted, if overflow/underflow occurs</td>
          </tr>

          <tr>
            <td><code>MILLISECOND</code></td>
            <td>Milliseconds are modified by interval amount; date/time are adjusted, if overflow/underflow occurs</td>
          </tr>
        </tbody>
      </table>
    </div>

    <Info>
      Any of these `unit` types can have a `SQL_TSI_` prefix prepended to them;
      e.g., both `DAY` and `SQL_TSI_DAY` are valid `unit` types for specifying a day
      interval.  They may also be single-quoted or unquoted.
    </Info>

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result *(in string format)*</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>TIMESTAMPADD(YEAR, 1, '2000-10-10')</code></td>
            <td><code>2001-10-10</code></td>
          </tr>

          <tr>
            <td><code>TIMESTAMPADD(QUARTER, 1, '2000-11-30')</code></td>
            <td><code>2001-02-28</code></td>
          </tr>

          <tr>
            <td><code>TIMESTAMPADD(MONTH, 1, '2000-01-31')</code></td>
            <td><code>2000-02-29</code></td>
          </tr>

          <tr>
            <td><code>TIMESTAMPADD(WEEK, 53, '2000-01-01')</code></td>
            <td><code>2001-01-06</code></td>
          </tr>

          <tr>
            <td><code>TIMESTAMPADD(DAY, 1, '2000-12-31')</code></td>
            <td><code>2001-01-01</code></td>
          </tr>

          <tr>
            <td><code>TIMESTAMPADD(HOUR, 12, '2000-10-10 12:34:56')</code></td>
            <td><code>2000-10-11 00:34:56.000</code></td>
          </tr>

          <tr>
            <td><code>TIMESTAMPADD(MINUTE, 1, '2000-10-10 12:34:56')</code></td>
            <td><code>2000-10-10 12:35:56.000</code></td>
          </tr>

          <tr>
            <td><code>TIMESTAMPADD(SECOND, 1, '2000-12-31 23:59:59')</code></td>
            <td><code>2001-01-01 00:00:00.000</code></td>
          </tr>

          <tr>
            <td><code>TIMESTAMPADD(MILLISECOND, 1, '2000-10-10 12:34:56')</code></td>
            <td><code>2000-10-10 12:34:56.001</code></td>
          </tr>

          <tr>
            <td><code>TIMESTAMPADD(SECOND, 1, TIME('12:34:56'))</code></td>
            <td><code>12:34:57.000</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="TIMESTAMPDIFF (unit, begin, end)" id="timestampdiff-unit-begin-end" defaultOpen>
    Calculates the difference between two date/time expressions, returning the result as an
    integral difference in the units specified; more precisely, how many whole date/time
    intervals of type `unit` need to be added to  (or subtracted from) `begin` to equal
    `end` (or get as close as possible **without** going past it) using the unit types and
    and rules specified in `TIMESTAMPADD`.

    Unlike `TIMEBOUNDARYDIFF`, all date/time components of both `begin` & `end` will be
    considered in the calculation, not just those that are up to the precision of `unit`.

    <Info>
      This *is not* symmetric with `TIMESTAMPADD` in all cases, as adding *1*
      `MONTH` to *Mar 31st* results in *Apr 30th*, but the `TIMESTAMPDIFF` in `MONTH`
      units between those two dates is *0*.
    </Info>

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>TIMESTAMPDIFF(MONTH, DATETIME('2000-10-10 01:23:45.678'), DATETIME('2000-12-31 12:34:56.789'))</code></td>
            <td><code>2</code></td>
          </tr>

          <tr>
            <td><code>TIMESTAMPDIFF(MONTH, DATETIME('2000-03-31 01:23:45.678'), DATETIME('2000-04-30 12:34:56.789'))</code></td>
            <td><code>0</code></td>
          </tr>

          <tr>
            <td><code>TIMESTAMPDIFF(MONTH, DATETIME('2000-12-31 01:23:45.678'), DATETIME('2000-10-10 12:34:56.789'))</code></td>
            <td><code>-2</code></td>
          </tr>

          <tr>
            <td><code>TIMESTAMPDIFF(HOUR, DATETIME('2000-10-10 12:34:56.789'), TIMESTAMP(978222896678))</code></td>
            <td><code>1955</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="TIMESTAMP_TRUNC(part, expr)" id="timestamp_trunc-part-expr" defaultOpen>
    Alias for `DATE_TRUNC(part, expr)`
  </Accordion>

  <Accordion title="UNIX_TIMESTAMP(expr)" id="unix_timestamp-expr" defaultOpen>
    Alias for `SECS_SINCE_EPOCH(expr)`
  </Accordion>

  <Accordion title="WEEK(expr)" id="week-expr" defaultOpen>
    Extracts the week of the year from `expr` \[`1` - `54`]; each full week starts on
    *Sunday* (A `1` is returned for the week containing *Jan 1st*)
  </Accordion>

  <Accordion title="YEAR(expr)" id="year-expr" defaultOpen>
    Extracts the year from `expr`; 4-digit year, A.D.
  </Accordion>
</AccordionGroup>

<a id="expression-functions-datetime-complex" />

#### Date/Time Complex Conversion Functions

<AccordionGroup>
  <Accordion title="DATE_TO_EPOCH_MSECS (year, month, day, hour, min, sec, msec)" id="date_to_epoch_msecs-year-month-day-hour-min-sec-msec" defaultOpen>
    Converts the full date to the number of milliseconds since the epoch

    Example:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <tbody>
          <tr>
            <td>**Function Call**</td>
            <td><code>DATE\_TO\_EPOCH\_MSECS(2017, 06, 15, 09, 22, 15, 42)</code></td>
          </tr>

          <tr>
            <td>**Return**</td>
            <td><code>1497518535042</code></td>
          </tr>

          <tr>
            <td>**Resolves To**</td>
            <td>*Thursday, June 15, 2017 9:22:15.042 AM*</td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="DATE_TO_EPOCH_SECS (year, month, day, hour, min, sec)" id="date_to_epoch_secs-year-month-day-hour-min-sec" defaultOpen>
    Converts the full date to the number of seconds since the epoch

    Example:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <tbody>
          <tr>
            <td>**Function Call**</td>
            <td><code>DATE\_TO\_EPOCH\_SECS(2017, 06, 15, 09, 22, 15)</code></td>
          </tr>

          <tr>
            <td>**Return**</td>
            <td><code>1494926535</code></td>
          </tr>

          <tr>
            <td>**Resolves To**</td>
            <td>*Thursday, June 15, 2017 9:22:15.042 AM*</td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="TIMESTAMP_FROM_DATE_TIME (date, time)" id="timestamp_from_date_time-date-time" defaultOpen>
    Converts the given date and time to a composite timestamp in milliseconds
    since the epoch

    Example:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <tbody>
          <tr>
            <td>**Function Call**</td>
            <td><code>TIMESTAMP\_FROM\_DATE\_TIME('2017-06-15', '10:37:30')</code></td>
          </tr>

          <tr>
            <td>**Return**</td>
            <td><code>1497523050000</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="WEEK_TO_EPOCH_MSECS (year, week_number)" id="week_to_epoch_msecs-year-week_number" defaultOpen>
    Converts the year and week number to the number of milliseconds since the
    epoch; negative values are accepted

    Example:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <tbody>
          <tr>
            <td>**Function Call**</td>
            <td><code>WEEK\_TO\_EPOCH\_MSECS(2017,-32)</code></td>
          </tr>

          <tr>
            <td>**Return**</td>
            <td><code>1463270400000</code></td>
          </tr>

          <tr>
            <td>**Resolves To**</td>
            <td>*Sunday, May 15, 2016 12:00:00 AM*</td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="WEEK_TO_EPOCH_SECS (year, week_number)" id="week_to_epoch_secs-year-week_number" defaultOpen>
    Converts the year and week number to the number of seconds since the epoch.
    Negative values are accepted.  Each new week begins Sunday at midnight.

    Example:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <tbody>
          <tr>
            <td>**Function Call**</td>
            <td><code>WEEK\_TO\_EPOCH\_SECS(2017,-32)</code></td>
          </tr>

          <tr>
            <td>**Return**</td>
            <td><code>1463270400</code></td>
          </tr>

          <tr>
            <td>**Resolves To**</td>
            <td>*Sunday, May 15, 2016 12:00:00 AM*</td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>
</AccordionGroup>

<a id="geospatial-functions" />

<a id="expression-functions-geo" />

### Geospatial/Geometry Functions

Five types of geospatial functions are available in Kinetica:

* Scalar Functions - apply a geospatial function at the record level to WKT or
  X/Y data
* Enhanced Performance Scalar Functions - apply performance-optimized
  geospatial functions to X/Y data
* Aggregate Functions - apply a geospatial function across groups of records to
  WKT or X/Y data
* Track Functions - apply scalar & aggregate functions to
  [track-based data](/content/location_intelligence/geo_objects#geospatial-tracks)
* H3 Functions - apply H3 gridding functions to WKT or X/Y data

<Tip>
  - Use `ST_ISVALID` to determine if a geometry object is valid. The
    functions below work best with valid geometry objects.
  - Use the `REMOVE_NULLABLE` [function](/content/concepts/expressions#null-expression-functions) to
    remove any `nullable` column types that could result from calculating a
    derived column (e.g., as in [Projections](/content/concepts/projections)) using one of the
    functions below.
</Tip>

<a id="expression-functions-geo-scalar-ep" />

#### Enhanced Performance Scalar Functions

The functions below all compare `x` and `y` coordinates to geometry objects
(or vice versa), thus increasing their performance in queries. Each of these
functions have a geometry-to-geometry version listed in the next section.

<AccordionGroup>
  <Accordion title="STXY_CONTAINS(geom, x, y)" id="stxy_contains-geom-x-y" defaultOpen>
    Returns `1` (true) if `geom` contains the `x` and `y` coordinate, e.g. lies in the interior
    of `geom`. The coordinate cannot be on the boundary and also be contained because `geom` does not
    contain its boundary
  </Accordion>

  <Accordion title="STXY_CONTAINSPROPERLY(geom, x, y)" id="stxy_containsproperly-geom-x-y" defaultOpen>
    Returns `1` (true) if the `x` and `y` coordinate intersects the interior of `geom` but not
    the boundary (or exterior) because `geom` does not contain its boundary but does contain itself
  </Accordion>

  <Accordion title="STXY_COVEREDBY(x, y, geom)" id="stxy_coveredby-x-y-geom" defaultOpen>
    Returns `1` (true) if the `x` and `y` coordinate is covered by `geom`
  </Accordion>

  <Accordion title="STXY_COVERS(geom, x, y)" id="stxy_covers-geom-x-y" defaultOpen>
    Returns `1` (true) if `geom` covers the `x` and `y` coordinate
  </Accordion>

  <Accordion title="STXY_DISJOINT(x, y, geom)" id="stxy_disjoint-x-y-geom" defaultOpen>
    Returns `1` (true) if the given `x` and `y` coordinate and the geometry `geom` do not
    spatially intersect.
  </Accordion>

  <Accordion title="STXY_DISTANCE (x, y, geom[, solution])" id="stxy_distance-x-y-geom-solution" defaultOpen>
    Calculates the minimum distance between the given `x` and `y` coordinate and `geom` using the
    specified solution type. Solution types available:

    * `0` (default) - Euclidean; returns 2-D Euclidean distance
    * `1` - Haversine; returns minimum sphere distance in meters
    * `2` - Vincenty; returns minimum spheroid distance in meters, more accurate than Haversine but
      slower performance

    <Info>
      If the `x` and `y` coordinate and `geom` intersect (verify using `ST_INTERSECTS`),
      the distance will always be `0`.
    </Info>
  </Accordion>

  <Accordion title="STXY_DWITHIN (x, y, geom, distance[, solution])" id="stxy_dwithin-x-y-geom-distance-solution" defaultOpen>
    Returns `1` (true) if the `x` and `y` coordinate is within the specified `distance` from
    `geom` using the specified solution type. Solution types available:

    * `0` (default) - Euclidean; uses degrees to calculate distance
    * `1` - Sphere; uses meters to calculate sphere distance
    * `2` - Spheroid; uses meters to calculate spheroid distance
  </Accordion>

  <Accordion title="STXY_ENVDWITHIN (x, y, geom, distance[, solution])" id="stxy_envdwithin-x-y-geom-distance-solution" defaultOpen>
    Returns `1` (true) if the `x` and `y` coordinate is within the specified `distance` from the
    bounding box of `geom` using the specified solution type. Solution types available:

    * `0` (default) - Euclidean; uses degrees to calculate distance
    * `1` - Sphere; uses meters to calculate distance
  </Accordion>

  <Accordion title="STXY_ENVINTERSECTS(x, y, geom)" id="stxy_envintersects-x-y-geom" defaultOpen>
    Returns `1` (true) if the bounding box of the given geometry `geom` intersects the `x` and
    `y` coordinate.
  </Accordion>

  <Accordion title="STXY_GEOHASH(x, y[, precision])" id="stxy_geohash-x-y-precision" defaultOpen>
    Returns a hash string representation of the given `x` and `y` coordinates with specified
    `precision` (the length of the resulting geohash string). The longer the `precision`, the more
    precise the hash is. By default, `precision` is set to `20`; the max for `precision` is `32`.

    See [Geohash](/content/snippets/geohash) for an example.
  </Accordion>

  <Accordion title="STXY_H3(x, y, resolution)" id="stxy_h3-x-y-resolution" defaultOpen>
    Alias for `H3_XYTOCELL`; see [H3 Functions](/content/location_intelligence/geo_functions#geo-functions-h3).
  </Accordion>

  <Accordion title="STXY_INTERSECTION(x, y, geom)" id="stxy_intersection-x-y-geom" defaultOpen>
    Returns the shared portion between the `x` and `y` coordinate and the given geometry `geom`,
    i.e. the point itself.
  </Accordion>

  <Accordion title="STXY_INTERSECTS(x, y, geom)" id="stxy_intersects-x-y-geom" defaultOpen>
    Returns `1` (true) if the `x` and `y` coordinate and `geom` intersect in 2-D.
  </Accordion>

  <Accordion title="STXY_TOUCHES(x, y, geom)" id="stxy_touches-x-y-geom" defaultOpen>
    Returns `1` (true) if the `x` and `y` coordinate and geometry `geom` have at least one point
    in common but their interiors do not intersect. If `geom` is a GEOMETRYCOLLECTION, a `0` is
    returned regardless if the point and geometry touch
  </Accordion>

  <Accordion title="STXY_WITHIN(x, y, geom)" id="stxy_within-x-y-geom" defaultOpen>
    Returns `1` (true) if the `x` and `y` coordinate is completely inside the `geom` geometry
    i.e., not on the boundary
  </Accordion>
</AccordionGroup>

<a id="expression-functions-geo-scalar" />

#### Scalar Functions

<AccordionGroup>
  <Accordion title="DIST(x1, y1, x2, y2)" id="dist-x1-y1-x2-y2" defaultOpen>
    Computes the Euclidean distance (in degrees), i.e. `SQRT( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) )`.
  </Accordion>

  <Accordion title="GEODIST(lon1, lat1, lon2, lat2)" id="geodist-lon1-lat1-lon2-lat2" defaultOpen>
    Computes the geographic great-circle distance (in meters) between two lat/lon points.
  </Accordion>

  <Accordion title="GEOHASH_DECODE_LATITUDE(geohash)" id="geohash_decode_latitude-geohash" defaultOpen>
    Decodes a given `geohash` and returns the latitude value for the given hash string. Supports a
    maximum geohash character length of *16*.
  </Accordion>

  <Accordion title="GEOHASH_DECODE_LONGITUDE(geohash)" id="geohash_decode_longitude-geohash" defaultOpen>
    Decodes a given `geohash` and returns the longitude value for the given hash string. Supports a
    maximum geohash character length of *16*.
  </Accordion>

  <Accordion title="GEOHASH_ENCODE(lat, lon, precision)" id="geohash_encode-lat-lon-precision" defaultOpen>
    Encodes a given coordinate pair and returns a hash string with a given `precision`. The maximum `precision` is *15*.
  </Accordion>

  <Accordion title="GEOMETRY(wkt)" id="geometry-wkt" defaultOpen>
    Alias for `ST_GEOMFROMTEXT(wkt)`
  </Accordion>

  <Accordion title="ST_ADDPOINT (linestring, point[, position])" id="st_addpoint-linestring-point-position" defaultOpen>
    Adds a given `point` geometry to the given `linestring` geometry at the specified
    `position`, which is a 0-based index.  If no `position` is specified, the point will be added to the end.
  </Accordion>

  <Accordion title="ST_ALMOSTEQUALS (geom1, geom2[, decimal])" id="st_almostequals-geom1-geom2-decimal" defaultOpen>
    Returns `1` (true) if given geometries, `geom1` and `geom2`, are almost spatially equal within
    the given amount of `decimal` scale. Note that geometries will still be considered equal if the
    decimal scale for the geometries is within a half order of magnitude of each other; e.g., if
    `decimal` is set to 2, then `POINT(63.4 123.45)` and `POINT(63.4 123.454)` are equal, but
    `POINT(63.4 123.45)` and `POINT(63.4 123.459)` are *not* equal. The geometry types must match to be
    considered equal.

    If no `decimal` scale is specified, a default scale of *6* will be applied.
  </Accordion>

  <Accordion title="ST_AREA(geom[, solution])" id="st_area-geom-solution" defaultOpen>
    Returns the area of the given geometry `geom` if it is a POLYGON or MULTIPOLYGON using the
    specified solution type. Returns `0` if the input geometry type is (MULTI)POINT or
    (MULTI)LINESTRING. Solution types available:

    * `0` (default) - 2D Euclidean area
    * `1` - curved surface area on a sphere in square meters
    * `2` - curved surface area on a spheroid in square meters
  </Accordion>

  <Accordion title="ST_AZIMUTH(geom1, geom2)" id="st_azimuth-geom1-geom2" defaultOpen>
    Returns the azimuth in radians defined by the segment between two POINTs, `geom1` and `geom2`.
    Returns a `null` if the input geometry type is MULTIPOINT, (MULTI)LINESTRING, or (MULTI)POLYGON.
  </Accordion>

  <Accordion title="ST_BOUNDARY(geom)" id="st_boundary-geom" defaultOpen>
    Returns the closure of the combinatorial boundary of a given geometry `geom`. Returns an empty
    geometry if `geom` is an empty geometry. Returns a `null` if `geom` is a GEOMETRYCOLLECTION
  </Accordion>

  <Accordion title="ST_BOUNDINGDIAGONAL(geom)" id="st_boundingdiagonal-geom" defaultOpen>
    Returns the diagonal of the given geometry's (`geom`) bounding box.
  </Accordion>

  <Accordion title="ST_BUFFER (geom, radius[, style[, solution]])" id="st_buffer-geom-radius-style-solution" defaultOpen>
    Returns a geometry that represents all points whose distance from the given geometry `geom` is
    less than or equal to the given distance `radius`. The `radius` units can be specified by the
    `solution` type (default is in degrees) and the `radius` is created in the provided `style`.
    The `style` options are specified as a list of blank-separated key-value pairs, e.g.,
    `'quad_segs=8 endcap=round'`. If an empty `style` list (`''`) is provided, the default settings
    will be used. The `style` parameter must be specified to provide a `solution` type.

    Available `style` options:

    * `quad_segs` - the number of segments used to approximate a quarter circle (default is `8`)
    * `endcap` - the endcap style of the buffer (default is `round`); options are `round`,
      `flat` (or `butt`), and `square`
    * `join` - the join style of the buffer (default is `round`); options are `round`, `mitre`
      (or `miter`), and `bevel`
    * `mitre_limit` - the mitre ratio limit expressed as a floating-point number (`miter_limit` is
      also acceptable)

    Available `solution` types:

    * `0` (default) - 2D Euclidean radius distance in degrees
    * `1` - curved surface radius distance on a sphere in meters
    * `2` - curved surface radius distance on a spheroid in meters

    <Tip>
      To create a 5-meter buffer around `geom` using the default styles:
      `ST_BUFFER(geom, 5, '', 1)`. To create a 5-foot (converting feet to meters) buffer
      around `geom` using the following styles:
      `ST_BUFFER(geom, 5*0.3048,'quad_segs=4 endcap=flat', 1)`
    </Tip>
  </Accordion>

  <Accordion title="ST_BUFFERBYCOMPONENT (geom, radius[, style[, solution]])" id="st_bufferbycomponent-geom-radius-style-solution" defaultOpen>
    Returns a buffered geometry similar to the output of `ST_BUFFER` using the same parameters. The only
    difference is the buffered geometry is calculated by independently buffering each individual component
    and then the buffered components are dissolved (i.e. unioned) together to produce the final output. This
    can produce very similar (but not identical) results to `ST_BUFFER` but will often run much faster.
  </Accordion>

  <Accordion title="ST_CENTROID(geom)" id="st_centroid-geom" defaultOpen>
    Calculates the center of the given geometry `geom` as a POINT. For (MULTI)POINTs, the center is
    calculated as the average of the input coordinates. For (MULTI)LINESTRINGs, the center is calculated
    as the weighted length of each given LINESTRING. For (MULTI)POLYGONs, the center is calculated as
    the weighted area of each given POLYGON. If `geom` is an empty geometry, an empty
    GEOMETRYCOLLECTION is returned
  </Accordion>

  <Accordion title="ST_CLIP(geom1, geom2)" id="st_clip-geom1-geom2" defaultOpen>
    Returns the geometry shared between given geometries `geom1` and `geom2`
  </Accordion>

  <Accordion title="ST_CLOSESTPOINT (geom1, geom2[, solution])" id="st_closestpoint-geom1-geom2-solution" defaultOpen>
    Calculates the 2-D `POINT` in `geom1` that is closest to `geom2` using the specified solution
    type. If `geom1` or `geom2` is empty, a `null` is returned. Solution types available:

    * `0` (default) - Euclidean; calculates the closest point using 2-D Euclidean distance
    * `1` - Haversine; calculates the closest point using sphere distance in meters
    * `2` - Vincenty; returns minimum spheroid distance in meters, more accurate than Haversine but
      slower performance
  </Accordion>

  <Accordion title="ST_COLLECT(geom1, geom2)" id="st_collect-geom1-geom2" defaultOpen>
    Returns a MULTI\* or GEOMETRYCOLLECTION comprising `geom1` and `geom2`. If `geom1` and `geom2`
    are the same, singular geometry type, a MULTI\* is returned, e.g., if `geom1` and `geom2` are both
    POINTs (empty or no), a MULTIPOINT is returned. If `geom1` and `geom2` are neither the same type
    nor singular geometries, a GEOMETRYCOLLECTION is returned.
  </Accordion>

  <Accordion title="ST_COLLECTIONEXTRACT (collection, type)" id="st_collectionextract-collection-type" defaultOpen>
    Returns only the specified `type` from the given geometry `collection`. Type is a number that
    maps to the following:

    * `1` = `POINT`
    * `2` = `LINESTRING`
    * `3` = `POLYGON`
  </Accordion>

  <Accordion title="ST_COLLECTIONHOMOGENIZE(collection)" id="st_collectionhomogenize-collection" defaultOpen>
    Returns the simplest form of the given `collection`, e.g., a collection with a single POINT will
    be returned as `POINT(x y)`, and a collection with multiple individual points will be returned as a
    MULTIPOINT.
  </Accordion>

  <Accordion title="ST_CONCAVEHULL (geom, target_percent[, allow_holes])" id="st_concavehull-geom-target_percent-allow_holes" defaultOpen>
    Returns a potentially concave geometry that encloses all geometries found in the given `geom` set.
    Use `target_percent` (values between 0 and 1) to determine the percent of area of a convex hull the
    concave hull will attempt to fill; `1` will return the same geometry as an `ST_CONVEXHULL`
    operation. Set `allow_holes` to `1` (true) to allow holes in the resulting geometry; default
    value is `0` (false). Note that `allow_holes` is independent of the area of `target_percent`.
  </Accordion>

  <Accordion title="ST_CONTAINS(geom1, geom2)" id="st_contains-geom1-geom2" defaultOpen>
    Returns `1` (true) if no points of `geom2` lie in the exterior of `geom1` and at least one
    point of `geom2` lies in the interior of `geom1`. Note that `geom1` does not contain its
    boundary but does contain itself.
  </Accordion>

  <Accordion title="ST_CONTAINSPROPERLY(geom1, geom2)" id="st_containsproperly-geom1-geom2" defaultOpen>
    Returns `1` (true) if `geom2` intersects the interior of `geom1` but not the boundary
    (or exterior). Note that `geom1` does not contain its boundary but does contain itself.
  </Accordion>

  <Accordion title="ST_CONVEXHULL(geom)" id="st_convexhull-geom" defaultOpen>
    Returns the minimum convex geometry that encloses all geometries in the given `geom` set.
  </Accordion>

  <Accordion title="ST_COORDDIM(geom)" id="st_coorddim-geom" defaultOpen>
    Returns the coordinate dimension of the given `geom`, e.g., a geometry with `x`, `y`, and `z`
    coordinates would return `3`.
  </Accordion>

  <Accordion title="ST_COVEREDBY(geom1, geom2)" id="st_coveredby-geom1-geom2" defaultOpen>
    Returns `1` (true) if no point in `geom1` is outside `geom2`.
  </Accordion>

  <Accordion title="ST_COVERS(geom1, geom2)" id="st_covers-geom1-geom2" defaultOpen>
    Returns `1` (true) if no point in `geom2` is outside `geom1`.
  </Accordion>

  <Accordion title="ST_CROSSES(geom1, geom2)" id="st_crosses-geom1-geom2" defaultOpen>
    Returns `1` (true) if the given geometries, `geom1` and `geom2`, spatially cross, meaning some
    but not all interior points in common. If `geom1` and/or `geom2` are a GEOMETRYCOLLECTION, a
    `0` is returned regardless of if the two geometries cross
  </Accordion>

  <Accordion title="ST_DIFFERENCE(geom1, geom2)" id="st_difference-geom1-geom2" defaultOpen>
    Returns a geometry that represents the part of `geom1` that does not intersect with `geom2`.
  </Accordion>

  <Accordion title="ST_DIMENSION(geom)" id="st_dimension-geom" defaultOpen>
    Returns the dimension of the given geometry `geom`, which is less than or equal to the coordinate
    dimension. If `geom` is a single geometry, a `0` is for `POINT`, a `1` is for `LINESTRING`,
    and a `2` is for `POLYGON`. If `geom` is a collection, it will return the largest dimension from
    the collection. If `geom` is empty, `0` is returned.
  </Accordion>

  <Accordion title="ST_DISJOINT(geom1, geom2)" id="st_disjoint-geom1-geom2" defaultOpen>
    Returns `1` (true) if the given geometries, `geom1` and `geom2`, do not spatially intersect.
  </Accordion>

  <Accordion title="ST_DISTANCE(geom1, geom2[, solution])" id="st_distance-geom1-geom2-solution" defaultOpen>
    Calculates the minimum distance between the given geometries, `geom1` and `geom2`, using the
    specified solution type. Solution types available:

    * `0` (default) - Euclidean; returns 2-D Euclidean distance
    * `1` - Haversine; returns minimum sphere distance in meters
    * `2` - Vincenty; returns minimum spheroid distance in meters, more accurate than Haversine but
      slower performance

    <Info>
      If `geom1` and `geom2` intersect (verify using `ST_INTERSECTS`), the distance will
      always be `0`.
    </Info>
  </Accordion>

  <Accordion title="ST_DISTANCEPOINTS (x1, y1, x2, y2[, solution])" id="st_distancepoints-x1-y1-x2-y2-solution" defaultOpen>
    Calculates the minimum distance between the given points, `x1, y1` and `x2, y2`, using the
    specified solution type. Solution types available:

    * `0` (default) - Euclidean; returns 2-D Euclidean distance
    * `1` - Haversine; returns minimum sphere distance in meters
    * `2` - Vincenty; returns minimum spheroid distance in meters, more accurate than Haversine but
      slower performance
  </Accordion>

  <Accordion title="ST_DFULLYWITHIN (geom1, geom2, distance[, solution])" id="st_dfullywithin-geom1-geom2-distance-solution" defaultOpen>
    Returns `1` (true) if the maximum distance between geometries `geom1` and `geom2` is less than
    or equal to the specified `distance` of each other using the specified solution type. If `geom1`
    or `geom2` is `null`, `0` (false) is returned. Solution types available:

    * `0` (default) - Euclidean; uses degrees to calculate distance
    * `1` - Sphere; uses meters to calculate distance
    * `2` - Spheroid; uses meters to calculate distance, more accurate than sphere but slower
      performance
  </Accordion>

  <Accordion title="ST_DWITHIN (geom1, geom2, distance[, solution])" id="st_dwithin-geom1-geom2-distance-solution" defaultOpen>
    Returns `1` (true) if the minimum distance between geometries `geom1` and `geom2` is within the
    specified `distance` of each other using the specified solution type. Solution types available:

    * `0` (default) - Euclidean; uses degrees to calculate distance
    * `1` - Sphere; uses meters to calculate distance
    * `2` - Spheroid; uses meters to calculate distance, more accurate than sphere but slower
      performance
  </Accordion>

  <Accordion title="ST_ELLIPSE(x, y, height, width)" id="st_ellipse-x-y-height-width" defaultOpen>
    Returns an ellipse using the following values:

    * `x` - the x coordinate or longitude used to center the ellipse
    * `y` - the y coordinate or latitude used to center the ellipse
    * `height` - the height of the ellipse (in degrees)
    * `width` - the width of the ellipse (in degrees)
  </Accordion>

  <Accordion title="ST_ENDPOINT(geom)" id="st_endpoint-geom" defaultOpen>
    Returns the last point of the given `geom` as a POINT if it's a LINESTRING.  If `geom` is not
    a LINESTRING, `null` is returned.
  </Accordion>

  <Accordion title="ST_ENVDWITHIN (geom1, geom2, distance[, solution])" id="st_envdwithin-geom1-geom2-distance-solution" defaultOpen>
    Returns `1` (true) if `geom1` is within the specified `distance` of the bounding box of
    `geom2` using the specified solution type. Solution types available:

    * `0` (default) - Euclidean; uses degrees to calculate distance
    * `1` - Sphere; uses meters to calculate distance
  </Accordion>

  <Accordion title="ST_ENVELOPE(geom)" id="st_envelope-geom" defaultOpen>
    Returns the bounding box of a given geometry `geom`.
  </Accordion>

  <Accordion title="ST_ENVINTERSECTS(geom1, geom2)" id="st_envintersects-geom1-geom2" defaultOpen>
    Returns `1` (true) if the bounding box of the given geometries, `geom1` and `geom2`, intersect.
  </Accordion>

  <Accordion title="ST_EQUALS(geom1, geom2)" id="st_equals-geom1-geom2" defaultOpen>
    Returns `1` (true) if the given geometries, `geom1` and `geom2`, are spatially equal. Note that
    order does not matter.
  </Accordion>

  <Accordion title="ST_EQUALSEXACT (geom1, geom2[, tolerance])" id="st_equalsexact-geom1-geom2-tolerance" defaultOpen>
    Returns `1` (true) if the given geometries, `geom1` and `geom2`, are almost spatially equal
    within some given `tolerance`. If the values within the given geometries are within the
    `tolerance` value of each other, they're considered equal, e.g., if `tolerance` is 2,
    POINT(1 1) and POINT(1 3) are considered equal, but POINT(1 1) and POINT(1 3.1) are not. Note that
    the geometry types have to match for them to be considered equal.  The default `tolerance` is *0*,
    which makes this function effectively equivalent to `ST_EQUALS(geom1, geom2)` in the default case.
  </Accordion>

  <Accordion title="ST_ERASE(geom1, geom2)" id="st_erase-geom1-geom2" defaultOpen>
    Returns the result of erasing a portion of `geom1` equal to the size of `geom2`.
  </Accordion>

  <Accordion title="ST_EXPAND(geom, units)" id="st_expand-geom-units" defaultOpen>
    Returns the bounding box expanded in all directions by the given `units` of the given `geom`. The
    expansion can also be defined for separate directions by providing separate parameters for each
    direction, e.g., `ST_EXPAND(geom, unitsx, unitsy, unitsz, unitsm)`.
  </Accordion>

  <Accordion title="ST_EXPANDBYRATE(geom, rate)" id="st_expandbyrate-geom-rate" defaultOpen>
    Returns the bounding box expanded by a given `rate` (a ratio of width and height) for the given
    geometry `geom`. The `rate` must be between 0 and 1.
  </Accordion>

  <Accordion title="ST_EXTERIORRING(geom)" id="st_exteriorring-geom" defaultOpen>
    Returns a LINESTRING representing the exterior ring of the given POLYGON `geom`
  </Accordion>

  <Accordion title="ST_FORCE2D(geom)" id="st_force2d-geom" defaultOpen>
    Returns the 2-dimensional version (e.g., X and Y coordinates) of `geom`, the provided geometry or
    set of geometries (e.g., via GEOMETRYCOLLECTION or WKT column name).
  </Accordion>

  <Accordion title="ST_FORCE3D(geom[, z])" id="st_force3d-geom-z" defaultOpen>
    Returns the 3-dimensional version (e.g., X, Y, and Z coordinates) of `geom`, a provided geometry or
    set of geometries (e.g., via GEOMETRYCOLLECTION or WKT column name), using `z` as the geometry's
    new z-value. The provided z-values can also be derived from a numeric column. If no `z` is provided,
    a `0` will be applied.

    <Info>
      If a WKT column is provided for `geom` and a numeric column is provided for `z`, the z
      values will be matched to the provided geometries by row in the source table. If a singular
      geometry is provided for `geom` and a column is provided for `z`, three-dimensional
      versions of the provided geometry will be returned for each z value found in the provided
      `z` column. If columns are provided for both `geom` and `z` and nulls are present in
      either column, the row containing null values will be skipped in the results.
    </Info>
  </Accordion>

  <Accordion title="ST_GENERATEPOINTS(geom, num)" id="st_generatepoints-geom-num" defaultOpen>
    Creates a MULTIPOINT containing a number `num` of randomly generated points within the boundary of
    `geom`.
  </Accordion>

  <Accordion title="ST_GEOHASH(geom[, precision])" id="st_geohash-geom-precision" defaultOpen>
    Returns a hash string representation of the given geometry `geom` with specified `precision`
    (the length of the resulting geohash string). The longer the `precision`, the more precise the hash is. By
    default, `precision` is set to `20`; the max for `precision` is `32`. Returns `null` if
    `geom` is an empty geometry.

    See [Geohash](/content/snippets/geohash) for an example.

    <Info>
      The value returned will *not* be a geohash of the exact geometry but a geohash of the
      centroid of the given geometry
    </Info>
  </Accordion>

  <Accordion title="ST_GEOMETRYFROMTEXT(wkt)" id="st_geometryfromtext-wkt" defaultOpen>
    Alias for `ST_GEOMFROMTEXT(wkt)`
  </Accordion>

  <Accordion title="ST_GEOMETRYN(geom, index)" id="st_geometryn-geom-index" defaultOpen>
    Returns the `index` geometry back from the given `geom` geometry. The `index` starts from 1 and goes to
    the number of geometries in `geom`.
  </Accordion>

  <Accordion title="ST_GEOMETRYTYPE(geom)" id="st_geometrytype-geom" defaultOpen>
    Returns the type of geometry from the given `geom`.
  </Accordion>

  <Accordion title="ST_GEOMETRYTYPEID(geom)" id="st_geometrytypeid-geom" defaultOpen>
    Returns the type ID of from `geom`. Type and ID mappings:

    * POINT = 0
    * LINESTRING = 1
    * POLYGON = 3
    * MULTIPOINT = 4
    * MULTILINESTRING = 5
    * MULTIPOLYGON = 6
    * GEOMETRYCOLLECTION = 7
  </Accordion>

  <Accordion title="ST_GEOMFROMGEOHASH (geohash[, precision])" id="st_geomfromgeohash-geohash-precision" defaultOpen>
    Returns a POLYGON boundary box using the given `geohash` with a precision set by the integer
    `precision`. If `precision` is specified, the function will use as many characters in the hash
    equal to `precision` to create the geometry. If no `precision` is specified, the full length of
    the `geohash` is used.

    See [Geohash](/content/snippets/geohash) for an example.
  </Accordion>

  <Accordion title="ST_GEOMFROMH3(h3_index)" id="st_geomfromh3-h3_index" defaultOpen>
    Alias for `H3_CELLTOBOUNDARY`; see [H3 Functions](/content/location_intelligence/geo_functions#geo-functions-h3).
  </Accordion>

  <Accordion title="ST_GEOMFROMTEXT(wkt)" id="st_geomfromtext-wkt" defaultOpen>
    Returns a geometry from the given Well-Known text representation `wkt`. Note that this function is
    only compatible with constants.
  </Accordion>

  <Accordion title="ST_H3(wkt, resolution)" id="st_h3-wkt-resolution" defaultOpen>
    Alias for `H3_GEOMTOCELL`; see [H3 Functions](/content/location_intelligence/geo_functions#geo-functions-h3).
  </Accordion>

  <Accordion title="ST_HEXGRID (xmin, ymin, xmax, ymax, cell_side[, limit])" id="st_hexgrid-xmin-ymin-xmax-ymax-cell_side-limit" defaultOpen>
    Creates a MULTIPOLYGON containing a grid of hexagons between given minimum and maximum points of a
    bounding box. The minimum point cannot be greater than or equal to the maximum point. The size (in
    meters) of the individual hexagons' sides is determined by `cell_side`. The `cell_side` cannot be
    greater than the width or height of the bounding box. The maximum number of cells that can be
    produced is determined by `limit`, a positive integer. Supported values for `limit`:

    * `-1` - No limit to the number of cells generated (effectively limited by system memory)
    * `0` (default) - 100 million cells
    * `<n>` - Custom limit of `n` cells

    If the custom limit request specifies more cells (based on the bounding box and the `cell_side`)
    than the system limit, a `null` is returned.
  </Accordion>

  <Accordion title="ST_INTERIORRINGN(geom, n)" id="st_interiorringn-geom-n" defaultOpen>
    Returns the `n`-th interior LINESTRING ring of the POLYGON `geom`. If `geom` is not a POLYGON
    or the given `n` is out of range, a `null` is returned. The index begins at 1
  </Accordion>

  <Accordion title="ST_INTERSECTION(geom1, geom2)" id="st_intersection-geom1-geom2" defaultOpen>
    Returns the shared portion between given geometries `geom1` and `geom2`
  </Accordion>

  <Accordion title="ST_INTERSECTS(geom1, geom2)" id="st_intersects-geom1-geom2" defaultOpen>
    Returns `1` (true) if the given geometries, `geom1` and `geom2`, intersect in 2-D
  </Accordion>

  <Accordion title="ST_ISCLOSED(geom)" id="st_isclosed-geom" defaultOpen>
    Returns `1` (true) if the given geometry's (`geom`) start and end points coincide
  </Accordion>

  <Accordion title="ST_ISCOLLECTION(geom)" id="st_iscollection-geom" defaultOpen>
    Returns `1` (true) if `geom` is a collection, e.g., GEOMETRYCOLLECTION, MULTIPOINT,
    MULTILINESTRING, etc.
  </Accordion>

  <Accordion title="ST_ISEMPTY(geom)" id="st_isempty-geom" defaultOpen>
    Returns `1` (true) if `geom` is empty
  </Accordion>

  <Accordion title="ST_ISRING(geom)" id="st_isring-geom" defaultOpen>
    Returns `1` (true) if LINESTRING `geom` is both closed (per `ST_ISCLOSED`) and "simple"
    (per `ST_ISSIMPLE`). Returns `0` if `geom` is not a LINESTRING
  </Accordion>

  <Accordion title="ST_ISSIMPLE(geom)" id="st_issimple-geom" defaultOpen>
    Returns `1` (true) if `geom` has no anomalous geometric points, e.g., self-intersection or
    self-tangency
  </Accordion>

  <Accordion title="ST_ISVALID(geom)" id="st_isvalid-geom" defaultOpen>
    Returns `1` (true) if `geom` (typically a \[MULTI]POLYGON) is well formed. A POLYGON is valid if
    its rings do not cross, and its boundary intersects only at POINTs (not along a line). The POLYGON must
    also not have dangling LINESTRINGs. A MULTIPOLYGON is valid if all of its elements are also valid, and
    the interior rings of those elements do not intersect. Each element's boundaries may touch but only
    at POINTs (not along a line).  `ST_MAKEVALID(geom)` can be used to help correct invalid geometries.
  </Accordion>

  <Accordion title="ST_ISVALIDREASON(geom)" id="st_isvalidreason-geom" defaultOpen>
    Returns `Valid Geometry` if `geom` is well formed, according to `ST_ISVALID(geom)`; otherwise,
    returns the reason `geom` is determined to be malformed.  `ST_MAKEVALID(geom)` can be used to
    help correct invalid geometries.

    Example:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <tbody>
          <tr>
            <td>**Function Call**</td>
            <td><code>ST\_ISVALIDREASON('POLYGON((-1 0, 1 0, 1 1, -1 -1))')</code></td>
          </tr>

          <tr>
            <td>**Return**</td>
            <td><code>Self-intersection\[0 0]</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="ST_LENGTH(geom[, solution])" id="st_length-geom-solution" defaultOpen>
    Returns the length of the geometry if it is a LINESTRING or MULTILINESTRING. Returns `0` if
    another type of geometry, e.g., POINT, MULTIPOINT, etc. GEOMETRYCOLLECTIONs are
    also supported but the aforementioned type limitation still applies; the collection will be
    recursively searched for LINESTRINGs and MULTILINESTRINGs and the summation of all supported geometry
    types is returned (unsupported types are ignored). Solution types available:

    * `0` (default) - 2D Euclidean length
    * `1` - length on a sphere in meters
    * `2` - length on a spheroid in meters
  </Accordion>

  <Accordion title="ST_LINEFROMMULTIPOINT(geom)" id="st_linefrommultipoint-geom" defaultOpen>
    Creates a LINESTRING from `geom` if it is a MULTIPOINT. Returns `null` if `geom` is not a
    MULTIPOINT
  </Accordion>

  <Accordion title="ST_LINEINTERPOLATEPOINT(geom, frac)" id="st_lineinterpolatepoint-geom-frac" defaultOpen>
    Returns a POINT on the LINESTRING `geom` that is the `frac` fraction of the distance along the line. If `geom` is either
    empty or **not** a LINESTRING, `null` is returned
  </Accordion>

  <Accordion title="ST_LINELOCATEPOINT(linestring, point)" id="st_linelocatepoint-linestring-point" defaultOpen>
    Returns the location of the closest point in the given `linestring` to the given `point` as a
    value between `0` and `1`. The return value is a fraction of the total `linestring` length.
  </Accordion>

  <Accordion title="ST_LINEMERGE(geom)" id="st_linemerge-geom" defaultOpen>
    Returns a LINESTRING or MULTILINESTRING from a given `geom`. If `geom` is a MULTILINESTRING
    comprising LINESTRINGs with shared endpoints, a contiguous LINESTRING is returned. If `geom` is a
    LINESTRING or a MULTILINESTRING comprising LINESTRINGS without shared endpoints, `geom` is returned
    If `geom` is an empty (MULTI)LINESTRING or a (MULTI)POINT or (MULTI)POLYGON, an empty
    GEOMETRYCOLLECTION is returned.
  </Accordion>

  <Accordion title="ST_LINESUBSTRING (geom, start_frac, end_frac)" id="st_linesubstring-geom-start_frac-end_frac" defaultOpen>
    Returns the fraction of a given `geom` LINESTRING from the point that is the `start_frac` fraction of the distance along
    the line to the point that is the `end_frac` fraction of the distance along the line.

    For example, given `LINESTRING(1 1, 2 2, 3 3)` a `start_fraction` of `0` and an `end_fraction` of `0.25` would yield
    the first quarter of the given LINESTRING, or `LINESTRING(1 1, 1.5 1.5)`.

    Returns `null` in the following cases:

    * input geometry is (MULTI)POINT, MULTILINESTRING, or (MULTI)POLYGON
    * `start_frac` is greater than `end_frac`
    * `start_frac` or `end_frac` are not between `0` & `1`, inclusive
  </Accordion>

  <Accordion title="ST_LONGESTLINE (geom1, geom2[, solution])" id="st_longestline-geom1-geom2-solution" defaultOpen>
    Returns the LINESTRING that represents the longest line of points between the two geometries. If
    multiple longest lines are found, only the first line found is returned. If `geom1` or `geom2` is
    empty, `null` is returned. Solution types available:

    * `0` (default) - Euclidean; uses degrees to calculate the longest line
    * `1` - Sphere; uses meters to calculate the longest line
    * `2` - Spheroid; uses meters to calculate the longest line, more accurate than sphere but slower
      performance
  </Accordion>

  <Accordion title="ST_MAKEENVELOPE (xmin, ymin, xmax, ymax)" id="st_makeenvelope-xmin-ymin-xmax-ymax" defaultOpen>
    Creates a rectangular POLYGON from the given min and max parameters
  </Accordion>

  <Accordion title="ST_MAKELINE(geom[, geom2])" id="st_makeline-geom-geom2" defaultOpen>
    Creates a LINESTRING from `geom` if it is a MULTIPOINT. If `geom` is a POINT, there must be at
    least one other POINT to construct a LINESTRING. If `geom` is a LINESTRING, it must have at least
    two points. Returns `null` if `geom` is not a POINT, MULTIPOINT, or LINESTRING

    <Info>
      This function can be rather costly in terms of performance
    </Info>
  </Accordion>

  <Accordion title="ST_MAKEPOINT(x, y)" id="st_makepoint-x-y" defaultOpen>
    Creates a POINT at the given coordinate

    <Info>
      This function can be rather costly in terms of performance
    </Info>
  </Accordion>

  <Accordion title="ST_MAKEPOLYGON(geom)" id="st_makepolygon-geom" defaultOpen>
    Creates a POLYGON from `geom`. Inputs must be closed LINESTRINGs

    <Info>
      This function can be rather costly in terms of performance
    </Info>
  </Accordion>

  <Accordion title="ST_MAKETRIANGLE2D (x1, y1, x2, y2, x3, y3)" id="st_maketriangle2d-x1-y1-x2-y2-x3-y3" defaultOpen>
    Creates a closed 2-D POLYGON with three vertices
  </Accordion>

  <Accordion title="ST_MAKETRIANGLE3D (x1, y1, z1, x2, y2, z2, x3, y3, z3)" id="st_maketriangle3d-x1-y1-z1-x2-y2-z2-x3-y3-z3" defaultOpen>
    Creates a closed 3-D POLYGON with three vertices
  </Accordion>

  <Accordion title="ST_MAKEVALID(geom[, options])" id="st_makevalid-geom-options" defaultOpen>
    Attempts to convert `geom` into a valid geometry when it is malformed, as determined by
    `ST_ISVALID(geom)`.  Returns `geom` if it is a valid geometry already.  The method used to convert
    invalid geometries into valid ones can be specified in `options` as a space-separated string of
    `x=y` key/value pairs.  The keys and corresponding values are as follows:

    * `method` - the algorithm used to convert invalid geometries into valid ones; either:

      * `linework` (default) - build geometry from lines extracted from `geom`
      * `structure` - build geometry from interior & exterior rings extracted from `geom`

    * `keepcollapsed` - if using the `method` of `structure`, whether to drop portions of the
      converted geometry that collapse to lower dimensions:

      * `true` (default) - keep portions of geometry that collapse to lower dimensions
      * `false` - don't keep portions of geometry that collapse to lower dimensions

    Example using default *linework* method:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <tbody>
          <tr>
            <td>**Function Call**</td>
            <td><code>ST\_MAKEVALID('POLYGON((-1 0, 1 0, 1 1, -1 -1))')</code></td>
          </tr>

          <tr>
            <td>**Return**</td>
            <td><code>MULTIPOLYGON (((-1 -1, -1 0, 0 0, -1 -1)), ((1 0, 0 0, 1 1, 1 0)))</code></td>
          </tr>
        </tbody>
      </table>
    </div>

    Example using the *structure* method without dropping collapsible parts of the converted geometry:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <tbody>
          <tr>
            <td>**Function Call**</td>
            <td><code>ST\_MAKEVALID('POLYGON((0 0, 0 0, 0 0, 0 0))', 'method=structure keepcollapsed=true')</code></td>
          </tr>

          <tr>
            <td>**Return**</td>
            <td><code>POINT (0 0)</code></td>
          </tr>
        </tbody>
      </table>
    </div>

    Example using the *structure* method with dropping collapsible parts of the converted geometry:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <tbody>
          <tr>
            <td>**Function Call**</td>
            <td><code>ST\_MAKEVALID('POLYGON((0 0, 0 0, 0 0, 0 0))', 'method=structure keepcollapsed=false')</code></td>
          </tr>

          <tr>
            <td>**Return**</td>
            <td><code>POLYGON EMPTY</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="ST_MAXDISTANCE (geom1, geom2[, solution])" id="st_maxdistance-geom1-geom2-solution" defaultOpen>
    Returns the maximum distance between the given `geom1` and `geom2` geometries using the specified
    solution type. If `geom1` or `geom2` is empty, `null` is returned. Solution types available:

    * `0` (default) - returns maximum 2-D Euclidean distance
    * `1` - Sphere; returns maximum distance in meters
    * `2` - Spheroid; returns maximum distance in meters, more accurate than sphere but slower
      performance
  </Accordion>

  <Accordion title="ST_MAXX(geom)" id="st_maxx-geom" defaultOpen>
    Returns the maximum x coordinate of a bounding box for the given `geom` geometry. This function
    works for 2-D and 3-D geometries.
  </Accordion>

  <Accordion title="ST_MAXY(geom)" id="st_maxy-geom" defaultOpen>
    Returns the maximum y coordinate of a bounding box for the given `geom` geometry. This function
    works for 2-D and 3-D geometries.
  </Accordion>

  <Accordion title="ST_MAXZ(geom)" id="st_maxz-geom" defaultOpen>
    Returns the maximum z coordinate of a bounding box for the given `geom` geometry. This function
    works for 2-D and 3-D geometries.
  </Accordion>

  <Accordion title="ST_MINX(geom)" id="st_minx-geom" defaultOpen>
    Returns the minimum x coordinate of a bounding box for the given `geom` geometry. This function
    works for 2-D and 3-D geometries.
  </Accordion>

  <Accordion title="ST_MINY(geom)" id="st_miny-geom" defaultOpen>
    Returns the minimum y coordinate of a bounding box for the given `geom` geometry. This function
    works for 2-D and 3-D geometries.
  </Accordion>

  <Accordion title="ST_MINZ(geom)" id="st_minz-geom" defaultOpen>
    Returns the minimum z coordinate of a bounding box for the given `geom` geometry. This function
    works for 2-D and 3-D geometries.
  </Accordion>

  <Accordion title="ST_MULTI(geom)" id="st_multi-geom" defaultOpen>
    Returns `geom` as a MULTI- geometry, e.g., a POINT would return a MULTIPOINT.
  </Accordion>

  <Accordion title="ST_MULTIPLERINGBUFFERS (geom, distance[, outside])" id="st_multipleringbuffers-geom-distance-outside" defaultOpen>
    Creates multiple buffers at specified `distance` around the given `geom` geometry. Multiple
    distances are specified as comma-separated values in an array, e.g., `[10,20,30]`. Valid values for
    `outside` are:

    * `FULL` - indicates that buffers will overlap or cover the given `geom` geometry. This is the
      default.
    * `OUTSIDE_ONLY` - indicates that buffers will be rings around the given `geom` geometry.
  </Accordion>

  <Accordion title="ST_NDIMS(geom)" id="st_ndims-geom" defaultOpen>
    Returns the number of dimensions in `geom`.  For X,Y data, this will return 2; if a Z component is
    present, it will return 3.
  </Accordion>

  <Accordion title="ST_NEAR(geom1, geom2)" id="st_near-geom1-geom2" defaultOpen>
    Returns the portion of `geom2` that is closest to `geom1`. If `geom2` is a singular geometry
    object (e.g., POINT, LINESTRING, POLYGON), `geom2` will be returned. If `geom2` a multi-geometry,
    e.g., MULTIPOINT, MULTILINESTRING, etc., the nearest singular geometry in `geom2` will be
    returned.
  </Accordion>

  <Accordion title="ST_NORMALIZE(geom)" id="st_normalize-geom" defaultOpen>
    Returns `geom` in its normalized (canonical) form, which may rearrange the points in lexicographical
    order.
  </Accordion>

  <Accordion title="ST_NPOINTS(geom)" id="st_npoints-geom" defaultOpen>
    Returns the number of points (vertices) in `geom`.
  </Accordion>

  <Accordion title="ST_NRINGS(geom)" id="st_nrings-geom" defaultOpen>
    Returns the total number of rings (including interior rings) in `geom`.  For non-polygonal geometries,
    it will return 0. For MULTIPOLYGONs, it will return the total number of rings across all components.
  </Accordion>

  <Accordion title="ST_NUMGEOMETRIES(geom)" id="st_numgeometries-geom" defaultOpen>
    If `geom` is a collection or MULTI- geometry, returns the number of geometries. If `geom` is a
    single geometry, returns 1.
  </Accordion>

  <Accordion title="ST_NUMINTERIORRINGS(geom)" id="st_numinteriorrings-geom" defaultOpen>
    Returns the number of interior rings if `geom` is a POLYGON. Returns `null` if `geom` is
    anything else.
  </Accordion>

  <Accordion title="ST_NUMPOINTS(geom)" id="st_numpoints-geom" defaultOpen>
    Returns the number of points in the `geom` LINESTRING. Returns `null` if `geom` is not a
    LINESTRING.
  </Accordion>

  <Accordion title="ST_OVERLAPS(geom1, geom2)" id="st_overlaps-geom1-geom2" defaultOpen>
    Returns `1` (true) if given geometries `geom1` and `geom2` share space. If `geom1` and/or
    `geom2` are a GEOMETRYCOLLECTION, a `0` is returned regardless of if the two geometries overlap
  </Accordion>

  <Accordion title="ST_PARTITION(geom[, threshold])" id="st_partition-geom-threshold" defaultOpen>
    Returns a MULTIPOLYGON representing the given `geom` partitioned into a number of POLYGONs with a
    maximum number of vertices equal to the given `threshold`. Minimum value for `threshold` is
    `10`; default value is `10000`. If `geom` is not a POLYGON or MULTIPOLYGON, `geom` is
    returned. If the number of vertices in `geom` is less than the `threshold`, `geom` is returned.
  </Accordion>

  <Accordion title="ST_PERIMETER(geom[, solution])" id="st_perimeter-geom-solution" defaultOpen>
    Returns the perimeter of the geometry if it is a POLYGON or MULTIPOLYGON. Returns `0` if another
    type of geometry, e.g., POINT, MULTIPOINT, LINESTRING, or MULTILINESTRING. GEOMETRYCOLLECTIONs are
    also supported but the aforementioned type limitation still applies; the collection will be
    recursively searched for POLYGONs and MULTIPOLYGONs and the summation of all supported geometry types
    is returned (unsupported types are ignored). Solution types available:

    * `0` (default) - 2D Euclidean length
    * `1` - length on a sphere in meters
    * `2` - length on a spheroid in meters
  </Accordion>

  <Accordion title="ST_POINT(x, y)" id="st_point-x-y" defaultOpen>
    Returns a POINT with the given `x` and `y` coordinates.
  </Accordion>

  <Accordion title="ST_POINTFROMGEOHASH (geohash[, precision])" id="st_pointfromgeohash-geohash-precision" defaultOpen>
    Returns a POINT using the given `geohash` with a precision set by the integer `precision`. If
    `precision` is specified, the function will use as many characters in the hash equal to
    `precision` to create the geometry. If no `precision` is specified, the full length of
    the `geohash` is used.

    <Info>
      The POINT returned represents the center of the bounding box of the geohash
    </Info>
  </Accordion>

  <Accordion title="ST_POINTGRID (xmin, ymin, xmax, ymax, cell_side[, limit])" id="st_pointgrid-xmin-ymin-xmax-ymax-cell_side-limit" defaultOpen>
    Creates a MULTIPOLYGON containing a square-shaped grid of points between given minimum and maximum
    points of a bounding box. The minimum point cannot be greater than or equal to the maximum point. The
    distance between the points (in meters) is determined by `cell_side`. The `cell_side` cannot be
    greater than the width or height of the bounding box. The maximum number of cells that can be
    produced is determined by `limit`, a positive integer. Supported values for `limit`:

    * `-1` - No limit to the number of cells generated (effectively limited by system memory)
    * `0` (default) - 100 million cells
    * `<n>` - Custom limit of `n` cells

    If the custom limit request specifies more cells (based on the bounding box and the `cell_side`)
    than the system limit, a `null` is returned.
  </Accordion>

  <Accordion title="ST_POINTN(geom, n)" id="st_pointn-geom-n" defaultOpen>
    Returns the `n`-th point in LINESTRING `geom`. Negative values are valid, but note that they are
    counted backwards from the end of `geom`. A `null` is returned if `geom` is not a LINESTRING.
  </Accordion>

  <Accordion title="ST_POINTS(geom)" id="st_points-geom" defaultOpen>
    Returns a MULTIPOINT containing all of the coordinates of `geom`.
  </Accordion>

  <Accordion title="ST_PROJECT(geom, distance, azimuth)" id="st_project-geom-distance-azimuth" defaultOpen>
    Returns a POINT projected from a start point `geom` along a geodesic calculated using `distance`
    and `azimuth`. If `geom` is **not** a POINT, `null` is returned.
  </Accordion>

  <Accordion title="ST_REMOVEPOINT(geom, offset)" id="st_removepoint-geom-offset" defaultOpen>
    Remove a point from LINESTRING `geom` using `offset` to skip over POINTs in the LINESTRING. The
    `offset` is 0-based.
  </Accordion>

  <Accordion title="ST_REMOVEREPEATEDPOINTS (geom, tolerance)" id="st_removerepeatedpoints-geom-tolerance" defaultOpen>
    Removes points from `geom` if the point's vertices are greater than or equal to the `tolerance`
    of the previous point in the geometry's list. If `geom` is not a MULTIPOINT, MULTILINESTRING, or a
    MULTIPOLYGON, no points will be removed.
  </Accordion>

  <Accordion title="ST_REVERSE(geom)" id="st_reverse-geom" defaultOpen>
    Return the geometry with its coordinate order reversed.
  </Accordion>

  <Accordion title="ST_ROTATE(geom, radians[, wkt])" id="st_rotate-geom-radians-wkt" defaultOpen>
    Rotates `geom` counter-clockwise by `radians` radians.  Optionally, the rotation origin can be provided as a WKT POINT
    WKT POINT (`wkt`).  If not provided, `geom` will be rotated around *(0, 0)*.
  </Accordion>

  <Accordion title="ST_ROTATE(geom, radians[, x, y])" id="st_rotate-geom-radians-x-y" defaultOpen>
    Rotates `geom` counter-clockwise by `radians` radians.  Optionally, the rotation origin can be provided as a coordinate
    pair (`x` & `y`).  If not provided, `geom` will be rotated around *(0, 0)*.
  </Accordion>

  <Accordion title="ST_SCALE(geom, wkt)" id="st_scale-geom-wkt" defaultOpen>
    Scales `geom` by multiplying its respective vertices by the corresponding *x*, *y* values in the given WKT POINT.

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <tbody>
          <tr>
            <td>**Function Call**</td>
            <td><code>ST\_SCALE('POLYGON((1 2, -2 1, -1 -2, 2 -1, 1 2))', GEOMETRY('POINT(3 5)'))</code></td>
          </tr>

          <tr>
            <td>**Return**</td>
            <td><code>POLYGON ((3 10, -6 5, -3 -10, 6 -5, 3 10))</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="ST_SCALE(geom, x, y)" id="st_scale-geom-x-y" defaultOpen>
    Scales `geom` by multiplying its respective vertices by the given `x` & `y` values.

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <tbody>
          <tr>
            <td>**Function Call**</td>
            <td><code>ST\_SCALE('POLYGON((1 2, -2 1, -1 -2, 2 -1, 1 2))', 3, 5)</code></td>
          </tr>

          <tr>
            <td>**Return**</td>
            <td><code>POLYGON ((3 10, -6 5, -3 -10, 6 -5, 3 10))</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="ST_SEGMENTIZE (geom, max_segment_size[, solution])" id="st_segmentize-geom-max_segment_size-solution" defaultOpen>
    Returns the given `geom`, but segmentized *n* number of times depending on how the
    `max_segment_size` distance (in units based on the `solution` type) divides up the original
    geometry. The new `geom` is guaranteed to have segments that are smaller than the given
    `max_segment_size`. Note that POINTs are not able to be segmentized. Collection geometries
    (GEOMETRYCOLLECTION, MULTILINESTRING, MULTIPOINT, etc.) can be segmentized, but only the individual
    parts will be segmentized, not the collection as a whole. Solution types available:

    * `0` - Euclidean; uses degrees to calculate distance
    * `1` (default) - Sphere; uses meters to calculate distance
  </Accordion>

  <Accordion title="ST_SETPOINT(geom1, position, geom2)" id="st_setpoint-geom1-position-geom2" defaultOpen>
    Replace a point of LINESTRING `geom1` with POINT `geom2` at `position` (base 0). Negative
    values are valid, but note that they are counted backwards from the end of `geom`.
  </Accordion>

  <Accordion title="ST_SHAREDPATH(geom1, geom2)" id="st_sharedpath-geom1-geom2" defaultOpen>
    Returns a collection containing paths shared by `geom1` and `geom2`.
  </Accordion>

  <Accordion title="ST_SHORTESTLINE(geom1, geom2)" id="st_shortestline-geom1-geom2" defaultOpen>
    Returns the 2-D LINESTRING that represents the shortest line of points between the two geometries. If
    multiple shortest lines are found, only the first line found is returned. If `geom1` or `geom2`
    is empty, `null` is returned
  </Accordion>

  <Accordion title="ST_SIMPLIFY(geom, tolerance)" id="st_simplify-geom-tolerance" defaultOpen>
    Returns a simplified version of the given `geom` using an algorithm to reduce the number of points
    comprising a given geometry while attempting to best retain the original shape. The given
    `tolerance` determines how much to simplify the geometry. The higher the `tolerance`, the more
    simplified the returned geometry. Some holes might be removed and some invalid polygons (e.g.,
    self-intersecting, etc.) might be present in the returned geometry. Only (MULTI)LINESTRINGs and
    (MULTI)POLYGONs can be simplified, including those found within GEOMETRYCOLLECTIONs; any other
    geometry objects will be returned unsimplified.

    <Info>
      The `tolerance` should be provided in the same units as the data. As a rule of thumb,
      a `tolerance` of `0.00001` would correspond to about one meter.
    </Info>
  </Accordion>

  <Accordion title="ST_SIMPLIFYPRESERVETOPOLOGY (geom, tolerance)" id="st_simplifypreservetopology-geom-tolerance" defaultOpen>
    Returns a simplified version of the given `geom` using an algorithm to reduce the number of points
    comprising a given geometry while attempting to best retain the original shape. The given
    `tolerance` determines how much to simplify the geometry. The higher the `tolerance`, the more
    simplified the returned geometry. No holes will be removed and no invalid polygons (e.g.,
    self-intersecting, etc.) will be present in the returned geometry. Only (MULTI)LINESTRINGs and
    (MULTI)POLYGONs can be simplified, including those found within GEOMETRYCOLLECTIONs; any other
    geometry objects will be returned unsimplified.

    <Info>
      The `tolerance` should be provided in the same units as the data. As a rule of thumb,
      a `tolerance` of `0.00001` would correspond to about one meter.
    </Info>
  </Accordion>

  <Accordion title="ST_SNAP(geom1, geom2, tolerance)" id="st_snap-geom1-geom2-tolerance" defaultOpen>
    Snaps `geom1` to `geom2` within the given `tolerance`. If the `tolerance` causes `geom1`
    to not snap, the geometries will be returned unchanged.
  </Accordion>

  <Accordion title="ST_SPLIT(geom1, geom2)" id="st_split-geom1-geom2" defaultOpen>
    Returns a collection of geometries resulting from the split between `geom1` and `geom2`
    geometries.
  </Accordion>

  <Accordion title="ST_SQUAREGRID (xmin, ymin, xmax, ymax, cell_side[, limit])" id="st_squaregrid-xmin-ymin-xmax-ymax-cell_side-limit" defaultOpen>
    Creates a MULTIPOLYGON containing a grid of squares between given minimum and maximum points of a
    bounding box. The minimum point cannot be greater than or equal to the maximum point. The size (in
    meters) of the individual squares' sides is determined by `cell_side`. The `cell_side` cannot be
    greater than the width or height of the bounding box. The maximum number of cells that can be
    produced is determined by `limit`, a positive integer. Supported values for `limit`:

    * `-1` - No limit to the number of cells generated (effectively limited by system memory)
    * `0` (default) - 100 million cells
    * `<n>` - Custom limit of `n` cells

    If the custom limit request specifies more cells (based on the bounding box and the `cell_side`)
    than the system limit, a `null` is returned.
  </Accordion>

  <Accordion title="ST_STARTPOINT(geom)" id="st_startpoint-geom" defaultOpen>
    Returns the first point of LINESTRING `geom` as a POINT. Returns `null` if `geom` is not a
    LINESTRING.
  </Accordion>

  <Accordion title="ST_SYMDIFFERENCE(geom1, geom2)" id="st_symdifference-geom1-geom2" defaultOpen>
    Returns a geometry that represents the portions of `geom1` and `geom2` geometries that do not
    intersect.
  </Accordion>

  <Accordion title="ST_TOUCHES(geom1, geom2)" id="st_touches-geom1-geom2" defaultOpen>
    Returns `1` (true) if the given geometries, `geom1` and `geom2`, have at least one point in
    common but their interiors do not intersect. If `geom1` and/or `geom2` are a GEOMETRYCOLLECTION,
    a `0` is returned regardless of if the two geometries touch
  </Accordion>

  <Accordion title="ST_TRANSLATE (geom, deltax, deltay[, deltaz])" id="st_translate-geom-deltax-deltay-deltaz" defaultOpen>
    Translate `geom` by given offsets `deltax` and `deltay`. A z-coordinate offset can be applied
    using `deltaz`.
    intersect.
  </Accordion>

  <Accordion title="ST_TRIANGLEGRID (xmin, ymin, xmax, ymax, cell_side[, limit])" id="st_trianglegrid-xmin-ymin-xmax-ymax-cell_side-limit" defaultOpen>
    Creates a MULTIPOLYGON containing a grid of triangles between given minimum and maximum points of a
    bounding box. The minimum point cannot be greater than or equal to the maximum point. The size (in
    meters) of the individual triangles' sides is determined by `cell_side`. The `cell_side` cannot be
    greater than the width or height of the bounding box. The maximum number of cells that can be
    produced is determined by `limit`, a positive integer. Supported values for `limit`:

    * `-1` - No limit to the number of cells generated (effectively limited by system memory)
    * `0` (default) - 100 million cells
    * `<n>` - Custom limit of `n` cells

    If the custom limit request specifies more cells (based on the bounding box and the `cell_side`)
    than the system limit, a `null` is returned.
  </Accordion>

  <Accordion title="ST_UNION(geom1, geom2)" id="st_union-geom1-geom2" defaultOpen>
    Returns a geometry that represents the point set union of the two given geometries, `geom1` and
    `geom2`.
  </Accordion>

  <Accordion title="ST_UNIONCOLLECTION(geom)" id="st_unioncollection-geom" defaultOpen>
    Returns a geometry that represents the point set union of a single given geometry `geom`.
  </Accordion>

  <Accordion title="ST_UPDATE(geom1, geom2)" id="st_update-geom1-geom2" defaultOpen>
    Returns a geometry that is `geom1` geometry updated by `geom2` geometry
  </Accordion>

  <Accordion title="ST_VORONOIPOLYGONS(geom[, tolerance])" id="st_voronoipolygons-geom-tolerance" defaultOpen>
    Returns a GEOMETRYCOLLECTION containing Voronoi polygons (regions consisting of points closer to
    a vertex in `geom` than any other vertices in `geom`) calculated from the vertices in `geom`
    and the given `tolerance`. The `tolerance` determines the distance at which points will be
    considered the same.  An empty GEOMETRYCOLLECTION is returned if `geom` is an empty geometry, a
    single POINT, or a LINESTRING or POLYGON composed of equivalent vertices (e.g.,
    `POLYGON((0 0, 0 0, 0 0, 0 0))`, `LINESTRING(0 0, 0 0)`).

    If no `tolerance` is specified, no vertices will be considered the same; each will have its own polygon.

    The bounding box for the result POLYGONs extends past the four edges of the input `geom` bounding box by
    an amount that is the greater of the input bounding box's height and width.  For instance, an input `geom`
    with a *3* x *4* bounding box will result in Voronoi polygons filling a space that is *11* x *12*.
  </Accordion>

  <Accordion title="ST_WITHIN(geom1, geom2)" id="st_within-geom1-geom2" defaultOpen>
    Returns `1` (true) if the `geom1` geometry is inside the `geom2` geometry. Note that as long as
    at least one point is inside of `geom2`, `geom1` is considered within `geom2` even if the rest
    of the `geom1` lies along the boundary of `geom2`
  </Accordion>

  <Accordion title="ST_WKBTOWKT(geom)" id="st_wkbtowkt-geom" defaultOpen>
    Returns the text form (WKT) of a geometry from the given byte form (WKB)
  </Accordion>

  <Accordion title="ST_WKTTOWKB(geom)" id="st_wkttowkb-geom" defaultOpen>
    Returns the byte form (WKB) of a geometry from the given text form (WKT)
  </Accordion>

  <Accordion title="ST_X(geom)" id="st_x-geom" defaultOpen>
    Returns the X coordinate of the POINT `geom`; if the coordinate is not available, `null` is
    returned. `geom` must be a POINT.
  </Accordion>

  <Accordion title="ST_XMAX(geom)" id="st_xmax-geom" defaultOpen>
    Alias for `ST_MAXX()`
  </Accordion>

  <Accordion title="ST_XMIN(geom)" id="st_xmin-geom" defaultOpen>
    Alias for `ST_MINX()`
  </Accordion>

  <Accordion title="ST_Y(geom)" id="st_y-geom" defaultOpen>
    Returns the Y coordinate of the POINT `geom`; if the coordinate is not available, `null` is
    returned. `geom` must be a POINT.
  </Accordion>

  <Accordion title="ST_YMAX(geom)" id="st_ymax-geom" defaultOpen>
    Alias for `ST_MAXY()`
  </Accordion>

  <Accordion title="ST_YMIN(geom)" id="st_ymin-geom" defaultOpen>
    Alias for `ST_MINY()`
  </Accordion>

  <Accordion title="ST_ZMAX(geom)" id="st_zmax-geom" defaultOpen>
    Alias for `ST_MAXZ()`
  </Accordion>

  <Accordion title="ST_ZMIN(geom)" id="st_zmin-geom" defaultOpen>
    Alias for `ST_MINZ()`
  </Accordion>
</AccordionGroup>

<a id="expression-functions-geo-aggregation" />

#### Aggregation Functions

The following functions can be used on geospatial/geometry columns within
[aggregations](/content/concepts/expressions#aggregate-expressions-label).

<AccordionGroup>
  <Accordion title="ST_AGGREGATE_COLLECT(geom)" id="st_aggregate_collect-geom" defaultOpen>
    Alias for `ST_COLLECT_AGGREGATE()`
  </Accordion>

  <Accordion title="ST_AGGREGATE_INTERSECTION(geom)" id="st_aggregate_intersection-geom" defaultOpen>
    Alias for `ST_INTERSECTION_AGGREGATE()`
  </Accordion>

  <Accordion title="ST_COLLECT_AGGREGATE(geom)" id="st_collect_aggregate-geom" defaultOpen>
    Returns a GEOMETRYCOLLECTION comprising all geometries found in the `geom` set.
    Any MULTI\* geometries will be divided into separate singular geometries, e.g.,
    MULTIPOINT((0 0), (1 1)) would be divided into POINT(0 0) and POINT(1 1) in the
    results; the same is true for elements of a GEOMETRYCOLLECTION found in `geom`,
    where a GEOMETRYCOLLECTION within the provided `geom` set will also be parsed,
    effectively flattening it and adding the individual geometries to the resulting
    GEOMETRYCOLLECTION. Any empty geometries in `geom` are ignored even if they are
    part of a GEOMETRYCOLLECTION. Any duplicate WKTs will be retained.
  </Accordion>

  <Accordion title="ST_DISSOLVE(geom)" id="st_dissolve-geom" defaultOpen>
    Dissolves all geometries within a given set into a single geometry. Note that the
    resulting single geometry can still be a group of noncontiguous geometries but
    represented as a single group, e.g., a GEOMETRYCOLLECTION.  Best performance when
    used in conjunction with adjacent geometries.
  </Accordion>

  <Accordion title="ST_DISSOLVEOVERLAPPING(geom)" id="st_dissolveoverlapping-geom" defaultOpen>
    Dissolves all geometries within a given set into a single geometry. Note that the
    resulting single geometry can still be a group of noncontiguous geometries but
    represented as a single group, e.g., a GEOMETRYCOLLECTION.  Best performance when
    used in conjunction with overlapping geometries.
  </Accordion>

  <Accordion title="ST_INTERSECTION_AGGREGATE(geom)" id="st_intersection_aggregate-geom" defaultOpen>
    Returns a POLYGON or MULTIPOLYGON comprising the shared portion between all
    geometries found in the `geom` set.  Returns an empty GEOMETRYCOLLECTION if
    there is no shared portion between all geometries. Functionally equivalent to
    `ST_INTERSECTION(ST_INTERSECTION(geom1, geom2), ... geomN)`.
  </Accordion>

  <Accordion title="ST_LINESTRINGFROMORDEREDPOINTS(x, y, t)" id="st_linestringfromorderedpoints-x-y-t" defaultOpen>
    Returns a LINESTRING that represents a "track" of the given points (`x`, `y`)
    ordered by the given sort column `t` (e.g., a timestamp or sequence number). If
    any of the values in the specified columns are `null`, the null "point" will be
    left out of the resulting LINESTRING. If there's only one non-null "point" in the
    source table, a POINT is returned. If there are no non-null "points" in the
    source table, a `null` is returned.
  </Accordion>

  <Accordion title="ST_LINESTRINGFROMORDEREDPOINTS3D(x, y, z, t)" id="st_linestringfromorderedpoints3d-x-y-z-t" defaultOpen>
    Returns a LINESTRING that represents a "track" of the given 3D points
    (`x`, `y`, `z`) ordered by the given sort column `t` (e.g., a timestamp
    or sequence number). If any of the values in the specified columns are `null`,
    the null "point" will be left out of the resulting LINESTRING. If there's only
    one non-null "point" in the source table, a POINT is returned. If there are no
    non-null "points" in the source table, a `null` is returned.
  </Accordion>

  <Accordion title="ST_POLYGONIZE(geom)" id="st_polygonize-geom" defaultOpen>
    Returns a GEOMETRYCOLLECTION containing POLYGONs comprising the provided
    (MULTI)LINESTRING(s). (MULTI)POINT and (MULTI)POLYGON geometries are ignored when
    calculating the resulting GEOMETRYCOLLECTION. If a valid POLYGON cannot be
    constructed from the provided (MULTI)LINESTRING(s), an empty GEOMETRYCOLLECTION
    will be returned.
  </Accordion>
</AccordionGroup>

<a id="expression-functions-geo-track" />

#### Track Functions

The following functions are available in both SQL and the native API.

<AccordionGroup>
  <Accordion title="ST_TRACKDURATION([unit,] t)" id="st_trackduration-unit-t" defaultOpen>
    Returns the total time, in the given `unit`, spanned by timestamp values in column
    `t`.  Grouping by *track* ID will return the duration per *track*.

    The duration can be returned in any of the following date/time units:

    * `YEAR`
    * `MONTH`
    * `DAY`
    * `HOUR`
    * `MINUTE`
    * `SECOND`
    * `MILLISECOND`

    The default `unit` is `MILLISECOND`.
  </Accordion>

  <Accordion title="ST_TRACKLENGTH(lat, lon, t[, solution])" id="st_tracklength-lat-lon-t-solution" defaultOpen>
    Returns the total length of the track whose position values are specified by `lat` &
    `lon` and whose ordering is determined by an ascending sort on the timestamp `t`.
    Length can be returned with any of the following solution types:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Type</th>
            <th>Description</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>0</code></td>
            <td>2D Euclidean length in degrees</td>
          </tr>

          <tr>
            <td><code>1</code></td>
            <td>(default) Length on a sphere in meters</td>
          </tr>

          <tr>
            <td><code>2</code></td>
            <td>Length on a spheroid in meters</td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>
</AccordionGroup>

<p><strong>ST\_TRACK\_DWITHIN</strong></p>

The `ST_TRACK_DWITHIN` table function finds tracks that are related, within
spatial or temporal bounds (or both) to the given track(s).  The track(s) to use
as the filter criteria will be specified by the `SEARCH_*` parameters.  The
`TRACK_*` parameters specify the set of tracks to search through for a match.

<Info>
  This function is only available in SQL or in the native API via
  [/execute/sql](/content/api/rest/execute_sql_rest).
</Info>

The basic form of the `ST_TRACK_DWITHIN` function follows.

```sql ST_TRACK_DWITHIN Table Function Syntax theme={null}
SELECT *
FROM TABLE
(
    ST_TRACK_DWITHIN
    (
        TRACK_TABLE => INPUT_TABLE(<table name | select statement>),
        TRACK_ID_COLUMN => < '<column name>' | <column position> >,
        TRACK_X_COLUMN => < '<column name>' | <column position> >,
        TRACK_Y_COLUMN => < '<column name>' | <column position> >,
        TRACK_ORDER_COLUMN => < '<column name>' | <column position> >,
        SEARCH_TABLE => INPUT_TABLE(<table name | select statement>),
        SEARCH_ID_COLUMN => < '<column name>' | <column position> >,
        SEARCH_X_COLUMN => < '<column name>' | <column position> >,
        SEARCH_Y_COLUMN => < '<column name>' | <column position> >,
        SEARCH_ORDER_COLUMN => < '<column name>' | <column position> >,
        [
            SEARCH_XY_DISTANCE => '<spatial distance with unit>',
            SPATIAL_SOLUTION_TYPE => <solution type>,
            SEARCH_TIME_DISTANCE => '<temporal distance with unit>'
        ]
    )
)
```

<AccordionGroup>
  <Accordion title="TRACK_TABLE" id="track_table" defaultOpen>
    Name of the table to search for tracks matching the track(s) specified in the `SEARCH_*` data set.

    To perform a search on the *flights* table, pass the name of the table to `INPUT_TABLE`:

    ```
    INPUT_TABLE(flights)
    ```

    To perform a search on the result of a query, pass the query to `INPUT_TABLE`:

    ```
    INPUT_TABLE
    (
        SELECT * FROM flights_west
        UNION
        SELECT * FROM flights_east
    )
    ```
  </Accordion>

  <Accordion title="TRACK_ID_COLUMN" id="track_id_column" defaultOpen>
    Table to search track column, containing the unique identifier for the track to which each track point
    belongs.
  </Accordion>

  <Accordion title="TRACK_X_COLUMN" id="track_x_column" defaultOpen>
    Table to search track column, containing the longitude value of each track point.
  </Accordion>

  <Accordion title="TRACK_Y_COLUMN" id="track_y_column" defaultOpen>
    Table to search track column, containing the latitude value of each track point.
  </Accordion>

  <Accordion title="TRACK_ORDER_COLUMN" id="track_order_column" defaultOpen>
    Table to search track column, by which the searched track points will be sorted in ascending order.
  </Accordion>

  <Accordion title="SEARCH_TABLE" id="search_table" defaultOpen>
    Name of the search criteria track table, containing the track(s) to be used as the filter criteria
    when searching for matching tracks in the `TRACK_*` data set.

    To match tracks from the *flights\_of\_interest* table, pass the name of the table to `INPUT_TABLE`:

    ```
    INPUT_TABLE(flights_of_interest)
    ```

    To match tracks from the result of a query, pass the query to `INPUT_TABLE`:

    ```
    INPUT_TABLE
    (
        SELECT * FROM flights_of_interest_west
        UNION
        SELECT * FROM flights_of_interest_east
    )
    ```
  </Accordion>

  <Accordion title="SEARCH_ID_COLUMN" id="search_id_column" defaultOpen>
    Search criteria track column, containing the unique identifier for the track to which each track point
    belongs.
  </Accordion>

  <Accordion title="SEARCH_X_COLUMN" id="search_x_column" defaultOpen>
    Search criteria track column, containing the longitude value of each track point.
  </Accordion>

  <Accordion title="SEARCH_Y_COLUMN" id="search_y_column" defaultOpen>
    Search criteria track column, containing the latitude value of each track point.
  </Accordion>

  <Accordion title="SEARCH_ORDER_COLUMN" id="search_order_column" defaultOpen>
    Search criteria track column, by which the filter track points will be sorted in ascending order.
  </Accordion>

  <Accordion title="SEARCH_XY_DISTANCE" id="search_xy_distance" defaultOpen>
    The radius around the given tracks to search for matching tracks.

    <Note>
      This parameter is not applicable when using a `SPATIAL_SOLUTION_TYPE` of `0`.
    </Note>

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Unit</th>
            <th>Description</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>f</code></td>
            <td>Feet</td>
          </tr>

          <tr>
            <td><code>ki</code></td>
            <td>Kilometers</td>
          </tr>

          <tr>
            <td><code>m</code></td>
            <td>(default) Meters</td>
          </tr>

          <tr>
            <td><code>mi</code></td>
            <td>Miles</td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="SPATIAL_SOLUTION_TYPE" id="spatial_solution_type" defaultOpen>
    Spatial match solution type; any of the following:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Type</th>
            <th>Description</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>0</code></td>
            <td>(default) 2D Euclidean length in degrees</td>
          </tr>

          <tr>
            <td><code>1</code></td>
            <td>Length on a sphere, returned in units specified by <code>SEARCH\_XY\_DISTANCE</code></td>
          </tr>

          <tr>
            <td><code>2</code></td>
            <td>Length on a spheroid, returned in units specified by <code>SEARCH\_XY\_DISTANCE</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="SEARCH_TIME_DISTANCE" id="search_time_distance" defaultOpen>
    The maximum allowable time difference between a search criteria track's point and a matched track's
    points.  The time can use any of the following suffices for units:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Unit</th>
            <th>Description</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>ms</code></td>
            <td>Milliseconds</td>
          </tr>

          <tr>
            <td><code>s</code></td>
            <td>(default) Seconds</td>
          </tr>

          <tr>
            <td><code>m</code></td>
            <td>Minutes</td>
          </tr>

          <tr>
            <td><code>h</code></td>
            <td>Hours</td>
          </tr>

          <tr>
            <td><code>d</code></td>
            <td>Days</td>
          </tr>

          <tr>
            <td><code>w</code></td>
            <td>Weeks</td>
          </tr>

          <tr>
            <td><code>months</code></td>
            <td>Months</td>
          </tr>

          <tr>
            <td><code>y</code></td>
            <td>Years</td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>
</AccordionGroup>

To see the matches between a set of flights and a given set of flights of
interest:

```sql ST_TRACK_DWITHIN Example theme={null}
SELECT *
FROM TABLE
(
	ST_TRACK_DWITHIN
	(
		TRACK_TABLE => INPUT_TABLE(example_geospatial.flights),
		TRACK_ID_COLUMN => 'id',
		TRACK_X_COLUMN => 'lon',
		TRACK_Y_COLUMN => 'lat',
		TRACK_ORDER_COLUMN => 'flight_time',
		SEARCH_TABLE => INPUT_TABLE
						(
							SELECT id, lon, lat, flight_time
							FROM example_geospatial.flights_northwest
							UNION
							SELECT id, lon, lat, flight_time
							FROM example_geospatial.flights_northeast
						),
		SEARCH_ID_COLUMN => 1,
		SEARCH_X_COLUMN => 2,
		SEARCH_Y_COLUMN => 3,
		SEARCH_ORDER_COLUMN => 4,
		SEARCH_TIME_DISTANCE => '5m',
		SEARCH_XY_DISTANCE => '1km',
		SPATIAL_SOLUTION_TYPE => 1
	)
)
```

<p><strong>ST\_TRACKINTERSECTS</strong></p>

The `ST_TRACKINTERSECTS` table function finds tracks pass through the given
geofence(s).  The geofence(s) use as the filter will be specified by the
`GEOFENCE_*` parameters.  The `TRACK_*` parameters specify the set of
tracks to search through for any intersecting the geofence(s).

The result will include a record for each intersecting track & geofence pair,
with:

* a `LINESTRING` representing the full track intersecting a geofence
* a `LINESTRING` representing the geofence it intersected

<Info>
  This function is only available in SQL or in the native API via
  [/execute/sql](/content/api/rest/execute_sql_rest).
</Info>

The basic form of the `ST_TRACKINTERSECTS` function follows.

```sql ST_TRACKINTERSECTS Table Function Syntax theme={null}
SELECT *
FROM TABLE
(
    ST_TRACKINTERSECTS
    (
        TRACK_TABLE => INPUT_TABLE(<table name | select statement>),
        TRACK_ID_COLUMN => < '<column name>' | <column position> >,
        TRACK_X_COLUMN => < '<column name>' | <column position> >,
        TRACK_Y_COLUMN => < '<column name>' | <column position> >,
        TRACK_ORDER_COLUMN => < '<column name>' | <column position> >,
        GEOFENCE_TABLE => INPUT_TABLE(<table name | select statement>),
        GEOFENCE_ID_COLUMN => < '<column name>' | <column position> >,
        GEOFENCE_WKT_COLUMN => < '<column name>' | <column position> >
    )
)
```

<AccordionGroup>
  <Accordion title="TRACK_TABLE" id="track_table-2" defaultOpen>
    Name of the table to search for tracks intersecting the geofence(s) specified in the `SEARCH_*` data
    set.

    To perform a search on the *flights* table, pass the name of the table to `INPUT_TABLE`:

    ```
    INPUT_TABLE(flights)
    ```

    To perform a search on the result of a query, pass the query to `INPUT_TABLE`:

    ```
    INPUT_TABLE
    (
        SELECT * FROM flights_west
        UNION
        SELECT * FROM flights_east
    )
    ```
  </Accordion>

  <Accordion title="TRACK_ID_COLUMN" id="track_id_column-2" defaultOpen>
    Table to search track column, containing the unique identifier for the track to which each track point
    belongs.
  </Accordion>

  <Accordion title="TRACK_X_COLUMN" id="track_x_column-2" defaultOpen>
    Table to search track column, containing the longitude value of each track point.
  </Accordion>

  <Accordion title="TRACK_Y_COLUMN" id="track_y_column-2" defaultOpen>
    Table to search track column, containing the latitude value of each track point.
  </Accordion>

  <Accordion title="TRACK_ORDER_COLUMN" id="track_order_column-2" defaultOpen>
    Table to search track column, by which the searched track points will be sorted in ascending order.
  </Accordion>

  <Accordion title="GEOFENCE_TABLE" id="geofence_table" defaultOpen>
    Name of the geofence table, containing the WKT(s) to be used as the filter criteria when searching for
    intersecting tracks in the `TRACK_*` data set.

    To search for tracks intersecting the geofence(s) from the *flight\_area\_of\_interest* table, pass the
    name of the geofence table to `INPUT_TABLE`:

    ```
    INPUT_TABLE(flight_area_of_interest)
    ```

    To search for tracks intersecting the geofence(s) from the result of a query, pass the query to
    `INPUT_TABLE`:

    ```
    INPUT_TABLE
    (
        SELECT * FROM flight_area_of_interest_west
        UNION
        SELECT * FROM flight_area_of_interest_east
    )
    ```
  </Accordion>

  <Accordion title="GEOFENCE_ID_COLUMN" id="geofence_id_column" defaultOpen>
    Geofence column, containing the unique identifier for the geofence.
  </Accordion>

  <Accordion title="GEOFENCE_WKT_COLUMN" id="geofence_wkt_column" defaultOpen>
    Geofence column, containing the WKT bounds of the geofence.
  </Accordion>
</AccordionGroup>

To see the intersections between a set of flights and an area of interest:

```sql ST_TRACKINTERSECTS Example theme={null}
SELECT *
FROM TABLE
(
	ST_TRACKINTERSECTS
	(
		TRACK_TABLE =>         INPUT_TABLE(example_geospatial.flights),
		TRACK_ID_COLUMN =>     'id',
		TRACK_X_COLUMN =>      'lon',
		TRACK_Y_COLUMN =>      'lat',
		TRACK_ORDER_COLUMN =>  'flight_time',
		GEOFENCE_TABLE =>      INPUT_TABLE(example_geospatial.track_geofence),
		GEOFENCE_ID_COLUMN =>  'fence_name',
		GEOFENCE_WKT_COLUMN => 'fence_wkt'
	)
)
ORDER BY id, fence_name
```

<a id="expression-functions-geo-h3" />

#### H3 Functions

The functions below support various operations using the H3 geospatial indexing scheme.

<AccordionGroup>
  <Accordion title="H3_CELLTOBOUNDARY(h3_index)" id="h3_celltoboundary-h3_index" defaultOpen>
    Returns a POLYGON boundary box of the H3 index identified by the given `h3_index`.

    See [Geohash-H3](/content/snippets/geohash-h3) for an example.
  </Accordion>

  <Accordion title="H3_CELLTOCENTERCHILD(h3_index, res)" id="h3_celltocenterchild-h3_index-res" defaultOpen>
    Alias for `H3_CELLTOFIRSTCHILD`.
  </Accordion>

  <Accordion title="H3_CELLTOCHILDN(h3_index, res, i)" id="h3_celltochildn-h3_index-res-i" defaultOpen>
    Returns the H3 index corresponding to the 0-based `i` th child at resolution `res` for the given
    `h3_index`.  The value `i` should be less than the number of children returned from calling
    `H3_CELLTOCHILDRENSIZE(h3_index, res)`.
  </Accordion>

  <Accordion title="H3_CELLTOCHILDPOS(h3_index, res)" id="h3_celltochildpos-h3_index-res" defaultOpen>
    Returns the position of the given `h3_index` within an ordered list of the children of the cell's
    parent at resolution `res`. This is the inverse of `H3_CHILDPOSTOCELL` (`H3_CELLTOCHILDN`).
  </Accordion>

  <Accordion title="H3_CELLTOCHILDRENSIZE(h3_index, res)" id="h3_celltochildrensize-h3_index-res" defaultOpen>
    Returns the number of child cells at resolution `res` for the given `h3_index`.
  </Accordion>

  <Accordion title="H3_CELLTOFIRSTCHILD(h3_index, res)" id="h3_celltofirstchild-h3_index-res" defaultOpen>
    Returns the H3 index corresponding to the first child at resolution `res` for the given `h3_index`.

    This is equivalent to `H3_CELLTOCHILDN(h3_index,res,0)`.
  </Accordion>

  <Accordion title="H3_CELLTOLASTCHILD(h3_index, res)" id="h3_celltolastchild-h3_index-res" defaultOpen>
    Returns the H3 index corresponding to the last child at resolution `res` for the given `h3_index`.

    This is equivalent to `H3_CELLTOCHILDN(h3_index,res,H3_CELLTOCHILDRENSIZE(h3_index, res)-1)`.
  </Accordion>

  <Accordion title="H3_CELLTOPARENT(h3_index, res)" id="h3_celltoparent-h3_index-res" defaultOpen>
    Returns the H3 index corresponding to the parent cell of the given `h3_index` at resolution `res`.
  </Accordion>

  <Accordion title="H3_CELLTOXY(h3_index)" id="h3_celltoxy-h3_index" defaultOpen>
    Returns a WKT POINT corresponding to the centroid of the given `h3_index`.
  </Accordion>

  <Accordion title="H3_CHILDPOSTOCELL(i, h3_index, res)" id="h3_childpostocell-i-h3_index-res" defaultOpen>
    Alias for `H3_CELLTOCHILDN(h3_index, res, i)`.
  </Accordion>

  <Accordion title="H3_GEOMTOCELL(geom, res)" id="h3_geomtocell-geom-res" defaultOpen>
    Returns the H3 index, similar to a geohash, for the cell containing the centroid of the geometry
    `geom` with the given resolution `res`.  The higher the resolution, the more precise the index
    is. The resolution `res` must be an integer between `0` and `15`.

    See [Geohash-H3](/content/snippets/geohash-h3) for an example.
  </Accordion>

  <Accordion title="H3_GETRESOLUTION(h3_index)" id="h3_getresolution-h3_index" defaultOpen>
    Returns the resolution of the H3 index `h3_index`.
  </Accordion>

  <Accordion title="H3_GRIDDISK(h3_index, k)" id="h3_griddisk-h3_index-k" defaultOpen>
    Returns an array of H3 indexes within a given distance `k` from the provided H3 index `h3_index`.
  </Accordion>

  <Accordion title="H3_GRIDDISKN(h3_index, k, i)" id="h3_griddiskn-h3_index-k-i" defaultOpen>
    Returns the `i` <sup>th</sup> H3 index within a given distance `k` from the provided H3 index
    `h3_index`.  This function would typically be used in conjunction with `H3_NUMGRIDDISK` via iter-join.
    The value of `i` should be between `0` and the result of `H3_NUMGRIDDISK(h3_index, k)` - `1`.
  </Accordion>

  <Accordion title="H3_GRIDRING(h3_index, k)" id="h3_gridring-h3_index-k" defaultOpen>
    Returns an array of H3 indexes comprising a hollow ring at a distance `k` from the provided
    H3 index `h3_index`.
  </Accordion>

  <Accordion title="H3_H3TOSTRING(h3_index)" id="h3_h3tostring-h3_index" defaultOpen>
    Returns the string representation of the H3 index `h3_index`.

    <Info>
      This function is the inverse of `H3_STRINGTOH3`.
    </Info>
  </Accordion>

  <Accordion title="H3_ISVALID(h3_index)" id="h3_isvalid-h3_index" defaultOpen>
    Returns `1` (true) if the given H3 index `h3_index` is a valid H3 index value; otherwise
    returns `0` (false).
  </Accordion>

  <Accordion title="H3_LATLNGTOCELL (latitude, longitude, res)" id="h3_latlngtocell-latitude-longitude-res" defaultOpen>
    Returns the H3 index, similar to a geohash, for the cell containing the `latitude` and `longitude`
    coordinate, with the given resolution `res`.  The higher the resolution, the more precise the index
    is. The resolution `res` must be an integer between `0` and `15`.

    Equivalent to `H3_XYTOCELL(longitude, latitude, res)`.
  </Accordion>

  <Accordion title="H3_NUMGRIDDISK(h3_index, k)" id="h3_numgriddisk-h3_index-k" defaultOpen>
    Returns the number of cells at a distance of `k` from the provided H3 index `h3_index`. This function
    would typically be used in conjunction with `H3_GRIDDISKN` via iter-join.
  </Accordion>

  <Accordion title="H3_NUMPOLYGONTOCELLS(geom, res)" id="h3_numpolygontocells-geom-res" defaultOpen>
    Returns the number of cells at the given resolution `res` that are within the given geometry `geom`.
    Only polygon geometries are supported. This function would typically be used in conjunction with
    `H3_POLYGONTOCELLSN` via iter-join.
  </Accordion>

  <Accordion title="H3_POLYGONTOCELLS(geom, res)" id="h3_polygontocells-geom-res" defaultOpen>
    Returns an array of H3 indexes at the given resolution `res` that are within the given geometry `geom`.
    Only polygon geometries are supported.
  </Accordion>

  <Accordion title="H3_POLYGONTOCELLSN(geom, res, i)" id="h3_polygontocellsn-geom-res-i" defaultOpen>
    Returns the `i` <sup>th</sup> H3 index at the given resolution `res` that is within the given geometry
    `geom`.  Only polygon geometries are supported. This function would typically be used in conjunction with
    `H3_NUMPOLYGONTOCELLS` via iter-join. The value of `i` should be between `0` and the value returned
    from `H3_NUMPOLYGONTOCELLS(geom, res)` - `1`.
  </Accordion>

  <Accordion title="H3_STRINGTOH3(h3_string)" id="h3_stringtoh3-h3_string" defaultOpen>
    Returns the H3 index corresponding to the string representation `h3_string`.

    <Info>
      This function is the inverse of `H3_H3TOSTRING`.
    </Info>
  </Accordion>

  <Accordion title="H3_XYTOCELL(x, y, res)" id="h3_xytocell-x-y-res" defaultOpen>
    Returns the H3 index, similar to a geohash, for the cell containing the `x` and `y` coordinate,
    with the given resolution `res`.  The higher the resolution, the more precise the index is. The
    resolution `res` must be an integer between `0` and `15`.

    Equivalent to `H3_LATLNGTOCELL(y, x, res)`.

    See [Geohash-H3](/content/snippets/geohash-h3) for an example.
  </Accordion>
</AccordionGroup>

<a id="expression-functions-json" />

### JSON Functions

<a id="expression-functions-json-scalar" />

#### Scalar Functions

These functions can be applied to individual *json* column values, as well as
*array* & *string* columns.  However, for some functions to work as expected,
the *array* or *string* value may need to be cast to JSON first.

<AccordionGroup>
  <Accordion title="JSON(expr)" id="json-expr" defaultOpen>
    Casts the given `expr` to JSON data type

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>JSON('\[1, 2, "C"]')</code></td>
            <td><code>\[1,2,"C"]</code></td>
          </tr>

          <tr>
            <td><code>JSON('\{"A": "B", "C": \{"D": 5, "F": 7}}')</code></td>
            <td><code>\{"A":"B","C":\{"D":5,"F":7}}</code></td>
          </tr>

          <tr>
            <td><code>JSON(null)</code></td>
            <td>*null*</td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="JSON_ARRAY (value[,...] <null_hand>)" id="json_array-value-<null_hand>" defaultOpen>
    Creates a JSON array out of the given list of values.

    An optional `<null_hand>` parameter can be added to the end of the list to specify
    handling of *null* values, though, at present, this only exists for compatibility with
    other databases' syntax--the option will be ignored and all *null* values will be added
    to the array as *null*.  Accepted null handling options:

    * `NULL ON NULL`

    <Info>
      This function is only available in SQL or in the native API via
      [/execute/sql](/content/api/rest/execute_sql_rest).
    </Info>

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>JSON\_ARRAY(1, 2, 'C')</code></td>
            <td><code>\[1,2,"C"]</code></td>
          </tr>

          <tr>
            <td><code>JSON\_ARRAY(JSON('\{"A": "B"}'), JSON('\{"C": 4}'))</code></td>
            <td><code>\[\{"A":"B"},\{"C":4}]</code></td>
          </tr>

          <tr>
            <td><code>JSON\_ARRAY(1, null, 'C' NULL ON NULL)</code></td>
            <td><code>\[1,null,"C"]</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="JSON_ARRAY_APPEND(arr, value)" id="json_array_append-arr-value" defaultOpen>
    Appends the given `value` to the given array `arr` of type string, array, or JSON

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>JSON\_ARRAY\_APPEND('\[1, 2]', 'C')</code></td>
            <td><code>\[1,2,"C"]</code></td>
          </tr>

          <tr>
            <td><code>JSON\_ARRAY\_APPEND('\{"A": "B"}', JSON('\{"C": 4}'))</code></td>
            <td><code>\[\{"A":"B"},\{"C":4}]</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="JSON_ARRAY_CONTAINS (json, path, val)" id="json_array_contains-json-path-val" defaultOpen>
    Returns whether the given JSON `json` contains the primitive value `val` at the JSON
    query path, `path`

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>JSON\_ARRAY\_CONTAINS('\[1, 2]', '\$', 2)</code></td>
            <td><code>true</code></td>
          </tr>

          <tr>
            <td><code>JSON\_ARRAY\_CONTAINS('\[1, 2]', '\$', 'C')</code></td>
            <td><code>false</code></td>
          </tr>

          <tr>
            <td><code>JSON\_ARRAY\_CONTAINS('\{"A": \[2, 3]}', '\$.A', 2)</code></td>
            <td><code>true</code></td>
          </tr>

          <tr>
            <td><code>JSON\_ARRAY\_CONTAINS('\{"A": \{"B": \[3, 4]}}', '\$\["A"]\["B"]', 4)</code></td>
            <td><code>true</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="JSON_CARDINALITY(json)" id="json_cardinality-json" defaultOpen>
    Alias for `JSON_LENGTH`
  </Accordion>

  <Accordion title="JSON_EXISTS(json, path)" id="json_exists-json-path" defaultOpen>
    Returns whether the given JSON `json` contains the JSON query path, `path`

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>JSON\_EXISTS('\[1, 2]', '\$')</code></td>
            <td><code>true</code></td>
          </tr>

          <tr>
            <td><code>JSON\_EXISTS('\[1, 2]', '\$.A')</code></td>
            <td><code>false</code></td>
          </tr>

          <tr>
            <td><code>JSON\_EXISTS('\{"A": \[2, 3]}', '\$.A')</code></td>
            <td><code>true</code></td>
          </tr>

          <tr>
            <td><code>JSON\_EXISTS('\{"A": \{"B": 3, "D": 5}}', '\$\["A"]\["D"]')</code></td>
            <td><code>true</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="JSON_KEYS(json, path)" id="json_keys-json-path" defaultOpen>
    Returns the set of keys of the JSON object at the given `path` in `json`; null, if the
    path doesn't exist or contains a non-object (non-map) value

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>JSON\_KEYS('\{}', '\$')</code></td>
            <td><code>\[]</code></td>
          </tr>

          <tr>
            <td><code>JSON\_KEYS('\[1, 2]', '\$.A')</code></td>
            <td>*null*</td>
          </tr>

          <tr>
            <td><code>JSON\_KEYS('\{"A": \[2, 3]}', '\$')</code></td>
            <td><code>\["A"]</code></td>
          </tr>

          <tr>
            <td><code>JSON\_KEYS('\{"A": \{"B": 3, "D": 5}}', '\$\["A"]')</code></td>
            <td><code>\["B","D"]</code></td>
          </tr>

          <tr>
            <td><code>JSON\_KEYS('\{"A": \{"B": 3, "D": 5}}', '\$\["A"]\["D"]')</code></td>
            <td>*null*</td>
          </tr>

          <tr>
            <td><code>JSON\_KEYS('\{"A": \{"B": 3, "D": \{}}}', '\$\["A"]\["D"]')</code></td>
            <td><code>\[]</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="JSON_LENGTH(json[, path])" id="json_length-json-path" defaultOpen>
    Returns the number of items in the top-level object of the given `json`, or at the
    level of the optional JSON `path`

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>JSON\_LENGTH('\{}')</code></td>
            <td><code>0</code></td>
          </tr>

          <tr>
            <td><code>JSON\_LENGTH('\[]')</code></td>
            <td><code>0</code></td>
          </tr>

          <tr>
            <td><code>JSON\_LENGTH('\[1, 2]')</code></td>
            <td><code>2</code></td>
          </tr>

          <tr>
            <td><code>JSON\_LENGTH('\{"A": \[2, 3]}')</code></td>
            <td><code>1</code></td>
          </tr>

          <tr>
            <td><code>JSON\_LENGTH('\{"A": \{"B": 3}, "D": "E"}')</code></td>
            <td><code>2</code></td>
          </tr>

          <tr>
            <td><code>JSON\_LENGTH('\{"A": \[2, 3]}', '\$.A')</code></td>
            <td><code>2</code></td>
          </tr>

          <tr>
            <td><code>JSON\_LENGTH('\{"A": \{"B": 3}, "D": "E"}', '\$.A')</code></td>
            <td><code>1</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="JSON_MAKE_ARRAY(value)" id="json_make_array-value" defaultOpen>
    Creates a JSON array out of the given `value`

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>JSON\_MAKE\_ARRAY(1)</code></td>
            <td><code>\[1]</code></td>
          </tr>

          <tr>
            <td><code>JSON\_MAKE\_ARRAY(JSON\_ARRAY(1,2,3))</code></td>
            <td><code>\[\[1,2,3]]</code></td>
          </tr>

          <tr>
            <td><code>JSON\_MAKE\_ARRAY(JSON('\{"A": "B"}'))</code></td>
            <td><code>\[\{"A":"B"}]</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="JSON_OBJECT (value[,...] <null_hand>)" id="json_object-value-<null_hand>" defaultOpen>
    Creates a JSON map out of the given `value` set

    An optional `<null_hand>` parameter can be added to the end of the list to specify
    handling of *null* values, though, at present, this only exists for compatibility with
    other databases' syntax--the option will be ignored and all *null* values will be added
    to the array as *null*.  Accepted null handling options:

    * `NULL ON NULL`

    <Info>
      This function is only available in SQL or in the native API via
      [/execute/sql](/content/api/rest/execute_sql_rest).
    </Info>

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>JSON\_OBJECT()</code></td>
            <td><code>\{}</code></td>
          </tr>

          <tr>
            <td><code>JSON\_OBJECT('A': 2)</code></td>
            <td><code>\{"A":2}</code></td>
          </tr>

          <tr>
            <td><code>JSON\_OBJECT('A' VALUE 2)</code></td>
            <td><code>\{"A":2}</code></td>
          </tr>

          <tr>
            <td><code>JSON\_OBJECT(KEY 'A' VALUE 2)</code></td>
            <td><code>\{"A":2}</code></td>
          </tr>

          <tr>
            <td><code>JSON\_OBJECT('A': 'B', 'C': null NULL ON NULL)</code></td>
            <td><code>\{"A":"B","C":null}</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="JSON_PRETTY(json)" id="json_pretty-json" defaultOpen>
    Returns a formatted version of the given `json` object

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <tbody>
          <tr>
            <td>**Function Call**</td>
            <td><code>JSON\_PRETTY('\[1,2,"C"]')</code></td>
          </tr>

          <tr>
            <td>**Return**</td>
            <td><pre><code>\[
            1,
            2,
            "C"
            ]</code></pre></td>
          </tr>
        </tbody>
      </table>
    </div>

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <tbody>
          <tr>
            <td>**Function Call**</td>
            <td><code>JSON\_PRETTY('\{"A": "B", "C": \{"D": 5, "F": 7}}')</code></td>
          </tr>

          <tr>
            <td>**Return**</td>
            <td><pre><code>\{
            "A": "B",
            "C": \{
            "D": 5,
            "F": 7
            }
            ]</code></pre></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="JSON_QUERY (json, path [<return>])" id="json_query-json-path-<return>" defaultOpen>
    Returns the JSON object at the given `path` in `json`; null, if the path doesn't exist
    or contains a primitive (non-object) value

    An optional `return` clause can be added to the end of the path to specify the return type
    of the object found, as well as the error handling for the object lookup.  The format of the
    clause is:

    ```
    [<wrapper> WRAPPER] [<empty_hand> ON EMPTY] [<error hand> ON ERROR]
    ```

    <Info>
      Return clause is only available in SQL or in the native API via
      [/execute/sql](/content/api/rest/execute_sql_rest).
    </Info>

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Parameter</th>
            <th>Description</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>\<wrapper></code></td>
            <td>Whether the returned object(s) should be wrapped in an array before being returned Valid wrapping schemes include: <ul><li><code>WITHOUT \[ARRAY]</code> - no wrapper is applied *(default)*</li><li><code>WITH \[UNCONDITIONAL] \[ARRAY]</code> - return the object(s) in an array</li><li><code>WITH CONDITIONAL \[ARRAY]</code> - if returning a single object, don't wrap it; if returning multiple objects, wrap them in an array</li></ul></td>
          </tr>

          <tr>
            <td><code>\<empty hand></code></td>
            <td>The scheme to use for handling empty returned objects Valid schemes include: <ul><li><code>NULL</code> - return *null* *(default)*</li><li><code>ERROR</code> - throw an error</li><li><code>EMPTY ARRAY</code> - return an empty array</li><li><code>EMPTY OBJECT</code> - return an empty object</li></ul></td>
          </tr>

          <tr>
            <td><code>\<error hand></code></td>
            <td>The scheme to use for handling errors in looking up the object Valid schemes include: <ul><li><code>NULL</code> - return *null* *(default)*</li><li><code>ERROR</code> - throw an error</li><li><code>EMPTY ARRAY</code> - return an empty array</li><li><code>EMPTY OBJECT</code> - return an empty object</li></ul></td>
          </tr>
        </tbody>
      </table>
    </div>

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>JSON\_QUERY('\[1, 2]', '\$')</code></td>
            <td><code>\[1,2]</code></td>
          </tr>

          <tr>
            <td><code>JSON\_QUERY('\[1, 2]', '\$.A')</code></td>
            <td>*null*</td>
          </tr>

          <tr>
            <td><code>JSON\_QUERY('\{"A": \[2, 3]}', '\$.A')</code></td>
            <td><code>\[2,3]</code></td>
          </tr>

          <tr>
            <td><code>JSON\_QUERY('\{"A": \{"B": 3, "D": 5}}', '\$\["A"]')</code></td>
            <td><code>\{"B":3,"D":5}</code></td>
          </tr>

          <tr>
            <td><code>JSON\_QUERY('\{"A": \{"B": 3, "D": 5}}', '\$\["A"]\["D"]')</code></td>
            <td>*null*</td>
          </tr>

          <tr>
            <td><code>JSON\_QUERY('\{"A": \{"B": 3, "D": \[5, 6]}}', '\$\["A"]\["D"]')</code></td>
            <td><code>\[5,6]</code></td>
          </tr>

          <tr>
            <td><code>JSON\_QUERY('\{"A": \[]}', '\$.B'  EMPTY ARRAY ON EMPTY)</code></td>
            <td><code>\[]</code></td>
          </tr>

          <tr>
            <td><code>JSON\_QUERY('\{"A": 0}', '\$.A'  EMPTY OBJECT ON ERROR)</code></td>
            <td><code>\{}</code></td>
          </tr>

          <tr>
            <td><code>JSON\_QUERY('\{"A": 2, "C": 4}', '\$.\*')</code></td>
            <td>*null*</td>
          </tr>

          <tr>
            <td><code>JSON\_QUERY('\{"A": 2, "C": 4}', '\$.\*' WITH WRAPPER)</code></td>
            <td><code>\[2,4]</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="JSON_REPLACE(json, path, repl)" id="json_replace-json-path-repl" defaultOpen>
    Returns the given `json` with the value at the JSON path `path` replaced with the
    replacement value `repl`

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>JSON\_REPLACE('\[1, 2]', '\$', '\[3, 4]')</code></td>
            <td><code>\[3,4]</code></td>
          </tr>

          <tr>
            <td><code>JSON\_REPLACE('\[1, 2]', '\$.A', '"B"')</code></td>
            <td><code>\[1,2]</code></td>
          </tr>

          <tr>
            <td><code>JSON\_REPLACE('\{"A": \[2, 3]}', '\$.A', '\{"D": 5}')</code></td>
            <td><code>\{"A":\{"D":5}}</code></td>
          </tr>

          <tr>
            <td><code>JSON\_REPLACE('\{"A": \{"B": 3}}', '\$\["A"]', '"D"')</code></td>
            <td><code>\{"A":"D"}</code></td>
          </tr>

          <tr>
            <td><code>JSON\_REPLACE('\{"A": \{"B": \[3, 4]}}', '\$\["A"]\["B"]', 5)</code></td>
            <td><code>\{"A":\{"B":5}}</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="JSON_TYPE(expr)" id="json_type-expr" defaultOpen>
    Returns the JSON type of the given `expr`

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Expression Type</th>
            <th>JSON Type</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>BOOLEAN</code></td>
            <td><code>BOOLEAN</code></td>
          </tr>

          <tr>
            <td><ul><li><code>TINYINT</code></li><li><code>SMALLINT</code></li><li><code>INTEGER</code></li><li><code>BIGINT</code></li><li><code>UNSIGNED BIGINT</code></li></ul></td>
            <td><code>LONG</code></td>
          </tr>

          <tr>
            <td><ul><li><code>REAL</code></li><li><code>DOUBLE</code></li></ul></td>
            <td><code>DOUBLE</code></td>
          </tr>

          <tr>
            <td><ul><li><code>JSON</code></li><li><code>VARCHAR</code></li></ul></td>
            <td><ul><li><code>BOOLEAN</code> - if <code>true</code> or <code>false</code></li><li><code>LONG</code> - if an integer value</li><li><code>DOUBLE</code> - if a floating-point value</li><li><code>STRING</code> - if a double-quoted literal</li><li><code>OBJECT</code> - if a JSON map</li><li><code>ARRAY</code> - if a JSON array</li></ul></td>
          </tr>

          <tr>
            <td><code>ARRAY</code> *(any)*</td>
            <td><code>ARRAY</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="JSON_VALUE (json, path [return])" id="json_value-json-path-return" defaultOpen>
    Returns the JSON value at the given `path` in `json`; null, if the path doesn't exist
    or contains an object (non-primitive) value

    An optional `return` clause can be added to the end of the path to specify the return type
    of the value found, as well as the error handling for the value lookup.  The format of the
    clause is:

    ```
    [RETURNING <type>] [<empty_hand> ON EMPTY] [<error hand> ON ERROR]
    ```

    <Info>
      Return clause is only available in SQL or in the native API via
      [/execute/sql](/content/api/rest/execute_sql_rest).
    </Info>

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Parameter</th>
            <th>Description</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>\<type></code></td>
            <td>The JSON type of the value to return; if the value is not already of that type, it will be cast to that type, if possible Valid types include: <ul><li><code>BOOLEAN</code></li><li><code>LONG</code></li><li><code>DOUBLE</code></li><li><code>STRING</code></li></ul></td>
          </tr>

          <tr>
            <td><code>\<empty hand></code></td>
            <td>The scheme to use for handling empty returned values Valid schemes include: <ul><li><code>NULL</code> - return *null* *(default)*</li><li><code>ERROR</code> - throw an error</li><li><code>DEFAULT \<expr></code> - return the given expression <code>expr</code></li></ul></td>
          </tr>

          <tr>
            <td><code>\<error hand></code></td>
            <td>The scheme to use for handling errors in looking up the value Valid schemes include: <ul><li><code>NULL</code> - return *null* *(default)*</li><li><code>ERROR</code> - throw an error</li><li><code>DEFAULT \<expr></code> - return the given expression <code>expr</code></li></ul></td>
          </tr>
        </tbody>
      </table>
    </div>

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>JSON\_VALUE('1', '\$')</code></td>
            <td><code>1</code></td>
          </tr>

          <tr>
            <td><code>JSON\_VALUE('\[1, 2]', '\$.A')</code></td>
            <td>*null*</td>
          </tr>

          <tr>
            <td><code>JSON\_VALUE('\["A", "B"]', '\$.1')</code></td>
            <td><code>B</code></td>
          </tr>

          <tr>
            <td><code>JSON\_VALUE('\{"A": \[2, 3]}', '\$\["A"]\["1"]')</code></td>
            <td><code>3</code></td>
          </tr>

          <tr>
            <td><code>JSON\_VALUE('\{"A": \{"B": 3, "D": 5}}', '\$\["A"]\["D"]')</code></td>
            <td><code>5</code></td>
          </tr>

          <tr>
            <td><code>JSON\_VALUE('\{"A": \{"B": 3, "D": \[5, 6]}}', '\$.A.D.1')</code></td>
            <td><code>6</code></td>
          </tr>

          <tr>
            <td><code>JSON\_VALUE('1', '\$' RETURNING DOUBLE)</code></td>
            <td><code>1.0</code></td>
          </tr>

          <tr>
            <td><code>JSON\_VALUE('\{"A": \[]}', '\$.B' DEFAULT '\<null>' ON EMPTY)</code></td>
            <td><code>\<null></code></td>
          </tr>

          <tr>
            <td><code>JSON\_VALUE('\{"A": \[]}', '\$.A' ERROR ON ERROR)</code></td>
            <td>*error returned*</td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>
</AccordionGroup>

<a id="expression-functions-json-agg" />

#### Aggregation Functions

The following functions can be used on [JSON](/content/concepts/json)
columns within [aggregations](/content/concepts/expressions#aggregate-expressions-label).

<AccordionGroup>
  <Accordion title="JSON_ARRAYAGG(expr)" id="json_arrayagg-expr" defaultOpen>
    Combines column values within a group into a single JSON array of those values.

    See [examples](/content/concepts/json#json-func-agg-ex-agg).
  </Accordion>

  <Accordion title="JSON_ARRAYAGG_DISTINCT(expr)" id="json_arrayagg_distinct-expr" defaultOpen>
    Combines column values within a group into a single JSON array of those values,
    removing any duplicates.

    See [examples](/content/concepts/json#json-func-agg-ex-agg-dist).
  </Accordion>

  <Accordion title="JSON_COLLECT_SET(expr)" id="json_collect_set-expr" defaultOpen>
    Alias for `JSON_ARRAYAGG_DISTINCT`.
  </Accordion>
</AccordionGroup>

<a id="expression-functions-math" />

### Math Functions

#### Scalar Functions

<AccordionGroup>
  <Accordion title="ABS(expr)" id="abs-expr" defaultOpen>
    Calculates the absolute value of `expr`
  </Accordion>

  <Accordion title="ACOS(expr)" id="acos-expr" defaultOpen>
    Returns the inverse cosine (arccosine) of `expr` as a *double*
  </Accordion>

  <Accordion title="ACOSF(expr)" id="acosf-expr" defaultOpen>
    Returns the inverse cosine (arccosine) of `expr` as a *float*
  </Accordion>

  <Accordion title="ACOSH(expr)" id="acosh-expr" defaultOpen>
    Returns the inverse hyperbolic cosine of `expr` as a *double*
  </Accordion>

  <Accordion title="ACOSHF(expr)" id="acoshf-expr" defaultOpen>
    Returns the inverse hyperbolic cosine of `expr` as a *float*
  </Accordion>

  <Accordion title="ASIN(expr)" id="asin-expr" defaultOpen>
    Returns the inverse sine (arcsine) of `expr` as a *double*
  </Accordion>

  <Accordion title="ASINF(expr)" id="asinf-expr" defaultOpen>
    Returns the inverse sine (arcsine) of `expr` as a *float*
  </Accordion>

  <Accordion title="ASINH(expr)" id="asinh-expr" defaultOpen>
    Returns the inverse hyperbolic sine of `expr` as a *double*
  </Accordion>

  <Accordion title="ASINHF(expr)" id="asinhf-expr" defaultOpen>
    Returns the inverse hyperbolic sine of `expr` as a *float*
  </Accordion>

  <Accordion title="ATAN(expr)" id="atan-expr" defaultOpen>
    Returns the inverse tangent (arctangent) of `expr` as a *double*
  </Accordion>

  <Accordion title="ATANF(expr)" id="atanf-expr" defaultOpen>
    Returns the inverse tangent (arctangent) of `expr` as a *float*
  </Accordion>

  <Accordion title="ATANH(expr)" id="atanh-expr" defaultOpen>
    Returns the inverse hyperbolic tangent of `expr` as a *double*
  </Accordion>

  <Accordion title="ATANHF(expr)" id="atanhf-expr" defaultOpen>
    Returns the inverse hyperbolic tangent of `expr` as a *float*
  </Accordion>

  <Accordion title="ATAN2(x, y)" id="atan2-x-y" defaultOpen>
    Returns the inverse tangent (arctangent) using two arguments as a *double*
  </Accordion>

  <Accordion title="ATAN2F(x, y)" id="atan2f-x-y" defaultOpen>
    Returns the inverse tangent (arctangent) using two arguments as a *float*
  </Accordion>

  <Accordion title="ATN2(x, y)" id="atn2-x-y" defaultOpen>
    Alias for `ATAN2`
  </Accordion>

  <Accordion title="ATN2F(x, y)" id="atn2f-x-y" defaultOpen>
    Alias for `ATAN2F`
  </Accordion>

  <Accordion title="CBRT(expr)" id="cbrt-expr" defaultOpen>
    Returns the cube root of `expr` as a *double*
  </Accordion>

  <Accordion title="CBRTF(expr)" id="cbrtf-expr" defaultOpen>
    Returns the cube root of `expr` as a *float*
  </Accordion>

  <Accordion title="CEIL(expr)" id="ceil-expr" defaultOpen>
    Alias for `CEILING`
  </Accordion>

  <Accordion title="CEILING(expr)" id="ceiling-expr" defaultOpen>
    Rounds `expr` up to the next highest integer
  </Accordion>

  <Accordion title="COS(expr)" id="cos-expr" defaultOpen>
    Returns the cosine of `expr` as a *double*
  </Accordion>

  <Accordion title="COSF(expr)" id="cosf-expr" defaultOpen>
    Returns the cosine of `expr` as a *float*
  </Accordion>

  <Accordion title="COSH(expr)" id="cosh-expr" defaultOpen>
    Returns the hyperbolic cosine of `expr` as a *double*
  </Accordion>

  <Accordion title="COSHF(expr)" id="coshf-expr" defaultOpen>
    Returns the hyperbolic cosine of `expr` as a *float*
  </Accordion>

  <Accordion title="COT(expr)" id="cot-expr" defaultOpen>
    Returns the cotangent of `expr` as a *double*
  </Accordion>

  <Accordion title="COTF(expr)" id="cotf-expr" defaultOpen>
    Returns the cotangent of `expr` as a *float*
  </Accordion>

  <Accordion title="DEGREES(expr)" id="degrees-expr" defaultOpen>
    Returns the conversion of `expr` (in radians) to degrees as a *double*
  </Accordion>

  <Accordion title="DEGREESF(expr)" id="degreesf-expr" defaultOpen>
    Returns the conversion of `expr` (in radians) to degrees as a *float*
  </Accordion>

  <Accordion title="DIVZ(a, b, c)" id="divz-a-b-c" defaultOpen>
    Returns the quotient `a / b` unless `b == 0`, in which case it returns `c`
  </Accordion>

  <Accordion title="EXP(expr)" id="exp-expr" defaultOpen>
    Returns *e* to the power of `expr` as a *double*
  </Accordion>

  <Accordion title="EXPF(expr)" id="expf-expr" defaultOpen>
    Returns *e* to the power of `expr` as a *float*
  </Accordion>

  <Accordion title="FLOOR(expr)" id="floor-expr" defaultOpen>
    Rounds `expr` down to the next lowest integer
  </Accordion>

  <Accordion title="GREATER(expr_a, expr_b)" id="greater-expr_a-expr_b" defaultOpen>
    Returns whichever of `expr_a` and `expr_b` has the larger value, based on typed
    comparison
  </Accordion>

  <Accordion title="HYPOT(x, y)" id="hypot-x-y" defaultOpen>
    Returns the hypotenuse of `x` and `y` as a *double*
  </Accordion>

  <Accordion title="HYPOTF(x, y)" id="hypotf-x-y" defaultOpen>
    Returns the hypotenuse of `x` and `y` as a *float*
  </Accordion>

  <Accordion title="IFERROR(expr, val)" id="iferror-expr-val" defaultOpen>
    Alias for `IF_ERROR(expr, val)`
  </Accordion>

  <Accordion title="IFINF(expr, val)" id="ifinf-expr-val" defaultOpen>
    Alias for `IF_INF(expr, val)`
  </Accordion>

  <Accordion title="IFINFINITY(expr, val)" id="ifinfinity-expr-val" defaultOpen>
    Alias for `IF_INF(expr, val)`
  </Accordion>

  <Accordion title="IFNAN(expr, val)" id="ifnan-expr-val" defaultOpen>
    Alias for `IF_NAN(expr, val)`
  </Accordion>

  <Accordion title="IF_ERROR(expr, val)" id="if_error-expr-val" defaultOpen>
    Evaluates the given *double* or *float* `expr`, and if it resolves to infinity or
    `NaN`, return `val`

    <Tip>
      Conceptually, this function is the same as
      `IF_INF(IF_NAN(expr, val), val)`
    </Tip>

    Example:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>IF\_ERROR((double(10)/0), 1)</code></td>
            <td><code>1.0</code></td>
          </tr>

          <tr>
            <td><code>IF\_ERROR(log(-1), 1)</code></td>
            <td><code>1.0</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="IF_INF(expr, val)" id="if_inf-expr-val" defaultOpen>
    Evaluates the given *double* or *float* `expr`, and if it resolves to infinity,
    return `val`

    Example:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>IF\_INF((double(10)/0), 999)</code></td>
            <td><code>999.0</code></td>
          </tr>

          <tr>
            <td><code>IF\_INF(log(-1), 999)</code></td>
            <td><code>NaN</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="IF_INFINITY(expr, val)" id="if_infinity-expr-val" defaultOpen>
    Alias for `IF_INF(expr, val)`
  </Accordion>

  <Accordion title="IF_NAN(expr, val)" id="if_nan-expr-val" defaultOpen>
    Evaluates the given *double* or *float* `expr`, and if it resolves to `NaN`,
    return `val`

    Example:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>IF\_NAN((double(10)/0), -1)</code></td>
            <td><code>Infinity</code></td>
          </tr>

          <tr>
            <td><code>IF\_NAN(log(-1), -1)</code></td>
            <td><code>-1.0</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="ISINFINITY(expr)" id="isinfinity-expr" defaultOpen>
    Returns `1` (true) if `expr` is infinity by IEEE standard; otherwise, returns
    `0` (false)
  </Accordion>

  <Accordion title="IS_INFINITY(expr)" id="is_infinity-expr" defaultOpen>
    Alias for `ISINFINITY`
  </Accordion>

  <Accordion title="ISNAN(expr)" id="isnan-expr" defaultOpen>
    Returns `1` (true) if `expr` is not a number by IEEE standard; otherwise, returns
    `0` (false)
  </Accordion>

  <Accordion title="IS_NAN(expr)" id="is_nan-expr" defaultOpen>
    Alias for `ISNAN`
  </Accordion>

  <Accordion title="ISNUMERIC(expr)" id="isnumeric-expr" defaultOpen>
    Returns `1` (true) if `expr` is a number by IEEE standard; otherwise, returns
    `0` (false)
  </Accordion>

  <Accordion title="IS_NUMERIC(expr)" id="is_numeric-expr" defaultOpen>
    Alias for `ISNUMERIC`
  </Accordion>

  <Accordion title="LDEXP(x, exp)" id="ldexp-x-exp" defaultOpen>
    Returns the value of `x` \* 2<sup>exp</sup> as a *double*
  </Accordion>

  <Accordion title="LDEXPF(x, exp)" id="ldexpf-x-exp" defaultOpen>
    Returns the value of `x` \* 2<sup>exp</sup> as a *float*
  </Accordion>

  <Accordion title="LESSER(expr_a, expr_b)" id="lesser-expr_a-expr_b" defaultOpen>
    Returns whichever of `expr_a` and `expr_b` has the smaller value, based on typed
    comparison
  </Accordion>

  <Accordion title="LN(expr)" id="ln-expr" defaultOpen>
    Returns the natural logarithm of `expr` as a *double*
  </Accordion>

  <Accordion title="LNF(expr)" id="lnf-expr" defaultOpen>
    Returns the natural logarithm of `expr` as a *float*
  </Accordion>

  <Accordion title="LOG(expr)" id="log-expr" defaultOpen>
    Alias for `LN`
  </Accordion>

  <Accordion title="LOG10(expr)" id="log10-expr" defaultOpen>
    Returns the *base-10* logarithm of `expr` as a *double*
  </Accordion>

  <Accordion title="LOG10F(expr)" id="log10f-expr" defaultOpen>
    Returns the *base-10* logarithm of `expr` as a *float*
  </Accordion>

  <Accordion title="LOG1P(expr)" id="log1p-expr" defaultOpen>
    Returns the natural logarithm of one plus `expr` as a *double*
  </Accordion>

  <Accordion title="LOG1PF(expr)" id="log1pf-expr" defaultOpen>
    Returns the natural logarithm of one plus `expr` as a *float*
  </Accordion>

  <Accordion title="LOG2(expr)" id="log2-expr" defaultOpen>
    Returns the binary (*base-2*) logarithm of `expr` as a *double*
  </Accordion>

  <Accordion title="LOG2F(expr)" id="log2f-expr" defaultOpen>
    Returns the binary (*base-2*) logarithm of `expr` as a *float*
  </Accordion>

  <Accordion title="LOGF(expr)" id="logf-expr" defaultOpen>
    Alias for `LNF`
  </Accordion>

  <Accordion title="MAX_CONSECUTIVE_BITS(expr)" id="max_consecutive_bits-expr" defaultOpen>
    Calculates the length of the longest series of consecutive `1` bits in the integer
    `expr`
  </Accordion>

  <Accordion title="MOD(dividend, divisor)" id="mod-dividend-divisor" defaultOpen>
    Calculates the remainder after integer division of `dividend` by `divisor`
  </Accordion>

  <Accordion title="NEXT_AFTER(expr[, target])" id="next_after-expr-target" defaultOpen>
    Returns the next representable floating-point value adjacent to
    `expr` in the direction of `target`, incrementing `expr`
    if `target` is greater, decrementing if lesser.  The default
    value of `target` is `MAX_DOUBLE` (always increments when
    omitted).  The return type matches the input (*float* or *double*).
  </Accordion>

  <Accordion title="NEXT_BEFORE(expr)" id="next_before-expr" defaultOpen>
    Returns the next representable floating-point value less than
    `expr`.  The return type matches the input (*float* or *double*).
  </Accordion>

  <Accordion title="PI()" id="pi" defaultOpen>
    Returns the value of *pi*
  </Accordion>

  <Accordion title="POW(base, exponent)" id="pow-base-exponent" defaultOpen>
    Alias for `POWER`
  </Accordion>

  <Accordion title="POWF(base, exponent)" id="powf-base-exponent" defaultOpen>
    Alias for `POWERF`
  </Accordion>

  <Accordion title="POWER(base, exponent)" id="power-base-exponent" defaultOpen>
    Returns `base` raised to the power of `exponent` as a *double*
  </Accordion>

  <Accordion title="POWERF(base, exponent)" id="powerf-base-exponent" defaultOpen>
    Returns `base` raised to the power of `exponent` as a *float*
  </Accordion>

  <Accordion title="RADIANS(expr)" id="radians-expr" defaultOpen>
    Returns the conversion of `expr` (in degrees) to radians as a *double*
  </Accordion>

  <Accordion title="RADIANSF(expr)" id="radiansf-expr" defaultOpen>
    Returns the conversion of `expr` (in degrees) to radians as a *float*
  </Accordion>

  <Accordion title="RAND([seed])" id="rand-seed" defaultOpen>
    Returns a random floating-point value, with an optional `seed`
  </Accordion>

  <Accordion title="REGR_VALX(y, x)" id="regr_valx-y-x" defaultOpen>
    Returns NULL if `y` is NULL; otherwise, returns `x`
  </Accordion>

  <Accordion title="REGR_VALY(y, x)" id="regr_valy-y-x" defaultOpen>
    Returns NULL if `x` is NULL; otherwise, returns `y`
  </Accordion>

  <Accordion title="ROUND(expr[, scale])" id="round-expr-scale" defaultOpen>
    Rounds `expr` to the nearest decimal number with `scale`
    decimal places when `scale` is a positive number; rounds to
    the nearest number such that the result has `-(scale)` zeros
    to the left of the decimal point when `scale` is negative; use
    `scale` of `0` to round to the nearest integer.

    The default value of `scale` is `0`.

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>ROUND(12345.678)</code></td>
            <td><code>12346</code></td>
          </tr>

          <tr>
            <td><code>ROUND(12345.678, 2)</code></td>
            <td><code>12345.68</code></td>
          </tr>

          <tr>
            <td><code>ROUND(12345.678, 0)</code></td>
            <td><code>12346</code></td>
          </tr>

          <tr>
            <td><code>ROUND(12345.678, -2)</code></td>
            <td><code>12300</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="SIGN(expr)" id="sign-expr" defaultOpen>
    Determines whether a number is positive, negative, or zero;
    returns one of the following three values:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Expression Value</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td>*positive*</td>
            <td><code>1</code></td>
          </tr>

          <tr>
            <td>*zero*</td>
            <td><code>0</code></td>
          </tr>

          <tr>
            <td>*negative*</td>
            <td><code>-1</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="SIN(expr)" id="sin-expr" defaultOpen>
    Returns the sine of `expr` as a *double*
  </Accordion>

  <Accordion title="SINF(expr)" id="sinf-expr" defaultOpen>
    Returns the sine of `expr` as a *float*
  </Accordion>

  <Accordion title="SINH(expr)" id="sinh-expr" defaultOpen>
    Returns the hyperbolic sine of `expr` as a *double*
  </Accordion>

  <Accordion title="SINHF(expr)" id="sinhf-expr" defaultOpen>
    Returns the hyperbolic sine of `expr` as a *float*
  </Accordion>

  <Accordion title="SQRT(expr)" id="sqrt-expr" defaultOpen>
    Returns the square root of `expr` as a *double*
  </Accordion>

  <Accordion title="SQRTF(expr)" id="sqrtf-expr" defaultOpen>
    Returns the square root of `expr` as a *float*
  </Accordion>

  <Accordion title="TAN(expr)" id="tan-expr" defaultOpen>
    Returns the tangent of `expr` as a *double*
  </Accordion>

  <Accordion title="TANF(expr)" id="tanf-expr" defaultOpen>
    Returns the tangent of `expr` as a *float*
  </Accordion>

  <Accordion title="TANH(expr)" id="tanh-expr" defaultOpen>
    Returns the hyperbolic tangent of `expr` as a *double*
  </Accordion>

  <Accordion title="TANHF(expr)" id="tanhf-expr" defaultOpen>
    Returns the hyperbolic tangent of `expr` as a *float*
  </Accordion>

  <Accordion title="TRUNCATE(expr[, scale])" id="truncate-expr-scale" defaultOpen>
    Rounds `expr` down to the nearest decimal number with
    `scale` decimal places when `scale` is a positive number;
    rounds down to the nearest number such that the result has
    `-(scale)` zeros to the left of the decimal point when
    `scale` is negative; use `scale` of `0` to round down to
    the nearest integer.

    The default value of `scale` is `0`.

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>TRUNCATE(12345.678)</code></td>
            <td><code>12345</code></td>
          </tr>

          <tr>
            <td><code>TRUNCATE(12345.678, 2)</code></td>
            <td><code>12345.67</code></td>
          </tr>

          <tr>
            <td><code>TRUNCATE(12345.678, 0)</code></td>
            <td><code>12345</code></td>
          </tr>

          <tr>
            <td><code>TRUNCATE(12345.678, -2)</code></td>
            <td><code>12300</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="WIDTH_BUCKET(expr, min, max, count)" id="width_bucket-expr-min-max-count" defaultOpen>
    Defines a set of `count` equal intervals (buckets) within the range of `min` &
    `max`, and puts the value of `expr` into one of those buckets, where the value is
    greater than or equal to the minimum value of the bucket and less than the maximum
    value of the bucket.  Returns the 1-based number of the bucket into which the value
    of `expr` fell.  For values smaller than `min`, `0` is returned; for values
    greater than or equal to `max`, `count + 1` is returned.  Examples:

    In the following examples, a set of *5* equal buckets are defined between *0* and
    *10* (*0-2*, *2-4*, *4-6*, *6-8*, & *8-10*), and various values are bucketed using
    that set.

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>WIDTH\_BUCKET(-1, 0, 10, 5)</code></td>
            <td><code>0</code></td>
          </tr>

          <tr>
            <td><code>WIDTH\_BUCKET(0, 0, 10, 5)</code></td>
            <td><code>1</code></td>
          </tr>

          <tr>
            <td><code>WIDTH\_BUCKET(5, 0, 10, 5)</code></td>
            <td><code>3</code></td>
          </tr>

          <tr>
            <td><code>WIDTH\_BUCKET(10, 0, 10, 5)</code></td>
            <td><code>6</code></td>
          </tr>

          <tr>
            <td><code>WIDTH\_BUCKET(11, 0, 10, 5)</code></td>
            <td><code>6</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>
</AccordionGroup>

<a id="expression-functions-math-agg" />

#### Aggregate Functions

The following functions can be used on numeric
columns within [aggregations](/content/concepts/expressions#aggregate-expressions-label).

<AccordionGroup>
  <Accordion title="APPROX_COUNT_DISTINCT(expr)" id="approx_count_distinct-expr" defaultOpen>
    The approximate number of distinct values of `expr`; this is faster to calculate than `COUNT_DISTINCT` but is only an approximation
  </Accordion>

  <Accordion title="APPROX_MEDIAN(expr)" id="approx_median-expr" defaultOpen>
    The approximate median of `expr`; the result should be within about *2%* of the true median value. This is equivalent to issuing
    `APPROX_PERCENTILE(expr, 50)`.
  </Accordion>

  <Accordion title="APPROX_PERCENTILE(expr, p)" id="approx_percentile-expr-p" defaultOpen>
    The approximate *pth* percentile of `expr`; `p` should be a value between *0.0* and *100.0*. `APPROX_PERCENTILE(expr, 50)` will return
    the approximate median of `expr`.
  </Accordion>

  <Accordion title="AVG(expr)" id="avg-expr" defaultOpen>
    Average of the values of `expr`
  </Accordion>

  <Accordion title="CORR(expr1, expr2)" id="corr-expr1-expr2" defaultOpen>
    Correlation coefficient of the values of `expr1` and `expr2`
  </Accordion>

  <Accordion title="CORRELATION(expr1, expr2)" id="correlation-expr1-expr2" defaultOpen>
    Alias for `CORR`
  </Accordion>

  <Accordion title="CORRCOEF(expr1, expr2)" id="corrcoef-expr1-expr2" defaultOpen>
    Alias for `CORR`
  </Accordion>

  <Accordion title="COUNT(expr)" id="count-expr" defaultOpen>
    Count of non-null values of `expr`; use `*` to count all values within an aggregation group or over an entire table
  </Accordion>

  <Accordion title="COUNT_DISTINCT(expr)" id="count_distinct-expr" defaultOpen>
    Count of the distinct values of `expr`
  </Accordion>

  <Accordion title="COV(expr1, expr2)" id="cov-expr1-expr2" defaultOpen>
    Alias for `COVAR_POP`
  </Accordion>

  <Accordion title="COVAR(expr1, expr2)" id="covar-expr1-expr2" defaultOpen>
    Alias for `COVAR_POP`
  </Accordion>

  <Accordion title="COVARIANCE(expr1, expr2)" id="covariance-expr1-expr2" defaultOpen>
    Alias for `COVAR_POP`
  </Accordion>

  <Accordion title="COVAR_POP(expr1, expr2)" id="covar_pop-expr1-expr2" defaultOpen>
    Population covariance of the values of `expr1` and `expr2`
  </Accordion>

  <Accordion title="COVAR_SAMP(expr1, expr2)" id="covar_samp-expr1-expr2" defaultOpen>
    Sample covariance of the values of `expr1` and `expr2`
  </Accordion>

  <Accordion title="KURT(expr)" id="kurt-expr" defaultOpen>
    Alias for `KURTOSIS_POP`
  </Accordion>

  <Accordion title="KURTOSIS(expr)" id="kurtosis-expr" defaultOpen>
    Alias for `KURTOSIS_POP`
  </Accordion>

  <Accordion title="KURTOSIS_POP(expr)" id="kurtosis_pop-expr" defaultOpen>
    Population kurtosis of the values of `expr`
  </Accordion>

  <Accordion title="KURTOSIS_SAMP(expr)" id="kurtosis_samp-expr" defaultOpen>
    Sample kurtosis of the values of `expr`
  </Accordion>

  <Accordion title="KURT_POP(expr)" id="kurt_pop-expr" defaultOpen>
    Alias for `KURTOSIS_POP`
  </Accordion>

  <Accordion title="KURT_SAMP(expr)" id="kurt_samp-expr" defaultOpen>
    Alias for `KURTOSIS_SAMP`
  </Accordion>

  <Accordion title="MAX(expr)" id="max-expr" defaultOpen>
    Maximum of the values of `expr`
  </Accordion>

  <Accordion title="MEAN(expr)" id="mean-expr" defaultOpen>
    Alias for `AVG`
  </Accordion>

  <Accordion title="MIN(expr)" id="min-expr" defaultOpen>
    Minimum of the values of `expr`
  </Accordion>

  <Accordion title="PRODUCT(expr)" id="product-expr" defaultOpen>
    Product of the values of `expr`
  </Accordion>

  <Accordion title="REGR_AVGX(y, x)" id="regr_avgx-y-x" defaultOpen>
    Average of the independent variable (`SUM(x)/N`) of the line determined by computing a least-squares-fit linear regression over the given (X, Y)
    pairs
  </Accordion>

  <Accordion title="REGR_AVGY(y, x)" id="regr_avgy-y-x" defaultOpen>
    Average of the dependent variable (`SUM(y)/N`) of the line determined by computing a least-squares-fit linear regression over the given (X, Y)
    pairs
  </Accordion>

  <Accordion title="REGR_COUNT(y, x)" id="regr_count-y-x" defaultOpen>
    Number of input rows used in computing a linear regression, where both expressions are non-null
  </Accordion>

  <Accordion title="REGR_INTERCEPT(y, x)" id="regr_intercept-y-x" defaultOpen>
    Y-intercept of the line determined by computing a least-squares-fit linear regression over the given (X, Y) pairs
  </Accordion>

  <Accordion title="REGR_R2(y, x)" id="regr_r2-y-x" defaultOpen>
    Square of the correlation coefficient, marking how well the least-squares-fit linear regression fit the data set
  </Accordion>

  <Accordion title="REGR_SLOPE(y, x)" id="regr_slope-y-x" defaultOpen>
    Slope of the line determined by computing a least-squares-fit linear regression over the given (X, Y) pairs
  </Accordion>

  <Accordion title="REGR_SXX(y, x)" id="regr_sxx-y-x" defaultOpen>
    "Sum of squares" of the independent variable (`SUM(x^2) - SUM(x)^2/N`) of the line determined by computing a least-squares-fit linear regression
    over the given (X, Y) pairs
  </Accordion>

  <Accordion title="REGR_SXY(y, x)" id="regr_sxy-y-x" defaultOpen>
    "Sum of Products" of independent variable times dependent variable (`SUM(x * y) - SUM(x) * SUM(y)/N`) of the line determined by computing a
    least-squares-fit linear regression over the given (X, Y) pairs
  </Accordion>

  <Accordion title="REGR_SYY(y, x)" id="regr_syy-y-x" defaultOpen>
    "Sum of squares" of the dependent variable (`SUM(y^2) - SUM(y)^2/N`) of the line determined by computing a least-squares-fit linear regression
    over the given (X, Y) pairs
  </Accordion>

  <Accordion title="SKEW(expr)" id="skew-expr" defaultOpen>
    Alias for `SKEWNESS_POP`
  </Accordion>

  <Accordion title="SKEWNESS(expr)" id="skewness-expr" defaultOpen>
    Alias for `SKEWNESS_POP`
  </Accordion>

  <Accordion title="SKEWNESS_POP(expr)" id="skewness_pop-expr" defaultOpen>
    Population skew of the values of `expr`
  </Accordion>

  <Accordion title="SKEWNESS_SAMP(expr)" id="skewness_samp-expr" defaultOpen>
    Sample skew of the values of `expr`
  </Accordion>

  <Accordion title="SKEW_POP(expr)" id="skew_pop-expr" defaultOpen>
    Alias for `SKEWNESS_POP`
  </Accordion>

  <Accordion title="SKEW_SAMP(expr)" id="skew_samp-expr" defaultOpen>
    Alias for `SKEWNESS_SAMP`
  </Accordion>

  <Accordion title="STDDEV(expr)" id="stddev-expr" defaultOpen>
    Population standard deviation over values of `expr` (i.e. the denominator is *N*)
  </Accordion>

  <Accordion title="STDDEV_POP(expr)" id="stddev_pop-expr" defaultOpen>
    Population standard deviation over values of `expr` (i.e. the denominator is *N*)
  </Accordion>

  <Accordion title="STDDEV_SAMP(expr)" id="stddev_samp-expr" defaultOpen>
    Sample standard deviation over values of `expr` (i.e. the denominator is *N-1*)
  </Accordion>

  <Accordion title="SUM(expr)" id="sum-expr" defaultOpen>
    Sum of the values of `expr`
  </Accordion>

  <Accordion title="VAR(expr)" id="var-expr" defaultOpen>
    Population variance over values of `expr` (i.e. the denominator is *N*)
  </Accordion>

  <Accordion title="VAR_POP(expr)" id="var_pop-expr" defaultOpen>
    Population variance over values of `expr` (i.e. the denominator is *N*)
  </Accordion>

  <Accordion title="VAR_SAMP(expr)" id="var_samp-expr" defaultOpen>
    Sample variance over values of `expr` (i.e. the denominator is *N-1*)
  </Accordion>

  <Accordion title="VARIANCE(expr)" id="variance-expr" defaultOpen>
    Alias for `VAR`
  </Accordion>

  <Accordion title="VARIANCE_POP(expr)" id="variance_pop-expr" defaultOpen>
    Alias for `VAR_POP`
  </Accordion>

  <Accordion title="VARIANCE_SAMP(expr)" id="variance_samp-expr" defaultOpen>
    Alias for `VAR_SAMP`
  </Accordion>
</AccordionGroup>

<a id="null-expression-functions" />

### Null Functions

<Note>
  Be mindful that no error is thrown when *Kinetica* tries to
  convert different data [type](/content/concepts/types#types) in the *Null*
  functions below, so if the output is unexpected, it may be that
  the *types* used aren't of the same *type*.
</Note>

<AccordionGroup>
  <Accordion title="IS_NULL(expr)" id="is_null-expr" defaultOpen>
    Returns `1` (true) if `expr` is *null*; otherwise, returns `0`
    (false)
  </Accordion>

  <Accordion title="ISNULL(expr)" id="isnull-expr" defaultOpen>
    Alias for `IS_NULL(expr)`
  </Accordion>

  <Accordion title="NULLIF(expr_a, expr_b)" id="nullif-expr_a-expr_b" defaultOpen>
    Returns *null* if `expr_a` equals `expr_b`; otherwise, returns the
    value of `expr_a`. Both expressions should be of the same convertible
    data type
  </Accordion>

  <Accordion title="NVL(expr_a, expr_b)" id="nvl-expr_a-expr_b" defaultOpen>
    Returns `expr_a` if it is not *null*; otherwise, returns `expr_b`.
    Both expressions should be of the same convertible data type; see
    [Short-Circuiting](/content/concepts/expressions#short-circuiting) for error-checking details
  </Accordion>

  <Accordion title="NVL2(expr, value_if_not_null, value_if_null)" id="nvl2-expr-value_if_not_null-value_if_null" defaultOpen>
    Evaluates `expr`: if `expr` does not return a *null*,
    `value_if_not_null` is returned. If `expr` does return a *null*,
    `value_if_null` is returned. Both `value_if_not_null` and
    `value_if_null` should be of the same data type as `expr` or
    implicitly convertible; see [Short-Circuiting](/content/concepts/expressions#short-circuiting) for error-checking details
  </Accordion>

  <Accordion title="REMOVE_NULLABLE(expr)" id="remove_nullable-expr" defaultOpen>
    Alias for `ZEROIFNULL`
  </Accordion>

  <Accordion title="ZEROIFNULL(expr)" id="zeroifnull-expr" defaultOpen>
    Replaces *null* values with appropriate values based on the column type (e.g., `0` if
    numeric column, an empty string if string column, etc.). Also removes the `nullable`
    [column property](/content/concepts/types) if used to calculate a derived column.
  </Accordion>
</AccordionGroup>

<a id="expression-functions-dist" />

### Record Distribution Functions

Record distribution functions provide a means to locate any database record
within the memory processing hierarchy; and through aggregating the results,
determine the distribution of records across the cluster.

<AccordionGroup>
  <Accordion title="KI_CHUNK()" id="ki_chunk" defaultOpen>
    Returns the index of the chunk within the rank/TOM containing this record.
    This value may change as data is added or deleted from a table.
  </Accordion>

  <Accordion title="KI_CHUNK_ID()" id="ki_chunk_id" defaultOpen>
    Returns the ID of the chunk within the rank/TOM containing this record.
    This value should remain the same even after system restarts.
  </Accordion>

  <Accordion title="KI_CHUNK_MAX(col)" id="ki_chunk_max-col" defaultOpen>
    Returns the maximum value for the specified column in its chunk.
    If the data has changed, this value may be higher than any actual values.
  </Accordion>

  <Accordion title="KI_CHUNK_MIN(col)" id="ki_chunk_min-col" defaultOpen>
    Returns the minimum value for the specified column in its chunk.
    If the data has changed, this value may be lower than any actual values.
  </Accordion>

  <Accordion title="KI_CHUNK_OFFSET()" id="ki_chunk_offset" defaultOpen>
    Returns the index of the record within the chunk.
  </Accordion>

  <Accordion title="KI_PARTITION()" id="ki_partition" defaultOpen>
    Returns the index of the partition within the rank/TOM containing this record, for
    [partitioned](/content/concepts/tables#partitioning) tables.
  </Accordion>

  <Accordion title="KI_RANK()" id="ki_rank" defaultOpen>
    Returns the index of the rank containing this record.
  </Accordion>

  <Accordion title="KI_TOM()" id="ki_tom" defaultOpen>
    Returns the index of the TOM within the rank containing this record.
  </Accordion>
</AccordionGroup>

<a id="expression-functions-string" />

### String Functions

There are two different types of string functions:

* [Scalar Functions](/content/concepts/expressions#expression-functions-string-scalar)
* [Aggregate Functions](/content/concepts/expressions#expression-functions-string-agg)

<Note>
  String columns are stored as byte arrays, but allow multi-byte
  characters, as they are UTF-8 encoded.  Some functions may behave in
  unexpected ways when given multi-byte input.
</Note>

<a id="expression-functions-string-scalar" />

#### Scalar Functions

<AccordionGroup>
  <Accordion title="ASCII(expr)" id="ascii-expr" defaultOpen>
    Returns the ASCII code for the first byte in `expr`
  </Accordion>

  <Accordion title="BIN(expr[, minimum_digits])" id="bin-expr-minimum_digits" defaultOpen>
    Convert the value represented by `expr` into a binary string
    representation.  Use optional `minimum_digits` to add leading 0s
    when needed; defaults to 1.

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>BIN(42)</code></td>
            <td><code>'101010'</code></td>
          </tr>

          <tr>
            <td><code>BIN(42, 8)</code></td>
            <td><code>'00101010'</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="CHAR(expr)" id="char-expr-2" defaultOpen>
    The character represented by the standard ASCII code `expr` in the
    range \[ `0` - `127` ]
  </Accordion>

  <Accordion title="CONCAT(expr_a, expr_b)" id="concat-expr_a-expr_b" defaultOpen>
    Performs a string concatenation of `expr_a` & `expr_b`; use nested
    `CONCAT` calls to concatenate more than two strings

    <Info>
      The resulting field size of any `CONCAT` will be a string
      field big enough to hold the concatenated fields, e.g.,
      concatenating a *char32* column and a *char64* column will
      result in a *char128* column.  Concatenations longer than
      256 characters will use an unrestricted-width string type.
    </Info>
  </Accordion>

  <Accordion title="CONCAT_TRUNCATE(expr_a, expr_b)" id="concat_truncate-expr_a-expr_b" defaultOpen>
    Returns the concatenation of `expr_a` and `expr_b`, truncated at
    the maximum size of the larger of `expr_a` and `expr_b`.
    For data columns, the size is explicit; for string constants, the size
    will be the smallest *charN* type that can hold the constant string.

    <Info>
      `CONCAT_TRUNCATE` will not work if any parameter is an
      unrestricted-width string.
    </Info>

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>CONCAT\_TRUNCATE('ABC123','!')</code></td>
            <td><code>ABC123!</code></td>
          </tr>

          <tr>
            <td><code>CONCAT\_TRUNCATE('AB','CDE')</code></td>
            <td><code>ABCD</code> *(char4 is* *the minimum size* *required to hold the* <code>CDE</code> *value, so* *the result is truncated* *at 4 characters)*</td>
          </tr>

          <tr>
            <td><code>CONCAT\_TRUNCATE('ABCD1234','DEFG')</code></td>
            <td><code>ABCD1234</code> *(an 8-character string* *is the minimum size* *required to hold the* <code>ABCD1234</code> *value, so* *no characters can be* *appended)*</td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="CONTAINS(match, expr)" id="contains-match-expr" defaultOpen>
    Returns `1` if `expr` contains `match` by
    string-literal comparison; otherwise, returns `0`
  </Accordion>

  <Accordion title="CONV(expr, from_base, to_base)" id="conv-expr-from_base-to_base" defaultOpen>
    Convert the value represented by the `expr` string from one
    numeric base to another.  Base parameters may be \[`2` - `36`].
    Binary, octal and hexadecimal strings may have an optional prefix.

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>CONV('42', 10, 16)</code></td>
            <td><code>'2A'</code></td>
          </tr>

          <tr>
            <td><code>CONV('2a', 16, 10)</code></td>
            <td><code>'42'</code></td>
          </tr>

          <tr>
            <td><code>CONV('11', 2, 10)</code></td>
            <td><code>'3'</code></td>
          </tr>

          <tr>
            <td><code>CONV('0o52', 8, 2)</code></td>
            <td><code>'101010'</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="DEC2HEX(expr[, minimum_digits])" id="dec2hex-expr-minimum_digits" defaultOpen>
    Alias for `HEX`
  </Accordion>

  <Accordion title="DIFFERENCE(expr_a, expr_b)" id="difference-expr_a-expr_b" defaultOpen>
    Returns a value between `0` and `4` that represents the difference
    between the sounds of `expr_a` and `expr_b` based on the
    `SOUNDEX()` value of the strings--a value of `4` is the best
    possible sound match
  </Accordion>

  <Accordion title="EDIT_DISTANCE(expr_a, expr_b)" id="edit_distance-expr_a-expr_b" defaultOpen>
    Returns the Levenshtein edit distance between `expr_a` and
    `expr_b`; the lower the value, the more similar the two strings are
  </Accordion>

  <Accordion title="ENDS_WITH(match, expr)" id="ends_with-match-expr" defaultOpen>
    Returns `1` if `expr` ends with `match` by
    string-literal comparison; otherwise, returns `0`
  </Accordion>

  <Accordion title="FROM_HEX(expr)" id="from_hex-expr" defaultOpen>
    Alias for `UNHEX`
  </Accordion>

  <Accordion title="HEX(expr[, minimum_digits])" id="hex-expr-minimum_digits" defaultOpen>
    Convert the value represented by `expr` into a hexadecimal string
    representation.  Use optional `minimum_digits` to add leading 0s
    when needed; defaults to 1.

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>HEX(42)</code></td>
            <td><code>'2A'</code></td>
          </tr>

          <tr>
            <td><code>HEX(42, 8)</code></td>
            <td><code>'0000002A'</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="HEX2DEC(expr)" id="hex2dec-expr" defaultOpen>
    Alias for `UNHEX`
  </Accordion>

  <Accordion title="ILIKE(expr, match[, esc_char])" id="ilike-expr-match-esc_char" defaultOpen>
    Returns whether `expr` matches the given `match`.  The
    match is a string literal one with the following exceptions:

    * `%` matches any string of 0 or more characters
    * `_` matches any single character
    * `[character_set]` matches any single character listed in the set.
      The `character_set` may contain ranges using a dash (`-`).  A
      A `character_set` starting with `^` will match any character not
      in the specified set.

    By default, the escape character used to match special characters,
    such as `%`, in the `expr` literally is `\`.  The `esc_char`,
    if given, will override this default escape character.

    `ILIKE` is case-insensitive.  For a case-sensitive match, see
    `LIKE`.

    <Info>
      The match expression has to match the reference expression
      completely--it will not return *true* for partial matches.
      Add `%` before and/or after the match for partial matches.
    </Info>

    Examples of successful matches:

    | Function Call                      |
    | ---------------------------------- |
    | `ILIKE('Brook', 'BROOK')`          |
    | `ILIKE('Brooke', 'BROOK_')`        |
    | `ILIKE('Brooklyn', 'BROOK%')`      |
    | `ILIKE('50_50', '50\\_50')`        |
    | `ILIKE('100%', '100\\%')`          |
    | `ILIKE('50\\50', '50\\\\50')`      |
    | `ILIKE('abqd', 'AB[A-Z]D')`        |
    | `ILIKE('abqd', 'AB[^0-9]D')`       |
    | `ILIKE('ab-d', 'AB[123~-]D', '~')` |
    | `ILIKE('a_c', 'A~_C', '~')`        |
    | `ILIKE('100%', '100~%', '~')`      |
  </Accordion>

  <Accordion title="INITCAP(expr)" id="initcap-expr" defaultOpen>
    Returns `expr` with the first letter of each word in uppercase
  </Accordion>

  <Accordion title="IPV4_PART(expr, part_num)" id="ipv4_part-expr-part_num" defaultOpen>
    Returns the octet of the IP address given in `expr` at the position
    specified by `part_num`.   Valid `part_num` values are constants
    from `1` to `4`.

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>IPV4\_PART('12.34.56.78', 1)</code></td>
            <td><code>12</code></td>
          </tr>

          <tr>
            <td><code>IPV4\_PART('12.34.56.78', 4)</code></td>
            <td><code>78</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="IS_IPV4(expr)" id="is_ipv4-expr" defaultOpen>
    Returns `1` if `expr` is an IPV4 address; returns `0` otherwise
  </Accordion>

  <Accordion title="ISIPV4(expr)" id="isipv4-expr" defaultOpen>
    Alias for `IS_IPV4`
  </Accordion>

  <Accordion title="LCASE(expr)" id="lcase-expr" defaultOpen>
    Converts `expr` to lowercase
  </Accordion>

  <Accordion title="LEFT(expr, num_bytes)" id="left-expr-num_bytes" defaultOpen>
    Returns the leftmost `num_bytes` bytes from `expr`
  </Accordion>

  <Accordion title="LEN(expr)" id="len-expr" defaultOpen>
    Alias for `LENGTH`
  </Accordion>

  <Accordion title="LENGTH(expr)" id="length-expr" defaultOpen>
    Returns the number of characters in `expr`
  </Accordion>

  <Accordion title="LIKE(expr, match[, esc_char])" id="like-expr-match-esc_char" defaultOpen>
    Returns whether `expr` matches the given `match`.  The
    match is a string literal one with the following exceptions:

    * `%` matches any string of 0 or more characters
    * `_` matches any single character
    * `[character_set]` matches any single character listed in the set.
      The `character_set` may contain ranges using a dash (`-`).  A
      A `character_set` starting with `^` will match any character not
      in the specified set.

    By default, the escape character used to match special characters,
    such as `%`, in the `expr` literally is `\`.  The `esc_char`,
    if given, will override this default escape character.

    `LIKE` is case-sensitive.  For a case-insensitive match, see
    `ILIKE`.

    <Info>
      The match expression has to match the reference expression
      completely--it will not return *true* for partial matches.
      Add `%` before and/or after the match for partial matches.
    </Info>

    Examples of successful matches:

    | Function Call                     |
    | --------------------------------- |
    | `LIKE('Brook', 'Brook')`          |
    | `LIKE('Brooke', 'Brook_')`        |
    | `LIKE('Brooklyn', 'Brook%')`      |
    | `LIKE('50_50', '50\\_50')`        |
    | `LIKE('100%', '100\\%')`          |
    | `LIKE('50\\50', '50\\\\50')`      |
    | `LIKE('abqd', 'ab[a-z]d')`        |
    | `LIKE('abqd', 'ab[^0-9]d')`       |
    | `LIKE('ab-d', 'ab[123~-]d', '~')` |
    | `LIKE('a_c', 'a~_c', '~')`        |
    | `LIKE('100%', '100~%', '~')`      |
  </Accordion>

  <Accordion title="LOCATE(match, expr[, start_pos])" id="locate-match-expr-start_pos" defaultOpen>
    Returns the starting position of the first match of `match` in
    `expr`, starting from position 1 or `start_pos` (if
    specified).  If `match` can't be found or `start_pos` is
    outside the range of letters in `expr`, a `0` is returned.
  </Accordion>

  <Accordion title="LOWER(expr)" id="lower-expr" defaultOpen>
    Alias for `LCASE`
  </Accordion>

  <Accordion title="LPAD(expr, length[, pad])" id="lpad-expr-length-pad" defaultOpen>
    Left pads the given `expr` string with the `pad` string
    to the given `length` of bytes. If `expr` is longer than
    `length`, the return value is shortened to `length` bytes. If
    `length` is larger than 256, it will be truncated to 256 bytes.  The
    default padding character is a space.

    <Warning>
      The use of multi-byte characters in this function may
      have unexpected results.
    </Warning>

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>LPAD('test', 9, 'pad')</code></td>
            <td><code>padpatest</code></td>
          </tr>

          <tr>
            <td><code>LPAD('test', 3, 'pad')</code></td>
            <td><code>tes</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="LTRIM(expr)" id="ltrim-expr" defaultOpen>
    Removes whitespace from the left side of `expr`
  </Accordion>

  <Accordion title="OCT(expr[, minimum_digits])" id="oct-expr-minimum_digits" defaultOpen>
    Convert the value represented by `expr` into an octal (base 8)
    string representation.  Use optional `minimum_digits` to add leading
    0s when needed; defaults to 1.

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>OCT(42)</code></td>
            <td><code>'52'</code></td>
          </tr>

          <tr>
            <td><code>OCT(42, 8)</code></td>
            <td><code>'00000052'</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="POSITION(match, expr[, start_pos])" id="position-match-expr-start_pos" defaultOpen>
    Alias for `LOCATE`
  </Accordion>

  <Accordion title="REGEXP_COUNT (expr, regex[, position [, mode]])" id="regexp_count-expr-regex-position-mode" defaultOpen>
    Returns a count of the number of times the `regex` pattern is
    matched in `expr`.  Matches do not overlap, so the start of a future
    match must start after the end of the previous match.

    The `regex` parameter is the regular expression to try to match.
    It must be a string-literal with 256 characters or fewer.  Generally,
    POSIX-compliant regular expressions are supported for `regex`.
    The escape character used to match wildcards in the `expr` literally
    is `\`.  See `REGEXP_LIKE` for more regular expression examples.

    The optional `position` parameter specifies where to start searching
    in `expr` for the first match.  The first character in the string
    has a `position` of `1` (the default).

    The optional `mode` parameter is a string which can be empty
    (the default) for the default behavior.  See `REGEXP_LIKE` for the
    list of supported mode flags.

    Examples of `REGEXP_COUNT`:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>REGEXP\_COUNT('abababab', 'abab')</code></td>
            <td>2</td>
          </tr>

          <tr>
            <td><code>REGEXP\_COUNT('abababab', 'abab', 2)</code></td>
            <td>1</td>
          </tr>

          <tr>
            <td><code>REGEXP\_COUNT('don''t', 'DON''T', 1, 'i')</code></td>
            <td>1</td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="REGEXP_INSTR (expr, regex [, position [, occurrence [, begin_end [, mode [,group]]]]])" id="regexp_instr-expr-regex-position-occurrence-begin_end-mode-group" defaultOpen>
    Returns the starting position (1-based) in `expr` where a `regex`
    match is found.  If no match is found, `0` is returned.

    The `regex` parameter is the regular expression to try to match.
    It must be a string-literal with 256 characters or fewer.  Generally,
    POSIX-compliant regular expressions are supported for `regex`.
    The escape character used to match wildcards in the `expr` literally
    is `\`.  See `REGEXP_LIKE` for more regular expression examples.

    The optional `position` parameter specifies where to start searching
    in `expr` for the first match.  The first character in the string
    has a `position` of `1` (the default).

    The optional `occurrence` parameter specifies which occurrence of
    the `regex` match is desired.  For example, `2` would return the
    second occurrence of `regex` in `expr`.  Matches do not overlap,
    so the start of a future match must start after the end of the
    previous match.

    The optional `begin_end` parameter specifies if the beginning or
    ending position is desired.  Use `0` (the default) for the beginning
    of the match and use `1` for the position after the end of the
    match.

    The optional `mode` parameter is a string which can be empty
    (the default) for the default behavior.  See `REGEXP_LIKE` for the
    list of supported mode flags.

    The optional `group` parameter specifies which regular expression
    group's (i.e., parentheses inside `regex`) beginning/ending position
    to return.  The default of `0` uses the entire matched expression,
    while a `group` of `1`  through `9` corresponds to the 1st group
    up through the 9th group of the match.

    Examples of `REGEXP_INSTR`:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>REGEXP\_INSTR('abcdefg', 'bc')</code></td>
            <td>2</td>
          </tr>

          <tr>
            <td><code>REGEXP\_INSTR('abcdefg', 'ab', 2)</code></td>
            <td>0</td>
          </tr>

          <tr>
            <td><code>REGEXP\_INSTR('abcabc', 'a', 1, 2)</code></td>
            <td>4</td>
          </tr>

          <tr>
            <td><code>REGEXP\_INSTR('abcabc', 'abc', 1, 1, 1)</code></td>
            <td>4</td>
          </tr>

          <tr>
            <td><code>REGEXP\_INSTR('abcabc', 'B C', 1, 1, 0, 'ix')</code></td>
            <td>2</td>
          </tr>

          <tr>
            <td><code>REGEXP\_INSTR('abcdefg', '(C(.(.)))', 1, 1, 0, 'i', 3)</code></td>
            <td>5</td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="REGEXP_LIKE(expr, regex[, mode])" id="regexp_like-expr-regex-mode" defaultOpen>
    Returns whether `expr` matches the given `regex`.  Generally,
    POSIX-compliant regular expressions are supported.

    The optional `mode` parameter is a string which can be empty
    (the default) for the default behavior.  It can contain the following
    letters for the associated optional modified behaviors:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Letter</th>
            <th>Meaning</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>i</code></td>
            <td>Case-insensitive matches</td>
          </tr>

          <tr>
            <td><code>m</code></td>
            <td>Treat input as multiple lines so <code>^</code> and <code>\$</code> match around newlines and not just the beginning and ending of the string</td>
          </tr>

          <tr>
            <td><code>n</code></td>
            <td>Allows <code>.</code> to also match a newline character</td>
          </tr>

          <tr>
            <td><code>x</code></td>
            <td>Ignore any whitespace (e.g., spaces) in <code>regex</code></td>
          </tr>
        </tbody>
      </table>
    </div>

    The escape character used to match wildcards in the `expr` literally
    is `\`.

    <Info>
      The `regex` can match the `expr` partially.  To perform
      full matches, `^` and `$` can be used to match the
      start and end of `expr`, respectively.
    </Info>

    Examples of successful matches:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Match Type</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>REGEXP\_LIKE('partial', 'part')</code></td>
            <td>Partial</td>
          </tr>

          <tr>
            <td><code>REGEXP\_LIKE('Case', 'cAsE', 'i')</code></td>
            <td>Case-insensitive</td>
          </tr>

          <tr>
            <td><code>REGEXP\_LIKE('dot', 'd.t')</code></td>
            <td>Any character</td>
          </tr>

          <tr>
            <td><code>REGEXP\_LIKE('range', 'ra\[a-z]ge')</code></td>
            <td>Character range</td>
          </tr>

          <tr>
            <td><code>REGEXP\_LIKE('zeroorone', 'z?zer(oor)?one')</code></td>
            <td>0 or 1 token</td>
          </tr>

          <tr>
            <td><code>REGEXP\_LIKE('zeroormore', 'z\*zer(\[om]or)\*e')</code></td>
            <td>0 or more tokens</td>
          </tr>

          <tr>
            <td><code>REGEXP\_LIKE('oneormore', 'o+n(\[em]or)+e')</code></td>
            <td>1 or more tokens</td>
          </tr>

          <tr>
            <td><code>REGEXP\_LIKE('A to Z', '^A.\*Z\$')</code></td>
            <td>Begin/End</td>
          </tr>

          <tr>
            <td><code>REGEXP\_LIKE('41ph4Num', '^\[\[:alnum:]]+\$')</code></td>
            <td>Character class</td>
          </tr>

          <tr>
            <td><code>REGEXP\_LIKE('Escape?', 'Escape?')</code></td>
            <td>Escape wildcard</td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="REGEXP_MATCH(expr, regex[, options])" id="regexp_match-expr-regex-options" defaultOpen>
    Alias for `REGEXP_LIKE`
  </Accordion>

  <Accordion title="REGEXP_REPLACE (expr, regex [, replace [, position [, occurrence [, mode]]]])" id="regexp_replace-expr-regex-replace-position-occurrence-mode" defaultOpen>
    Returns the `expr` string after replacing `regex` matches with the
    `replace` string parameter.

    The `regex` parameter is the regular expression to try to match.
    It must be a string-literal with 256 characters or fewer.  Generally,
    POSIX-compliant regular expressions are supported for `regex`.
    The escape character used to match wildcards in the `expr` literally
    is `\`.  See `REGEXP_LIKE` for more regular expression examples.

    The `replace` parameter is the optional text with which to replace
    each match of `regex` in `expr`.  The default is an empty string,
    which will simply remove the specified occurrences of `regex` in
    `expr`.  A `replace` of `\0` will insert the entire matched
    expression, while a `replace` of `\1` through `\9` will use the
    corresponding matched grouping (parentheses inside `regex`) as the
    replacement text.

    The optional `position` parameter specifies where to start searching
    in `expr` for the first match.  The first character in the string
    has a `position` of `1` (the default).

    The optional `occurrence` parameter specifies which occurrence of
    the `regex` match to replace.  For example, `2` would only replace
    the second occurrence of `regex` in `expr`.  Matches do not
    overlap, so the start of a future match must start after the end of
    the previous match.  Use `0` (the default) to replace all
    occurrences.

    The optional `mode` parameter is a string which can be empty
    (the default) for the default behavior.  See `REGEXP_LIKE` for the
    list of supported mode flags.

    Examples of `REGEXP_REPLACE`:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>REGEXP\_REPLACE('abc', 'b')</code></td>
            <td>ac</td>
          </tr>

          <tr>
            <td><code>REGEXP\_REPLACE('abc', 'b.', 'x')</code></td>
            <td>ax</td>
          </tr>

          <tr>
            <td><code>REGEXP\_REPLACE('abcd', '.', 'x', 3, 1)</code></td>
            <td>abxd</td>
          </tr>

          <tr>
            <td><code>REGEXP\_REPLACE('abcd', '(b(.))', '-\2-')</code></td>
            <td>a-c-d</td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="REGEXP_SUBSTR (expr, regex [, position [, occurrence [, mode [,group]]]])" id="regexp_substr-expr-regex-position-occurrence-mode-group" defaultOpen>
    Returns the portion of the `expr` string that matched `regex`.
    An empty string is returned if no match is found.

    The `regex` parameter is the regular expression to try to match.
    It must be a string-literal with 256 characters or fewer.  Generally,
    POSIX-compliant regular expressions are supported for `regex`.
    The escape character used to match wildcards in the `expr` literally
    is `\`.  See `REGEXP_LIKE` for more regular expression examples.

    The optional `position` parameter specifies where to start searching
    in `expr` for the first match.  The first character in the string
    has a `position` of `1` (the default).

    The optional `occurrence` parameter specifies which occurrence of
    the `regex` match is desired.  For example, `2` would return the
    second occurrence of `regex` in `expr`.  Matches do not overlap,
    so the start of a future match must start after the end of the
    previous match.

    The optional `mode` parameter is a string which can be empty
    (the default) for the default behavior.  See `REGEXP_LIKE` for the
    list of supported mode flags.

    The optional `group` parameter specifies which regular expression
    grouping (i.e., parentheses inside `regex`) to use.  The default of
    `0` uses the entire matched expression, while a `group` of `1`
    through `9` corresponds to the 1st group up through the 9th group of
    the match.

    Examples of `REGEXP_SUBSTR`:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>REGEXP\_SUBSTR('abcdefg', 'b.')</code></td>
            <td>bc</td>
          </tr>

          <tr>
            <td><code>REGEXP\_SUBSTR('abcadeafghij', 'a...', 2, 1)</code></td>
            <td>adea</td>
          </tr>

          <tr>
            <td><code>REGEXP\_SUBSTR('abcadeafghij', 'a...', 1, 2)</code></td>
            <td>afgh</td>
          </tr>

          <tr>
            <td><code>REGEXP\_SUBSTR('abcdefg', '(C(.(.)))', 1, 1, 'i', 3)</code></td>
            <td>e</td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="REPLACE(expr, match, repl)" id="replace-expr-match-repl" defaultOpen>
    Replaces every occurrence of `match` in `expr` with `repl`
  </Accordion>

  <Accordion title="REPLACE_CHAR(expr, match, repl)" id="replace_char-expr-match-repl" defaultOpen>
    Replaces every occurrence of the single-byte character `match` in
    `expr` with the single-byte character `repl`
  </Accordion>

  <Accordion title="REPLACE_TRUNCATE(expr, match, repl)" id="replace_truncate-expr-match-repl" defaultOpen>
    Replaces every occurrence of `match` in `expr` with `repl`, and
    then truncates the resulting string at 256 bytes if it is longer than
    that

    <Info>
      `REPLACE_TRUNCATE` will not work if any parameter is an
      unrestricted-width string.
    </Info>

    <Warning>
      The use of multi-byte characters in this function may
      have unexpected results.
    </Warning>
  </Accordion>

  <Accordion title="REVERSE(expr)" id="reverse-expr" defaultOpen>
    Returns `expr` with the order of bytes reversed.

    <Warning>
      The use of multi-byte characters in this function may
      have unexpected results.
    </Warning>

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>REVERSE('Reverse')</code></td>
            <td><code>esreveR</code></td>
          </tr>

          <tr>
            <td><code>REVERSE('Was it a bat I saw?')</code></td>
            <td><code>?was I tab a ti saW</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="RIGHT(expr, num_bytes)" id="right-expr-num_bytes" defaultOpen>
    Returns the rightmost `num_bytes` bytes from `expr`
  </Accordion>

  <Accordion title="RPAD(expr, length, pad)" id="rpad-expr-length-pad" defaultOpen>
    Right pads the given `expr` string with the `pad` string
    to the given `length` of bytes. If `expr` is longer than
    `length`, the return value is shortened to `length` bytes. If
    `length` is larger than 256, it will be truncated to 256 bytes.  The
    default padding character is a space.

    <Warning>
      The use of multi-byte characters in this function may
      have unexpected results.
    </Warning>

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>RPAD('test', 9, 'pad')</code></td>
            <td><code>testpadpa</code></td>
          </tr>

          <tr>
            <td><code>RPAD('test', 3, 'pad')</code></td>
            <td><code>tes</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="RTRIM(expr)" id="rtrim-expr" defaultOpen>
    Removes whitespace from the right side of `expr`
  </Accordion>

  <Accordion title="SOUNDEX(expr)" id="soundex-expr" defaultOpen>
    Returns a soundex value from `expr`. Only the first word in the
    string will be considered in the calculation.

    <Info>
      This is the algorithm used by most programming languages.
    </Info>
  </Accordion>

  <Accordion title="SPACE(n)" id="space-n" defaultOpen>
    Returns a string consisting of `n` space characters. The value of
    `n` can only be within the range of 0-256.
  </Accordion>

  <Accordion title="SPLIT(expr, delim, group_num)" id="split-expr-delim-group_num" defaultOpen>
    Splits `expr` into groups delimited by the `delim` single-byte
    character and returns the `group_num` split group.  If `group_num`
    is positive, groups will be counted from the beginning of `expr`; if
    negative, groups will be counted from the end of `expr` going
    backwards.  Two consecutive delimiters will result in an empty string
    being added to the list of selectable groups.  If no instances of
    `delim` exist in `expr`, the entire string is available at group
    `1` (and `-1`).  Group `0` returns nothing.

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>SPLIT('apple', 'p', 1)</code></td>
            <td><code>a</code></td>
          </tr>

          <tr>
            <td><code>SPLIT('apple', 'p', 2)</code></td>
            <td>*\<empty string>*</td>
          </tr>

          <tr>
            <td><code>SPLIT('apple', 'p', -1)</code></td>
            <td><code>le</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="STARTS_WITH(match, expr)" id="starts_with-match-expr" defaultOpen>
    Returns `1` if `expr` starts with `match` by
    string-literal comparison; otherwise, returns `0`
  </Accordion>

  <Accordion title="STRCMP(expr_a, expr_b)" id="strcmp-expr_a-expr_b" defaultOpen>
    Compares `expr_a` to `expr_b` in a lexicographical sort

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Situation</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>expr\_a</code> and <code>expr\_b</code> are the same</td>
            <td><code>0</code></td>
          </tr>

          <tr>
            <td><code>expr\_a</code> comes before <code>expr\_b</code>, lexicographically</td>
            <td><code>-1</code></td>
          </tr>

          <tr>
            <td><code>expr\_a</code> comes after <code>expr\_b</code>, lexicographically</td>
            <td><code>1</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="SUBSTR(expr, start_pos[, num_chars])" id="substr-expr-start_pos-num_chars" defaultOpen>
    Alias for `SUBSTRING`
  </Accordion>

  <Accordion title="SUBSTRING(expr, start_pos[, num_bytes])" id="substring-expr-start_pos-num_bytes" defaultOpen>
    Returns `num_bytes` bytes from the `expr`, starting at the 1-based
    `start_pos` byte.  If `num_bytes` is not specified, all bytes
    after `start_pos` will be returned.

    <Warning>
      The use of multi-byte characters in this function may
      have unexpected results.
    </Warning>

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>SUBSTRING('banana', 3)</code></td>
            <td><code>nana</code></td>
          </tr>

          <tr>
            <td><code>SUBSTRING('banana', 3, 2)</code></td>
            <td><code>na</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="TO_HEX(expr[, minimum_digits])" id="to_hex-expr-minimum_digits" defaultOpen>
    Alias for `HEX`
  </Accordion>

  <Accordion title="TRIM(expr)" id="trim-expr" defaultOpen>
    Removes whitespace from both sides of `expr`
  </Accordion>

  <Accordion title="UCASE(expr)" id="ucase-expr" defaultOpen>
    Converts `expr` to uppercase
  </Accordion>

  <Accordion title="UNHEX(expr)" id="unhex-expr" defaultOpen>
    Convert the hexadecimal string `expr` into a (decimal) number.

    Examples:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>UNHEX('42')</code></td>
            <td><code>66</code></td>
          </tr>

          <tr>
            <td><code>UNHEX('1A')</code></td>
            <td><code>26</code></td>
          </tr>

          <tr>
            <td><code>UNHEX('1a')</code></td>
            <td><code>26</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="UPPER(expr)" id="upper-expr" defaultOpen>
    Alias for `UCASE`
  </Accordion>
</AccordionGroup>

<a id="expression-functions-string-agg" />

#### Aggregate Functions

The following functions can be used on *string* columns within
[aggregations](/content/concepts/expressions#aggregate-expressions-label).

These functions can be used to convert string column values into delimited lists
of those values.

<AccordionGroup>
  <Accordion title="STRING_AGG(expr[, delim])" id="string_agg-expr-delim" defaultOpen>
    Combines column values within a group into a single delimited *string* of those values.

    The default delimiter is a comma.
  </Accordion>

  <Accordion title="STRING_AGG_DISTINCT(expr[, delim])" id="string_agg_distinct-expr-delim" defaultOpen>
    Combines column values within a group into a single delimited *string* of those values,
    removing any duplicates.

    The default delimiter is a comma.
  </Accordion>
</AccordionGroup>

<a id="expression-functions-security" />

### User/Security Functions

<AccordionGroup>
  <Accordion title="CURRENT_SCHEMA()" id="current_schema" defaultOpen>
    Returns the default schema of the current user
  </Accordion>

  <Accordion title="CURRENT_USER()" id="current_user" defaultOpen>
    Alias for `USER`
  </Accordion>

  <Accordion title="HASH(column[, seed])" id="hash-column-seed" defaultOpen>
    Returns a non-negative integer representing an obfuscated version
    of `column`, using the given `seed`; default `seed` is `0`
  </Accordion>

  <Accordion title="IS_MEMBER(role[, user/role])" id="is_member-role-user/role" defaultOpen>
    Returns whether the current user (or the given `user/role`,
    if specified) has been assigned the given `role`, either
    directly or indirectly:

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Situation</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td>Current user (or given <code>user/role</code>) has been granted <code>role</code></td>
            <td><code>true</code></td>
          </tr>

          <tr>
            <td>Current user (or given <code>user/role</code>) has not been granted <code>role</code></td>
            <td><code>false</code></td>
          </tr>

          <tr>
            <td>Role <code>role</code> does not exist</td>
            <td>*null*</td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="IS_ROLEMEMBER(role[, user/role])" id="is_rolemember-role-user/role" defaultOpen>
    Alias for `IS_MEMBER`
  </Accordion>

  <Accordion title="MASK(expr, start, length[, char])" id="mask-expr-start-length-char" defaultOpen>
    Masks `length` bytes of `expr`, beginning at the byte position
    identified by `start`, with `*` characters (or the single-byte
    character specified in `char`):

    <Warning>
      The use of multi-byte characters in this function may
      have unexpected results.
    </Warning>

    <div>
      <table class="table w-full [&_td]:min-w-[150px] [&_th]:text-left [&_td[data-numeric]]:tabular-nums">
        <thead>
          <tr>
            <th>Function Call</th>
            <th>Result</th>
          </tr>
        </thead>

        <tbody>
          <tr>
            <td><code>MASK('Characters', 4, 5)</code></td>
            <td><code>Cha\*\*\*\*\*rs</code></td>
          </tr>

          <tr>
            <td><code>MASK('Characters', 5, 2, '#')</code></td>
            <td><code>Char##ters</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="NEW_UUID()" id="new_uuid" defaultOpen>
    Returns a randomly-generated UUID
  </Accordion>

  <Accordion title="OBFUSCATE(column[, seed])" id="obfuscate-column-seed" defaultOpen>
    Alias for `HASH`
  </Accordion>

  <Accordion title="SHA256(expr)" id="sha256-expr" defaultOpen>
    Returns the hex digits of the SHA-256 hash of the given value
    `expr` as a `char64` string.
  </Accordion>

  <Accordion title="SYSTEM_USER()" id="system_user" defaultOpen>
    Alias for `USER`
  </Accordion>

  <Accordion title="USER()" id="user" defaultOpen>
    Returns the username of the current user
  </Accordion>
</AccordionGroup>

<a id="column-expressions-label" />

## Column Expressions

Many of the functions above accept expressions as inputs in place of column
names for selecting data from [tables](/content/concepts/tables#table) e.g.
[/aggregate/minmax](/content/api/rest/aggregate_minmax_rest).  Given below are some examples of column
expressions:

```
(x + y)
(2 * col1) + col2
```

<a id="filter-expressions-label" />

## Filter Expressions

Data can be filtered with the use of *filter expressions* within many endpoints;
e.g., [/filter](/content/api/rest/filter_rest).  These expressions may contain
*column expressions* as well as tests for equality/inequality for selecting
records from the database.  A *filter expression* cannot contain
aggregation functions and should evaluate to a logical value
( *true* or *false* ).  When the result of an expression evaluation is a
numerical value, the result is converted to a logical value as follows:  `0`
is considered *false* and any other value is considered as *true*.  Some
examples of *filter expressions* are given below:

```
(x > y)
(a != b) or (c = d)
(timestamp > 1456749296789) and (x <= 10.0)
ABS(timestamp - 1456749296789) < 60 * 60 * 1000
QUARTER(timestamp) = 1 and MOD(YEAR(timestamp), 4) = 0
msg_id == 'MSGID1'
(x = 5) and y in (10,20,30)
```

<a id="aggregate-expressions-label" />

## Aggregate Expressions

Some endpoints accept *aggregation expressions* as inputs for selecting
data from [tables](/content/concepts/tables#table), e.g., [/aggregate/groupby](/content/api/rest/aggregate_groupby_rest).  Such
expressions can only contain aggregation functions and non-nested functions of
aggregation functions.

Aggregation functions include:

* [Array Aggregation Functions](/content/concepts/expressions#expression-functions-array-agg)
* [Geometry Aggregation Functions](/content/concepts/expressions#expression-functions-geo-aggregation)
* [JSON Aggregation Functions](/content/concepts/expressions#expression-functions-json-agg)
* [Lookup/Grouping Aggregation Functions](/content/concepts/expressions#expression-functions-lookup-agg)
* [Math Aggregation Functions](/content/concepts/expressions#expression-functions-math-agg)
* [String Aggregation Functions](/content/concepts/expressions#expression-functions-string-agg)

<a id="expression-functions-lookup-agg" />

### Lookup/Grouping Functions

<AccordionGroup>
  <Accordion title="ARG_MAX(agg_expr, ret_expr)" id="arg_max-agg_expr-ret_expr" defaultOpen>
    The value of `ret_expr` where `agg_expr` is the maximum value (e.g. `ARG_MAX(cost, product_id)`
    returns the product ID of the highest cost product). `ARG_MAX(a, b)` is equivalent to `LAST(b, a)`.
  </Accordion>

  <Accordion title="ARG_MIN(agg_expr, ret_expr)" id="arg_min-agg_expr-ret_expr" defaultOpen>
    The value of `ret_expr` where `agg_expr` is the minimum value (e.g. `ARG_MIN(cost, product_id)`
    returns the product ID of the lowest cost product). `ARG_MIN(a, b)` is equivalent to `FIRST(b, a)`.
  </Accordion>

  <Accordion title="FIRST(ret_expr, agg_expr)" id="first-ret_expr-agg_expr" defaultOpen>
    The value of `ret_expr` where `agg_expr` is the minimum value (e.g. `FIRST(product_id, cost)`
    returns the product ID of the lowest cost product). `FIRST(a, b)` is equivalent to `ARG_MIN(b, a)`.
  </Accordion>

  <Accordion title="GROUPING(expr)" id="grouping-expr" defaultOpen>
    Used primarily with [Rollup](/content/concepts/rollup), [Cube](/content/concepts/cube), and
    [Grouping Sets](/content/concepts/grouping_sets), to distinguish the source of *null* values in an aggregated result
    set, returns whether `expr` is part of the aggregation set used to calculate the values in a given
    result set row.  Returns `0` if `expr` is part of the row's aggregation set, `1` if `expr` is
    not (meaning that aggregation took place across all `expr` values).

    For example, in a `ROLLUP(A)` operation, there will be two potential rows with *null* in the result
    set for column `A`.  One row will contain *null* values of `A` aggregated together, and the other
    will contain *null*, but be an aggregation over the entire table, irrespective of `A` values.  In
    this case, `GROUPING(A)` will return `0` for the *null* values of `A` aggregated together (as
    well as all other grouped `A` values) and `1` for the row resulting from aggregating across all
    `A` values.
  </Accordion>

  <Accordion title="LAST(ret_expr, agg_expr)" id="last-ret_expr-agg_expr" defaultOpen>
    The value of `ret_expr` where `agg_expr` is the maximum value (e.g. `LAST(product_id, cost)`
    returns the product ID of the highest cost product). `LAST(a, b)` is equivalent to `ARG_MAX(b, a)`.
  </Accordion>
</AccordionGroup>

<a id="short-circuiting" />

## Short-Circuiting

The logical operators `and` & `or` implement a version of boolean
short-circuiting where if either side of the expression encounters an error
(divide-by-zero, etc.) but the other side evaluates to a value that alone would
determine the overall value of the logical expression, the error will be ignored
and the logical value returned:

* If one side of an `and` evaluates to *false* and the other side evaluates to
  an error, *false* will be returned.
* If one side of an `or` evaluates to *true* and the other side evaluates to
  an error, *true* will be returned.

In the normal case, both sides of either of these operators would be evaluated
simultaneously.  However, to allow these operators to be used to check for error
conditions, if an error is encountered on either side but the other side is
enough information to determine the overall value of the expression, the error
will be ignored.

This same behavior applies to the evaluation branches of the following
functions:

* `IF`
* `NVL`
* `NVL2`

It also applies to
[SQL conditional functions](/content/sql/query#sql-conditional-functions).
