> ## 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.

# String Functions

<a id="sql-string-functions" />

There are four different types of string functions:

* [Scalar Functions](/content/sql/query/string-functions#sql-string-functions-scalar)
* [Aggregation Functions](/content/sql/query/string-functions#sql-string-functions-agg)
* [LIKE / ILIKE](/content/sql/query/string-functions#sql-string-functions-like)
* [FILTER\_BY\_STRING](/content/sql/query/string-functions#sql-string-functions-fts)

<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="sql-string-functions-charn" />

<a id="sql-string-functions-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" 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
      `VARCHAR(N)` field big enough to hold the concatenated
      fields, e.g., concatenating a `VARCHAR(32)` column and a
      `VARCHAR(64)` column will result in a `VARCHAR(128)`
      column.  Columns of type `VARCHAR(256)` used with
      `CONCAT` will result in a `VARCHAR(256)` column,
      truncated at 256 characters.
    </Info>

    <Tip>
      The `||` operator can be used in place of `CONCAT` to
      perform string concatenation; e.g., the following two
      expressions are equivalent:

      ```
      expr_a || expr_b || expr_c
      ```

      ```
      CONCAT(CONCAT(expr_a, expr_b), expr_c)
      ```
    </Tip>

    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(CONCAT('ABC','123'),'!')</code></td>
            <td><code>ABC123!</code></td>
          </tr>

          <tr>
            <td><code>'ABC' || '123' || '!'</code></td>
            <td><code>ABC123!</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </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="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="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="PG_SIZE_PRETTY(expr)" id="pg_size_pretty-expr" defaultOpen>
    Alias for `SIZE_PRETTY`
  </Accordion>

  <Accordion title="POSITION(match IN expr)" id="position-match-in-expr" defaultOpen>
    Returns the starting position of the first match of `match` in
    `expr`, starting from position 1.  If `match` can't be
    found, a `0` is returned.
  </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="SIZE_PRETTY(expr)" id="size_pretty-expr" defaultOpen>
    Convert the byte count `expr` into a human-readable size
    string using 1024-based units (`bytes`, `KB`, `MB`,
    `GB`, `TB`, `PB`).  The unit is selected so the printed
    number should have at most 3 digits.

    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>SIZE\_PRETTY(2048)</code></td>
            <td><code>'2 KB'</code></td>
          </tr>

          <tr>
            <td><code>SIZE\_PRETTY(10485760)</code></td>
            <td><code>'10 MB'</code></td>
          </tr>

          <tr>
            <td><code>SIZE\_PRETTY(1073741824)</code></td>
            <td><code>'1 GB'</code></td>
          </tr>
        </tbody>
      </table>
    </div>
  </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="sql-string-functions-agg" />

## Aggregation Functions

The following functions can be used on *string* columns within
[aggregations](/content/sql/query/aggregation#sql-aggregation).

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="sql-string-functions-like" />

## LIKE / ILIKE

Simple pattern-matching capability is provided through the use of the `LIKE` and `ILIKE`
clauses, for [string columns](/content/sql/ddl/column-types#sql-column-types).  `LIKE` is case-sensitive,
while `ILIKE` is case-insensitive.

```sql title="LIKE / ILIKE Syntax" theme={null}
<expr> [NOT] <LIKE | ILIKE> <match> [ESCAPE '<esc_char>']
```

This clause matches records where reference expression `expr` does (or does
`NOT`) match the string value of `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
  `character_set` starting with `^` will match any character not in the
  specified set.

By default, there is no escape character.  Use the `ESCAPE` clause to specify
an escape character.  The escape character is used to match special characters
in the `expr` literally.  For example, `~%` will match the `%` character
if `~` is the escape character.

To search for employees whose last name starts with *C*, ends with *a*, and has
exactly five letters:

```sql LIKE Single Character Case-Sensitive Match Example theme={null}
SELECT *
FROM example.employee
WHERE last_name LIKE 'C___a'
```

To search for employees whose first name does not start with *Brook*, regardless
of case:

```sql ILIKE Multiple Character Case-Insensitive Match Example theme={null}
SELECT *
FROM example.employee
WHERE first_name NOT ILIKE 'brook%'
```

To search for employees whose first name has a capital letter after the first
letter:

```sql LIKE Character Range Case-Sensitive Match Example theme={null}
SELECT *
FROM example.employee
WHERE first_name LIKE '%_[A-Z]%'
```

To search for employees whose first name does not contain an underscore,
redefining the default escape character to a `~` to escape the underscore:

```sql ILIKE Custom Escape Character Case-Insensitive Match Example theme={null}
SELECT *
FROM example.employee
WHERE first_name NOT ILIKE '%~_%' ESCAPE '~'
```

<a id="sql-string-functions-fts" />

## FILTER\_BY\_STRING

The `FILTER_BY_STRING` table function allows for several types of pattern
matching for [fixed-width string columns](/content/sql/ddl/column-types#sql-column-types)
(`VARCHAR(1)` - `VARCHAR(256)`), as well as
[full text search](/content/concepts/full_text_search) capability for all
string columns with the `TEXT_SEARCH`
[column property](/content/sql/ddl/column-properties#sql-column-properties).  Its features are based
on the [/filter/bystring](/content/api/rest/filter_bystring_rest) endpoint.

The basic form of the `FILTER_BY_STRING` function when called in a `SELECT`
statement follows.

```sql title="FILTER_BY_STRING Table Function Syntax" theme={null}
SELECT *
FROM TABLE
(
	FILTER_BY_STRING
	(
		TABLE_NAME => INPUT_TABLE(<table name | select statement>),
		[COLUMN_NAMES => '<column list>',]
		MODE => '<filter type>',
		EXPRESSION => '<filter expression>',
		[OPTIONS => KV_PAIRS('<option name>' = '<option value>'[,...])]
	)
)
```

The basic form of the `FILTER_BY_STRING` function when called in an
`EXECUTE FUNCTION` statement follows.  When called this way, the results are
saved in the specified *view*.

```sql title="FILTER_BY_STRING Execute Function Syntax" theme={null}
EXECUTE FUNCTION FILTER_BY_STRING
(
	TABLE_NAME => INPUT_TABLE(<table name | select statement>),
	VIEW_NAME => '[<schema name>.]<view name>',
	[COLUMN_NAMES => '<column list>',]
	MODE => '<filter type>',
	EXPRESSION => '<filter expression>',
	[OPTIONS => KV_PAIRS('<option name>' = '<option value>'[,...])]
)
```

<AccordionGroup>
  <Accordion title="TABLE_NAME" id="table_name" defaultOpen>
    The data set to filter, which should be passed via query to the `INPUT_TABLE` function.

    To perform a string filter on a column in the *customer* table, pass the name of the table to
    `INPUT_TABLE`:

    ```
    INPUT_TABLE(customer)
    ```

    To perform a string filter on a column in the result of a query, pass the query to `INPUT_TABLE`:

    ```
    INPUT_TABLE(SELECT * FROM customer_west UNION SELECT * FROM customer_east)
    ```
  </Accordion>

  <Accordion title="VIEW_NAME" id="view_name" defaultOpen>
    Name of the view in which the results are to be stored, in \[schema\_name.]table\_name format,
    using standard [name resolution rules](/content/sql/naming#sql-name-resolution) and meeting
    [table naming criteria](/content/sql/naming#sql-naming-criteria)

    <Note>
      This parameter is only applicable when using `EXECUTE FUNCTION` syntax.
    </Note>
  </Accordion>

  <Accordion title="COLUMN_NAMES" id="column_names" defaultOpen>
    Comma-separated list of columns to which the filter will be applied.

    <Note>
      Omit this parameter when using the `search` filter `MODE`.
    </Note>
  </Accordion>

  <Accordion title="MODE" id="mode" defaultOpen>
    Type of string filter to apply:

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

        <tbody>
          <tr>
            <td><code>contains</code></td>
            <td>Partial substring match *(not accelerated)*. If the column is a string type (non-charN) and the number of records is too large, it will return 0.</td>
          </tr>

          <tr>
            <td><code>equals</code></td>
            <td>Exact whole-string match *(accelerated)*.</td>
          </tr>

          <tr>
            <td><code>regex</code></td>
            <td>Full regular expression search *(not accelerated)*. If the column is a string type (non-charN) and the number of records is too large, it will return 0.</td>
          </tr>

          <tr>
            <td><code>search</code></td>
            <td>Full text search with wildcards and boolean operators, for string columns (<code>VARCHAR</code>) that have the <code>TEXT\_SEARCH</code> [column property](/content/sql/ddl/column-properties#sql-column-properties) applied. See [Full Text Search](/content/concepts/full_text_search) for syntax & grammar detail. <Note>Omit the `COLUMN_NAMES` parameter when using this `MODE`. All text-searchable string columns will be searched.  Also, only a table name can be used for `TABLE_NAME`--a query cannot be used.</Note></td>
          </tr>

          <tr>
            <td><code>starts\_with</code></td>
            <td>Match strings that start with the given expression *(not accelerated)*. If the column is a string type (non-charN) and the number of records is too large, it will return 0.</td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>

  <Accordion title="EXPRESSION" id="expression" defaultOpen>
    String literal or pattern, depending on `MODE` selected, to use in filtering string columns
  </Accordion>

  <Accordion title="OPTIONS" id="options" defaultOpen>
    Optional list of string filtering options, specified as a set of key/value pairs passed as a
    comma-delimited list of `<key> = '<value>'` assignments to the `KV_PAIRS` function; e.g.:

    ```
    KV_PAIRS(case_sensitive = 'false')
    ```

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

        <tbody>
          <tr>
            <td><code>case\_sensitive</code></td>
            <td>If *true*, the filter will be case-sensitive; if false, case-insensitive. <Note>Not applicable when `MODE` is `search`.</Note></td>
          </tr>
        </tbody>
      </table>
    </div>
  </Accordion>
</AccordionGroup>

To see the message text & time for events in the *event\_log* table containing
the word *ERROR*:

```sql FILTER_BY_STRING Example theme={null}
SELECT *
FROM TABLE
(
    FILTER_BY_STRING
    (
        TABLE_NAME => INPUT_TABLE(SELECT event_time, message FROM example.event_log),
        COLUMN_NAMES => 'message',
        MODE => 'contains',
        EXPRESSION => 'ERROR'
    )
)
```
