Ever since version 10.3.1, MariaDB has included both a LENGTH() function and a LENGTHB() function.
That second one has a B at the end of the name. So it’s kind of like Length A and Length B, except that Length A doesn’t have the A.
Confused?
I was, when I first encountered LENGTHB(). I already knew about LENGTH(), so why the need for a “B” version?
Let’s find out.
Oracle Compatibility
According to MariaDB issue 12783, before LENGTHB() was introduced (and before LENGTH() was modified) things worked like this:
- MariaDB translates function
LENGTH()to SQL Standard functionOCTET_LENGTH(). - Oracle translates function
LENGTH()to SQL Standard functionCHAR_LENGTH().
The decision was then made to change MariaDB’s LENGTH() function so it behaves differently, depending on what SQL mode it’s running in. Specifically:
- When running in default mode (i.e.
sql_mode=DEFAULT), MariaDB will continue to translateLENGTH()toOCTET_LENGTH(). - However, when running in Oracle mode (i.e.
sql_mode=ORACLE), it translatesLENGTH()toCHAR_LENGTH()instead.
Introducing LENGTHB()
Which brings us to the LENGTHB() function.
The LENGTHB() function was added as part of the same work.
LENGTHB() is a synonym for OCTET_LENGTH() regardless of the SQL mode. In other words, LENGTHB() translates to OCTET_LENGTH() when sql_mode=DEFAULT and when sql_mode=ORACLE.
This enables us to use LENGTHB() in our code without worrying about it being affected by the user’s sql_mode settings.
The Difference
The difference between these two functions is outlined in the following table.
| Function | Default Mode | Oracle Mode |
|---|---|---|
LENGTH() | Returns the number of bytes. | Returns the number of characters. |
LENGTHB() | Returns the number of bytes. | Returns the number of bytes. |
Note that this difference is only present from MariaDB 10.3.1. Prior to that, LENGTHB() doesn’t exist, and LENGTH() simply translates to OCTET_LENGTH().
Example
Here’s an example that demonstrates the difference between LENGTH() and LENGTHB().
Let’s set our session to use the default mode:
SET SESSION sql_mode=DEFAULT;
My session was probably already in the default mode, but there’s no harm in explicitly setting it.
Now let’s run LENGTH() and LENGTHB() with the same argument:
SELECT
LENGTH('café'),
LENGTHB('café');
Result:
+-----------------+------------------+
| LENGTH('café') | LENGTHB('café') |
+-----------------+------------------+
| 5 | 5 |
+-----------------+------------------+
So, when in default mode, they both return the same value.
In this case, they both returned 5, because there are 5 bytes in that string (the é character uses 2 bytes, and all others use 1 byte each).
Now let’s switch over to Oracle mode:
SET SESSION sql_mode=ORACLE;
Now let’s rerun the above statement:
SELECT
LENGTH('café'),
LENGTHB('café');
Result:
+-----------------+------------------+
| LENGTH('café') | LENGTHB('café') |
+-----------------+------------------+
| 4 | 5 |
+-----------------+------------------+
This time there’s a difference between the two functions. This time LENGTH() returned 4. That’s 1 less than previously.
This is because LENGTH() behaves differently in Oracle mode. As mentioned, when sql_mode=ORACLE, the LENGTH() function translates to CHAR_LENGTH(), which returns the number of characters – not bytes.
In the previous example, LENGTH() returned the number of bytes because, when sql_mode=DEFAULT, it translates to OCTET_LENGTH().