Cette rubrique décrit la compatibilité des instances analytiques basées sur DuckDB fournies par ApsaraDB RDS for MySQL.
Les notes de compatibilité suivantes nécessitent toutes l'activation du paramètre duckdb_sql_normalization.
Types de données pris en charge
Le tableau suivant répertorie uniquement les types de données pour lesquels les instances analytiques basées sur DuckDB diffèrent de MySQL.
Type | Type de données MySQL | Compatibilité |
Types de chaînes |
| Seuls les jeux de caractères et les classements UTF-8 sont pris en charge. |
Types temporels |
| Une instance analytique basée sur DuckDB prend en charge une plage de MySQL prend en charge la plage |
| Les instances analytiques basées sur DuckDB prennent en charge une plage allant de Pour la plage | |
| La plage prise en charge pour les instances analytiques basées sur DuckDB va de Pour les données comprises dans la plage | |
Types de données spatiales |
| Incompatible |
Limites des instructions SELECT
-
Conversion de jeu de caractères
Pour les fonctions de conversion de jeu de caractères, quelle que soit la cible, toutes les conversions sont normalisées vers le jeu de caractères
utf8mb4et transmises à DuckDB pour exécution. Par exemple :SELECT convert(id using gbk) FROM t1; SELECT cast(id AS CHAR CHARACTER SET utf8mb4) FROM t1; -
Unité d'intervalle
Les unités d'intervalle suivantes ne sont pas prises en charge :
YEAR_MONTH, DAY_HOUR, HOUR_MINUTE, DAY_MINUTE, HOUR_SECOND, DAY_SECOND, SECOND_MICROSECOND, HOUR_MICROSECOND, DAY_MICROSECOND, MINUTE_SECOND, MINUTE_MICROSECOND, SQL_TSI_HOUR -
Sous-requêtes
Les sous-requêtes non scalaires avec des conditions d'égalité ne sont pas prises en charge. Exemple :
SELECT * FROM t1 WHERE (id, col1) = (SELECT id, col1 FROM t1); -
Conversion du type BINARY(num)
La conversion explicite vers le type de données
BINARY(num)n'est pas prise en charge et la longueur de bits spécifiée est ignorée. Exemple :SELECT CAST('abc' AS binary(1)); -
Conversion du type UNSIGNED
La conversion explicite vers le type de données
UNSIGNEDn'est pas prise en charge. Par exemple :SELECT CAST(1 AS UNSIGNED);
Problèmes de conversion de type de données
Pour une efficacité d'exécution optimale, les instances analytiques basées sur DuckDB appliquent des contraintes de type strictes lors de l'exécution. Lorsqu'une requête est exécutée, le système effectue automatiquement des conversions de type en fonction du contexte. Ce type de conversion est appelé conversion implicite de type. Pour les scénarios où la conversion ne peut pas être effectuée implicitement, vous devez utiliser la fonction CAST ou CONVERT pour spécifier explicitement la conversion de type et garantir l'exécution correcte de la requête.
Règles de conversion implicite de type dans les fonctions
/ indique qu'aucune conversion implicite n'est impliquée. ✔️ indique que la conversion implicite est prise en charge. ✖️ indique que la conversion implicite n'est pas prise en charge.
Les types chaîne réguliers font référence aux types de données MySQL suivants :
CHAR,VARCHAR,TINYTEXT,TEXT,MEDIUMTEXT,LONGTEXT,JSON,SETetENUM.Les types chaîne binaires font référence aux types de données MySQL suivants :
BINARY,VARBINARY,BIT,TINYBLOB,BLOB,MEDIUMBLOBetLONGBLOB.La conversion d'un type entier avec une plage de valeurs plus large vers un type entier avec une plage de valeurs plus petite n'est pas prise en charge.
Conversion vers les types scalaires de base
Type source | Conversion implicite vers les types scalaires de base | ||
Littéral chaîne | Littéral numérique | ||
Scalaire de base | Littéral chaîne | / | ✖️ |
Littéral numérique | ✖️ | / | |
Valeur | BOOLEAN | ✖️ | ✖️ |
Types entiers | ✖️ | ✖️ | |
FLOAT | ✖️ | ✖️ | |
DOUBLE | ✖️ | ✖️ | |
DECIMAL | ✖️ | ✖️ | |
Chaîne | Chaîne régulière | ✖️ | ✖️ |
Chaîne binaire | ✖️ | ✖️ | |
Date et heure | YEAR | ✖️ | ✖️ |
DATE | ✖️ | ✖️ | |
TIME | ✖️ | ✖️ | |
DATETIME | ✖️ | ✖️ | |
TIMESTAMP | ✖️ | ✖️ | |
Conversion vers les types numériques
Type source | Conversion implicite vers les types numériques | |||||
BOOLEAN | Types entiers | FLOAT | DOUBLE | DECIMAL | ||
Scalaire de base | Littéral chaîne | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ |
Littéral numérique | ✖️ | ✔️ | ✔️ | ✔️ | ✔️ | |
Numérique | BOOLEAN | / | ✖️ | ✖️ | ✖️ | ✖️ |
Types entiers | ✖️ | / | ✔️ | ✔️ | ✔️ | |
FLOAT | ✖️ | ✔️ : Seule la conversion vers BIGINT est prise en charge. | / | ✔️ | ✖️ | |
DOUBLE | ✖️ | ✔️ : Seule la conversion vers BIGINT est prise en charge. | ✖️ | / | ✖️ | |
DECIMAL | ✖️ | ✔️ | ✔️ | ✔️ | / | |
Chaîne | Chaîne régulière | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ |
Chaîne binaire | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
Date et heure | YEAR | ✖️ | ✔️ | ✔️ | ✔️ | ✔️ |
DATE | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ | |
TIME | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ | |
DATETIME | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ | |
TIMESTAMP | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ | |
Conversion vers les types chaîne
Type source | Conversion implicite vers les types chaîne | ||
Chaîne régulière | Chaîne binaire | ||
Scalaire de base | Littéral chaîne | ✔️ | ✖️ |
Littéral numérique | ✖️ | ✖️ | |
Numérique | BOOLEAN | ✖️ | ✖️ |
Types entiers | ✔️ | ✖️ | |
FLOAT | ✔️ | ✖️ | |
DOUBLE | ✔️ | ✖️ | |
DECIMAL | ✔️ | ✖️ | |
Chaîne | Chaîne régulière | / | ✖️ |
Chaîne binaire | ✖️ | / | |
Date et heure | YEAR | ✔️ | ✖️ |
DATE | ✔️ | ✖️ | |
TIME | ✔️ | ✖️ | |
DATETIME | ✔️ | ✖️ | |
TIMESTAMP | ✔️ | ✖️ | |
Conversion vers les types de date et d'heure
Type source | Conversion implicite vers les types de date et d'heure | |||||
YEAR | DATE | TIME | DATETIME | TIMESTAMP | ||
Scalaire de base | Littéral de chaîne | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ |
Littéral numérique | ✔️ | ✖️ | ✖️ | ✖️ | ✖️ | |
valeur | BOOLEAN | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ |
Types entiers | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
FLOAT | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
DOUBLE | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
DECIMAL | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
Chaîne | Chaîne régulière | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ |
Chaîne binaire | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
Date et heure | YEAR | / | ✖️ | ✖️ | ✖️ | ✖️ |
DATE | ✖️ | / | ✖️ | ✔️ | ✔️ | |
TIME | ✖️ | ✖️ | / | ✔️ | ✔️ | |
DATETIME | ✖️ | ✖️ | ✖️ | / | ✔️ | |
TIMESTAMP | ✖️ | ✖️ | ✖️ | ✔️ | / | |
Règles de conversion implicite de type dans les comparaisons
Les instances analytiques basées sur DuckDB appliquent des règles plus strictes et plus cohérentes en matière de conversion de type et de comparaison. Toutefois, ce comportement peut différer de celui de MySQL dans certains scénarios :
Conversion implicite d'une chaîne vers une date : lors de la conversion implicite d'une chaîne vers une date, si le format de la chaîne ne peut pas être analysé correctement pour produire une valeur de date valide, la requête SQL échoue et renvoie une erreur.
Règles de comparaison entre types entiers : lorsque différents types entiers sont comparés, les instances analytiques basées sur DuckDB les convertissent vers le type entier disposant de la plage de valeurs la plus large.
Ordre de conversion de type pour les expressions à plusieurs opérandes : pour les expressions à plusieurs opérandes telles que
col1 in (col2, col3, col4, ...), col1 between col2 and col3, coalesce(col1, col2, col3, ...), la conversion de type est effectuée séquentiellement.-
Différence de compatibilité pour le type YEAR : dans les instances analytiques basées sur DuckDB, le type YEAR est converti en type INTEGER pour la comparaison, ce qui peut entraîner une incompatibilité avec MySQL. Exemple :
CREATE TABLE t1 (id YEAR PRIMARY KEY); INSERT INTO t1 VALUES (1980); SELECT * FROM t1 WHERE id BETWEEN 70 AND 90; # MySQL query result +------+ | id | +------+ | 1980 | +------+ # DuckDB-based analytical instance query result Empty set. -
Règles de conversion de chaîne pour le type Boolean : les instances analytiques basées sur DuckDB prennent en charge la conversion de six chaînes (
'1','0','yes','no','true'et'false') vers le type BOOLEAN. Toute tentative de conversion d'une autre chaîne génère une erreur. MySQL convertit'1'entrueet toutes les autres chaînes enfalse. Par conséquent, l'instruction SQL suivante peut renvoyer des résultats incohérents :CREATE TABLE t1 (id INT PRIMARY KEY); INSERT INTO t1 VALUES (1); SELECT id FROM t1 WHERE 'true'; # MySQL query result Empty set # DuckDB-based analytical instance query result +------+ | id | +------+ | 1 | +------+
Lorsque des données de types différents sont comparées, le système convertit les données en un type commun pour la comparaison, selon les règles présentées dans les tableaux suivants. Si une comparaison entre types n'est pas prise en charge (✖️), une erreur est signalée.
Les types de chaînes régulières correspondent aux types de données MySQL suivants :
CHAR,VARCHAR,TINYTEXT,TEXT,MEDIUMTEXT,LONGTEXT,JSON,SETetENUM.Les types de chaînes binaires correspondent aux types de données MySQL suivants :
BINARY,VARBINARY,BIT,TINYBLOB,BLOB,MEDIUMBLOBetLONGBLOB.
Comparaison avec les types scalaires de base
Type source | Comparaison avec les types scalaires de base | ||
Littéral chaîne | Littéral numérique | ||
Scalaire de base | Littéral chaîne | String | Littéral numérique |
Littéral numérique | Littéral numérique | Type numérique à plage plus large | |
Valeur | BOOLEAN | BOOLEAN | Type numérique à plage plus large |
Types entiers | Types entiers | Type numérique à plage plus large | |
FLOAT | FLOAT | Type numérique à plage plus large | |
DOUBLE | DOUBLE | Type numérique à plage plus large | |
DECIMAL | DECIMAL | Type numérique à plage plus large | |
String | Chaîne régulière | Chaîne régulière | Littéral numérique |
Chaîne binaire | Chaîne binaire | ✖️ | |
Date et heure | YEAR | YEAR | Type numérique à plage plus large |
DATE | DATETIME | ✖️ | |
TIME | TIME | ✖️ | |
DATETIME | DATETIME | ✖️ | |
TIMESTAMP | TIMESTAMP | ✖️ | |
Comparaison avec les types numériques
Type source | Comparaison avec les types numériques | |||||
BOOLEAN | Types entiers | FLOAT | DOUBLE | DECIMAL | ||
Scalaire de base | Littéral chaîne | BOOLEAN | Types entiers | FLOAT | DOUBLE | DECIMAL |
Littéral numérique | Type numérique à plage plus large | Type numérique à plage plus large | Type numérique à plage plus large | Type numérique à plage plus large | Type numérique à plage plus large | |
Numeric | BOOLEAN | BOOLEAN | Types entiers | FLOAT (comparaison d'inégalité ✖️) | DOUBLE (comparaison d'inégalité ✖️) | DECIMAL (comparaison d'inégalité ✖️) |
Types entiers | Types entiers | Types entiers | FLOAT | DOUBLE | DECIMAL | |
FLOAT | FLOAT (comparaison d'inégalité ✖️) | FLOAT | FLOAT | DOUBLE | FLOAT | |
DOUBLE | DOUBLE (comparaison d'inégalité ✖️) | DOUBLE | DOUBLE | DOUBLE | DOUBLE | |
DECIMAL | DECIMAL (comparaison d'inégalité ✖️) | DECIMAL | FLOAT | DOUBLE | DECIMAL | |
String | Chaîne régulière | BOOLEAN | Types entiers | FLOAT | DOUBLE | DECIMAL |
Chaîne binaire | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
Date et heure | YEAR | INTEGER | Type entier à plage plus large | FLOAT | DOUBLE | DECIMAL |
DATE | ✖️ | ✖️ | ✖️ | DOUBLE | ✖️ | |
TIME | ✖️ | ✖️ | ✖️ | DOUBLE | ✖️ | |
DATETIME | ✖️ | ✖️ | ✖️ | DOUBLE | ✖️ | |
TIMESTAMP | ✖️ | ✖️ | ✖️ | DOUBLE | ✖️ | |
Comparaison avec les types de chaînes
Type source | Comparaison avec les types de chaînes | ||
Chaîne régulière | Chaîne binaire | ||
Scalaire de base | Littéral chaîne | Chaîne régulière | Chaîne binaire |
Littéral numérique | Littéral numérique | ✖️ | |
Numeric | BOOLEAN | BOOLEAN | ✖️ |
Types entiers | Types entiers | ✖️ | |
FLOAT | FLOAT | ✖️ | |
DOUBLE | DOUBLE | ✖️ | |
DECIMAL | DECIMAL | ✖️ | |
String | Chaîne régulière | Chaîne régulière | Chaîne binaire |
Chaîne binaire | Chaîne binaire | Chaîne binaire | |
Date et heure | YEAR | INTEGER | ✖️ |
DATE | DATE | ✖️ | |
TIME | TIME | ✖️ | |
DATETIME | DATETIME | ✖️ | |
TIMESTAMP | TIMESTAMP | ✖️ | |
Comparaison avec les types de date et d'heure
Type source | Comparaison avec les types de date et d'heure | |||||
YEAR | DATE | TIME | DATETIME | TIMESTAMP | ||
Scalaire de base | Littéral de chaîne | YEAR | DATETIME | TIME | DATETIME | TIMESTAMP |
Littéral numérique | Type numérique à plage plus large | ✖️ | ✖️ | ✖️ | ✖️ | |
Numeric | BOOLEAN | INTEGER | ✖️ | ✖️ | ✖️ | ✖️ |
Types entiers | Type entier à plage plus large | ✖️ | ✖️ | ✖️ | ✖️ | |
FLOAT | FLOAT | ✖️ | ✖️ | ✖️ | ✖️ | |
DOUBLE | DOUBLE | DOUBLE | DOUBLE | DOUBLE | DOUBLE | |
DECIMAL | DECIMAL | ✖️ | ✖️ | ✖️ | ✖️ | |
String | Chaîne régulière | INTEGER | DATE | TIME | DATETIME | TIMESTAMP |
Chaîne binaire | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
Date et heure | YEAR | INTEGER | ✖️ | ✖️ | ✖️ | ✖️ |
DATE | ✖️ | DATE | ✖️ | DATETIME | TIMESTAMP | |
TIME | ✖️ | ✖️ | TIME | ✖️ | ✖️ | |
DATETIME | ✖️ | DATETIME | ✖️ | DATETIME | DATETIME | |
TIMESTAMP | ✖️ | TIMESTAMP | ✖️ | DATETIME | TIMESTAMP | |
Incohérences potentielles dans les résultats des requêtes
Opérations numériques
-
Les comparaisons de nombres à virgule flottante peuvent être incompatibles. Exemple :
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 query result +------+ | id | +------+ | 1.23 | | 1.24 | +------+ # DuckDB-based analytical instance query result +------+ | id | +------+ | 1.24 | +------+ Les résultats d'opérations complexes sur les nombres à virgule flottante peuvent varier en raison d'erreurs d'arrondi propres à ce type de données.
-
Lorsqu'une opération est effectuée entre des types INTEGER et DECIMAL, le résultat ne doit pas dépasser la plage de valeurs du type. Dans le cas contraire, une erreur de dépassement de capacité peut entraîner l'échec de l'exécution.
CREATE TABLE t1 (id TINYINT PRIMARY KEY); INSERT INTO t1 VALUES (100); SELECT id * 2 FROM t1; # MySQL query result +--------+ | id * 2 | +--------+ | 200 | +--------+ # DuckDB-based analytical instance query result ERROR 7577 (HY000): [DuckDB] Out of Range Error: Overflow in multiplication of INT8 (100 * 2)!.
Résultats incohérents dus aux règles de collation
Les collations de la série utf8mb4_0900_xx sont incompatibles lors de la comparaison de certains caractères symboliques. Par exemple :
CREATE TABLE t1 ( id varchar(20) COLLATE utf8mb4_0900_ai_ci PRIMARY KEY );
INSERT INTO t1 VALUES ('!'), ('_');
SELECT * FROM t1 ORDER BY id;
# MySQL query result
+----+
| id |
+----+
| _ |
| ! |
+----+
# DuckDB-based analytical instance query result
+----+
| id |
+----+
| ! |
| _ |
+----+
Gestion des valeurs NULL dans les sous-requêtes vectorielles avec IN
Dans les instances analytiques basées sur DuckDB, la gestion des valeurs NULL dans les sous-requêtes vectorielles utilisant l'opérateur IN peut être incompatible avec MySQL. Exemple :
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 query result
+-----------------------------------------+
| (id, col1) in (select id, col1 from t2) |
+-----------------------------------------+
| NULL |
| 0 |
+-----------------------------------------+
# DuckDB-based analytical instance query result
+-----------------------------------------+
| (id, col1) in (select id, col1 from t2) |
+-----------------------------------------+
| NULL |
| NULL |
+-----------------------------------------+
Pour les données (2, 2), aucun élément correspondant au préfixe vectoriel n'existe dans la clause IN. Dans ce cas, MySQL renvoie 0, tandis que l'instance analytique basée sur DuckDB renvoie NULL.
Limites des fonctions
Le tableau suivant répertorie uniquement les fonctions pour lesquelles les instances analytiques basées sur DuckDB diffèrent de MySQL.
Fonctions d'agrégation
|
Nom de la fonction |
Prise en charge |
Limites |
|
|
Oui |
Les types String, DECIMAL et date ne sont pas pris en charge. |
|
|
Oui |
Les types String, DECIMAL et date ne sont pas pris en charge. |
|
|
Oui |
Les types String, DECIMAL et date ne sont pas pris en charge. |
|
|
Non |
/ |
Fonctions numériques
Les fonctions numériques ne prennent pas en charge le type BOOLEAN.
|
Nom de la fonction |
Prise en charge |
Limites |
|
|
Non |
/ |
|
|
Non |
/ |
|
|
Non |
/ |
Fonctions de chaîne
MySQL DuckDB fait une distinction stricte entre les chaînes binaires (telles que BLOB et VARBINARY) et les chaînes de caractères (telles que VARCHAR, TEXT et JSON). Par conséquent, les limites d'utilisation suivantes pour les fonctions de chaîne s'appliquent uniquement aux entrées de type chaîne, et non aux entrées de type chaîne binaire. Certaines fonctions acceptant des chaînes binaires en entrée incluent : CONCAT(), CONCAT_WS(), LENGTH(), MID(), OCTET_LENGTH(), REPEAT() et TO_BASE64(). Sauf indication contraire, ces fonctions n'ont aucune restriction d'utilisation.
|
Nom de la fonction |
Prise en charge |
Limites |
|
|
Oui |
Dans MySQL, |
|
|
Non |
/ |
|
|
Non |
/ |
|
|
Non |
/ |
|
|
Oui |
Le premier paramètre de cette fonction doit être de type chaîne. Un type non chaîné peut produire des résultats incohérents avec MySQL. |
|
|
Non |
/ |
|
|
Oui |
Cette fonction signale une erreur si le décodage base64 échoue. |
|
|
Oui |
|
|
|
Non |
/ |
|
|
Non |
/ |
|
|
Non |
/ |
|
|
Oui |
|
|
|
Oui |
Dans MySQL, |
|
|
Non |
/ |
|
|
Non |
/ |
|
|
Non |
/ |
|
|
Oui |
Une erreur est signalée si la fonction rencontre un caractère non hexadécimal. |
|
|
Non |
/ |
Fonctions de date
Nom de la fonction | Prise en charge | Limites |
| Oui | Si la valeur de retour dépasse la plage de valeurs des données de type time pour l'instance analytique basée sur DuckDB, des résultats incohérents apparaîtront. |
| Oui |
|
| Non | / |
| Oui | Les années supérieures à 9999 ne sont pas prises en charge. |
| Oui | Les années supérieures à 9999 ne sont pas prises en charge. |
| Oui | Si la valeur de retour dépasse la plage de valeurs du type de données time pour l'instance analytique basée sur DuckDB, des résultats incohérents peuvent se produire. |
| Oui |
|
| Oui | Si la valeur de retour est en dehors de la plage de valeurs des données de type time pour une instance analytique basée sur DuckDB, des résultats incohérents peuvent se produire. |
| Oui | Le format DAY TIME n'est pas pris en charge. Par exemple : |
| Non | / |
Fonctions JSON
|
Nom de la fonction |
Prise en charge ? |
Limites |
|
|
Non |
/ |
|
|
Non |
/ |
|
|
Non |
/ |
|
|
Non |
/ |
|
|
Oui |
L'ordre des champs dans l'objet JSON fusionné peut différer de celui de MySQL. |
|
|
Non |
/ |
|
|
Non |
/ |
|
|
Non |
/ |
|
|
Non |
/ |
|
|
Non |
/ |
|
|
Non |
/ |
|
|
Non |
/ |
|
|
Non |
/ |
|
|
Non |
/ |
|
|
Non |
/ |
|
|
Non |
/ |
Fonctions de fenêtrage
|
Nom de la fonction |
Prise en charge |
Limites |
|
|
Non |
/ |
|
|
Non |
/ |