# String Operations
SQL defines two primary character types: `character varying(n)` and
`character(n)`, where n is a positive integer. Both of these types
can store strings up to n characters (not bytes) in length. An attempt
to store a longer string into a column of these types will result in
an error, unless the excess characters are all spaces, in which case
the string will be truncated to the maximum length. (This somewhat
bizarre exception is required by the SQL standard.) If the string to
be stored is shorter than the declared length, values of type
character will be space-padded; values of type character varying will
simply store the shorter string.
In addition, we provide the `text`, or `varchar` type, which stores
strings of any length.
Trailing spaces are removed when converting a character value to one
of the other string types. Note that trailing spaces are semantically
significant in character varying and text values, and when using
pattern matching (e.g., LIKE and regular expressions).
## String constants (literals)
A string constant in SQL is an arbitrary sequence of characters
bounded by single quotes (`'`), for example `'This is a string'`. To
include a single-quote character within a string constant, write two
adjacent single quotes, e.g., `'Dianne''s horse'`. Note that this is
not the same as a double-quote character (`"`).
Two string constants that are only separated by whitespace with at
least one newline are concatenated and effectively treated as if the
string had been written as one constant. For example:
```sql
SELECT 'foo'
'bar'
```
is equivalent to:
```sql
SELECT 'foobar'
```
but:
```sql
SELECT 'foo' 'bar'
```
is not valid syntax.
## Escaped characters
We also accepts escaped characters withing string constants, which are
an extension to the SQL standard. Within an escape string, a
backslash character (`\`) begins a C-like backslash escape sequence, in
which the combination of backslash and following character(s)
represent a special byte value:
|Backslash Escape Sequence|Interpretation|
|-------------------------|--------------|
|\b | backspace |
|\f | form feed |
|\n | newline |
|\r | carriage return |
|\t | tab |
|\o, \oo, \ooo | (o = 0–7) octal byte value |
|\xh, \xhh (h = 0–9, A–F) | hexadecimal byte value |
|\uxxxx, \Uxxxxxxxx (x = 0–9, A–F) | 16 or 32-bit hexadecimal Unicode character value |
Any other character following a backslash is taken literally. Thus, to
include a backslash character, write two backslashes `\\`. Also, a
single quote can be included in an escape string by writing `\'`, in
addition to the normal way of `''`.
## Operations on string values
| Operation |
Description |
Examples |
|| |
String concatenation (infix). Note that concatenation does *not* strip trailing spaces
from CHAR(N) values, unlike other SQL dialects. If such behavior is desired, an explicit
cast to `varchar` can be added. |
'Post' || 'greSQL' => PostgreSQL |
string LIKE pattern [ESCAPE escape-character] and
string NOT LIKE pattern [ESCAPE escape-character] |
The LIKE expression returns true if the string matches the supplied pattern.
(As expected, the NOT LIKE expression returns false if LIKE returns true. |
See below for details. |
string ILIKE pattern and
string NOT ILIKE pattern
|
The ILIKE expression returns true if the string matches the supplied pattern,
performing a case-insensitive comparison. This means that differences in character case
between the string and the pattern are ignored.
(Similarly, the NOT ILIKE expression returns false if ILIKE returns true.)
|
See below for details.
|
string RLIKE pattern and
string NOT RLIKE pattern |
The RLIKE expression returns true if the string matches the supplied pattern.
The pattern is a standard Java regular expression. |
'string' RLIKE 's..i.*' => TRUE |
ASCII ( string ) |
Returns the numeric code of the first character of the argument. In UTF8 encoding, returns the Unicode code point of the character. In other multibyte encodings, the argument must be an ASCII character. Returns 0 if the string is empty. |
ascii('x') => 120 |
CHAR_LENGTH(string) or CHARACTER_LENGTH(string) or LENGTH(string) or LEN(string) |
Returns number of characters in the string. |
char_length('josé') => 4 |
CHR ( integer ) |
Returns a string containing the character with the given code. If the code is incorrect (e.g., negative), the result is an empty string. |
chr(65) => A |
CONCAT(string1, ..., stringN) |
String concatenation. Can have any number of arguments. |
CONCAT('Post', 'greSQL', 1) => PostgreSQL1 |
CONCAT_WS(sep, string1, ..., stringN) |
String concatenation with separator sep. Can have any number of arguments. sep is intercalated between all strings. If sep is NULL result is NULL. Other NULL arguments are ignored. |
CONCAT_WS(',', 'Post', 'greSQL', NULL, '1') => Post,greSQL,,1 |
INITCAP ( string ) |
Converts the first letter of each word to upper case and the rest to lower case. Words are sequences of alphanumeric characters separated by non-alphanumeric characters. |
initcap('hi THOMAS') => Hi Thomas |
LEFT ( string, count ) |
Returns first count characters in the string. If any argument is NULL, return NULL. |
left('abcde', 2) => ab |
LOWER ( string ) |
Converts the string to all lower case. |
lower('TOM') => tom |
OVERLAY ( string PLACING newsubstring FROM start [ FOR remove ] ) |
Replaces the substring of string that starts at the start'th character and extends for remove characters with newsubstring. If count is omitted, it defaults to the length of newsubstring. If 'start' is nott positive, the original string is unchanged. If 'start' is bigger than the length of 'string', the result is the concatenation of the two strings. If 'remove' is negative it is considered 0. |
overlay('Txxxxas' placing 'hom' from 2 for 4) => Thomas |
POSITION(substring IN string) |
Returns first starting index of the specified substring within string, or zero if it's not present. First character has index 1. |
position('om' in 'Thomas') => 3 |
REGEXP_REPLACE(expr, pat[, repl]) |
Replaces occurrences in the string `expr` that match the regular expression
specified by the pattern `pat` with the replacement string `repl`, and returns
the resulting string. If any one of `expr`, `pat`, or `repl` is `NULL`, the return value is `NULL`.
If `repl` is missing, it is assumed to be the empty string. If the regular
expression is invalid, the original string is returned. |
|
REPEAT ( string, count ) |
Repeats string the specified number of times. The result is an empty string for a negative or 0 count. |
repeat('Pg', 4) => PgPgPgPg |
REPLACE ( haystack, needle, replacement ) |
Replaces all occurrences of `needle` in `haystack` with `replacement`. |
replace('abcdefabcdef', 'cd', 'XX') => abXXefabXXef |
RLIKE(string, pattern) |
A function equivalent to the RLIKE operator above. |
RLIKE('string', 's..i.*') => TRUE |
SPLIT(string [, delimiter]) |
Produce an array of strings, by splitting the first argument at each delimiter occurrence.
If the delimiter is empty, return an array with the original string. If the original
string is empty, return an empty array. If either argument is `NULL`, return `NULL`.
If delimiter is absent assume it is the string ','. |
SPLIT('a|b|c|', '|') => { 'a', 'b', 'c', '' } |
SPLIT_PART(string, delimiter, n) |
This function uses 1-based indexing. It extracts the n'th part of the string by splitting it at each occurrence of the delimiter.
n = 1 refers to the first part of the string after splitting.
n = 2 refers to the second part, and so on.
- If
n is negative, it returns the abs(n)'th part from the end of the string.
- If
n is out of bounds, it returns an empty string.
|
SPLIT_PART('a|b|c|', '|', 2) => b
SPLIT_PART('a|b|c|', '|', -2) => c
SPLIT_PART('a|b|c|', '|', 5) => ''
|
SUBSTR ( string, start, [ , length ] |
Extracts the substring of string starting at the "start"'th character if that is specified, and stopping after "length" characters if the value is specified. If "start" is negative, it is replaced with 1. If "count" is negative the empty string is returned. The index of the first character is 1. |
SUBSTR('Thomas', 2, 3) => hom
SUBSTR('Thomas', 3) => omas
|
SUBSTRING ( string [ FROM start ] [ FOR count ] ) |
Extracts the substring of string starting at the "start"'th character if that is specified, and stopping after "count" characters if the value is specified. At least one of "start" or "count" must be provided. If "start" is negative, it is replaced with 1. If "count" is negative the empty string is returned. The index of the first character is 1. |
SUBSTRING('Thomas' from 2 for 3) => hom
SUBSTRING('Thomas' from 3) => omas
SUBSTRING('Thomas' for 2) => Th |
TRIM ( [ LEADING | TRAILING | BOTH ] characters FROM string ) |
Remove the specified characters from the specified ends of the string argument |
TRIM(both 'xyz' from 'yxTomxx') => Tom
TRIM(leading 'xyz' from 'yxTomxx') => Tomxx |
UPPER ( string ) |
Converts the string to all upper case. |
upper('tom') => TOM |
## `LIKE`
string `LIKE` pattern [`ESCAPE` escape-character]
string `NOT LIKE` pattern [`ESCAPE` escape-character]
If pattern does not contain percent signs or underscores, then the
pattern only represents the string itself; in that case `LIKE` acts
like the equals operator. An underscore (`_`) in pattern stands for
(matches) any single character; a percent sign (`%`) matches any
sequence of zero or more characters.
Some examples:
```sql
'abc' LIKE 'abc' true
'abc' LIKE 'a%' true
'abc' LIKE '_b_' true
'abc' LIKE 'c' false
```
`LIKE` pattern matching always covers the entire string. Therefore, if
it's desired to match a sequence anywhere within a string, the pattern
must start and end with a percent sign.
To match a literal underscore or percent sign without matching other
characters, the respective character in pattern must be preceded by
the escape character. The default escape character is the backslash
but a different one can be selected by using the ESCAPE clause. To
match the escape character itself, write two escape characters. The
escape character cannot be one of the special pattern characters `_`
or `%`.
Some examples where the escape character is changed to `#`:
```sql
SELECT 'hawkeye' LIKE 'h%' ESCAPE '#' true
SELECT 'hawkeye' NOT LIKE 'h%' ESCAPE '#' false
SELECT 'h%' LIKE 'h#%' ESCAPE '#' true
SELECT 'h%' NOT LIKE 'h#%' ESCAPE '#' false
SELECT 'h%wkeye' LIKE 'h#%' ESCAPE '#' false
SELECT 'h%wkeye' NOT LIKE 'h#%' ESCAPE '#' true
SELECT 'h%wkeye' LIKE 'h#%%' ESCAPE '#' true
SELECT 'h%wkeye' NOT LIKE 'h#%%' ESCAPE '#' false
SELECT 'h%awkeye' LIKE 'h#%a%k%e' ESCAPE '#' true
```
When either argument or `LIKE`, `NOT LIKE` is `NULL`, the result is `NULL`.
## `ILIKE`
string `ILIKE` pattern
string `NOT ILIKE` pattern
The `ILIKE` expression performs a case-insensitive pattern match. If the pattern does not contain percent signs or underscores, then the pattern represents the string itself, and `ILIKE` acts like the equals operator, ignoring character case. An underscore (`_`) in the pattern matches any single character, while a percent sign (`%`) matches any sequence of zero or more characters.
Some examples:
```sql
SELECT 'hawkeye' ILIKE 'h%' true
SELECT 'hawkeye' NOT ILIKE 'h%' false
SELECT 'hawkeye' ILIKE 'H%' true
SELECT 'hawkeye' NOT ILIKE 'H%' false
SELECT 'hawkeye' ILIKE 'H%Eye' true
SELECT 'hawkeye' NOT ILIKE 'H%Eye' false
SELECT 'Hawkeye' ILIKE 'h%' true
SELECT 'Hawkeye' NOT ILIKE 'h%' false
SELECT 'ABC' ILIKE '_b_' true
SELECT 'ABC' NOT ILIKE '_b_' false
```
When either argument or `ILIKE`, `NOT ILIKE` is `NULL`, the result is `NULL`.
## POSIX regular expressions
Regular expressions are matched using the `RLIKE` function. If either
argument of `RLIKE` is `NULL`, the result is also `NULL`.
The description below is from the [Postgres
documentation](https://www.postgresql.org/docs/15/functions-matching.html#FUNCTIONS-POSIX-REGEXP),
where credit is given to Henry Spencer.
POSIX regular expressions provide a more powerful means for pattern
matching than the `LIKE` and `SIMILAR TO` operators. Many Unix tools
such as `egrep`, `sed`, or `awk` use a pattern matching language that
is similar to the one described here.
Currently our compiler does *not* support `SIMILAR TO` regular
expressions.
A regular expression is a character sequence that is an abbreviated
definition of a set of strings (a regular set). A string is said to
match a regular expression if it is a member of the regular set
described by the regular expression. As with `LIKE`, pattern
characters match string characters exactly unless they are special
characters in the regular expression language — but regular
expressions use different special characters than `LIKE` does. Unlike
`LIKE` patterns, a regular expression is allowed to match anywhere
within a string, unless the regular expression is explicitly anchored
to the beginning or end of the string.
A *regular expression* is defined as one or more *branches*, separated
by `|`. It matches anything that matches one of the branches.
A *branch* is zero or more *quantified atoms* or *constraints*,
concatenated. It matches a match for the first, followed by a match
for the second, etc.; an empty branch matches the empty string.
A *quantified atom* is an *atom* possibly followed by a single
*quantifier*. Without a quantifier, it matches a match for the
atom. With a quantifier, it can match some number of matches of the
atom. An atom can be any of the possibilities shown in the Table
below.