This page covers compatibility differences between ApsaraDB RDS for MySQL instances that use the DuckDB analytic engine and standard MySQL. Use it to identify supported data types, SQL syntax restrictions, implicit conversion rules, and function availability before writing or migrating queries.
DuckDB uses a strict type system that enforces explicit type boundaries. This design improves query execution efficiency but means some MySQL features — particularly those relying on implicit type coercion, loose alias syntax, or functions that accept mixed types — behave differently or are not supported.
Supported data types
| Category | MySQL data type | Compatibility notes |
|---|---|---|
| Numeric | BOOLEAN | Compatible |
TINYINT, TINYINT UNSIGNED | Compatible | |
SMALLINT, SMALLINT UNSIGNED | Compatible | |
INT, INTEGER, INT UNSIGNED, INTEGER UNSIGNED | Compatible | |
BIGINT, BIGINT UNSIGNED | Compatible | |
FLOAT | Compatible | |
DOUBLE | Compatible | |
DECIMAL(m,d) | If m <= 38: fully compatible. If m > 38: stored as DOUBLE, which may cause precision loss. | |
| Character | CHAR, VARCHAR | Only UTF-8 character sets and collations are supported. |
TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT | Compatible | |
JSON | Compatible | |
SET | Compatible | |
ENUM | Compatible | |
| Binary | BINARY, VARBINARY | Compatible |
BIT | Compatible | |
TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB | Compatible | |
| Time | YEAR | Compatible |
TIME | Supported range: '00:00:00' to '23:59:59' (HH:MM:SS). MySQL supports '-838:59:59' to '838:59:59'. Data outside the DuckDB range may produce inconsistent query results. | |
DATE | Supported range: '0001-01-01' to '9999-12-31' (YYYY-MM-DD). MySQL supports '0000-00-00' to '0001-01-01'. Data outside the DuckDB range may produce inconsistent query results. | |
DATETIME | Supported range: '0001-01-01 00:00:00.000000' to '9999-12-31 00:00:00.999999' UTC (YYYY-MM-DD HH:MM:SS.MS). MySQL supports '0000-00-00 00:00:00' to '0001-01-01 00:00:00'. Data outside the DuckDB range may produce inconsistent query results. | |
TIMESTAMP | Compatible | |
| Spatial | GEOMETRY, POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING, MULTIPOLYGON, GEOMETRYCOLLECTION | Incompatible |
SELECT statement limits
The following SQL syntax is not supported in DuckDB analytic instances.
Comments starting with `#`
Use -- or /* */ comments instead.
-- Not supported
SELECT * FROM t1 #comment;
-- Use this instead
SELECT * FROM t1 -- comment
;Character set conversion
Character set conversions of any kind are not supported, including conversions to supported character sets.
-- Not supported
SELECT CONVERT(id USING gbk) FROM t1;
SELECT CAST(id AS CHAR CHARACTER SET utf8mb4) FROM t1;Mixing explicit and implicit JOIN syntax
A single SQL statement cannot combine explicit JOIN keywords and implicit comma-separated joins.
-- Not supported
SELECT * FROM t1 JOIN (t2, t3);Unsupported interval units
The following interval units are not supported:
YEAR_MONTH, DAY_HOUR, HOUR_MINUTE, DAY_MINUTE, HOUR_SECOND, DAY_SECOND,
SECOND_MICROSECOND, HOUR_MICROSECOND, DAY_MICROSECOND, MINUTE_SECOND,
MINUTE_MICROSECOND, SQL_TSI_HOURNon-constant interval expressions
In an INTERVAL expr unit expression, if expr is a non-constant expression, enclose it in parentheses.
-- Not supported
SELECT '2018-12-31 23:59:59' + INTERVAL -1 SECOND;
-- Use this instead
SELECT '2018-12-31 23:59:59' + INTERVAL (-1) SECOND;Alias syntax without AS
The expr 'alias' and expr "alias" shorthand are not supported. Use AS, backticks, or AS with quotes.
-- Not supported
SELECT 1 '1';
SELECT 1 "1";
-- Supported alternatives
SELECT 1 AS '1';
SELECT 1 AS "1";
SELECT 1 AS `1`;
SELECT 1 `1`;If an alias is a reserved keyword, use AS or backticks:
-- Not supported
SELECT id time FROM t1;
-- Supported alternatives
SELECT id AS time FROM t1;
SELECT id `time` FROM t1;
SELECT id AS `time` FROM t1;
SELECT id AS 'time' FROM t1;
SELECT id AS "time" FROM t1;Equality comparisons with non-scalar subqueries
-- Not supported
SELECT * FROM t1 WHERE (id, col1) = (SELECT id, col1 FROM t1);Explicit casts to BINARY(num), SIGNED, or UNSIGNED
-- Not supported
SELECT CAST('abc' AS BINARY(1));
SELECT CAST(1 AS SIGNED);
SELECT CAST(1 AS UNSIGNED);The BINARY column modifier
-- Not supported
SELECT BINARY id FROM t1;Complex arithmetic expressions with ambiguous operator sequences
For complex arithmetic expressions, use parentheses to make the order of operations explicit.
-- Cannot be correctly parsed
SELECT 1 !=-1;
SELECT --1;
-- Use these instead
SELECT 1 != (-1);
SELECT -(-1);Type conversion
DuckDB analytic instances use a strict type system. During query execution, the engine performs implicit type conversions where the context allows. When implicit conversion is not possible, use CAST or CONVERT to specify the target type explicitly.
Implicit conversion in functions
The tables below show which conversions are performed automatically when passing values to functions.
Legend: / = no conversion needed (same type) · ✔ = implicit conversion supported · ✖ = not supported; use CAST or CONVERT
Type definitions used in these tables:
Regular string types:
CHAR,VARCHAR,TINYTEXT,TEXT,MEDIUMTEXT,LONGTEXT,JSON,SET,ENUMBinary string types:
BINARY,VARBINARY,BIT,TINYBLOB,BLOB,MEDIUMBLOB,LONGBLOBConverting an integer type to another integer type with a smaller value range is not supported.
Conversion to basic scalar types
| Source type | To string literal | To numeric literal |
|---|---|---|
| String literal | / | ✖ |
| Numeric literal | ✖ | / |
| BOOLEAN | ✖ | ✖ |
| Integer types | ✖ | ✖ |
| FLOAT | ✖ | ✖ |
| DOUBLE | ✖ | ✖ |
| DECIMAL | ✖ | ✖ |
| Regular string | ✖ | ✖ |
| Binary string | ✖ | ✖ |
| YEAR | ✖ | ✖ |
| DATE | ✖ | ✖ |
| TIME | ✖ | ✖ |
| DATETIME | ✖ | ✖ |
| TIMESTAMP | ✖ | ✖ |
Conversion to numeric types
| Source type | To BOOLEAN | To integer types | To FLOAT | To DOUBLE | To DECIMAL |
|---|---|---|---|---|---|
| String literal | ✖ | ✖ | ✖ | ✔ | ✖ |
| Numeric literal | ✖ | ✔ | ✔ | ✔ | ✔ |
| BOOLEAN | / | ✖ | ✖ | ✖ | ✖ |
| Integer types | ✖ | / | ✔ | ✔ | ✔ |
| FLOAT | ✖ | ✔ (BIGINT only) | / | ✔ | ✖ |
| DOUBLE | ✖ | ✔ (BIGINT only) | ✖ | / | ✖ |
| DECIMAL | ✖ | ✔ | ✔ | ✔ | / |
| Regular string | ✖ | ✖ | ✖ | ✔ | ✖ |
| Binary string | ✖ | ✖ | ✖ | ✖ | ✖ |
| YEAR | ✖ | ✔ | ✔ | ✔ | ✔ |
| DATE | ✖ | ✖ | ✖ | ✔ | ✖ |
| TIME | ✖ | ✖ | ✖ | ✔ | ✖ |
| DATETIME | ✖ | ✖ | ✖ | ✔ | ✖ |
| TIMESTAMP | ✖ | ✖ | ✖ | ✔ | ✖ |
Conversion to string types
| Source type | To regular string | To binary string |
|---|---|---|
| String literal | ✔ | ✖ |
| Numeric literal | ✖ | ✖ |
| BOOLEAN | ✖ | ✖ |
| Integer types | ✔ | ✖ |
| FLOAT | ✔ | ✖ |
| DOUBLE | ✔ | ✖ |
| DECIMAL | ✔ | ✖ |
| Regular string | / | ✖ |
| Binary string | ✖ | / |
| YEAR | ✔ | ✖ |
| DATE | ✔ | ✖ |
| TIME | ✔ | ✖ |
| DATETIME | ✔ | ✖ |
| TIMESTAMP | ✔ | ✖ |
Conversion to date and time types
| Source type | To YEAR | To DATE | To TIME | To DATETIME | To TIMESTAMP |
|---|---|---|---|---|---|
| String literal | ✖ | ✖ | ✖ | ✖ | ✖ |
| Numeric literal | ✔ | ✖ | ✖ | ✖ | ✖ |
| BOOLEAN | ✖ | ✖ | ✖ | ✖ | ✖ |
| Integer types | ✖ | ✖ | ✖ | ✖ | ✖ |
| FLOAT | ✖ | ✖ | ✖ | ✖ | ✖ |
| DOUBLE | ✖ | ✖ | ✖ | ✖ | ✖ |
| DECIMAL | ✖ | ✖ | ✖ | ✖ | ✖ |
| Regular string | ✖ | ✖ | ✖ | ✖ | ✖ |
| Binary string | ✖ | ✖ | ✖ | ✖ | ✖ |
| YEAR | / | ✖ | ✖ | ✖ | ✖ |
| DATE | ✖ | / | ✖ | ✔ | ✔ |
| TIME | ✖ | ✖ | / | ✔ | ✔ |
| DATETIME | ✖ | ✖ | ✖ | / | ✔ |
| TIMESTAMP | ✖ | ✖ | ✖ | ✔ | / |
Implicit conversion in comparisons
DuckDB analytic instances apply stricter, more consistent rules for type conversion in comparisons. The following behaviors differ from standard MySQL.
String to date conversion
When a string is implicitly converted to a date type for comparison, the query fails with an error if the string cannot be parsed into a valid date value. In MySQL, invalid date strings may silently return unexpected results.
Integer type comparison
When two different integer types are compared, both are converted to the integer type with the larger value range.
Multi-element expression evaluation order
In multi-element expressions such as col1 IN (col2, col3, col4, ...), col1 BETWEEN col2 AND col3, and COALESCE(col1, col2, col3, ...), type conversion is performed sequentially from left to right.
YEAR type comparison
DuckDB converts the YEAR type to INTEGER for comparison. MySQL treats YEAR values using two-digit year logic for values between 00 and 99, so the same query can return different rows.
CREATE TABLE t1 (id YEAR PRIMARY KEY);
INSERT INTO t1 VALUES (1980);
SELECT * FROM t1 WHERE id BETWEEN 70 AND 90;
-- MySQL result: two-digit year 70–90 maps to 1970–1990, so 1980 matches
+------+
| id |
+------+
| 1980 |
+------+
-- DuckDB analytic instance result: compares 1980 BETWEEN 70 AND 90 as integers, no match
Empty set.Boolean type string conversion
DuckDB converts the strings '1', '0', 'yes', 'no', 'true', and 'false' to BOOLEAN. Any other string returns an error. MySQL converts '1' to true and all other strings to false, so queries using non-numeric boolean strings produce different results.
CREATE TABLE t1 (id INT PRIMARY KEY);
INSERT INTO t1 VALUES (1);
SELECT id FROM t1 WHERE 'true';
-- MySQL result: 'true' is not '1', so it is treated as false and returns no rows
Empty set
-- DuckDB analytic instance result: 'true' is a valid boolean string, so rows are returned
+------+
| id |
+------+
| 1 |
+------+Comparison result types
When data of different types is compared, DuckDB converts both operands to a common type before performing the comparison. For unsupported comparisons (✖), the query returns an error.
Type definitions: same as the conversion tables above.
Comparison with basic scalar types
| Source type | vs. string literal | vs. numeric literal |
|---|---|---|
| String literal | String | Numeric literal |
| Numeric literal | Numeric literal | Numeric type with the larger range |
| BOOLEAN | BOOLEAN | Numeric type with the larger range |
| Integer types | Integer types | Numeric type with the larger range |
| FLOAT | FLOAT | Numeric type with the larger range |
| DOUBLE | DOUBLE | Numeric type with the larger range |
| DECIMAL | DECIMAL | Numeric type with the larger range |
| Regular string | Regular string | Numeric literal |
| Binary string | Binary string | ✖ |
| YEAR | YEAR | Numeric type with the larger range |
| DATE | DATETIME | ✖ |
| TIME | TIME | ✖ |
| DATETIME | DATETIME | ✖ |
| TIMESTAMP | TIMESTAMP | ✖ |
Comparison with numeric types
| Source type | vs. BOOLEAN | vs. integer types | vs. FLOAT | vs. DOUBLE | vs. DECIMAL |
|---|---|---|---|---|---|
| String literal | BOOLEAN | Integer types | FLOAT | DOUBLE | DECIMAL |
| Numeric literal | Numeric type with larger range | Numeric type with larger range | Numeric type with larger range | Numeric type with larger range | Numeric type with larger range |
| BOOLEAN | BOOLEAN | Integer types | FLOAT (inequality ✖) | DOUBLE (inequality ✖) | DECIMAL (inequality ✖) |
| Integer types | Integer types | Integer types | FLOAT | DOUBLE | DECIMAL |
| FLOAT | FLOAT (inequality ✖) | FLOAT | FLOAT | DOUBLE | FLOAT |
| DOUBLE | DOUBLE (inequality ✖) | DOUBLE | DOUBLE | DOUBLE | DOUBLE |
| DECIMAL | DECIMAL (inequality ✖) | DECIMAL | FLOAT | DOUBLE | DECIMAL |
| Regular string | BOOLEAN | Integer types | FLOAT | DOUBLE | DECIMAL |
| Binary string | ✖ | ✖ | ✖ | ✖ | ✖ |
| YEAR | INTEGER | Integer type with larger range | FLOAT | DOUBLE | DECIMAL |
| DATE | ✖ | ✖ | ✖ | DOUBLE | ✖ |
| TIME | ✖ | ✖ | ✖ | DOUBLE | ✖ |
| DATETIME | ✖ | ✖ | ✖ | DOUBLE | ✖ |
| TIMESTAMP | ✖ | ✖ | ✖ | DOUBLE | ✖ |
Comparison with string types
| Source type | vs. regular string | vs. binary string |
|---|---|---|
| String literal | Regular string | Binary string |
| Numeric literal | Numeric literal | ✖ |
| BOOLEAN | BOOLEAN | ✖ |
| Integer types | Integer types | ✖ |
| FLOAT | FLOAT | ✖ |
| DOUBLE | DOUBLE | ✖ |
| DECIMAL | DECIMAL | ✖ |
| Regular string | Regular string | Binary string |
| Binary string | Binary string | Binary string |
| YEAR | INTEGER | ✖ |
| DATE | DATE | ✖ |
| TIME | TIME | ✖ |
| DATETIME | DATETIME | ✖ |
| TIMESTAMP | TIMESTAMP | ✖ |
Comparison with date and time types
| Source type | vs. YEAR | vs. DATE | vs. TIME | vs. DATETIME | vs. TIMESTAMP |
|---|---|---|---|---|---|
| String literal | YEAR | DATETIME | TIME | DATETIME | TIMESTAMP |
| Numeric literal | Numeric type with larger range | ✖ | ✖ | ✖ | ✖ |
| BOOLEAN | INTEGER | ✖ | ✖ | ✖ | ✖ |
| Integer types | Integer type with larger range | ✖ | ✖ | ✖ | ✖ |
| FLOAT | FLOAT | ✖ | ✖ | ✖ | ✖ |
| DOUBLE | DOUBLE | DOUBLE | DOUBLE | DOUBLE | DOUBLE |
| DECIMAL | DECIMAL | ✖ | ✖ | ✖ | ✖ |
| Regular string | INTEGER | DATE | TIME | DATETIME | TIMESTAMP |
| Binary string | ✖ | ✖ | ✖ | ✖ | ✖ |
| YEAR | INTEGER | ✖ | ✖ | ✖ | ✖ |
| DATE | ✖ | DATE | ✖ | DATETIME | TIMESTAMP |
| TIME | ✖ | ✖ | TIME | ✖ | ✖ |
| DATETIME | ✖ | DATETIME | ✖ | DATETIME | DATETIME |
| TIMESTAMP | ✖ | TIMESTAMP | ✖ | DATETIME | TIMESTAMP |
Potential inconsistencies in query results
The following scenarios may produce different results between DuckDB analytic instances and MySQL.
Floating-point comparison
DuckDB's strict floating-point semantics can produce different comparison results. The root cause is that MySQL promotes FLOAT columns to higher precision during comparisons, so the stored value appears to exceed the literal threshold. DuckDB evaluates at the declared precision.
CREATE TABLE t1 (id FLOAT PRIMARY KEY);
INSERT INTO t1 VALUES (1.22), (1.23), (1.24);
SELECT * FROM t1 WHERE t1.id > 1.23;
-- MySQL result: the stored FLOAT 1.23 rounds up in comparison,
-- so it is treated as greater than the literal 1.23
+------+
| id |
+------+
| 1.23 |
| 1.24 |
+------+
-- DuckDB analytic instance result: comparison uses declared FLOAT precision
+------+
| id |
+------+
| 1.24 |
+------+Complex compound operations on floating-point numbers may also differ because of intermediate rounding.
Integer and DECIMAL arithmetic overflow
When performing arithmetic between integer and DECIMAL types, the result must not exceed the value range of the column type. MySQL promotes the result to a wider type automatically. DuckDB enforces the declared type, so an overflow causes the query to fail.
To prevent this error, cast the column to a wider type before the operation.
CREATE TABLE t1 (id TINYINT PRIMARY KEY);
INSERT INTO t1 VALUES (100);
SELECT id * 2 FROM t1;
-- MySQL result: result is promoted to a wider integer type
+--------+
| id * 2 |
+--------+
| 200 |
+--------+
-- DuckDB analytic instance result: overflow in TINYINT (INT8)
ERROR 7577 (HY000): [DuckDB] Out of Range Error: Overflow in multiplication of INT8 (100 * 2)!
-- Fix: cast to a wider type first
SELECT CAST(id AS INT) * 2 FROM t1;Collation differences for symbol characters
Collations in the utf8mb4_0900_xx series sort some symbol characters differently than MySQL. This is because DuckDB uses Unicode sort order, while MySQL's utf8mb4_0900_xx collations apply language-specific weights that place certain symbols in a different position.
CREATE TABLE t1 (id VARCHAR(20) COLLATE utf8mb4_0900_ai_ci PRIMARY KEY);
INSERT INTO t1 VALUES ('!'), ('_');
SELECT * FROM t1 ORDER BY id;
-- MySQL result
+----+
| id |
+----+
| _ |
| ! |
+----+
-- DuckDB analytic instance result
+----+
| id |
+----+
| ! |
| _ |
+----+NULL handling in vector subqueries with IN
DuckDB handles NULL values differently in vector subqueries with IN. When a subquery contains NULL values, MySQL may return 0 for rows with no matching prefix. DuckDB returns NULL because the presence of a NULL value in the subquery makes the result indeterminate — consistent with SQL three-valued logic.
CREATE TABLE t1 (id INT PRIMARY KEY, col1 INT);
INSERT INTO t1 VALUES (1, 1), (2, 2);
CREATE TABLE t2 (id INT PRIMARY KEY, col1 INT);
INSERT INTO t2 VALUES (1, NULL);
SELECT (id, col1) IN (SELECT id, col1 FROM t2) FROM t1;
-- MySQL result
+-----------------------------------------+
| (id, col1) in (select id, col1 from t2) |
+-----------------------------------------+
| NULL |
| 0 |
+-----------------------------------------+
-- DuckDB analytic instance result
+-----------------------------------------+
| (id, col1) in (select id, col1 from t2) |
+-----------------------------------------+
| NULL |
| NULL |
+-----------------------------------------+For the row (2, 2), there is no matching vector prefix in t2. MySQL returns 0. DuckDB returns NULL because the NULL in t2 means a match cannot be ruled out.
Function support
Aggregate functions
| Function | Supported | Limits |
|---|---|---|
AVG | Yes | None |
BIT_AND | Yes | String, DECIMAL, and date types are not supported. |
BIT_OR | Yes | String, DECIMAL, and date types are not supported. |
BIT_XOR | Yes | String, DECIMAL, and date types are not supported. |
COUNT | Yes | None |
COUNT(DISTINCT) | Yes | None |
GROUP_CONCAT | Yes | Multi-column GROUP_CONCAT and SEPARATOR are not supported. |
JSON_ARRAYAGG | No | — |
JSON_OBJECTAGG | No | — |
MAX | Yes | None |
MIN | Yes | None |
STD | Yes | None |
STDDEV | Yes | None |
STDDEV_POP | Yes | None |
STDDEV_SAMP | Yes | None |
SUM | Yes | None |
VAR_POP | Yes | None |
VAR_SAMP | Yes | None |
VARIANCE | Yes | None |
Numeric functions
Numeric functions do not support the BOOLEAN type.
| Function | Supported | Limits |
|---|---|---|
%, MOD | Yes | None |
*, +, -, / | Yes | None |
ABS() | Yes | None |
ACOS() | Yes | None |
ASIN() | Yes | None |
ATAN() | Yes | The two-argument form ATAN(y, x) is not supported. |
ATAN2() | No | — |
CEIL(), CEILING() | Yes | None |
CONV() | No | — |
COS() | Yes | None |
COT() | Yes | None |
CRC32() | No | — |
DEGREES() | Yes | None |
DIV | Yes | None |
EXP() | Yes | None |
FLOOR() | Yes | None |
LN() | Yes | None |
LOG(), LOG10(), LOG2() | Yes | None |
PI() | Yes | None |
POW(), POWER() | Yes | None |
RADIANS() | Yes | None |
RAND() | Yes | None |
ROUND() | Yes | None |
SIGN() | Yes | None |
SIN() | Yes | None |
SQRT() | Yes | None |
TAN() | Yes | None |
TRUNCATE() | No | — |
String functions
DuckDB analytic instances strictly distinguish binary string types (BLOB, VARBINARY) from regular string types (VARCHAR, TEXT, JSON). String functions accept only regular strings unless noted otherwise.
| Function | Supported | Limits |
|---|---|---|
ASCII() | Yes | None |
BIN() | Yes | BIN('') returns '0' instead of NULL (MySQL behavior). |
BIT_LENGTH() | Yes | None |
CHAR() | No | — |
CHAR_LENGTH(), CHARACTER_LENGTH() | Yes | None |
CONCAT() | Yes | Accepts binary strings. |
CONCAT_WS() | Yes | Accepts binary strings. |
ELT() | No | — |
EXPORT_SET() | No | — |
FIELD() | No | — |
FIND_IN_SET() | Yes | The first parameter must be a character type. Non-character types may produce results inconsistent with MySQL. |
FORMAT() | No | — |
FROM_BASE64() | Yes | Returns an error if decoding fails. |
HEX() | Yes | None |
INSERT() | Yes | None |
INSTR() | Yes | None |
LCASE() | Yes | None |
LEFT() | Yes | None |
LENGTH() | Yes | Accepts binary strings. |
LIKE | Yes | Not affected by collation rules. |
LOAD_FILE() | No | — |
LOCATE() | Yes | None |
LOWER() | Yes | None |
LPAD() | Yes | None |
LTRIM() | Yes | None |
MAKE_SET() | No | — |
MATCH() | No | — |
MID() | Yes | Accepts binary strings. |
NOT LIKE | Yes | Not affected by collation rules. |
NOT REGEXP | No | — |
OCT() | Yes | OCT('') returns '0' instead of NULL (MySQL behavior). |
OCTET_LENGTH() | Yes | Accepts binary strings. |
ORD() | Yes | None |
POSITION() | Yes | None |
QUOTE() | No | — |
REGEXP | No | — |
REGEXP_INSTR() | No | — |
REGEXP_LIKE() | No | — |
REGEXP_REPLACE() | No | — |
REGEXP_SUBSTR() | No | — |
REPEAT() | Yes | Accepts binary strings. |
REPLACE() | Yes | None |
REVERSE() | Yes | None |
RIGHT() | Yes | None |
RLIKE | No | — |
RPAD() | Yes | None |
RTRIM() | Yes | None |
SOUNDEX() | No | — |
SOUNDEX LIKE | No | — |
SPACE() | Yes | None |
STRCMP() | Yes | None |
SUBSTR() | Yes | The SUBSTR(str FROM pos) and SUBSTR(str FROM pos FOR len) syntax is not supported. |
SUBSTRING() | Yes | The SUBSTRING(str FROM pos) and SUBSTRING(str FROM pos FOR len) syntax is not supported. |
SUBSTRING_INDEX() | Yes | None |
TO_BASE64() | Yes | Accepts binary strings. Returns a binary string. |
TRIM() | Yes | None |
UCASE() | Yes | None |
UNHEX() | Yes | Returns a binary string. Returns an error if a non-hexadecimal digit is encountered. |
UPPER() | Yes | None |
WEIGHT_STRING() | No | — |
Date functions
Date functions do not accept strings as input. Pass values using explicit type conversion with CAST, or use typed literal syntax.
-- For string columns in a table
SELECT ADDDATE(CAST(varchar_col AS DATE), INTERVAL 1 DAY) FROM t1;
SELECT ADDDATE(CAST(varchar_col AS TIME), INTERVAL 1 DAY) FROM t1;
SELECT ADDDATE(CAST(varchar_col AS DATETIME), INTERVAL 1 DAY) FROM t1;
-- For string literal constants
SELECT ADDDATE(DATE '2020-01-01', INTERVAL 1 DAY) FROM t1;
SELECT ADDDATE(TIME '12:00:00', INTERVAL 1 DAY) FROM t1;
SELECT ADDDATE(TIMESTAMP '2020-01-01 12:00:00', INTERVAL 1 DAY) FROM t1;| Function | Supported | Limits |
|---|---|---|
ADDDATE() | Yes | When the first parameter is a TIME type, the function implicitly converts TIME to TIMESTAMP before calculating. To avoid this, use DATE_ADD() instead. |
ADDTIME() | Yes | If the return value exceeds the DuckDB TIME range, results will be inconsistent. |
CONVERT_TZ() | Yes | None |
CURRENT_DATE(), CURRENT_DATE | Yes | None |
CURRENT_TIME(), CURRENT_TIME | Yes | None |
CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP | Yes | None |
CURTIME() | Yes | None |
DATE() | Yes | None |
DATE_ADD() | Yes | When the first parameter is a TIME type, no implicit TIME-to-TIMESTAMP conversion is performed. |
DATE_FORMAT() | Yes | The %X, %V, and %u format specifiers are not supported. |
DATE_SUB() | Yes | Same behavior as DATE_ADD(). |
DATEDIFF() | Yes | None |
DAY() | Yes | None |
DAYNAME() | Yes | None |
DAYOFMONTH() | Yes | None |
DAYOFWEEK() | Yes | None |
DAYOFYEAR() | Yes | None |
EXTRACT() | Yes | None |
FROM_DAYS() | Yes | None |
FROM_UNIXTIME() | Yes | None |
GET_FORMAT() | No | — |
HOUR() | Yes | None |
LAST_DAY | Yes | None |
LOCALTIME(), LOCALTIME | Yes | None |
LOCALTIMESTAMP, LOCALTIMESTAMP() | Yes | None |
MAKEDATE() | Yes | None |
MAKETIME() | Yes | None |
MICROSECOND() | Yes | None |
MINUTE() | Yes | None |
MONTH() | Yes | None |
MONTHNAME() | Yes | None |
NOW() | Yes | None |
PERIOD_ADD() | Yes | Years greater than 9999 are not supported. |
PERIOD_DIFF() | Yes | Years greater than 9999 are not supported. |
QUARTER() | Yes | None |
SEC_TO_TIME() | Yes | If the return value exceeds the DuckDB TIME range, results will be inconsistent. |
SECOND() | Yes | None |
STR_TO_DATE() | Yes | The %X, %V, and %u format specifiers are not supported. Returns NULL if a format specifier is not matched. |
SUBDATE() | Yes | Same behavior as ADDDATE(). |
SUBTIME() | Yes | If the return value exceeds the DuckDB TIME range, results will be inconsistent. |
SYSDATE() | Yes | None |
TIME() | No | — |
TIME_FORMAT() | Yes | None |
TIME_TO_SEC() | Yes | The DAY TIME input format is not supported (for example, TIME_TO_SEC('1 12:00:00')). |
TIMEDIFF() | No | — |
TIMESTAMP() | No | — |
TIMESTAMPADD() | Yes | None |
TIMESTAMPDIFF() | Yes | None |
TO_DAYS() | Yes | None |
TO_SECONDS() | Yes | None |
UNIX_TIMESTAMP() | Yes | None |
UTC_DATE() | Yes | None |
UTC_TIME() | Yes | None |
UTC_TIMESTAMP() | Yes | None |
WEEK() | Yes | None |
WEEKDAY() | Yes | None |
WEEKOFYEAR() | Yes | None |
YEAR() | Yes | None |
YEARWEEK() | Yes | None |
JSON functions
| Function | Supported | Limits |
|---|---|---|
JSON_ARRAY() | Yes | None |
JSON_ARRAY_APPEND() | No | — |
JSON_ARRAY_INSERT() | No | — |
JSON_CONTAINS() | No | — |
JSON_CONTAINS_PATH() | No | — |
JSON_DEPTH() | Yes | None |
JSON_EXTRACT() | Yes | None |
JSON_INSERT() | No | — |
JSON_KEYS() | Yes | None |
JSON_LENGTH() | Yes | None |
JSON_MERGE() | No | — |
JSON_MERGE_PATCH() | Yes | Supports merging two JSON objects only. The field order of the merged result may differ from MySQL. |
JSON_MERGE_PRESERVE() | No | — |
JSON_OBJECT() | Yes | None |
JSON_OVERLAPS() | Yes | None |
JSON_PRETTY() | Yes | None |
JSON_QUOTE() | Yes | None |
JSON_REMOVE() | No | — |
JSON_REPLACE() | No | — |
JSON_SCHEMA_VALID() | No | — |
JSON_SCHEMA_VALIDATION_REPORT() | No | — |
JSON_SEARCH() | No | — |
JSON_SET() | No | — |
JSON_STORAGE_FREE() | No | — |
JSON_STORAGE_SIZE() | No | — |
JSON_TABLE() | No | — |
JSON_TYPE() | No | — |
JSON_UNQUOTE() | No | — |
JSON_VALID() | Yes | None |
JSON_VALUE() | No | — |
MEMBER OF() | No | — |
Window functions
All standard window functions are fully supported.
| Function | Supported | Limits |
|---|---|---|
CUME_DIST() | Yes | None |
DENSE_RANK() | Yes | None |
FIRST_VALUE() | Yes | None |
LAG() | Yes | None |
LAST_VALUE() | Yes | None |
LEAD() | Yes | None |
NTH_VALUE() | Yes | None |
NTILE() | Yes | None |
PERCENT_RANK() | Yes | None |
RANK() | Yes | None |
ROW_NUMBER() | Yes | None |
Other limitations
View queries are not supported in DuckDB analytic instances.