Este tópico descreve a compatibilidade das instâncias analíticas baseadas em DuckDB fornecidas pelo ApsaraDB RDS for MySQL.
Todas as notas de compatibilidade a seguir exigem a ativação do parâmetro duckdb_sql_normalization.
Tipos de dados suportados
A tabela a seguir lista apenas os tipos de dados em que as instâncias analíticas baseadas em DuckDB diferem do MySQL.
Tipo | Tipo de dados MySQL | Compatibilidade |
Tipos string |
| Somente conjuntos de caracteres e collations UTF-8 são suportados. |
Tipos de tempo |
| Uma instância analítica baseada em DuckDB suporta o intervalo de O MySQL suporta o intervalo |
| Instâncias analíticas baseadas em DuckDB suportam o intervalo de Para o intervalo de | |
| O intervalo suportado para instâncias analíticas baseadas em DuckDB é de Para dados no intervalo de | |
Tipos de dados espaciais |
| Incompatível |
Limitações em instruções SELECT
-
Conversão de conjunto de caracteres
Para funções de conversão de conjunto de caracteres, independentemente do conjunto alvo, todas as conversões são padronizadas para o conjunto de caracteres
utf8mb4e delegadas ao DuckDB para execução. Por exemplo:SELECT convert(id using gbk) FROM t1; SELECT cast(id AS CHAR CHARACTER SET utf8mb4) FROM t1; -
Unidade de intervalo
As seguintes unidades de intervalo não são suportadas:
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 -
Subconsultas
Subconsultas não escalares com condições de igualdade não são suportadas. Exemplo:
SELECT * FROM t1 WHERE (id, col1) = (SELECT id, col1 FROM t1); -
Conversão de tipo BINARY(num)
A conversão explícita para o tipo de dados
BINARY(num)não é suportada, e o comprimento de bits especificado será ignorado. Exemplo:SELECT CAST('abc' AS binary(1)); -
Conversão de tipo UNSIGNED
A conversão explícita para o tipo de dados
UNSIGNEDnão é suportada. Por exemplo:SELECT CAST(1 AS UNSIGNED);
Problemas de conversão de tipos de dados
Para garantir eficiência máxima na execução, instâncias analíticas baseadas em DuckDB utilizam restrições de tipo rigorosas durante o processamento. Ao executar uma consulta, o sistema realiza automaticamente conversões de tipo com base no contexto. Esse tipo de conversão é chamado de conversão implícita de tipos. Nos cenários em que a conversão não puder ser concluída implicitamente, use a função CAST ou CONVERT para especificar explicitamente a conversão de tipo e assegurar a execução correta da consulta.
Regras para conversão implícita de tipos em funções
/ indica que não há conversão implícita envolvida. ✔️ indica que a conversão implícita é suportada. ✖️ indica que a conversão implícita não é suportada.
Tipos string regulares referem-se aos seguintes tipos de dados do MySQL:
CHAR,VARCHAR,TINYTEXT,TEXT,MEDIUMTEXT,LONGTEXT,JSON,SETeENUM.Tipos string binários referem-se aos seguintes tipos de dados do MySQL:
BINARY,VARBINARY,BIT,TINYBLOB,BLOB,MEDIUMBLOBeLONGBLOB.A conversão de um tipo inteiro com maior intervalo de valores para um tipo inteiro com menor intervalo de valores não é suportada.
Conversão para tipos escalares básicos
Tipo de origem | Conversão implícita para tipos escalares básicos | ||
Literal string | Literal numérico | ||
Escalar básico | Literal string | / | ✖️ |
Literal numérico | ✖️ | / | |
Valor | BOOLEAN | ✖️ | ✖️ |
Tipos inteiros | ✖️ | ✖️ | |
FLOAT | ✖️ | ✖️ | |
DOUBLE | ✖️ | ✖️ | |
DECIMAL | ✖️ | ✖️ | |
String | String regular | ✖️ | ✖️ |
String binária | ✖️ | ✖️ | |
Data e hora | YEAR | ✖️ | ✖️ |
DATE | ✖️ | ✖️ | |
TIME | ✖️ | ✖️ | |
DATETIME | ✖️ | ✖️ | |
TIMESTAMP | ✖️ | ✖️ | |
Conversão para tipos numéricos
Tipo de origem | Conversão implícita para tipos numéricos | |||||
BOOLEAN | Tipos inteiros | FLOAT | DOUBLE | DECIMAL | ||
Escalar básico | Literal string | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ |
Literal numérico | ✖️ | ✔️ | ✔️ | ✔️ | ✔️ | |
Numérico | BOOLEAN | / | ✖️ | ✖️ | ✖️ | ✖️ |
Tipos inteiros | ✖️ | / | ✔️ | ✔️ | ✔️ | |
FLOAT | ✖️ | ✔️: Apenas conversão para BIGINT é suportada. | / | ✔️ | ✖️ | |
DOUBLE | ✖️ | ✔️: Apenas conversão para BIGINT é suportada. | ✖️ | / | ✖️ | |
DECIMAL | ✖️ | ✔️ | ✔️ | ✔️ | / | |
String | String regular | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ |
String binária | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
Data e hora | YEAR | ✖️ | ✔️ | ✔️ | ✔️ | ✔️ |
DATE | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ | |
TIME | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ | |
DATETIME | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ | |
TIMESTAMP | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ | |
Conversão para tipos string
Tipo de origem | Conversão implícita para tipos string | ||
String regular | String binária | ||
Escalar básico | Literal string | ✔️ | ✖️ |
Literal numérico | ✖️ | ✖️ | |
Numérico | BOOLEAN | ✖️ | ✖️ |
Tipos inteiros | ✔️ | ✖️ | |
FLOAT | ✔️ | ✖️ | |
DOUBLE | ✔️ | ✖️ | |
DECIMAL | ✔️ | ✖️ | |
String | String regular | / | ✖️ |
String binária | ✖️ | / | |
Data e hora | YEAR | ✔️ | ✖️ |
DATE | ✔️ | ✖️ | |
TIME | ✔️ | ✖️ | |
DATETIME | ✔️ | ✖️ | |
TIMESTAMP | ✔️ | ✖️ | |
Conversão para tipos de data e hora
Tipo de origem | Conversão implícita para tipos de data e hora | |||||
YEAR | DATE | TIME | DATETIME | TIMESTAMP | ||
Escalar básico | Literal string | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ |
Literal numérico | ✔️ | ✖️ | ✖️ | ✖️ | ✖️ | |
valor | BOOLEAN | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ |
Tipos inteiros | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
FLOAT | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
DOUBLE | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
DECIMAL | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
String | String regular | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ |
String binária | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
Data e hora | YEAR | / | ✖️ | ✖️ | ✖️ | ✖️ |
DATE | ✖️ | / | ✖️ | ✔️ | ✔️ | |
TIME | ✖️ | ✖️ | / | ✔️ | ✔️ | |
DATETIME | ✖️ | ✖️ | ✖️ | / | ✔️ | |
TIMESTAMP | ✖️ | ✖️ | ✖️ | ✔️ | / | |
Regras para conversão implícita de tipos em comparações
Instâncias analíticas baseadas em DuckDB possuem regras mais rigorosas e consistentes para conversão de tipos e comparação. No entanto, esse comportamento pode diferir do MySQL em alguns cenários:
Conversão implícita de string para data: Quando uma string é convertida implicitamente para data, se o formato da string não puder ser analisado corretamente como um valor de data válido, a consulta SQL falhará e reportará um erro.
Regras de comparação entre tipos inteiros: Ao comparar diferentes tipos inteiros, instâncias analíticas baseadas em DuckDB os convertem para o tipo inteiro com o maior intervalo de valores.
Ordem de conversão de tipos para expressões com múltiplos operandos: Para expressões com múltiplos operandos, como
col1 in (col2, col3, col4, ...), col1 between col2 and col3, coalesce(col1, col2, col3, ...), a conversão de tipos é realizada sequencialmente.-
Diferença de compatibilidade para o tipo YEAR: Em instâncias analíticas baseadas em DuckDB, o tipo YEAR é convertido para o tipo INTEGER para comparação, o que pode causar incompatibilidade com o MySQL. Exemplo:
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. -
Regras de conversão de string para o tipo Boolean: Instâncias analíticas baseadas em DuckDB suportam a conversão de seis strings (
'1','0','yes','no','true'e'false') para o tipo BOOLEAN. Qualquer tentativa de converter outras strings resulta em erro. O MySQL converte'1'paratruee todas as outras strings parafalse. Portanto, a seguinte instrução SQL pode retornar resultados inconsistentes: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 | +------+
Ao comparar dados de tipos diferentes, o sistema converte os dados para um tipo comum para comparação, seguindo as regras nas tabelas a seguir. Se a comparação entre tipos não for suportada (✖️), um erro será reportado.
Tipos string regulares referem-se aos seguintes tipos de dados do MySQL:
CHAR,VARCHAR,TINYTEXT,TEXT,MEDIUMTEXT,LONGTEXT,JSON,SETeENUM.Tipos string binários referem-se aos seguintes tipos de dados do MySQL:
BINARY,VARBINARY,BIT,TINYBLOB,BLOB,MEDIUMBLOBeLONGBLOB.
Comparação com tipos escalares básicos
Tipo de origem | Comparação com tipos escalares básicos | ||
Literal string | Literal numérico | ||
Escalar básico | Literal string | String | Literal numérico |
Literal numérico | Literal numérico | Tipo numérico de maior intervalo | |
Valor | BOOLEAN | BOOLEAN | Tipo numérico de maior intervalo |
Tipos inteiros | Tipos inteiros | Tipo numérico de maior intervalo | |
FLOAT | FLOAT | Tipo numérico de maior intervalo | |
DOUBLE | DOUBLE | Tipo numérico de maior intervalo | |
DECIMAL | DECIMAL | Tipo numérico de maior intervalo | |
String | String regular | String regular | Literal numérico |
String binária | String binária | ✖️ | |
Data e hora | YEAR | YEAR | Tipo numérico de maior intervalo |
DATE | DATETIME | ✖️ | |
TIME | TIME | ✖️ | |
DATETIME | DATETIME | ✖️ | |
TIMESTAMP | TIMESTAMP | ✖️ | |
Comparação com tipos numéricos
Tipo de origem | Comparação com tipos numéricos | |||||
BOOLEAN | Tipos inteiros | FLOAT | DOUBLE | DECIMAL | ||
Escalar básico | Literal string | BOOLEAN | Tipos inteiros | FLOAT | DOUBLE | DECIMAL |
Literal numérico | Tipo numérico de maior intervalo | Tipo numérico de maior intervalo | Tipo numérico de maior intervalo | Tipo numérico de maior intervalo | Tipo numérico de maior intervalo | |
Numérico | BOOLEAN | BOOLEAN | Tipos inteiros | FLOAT (comparação de desigualdade ✖️) | DOUBLE (comparação de desigualdade ✖️) | DECIMAL (comparação de desigualdade ✖️) |
Tipos inteiros | Tipos inteiros | Tipos inteiros | FLOAT | DOUBLE | DECIMAL | |
FLOAT | FLOAT (comparação de desigualdade ✖️) | FLOAT | FLOAT | DOUBLE | FLOAT | |
DOUBLE | DOUBLE (comparação de desigualdade ✖️) | DOUBLE | DOUBLE | DOUBLE | DOUBLE | |
DECIMAL | DECIMAL (comparação de desigualdade ✖️) | DECIMAL | FLOAT | DOUBLE | DECIMAL | |
String | String regular | BOOLEAN | Tipos inteiros | FLOAT | DOUBLE | DECIMAL |
String binária | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
Data e hora | YEAR | INTEGER | Tipo inteiro de maior intervalo | FLOAT | DOUBLE | DECIMAL |
DATE | ✖️ | ✖️ | ✖️ | DOUBLE | ✖️ | |
TIME | ✖️ | ✖️ | ✖️ | DOUBLE | ✖️ | |
DATETIME | ✖️ | ✖️ | ✖️ | DOUBLE | ✖️ | |
TIMESTAMP | ✖️ | ✖️ | ✖️ | DOUBLE | ✖️ | |
Comparação com tipos string
Tipo de origem | Comparação com tipos string | ||
String regular | String binária | ||
Escalar básico | Literal string | String regular | String binária |
Literal numérico | Literal numérico | ✖️ | |
Numérico | BOOLEAN | BOOLEAN | ✖️ |
Tipos inteiros | Tipos inteiros | ✖️ | |
FLOAT | FLOAT | ✖️ | |
DOUBLE | DOUBLE | ✖️ | |
DECIMAL | DECIMAL | ✖️ | |
String | String regular | String regular | String binária |
String binária | String binária | String binária | |
Data e hora | YEAR | INTEGER | ✖️ |
DATE | DATE | ✖️ | |
TIME | TIME | ✖️ | |
DATETIME | DATETIME | ✖️ | |
TIMESTAMP | TIMESTAMP | ✖️ | |
Comparação com tipos de data e hora
Tipo de origem | Comparação com tipos de data e hora | |||||
YEAR | DATE | TIME | DATETIME | TIMESTAMP | ||
Escalar básico | Literal string | YEAR | DATETIME | TIME | DATETIME | TIMESTAMP |
Literal numérico | Tipo numérico de maior intervalo | ✖️ | ✖️ | ✖️ | ✖️ | |
Numérico | BOOLEAN | INTEGER | ✖️ | ✖️ | ✖️ | ✖️ |
Tipos inteiros | Tipo inteiro de maior intervalo | ✖️ | ✖️ | ✖️ | ✖️ | |
FLOAT | FLOAT | ✖️ | ✖️ | ✖️ | ✖️ | |
DOUBLE | DOUBLE | DOUBLE | DOUBLE | DOUBLE | DOUBLE | |
DECIMAL | DECIMAL | ✖️ | ✖️ | ✖️ | ✖️ | |
String | String regular | INTEGER | DATE | TIME | DATETIME | TIMESTAMP |
String binária | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
Data e hora | YEAR | INTEGER | ✖️ | ✖️ | ✖️ | ✖️ |
DATE | ✖️ | DATE | ✖️ | DATETIME | TIMESTAMP | |
TIME | ✖️ | ✖️ | TIME | ✖️ | ✖️ | |
DATETIME | ✖️ | DATETIME | ✖️ | DATETIME | DATETIME | |
TIMESTAMP | ✖️ | TIMESTAMP | ✖️ | DATETIME | TIMESTAMP | |
Possíveis inconsistências nos resultados de consultas
Operações numéricas
-
Comparações de números de ponto flutuante podem ser incompatíveis. Exemplo:
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 | +------+ Resultados de operações complexas com números de ponto flutuante podem ser inconsistentes devido a erros de ponto flutuante.
-
Ao realizar uma operação entre tipos inteiros e DECIMAL, o resultado não deve exceder o intervalo de valores do tipo. Caso contrário, um erro de estouro pode causar falha na execução.
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)!.
Resultados inconsistentes causados por regras de collation
Collations da série utf8mb4_0900_xx são incompatíveis ao comparar certos caracteres de símbolos. Por exemplo:
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 |
+----+
| ! |
| _ |
+----+
Tratamento de valores NULL em subconsultas vetoriais com IN
Em instâncias analíticas baseadas em DuckDB, o tratamento de valores NULL em subconsultas vetoriais com IN pode ser incompatível com o MySQL. Exemplo:
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 |
+-----------------------------------------+
Para os dados (2, 2), não existe nenhum item correspondente para o prefixo vetorial na cláusula IN. Nesse caso, o MySQL retorna 0, enquanto a instância analítica baseada em DuckDB retorna NULL.
Limitações em funções
A tabela a seguir lista apenas as funções em que as instâncias analíticas baseadas em DuckDB diferem do MySQL.
Funções de agregação
|
Nome da função |
Suportada |
Limitações |
|
|
Sim |
Tipos string, DECIMAL e data não são suportados. |
|
|
Sim |
Tipos string, DECIMAL e data não são suportados. |
|
|
Sim |
Tipos string, DECIMAL e data não são suportados. |
|
|
Não |
/ |
Funções numéricas
Funções numéricas não suportam o tipo BOOLEAN.
|
Nome da função |
Suportada |
Limitações |
|
|
Não |
/ |
|
|
Não |
/ |
|
|
Não |
/ |
Funções de string
O DuckDB distingue estritamente entre strings binárias (como BLOB e VARBINARY) e strings (como VARCHAR, TEXT e JSON). Portanto, as seguintes limitações de uso para funções de string aplicam-se apenas a entradas de string, e não a entradas de string binária. Algumas funções que aceitam strings binárias como entrada incluem: CONCAT(), CONCAT_WS(), LENGTH(), MID(), OCTET_LENGTH(), REPEAT() e TO_BASE64(). Salvo indicação em contrário, essas funções não possuem restrições de uso.
|
Nome da função |
Suportada |
Limitações |
|
|
Sim |
No MySQL, |
|
|
Não |
/ |
|
|
Não |
/ |
|
|
Não |
/ |
|
|
Sim |
O primeiro parâmetro desta função deve ser do tipo string. Um tipo não string pode produzir resultados inconsistentes com o MySQL. |
|
|
Não |
/ |
|
|
Sim |
Esta função reporta um erro se a decodificação base64 falhar. |
|
|
Sim |
|
|
|
Não |
/ |
|
|
Não |
/ |
|
|
Não |
/ |
|
|
Sim |
|
|
|
Sim |
No MySQL, |
|
|
Não |
/ |
|
|
Não |
/ |
|
|
Não |
/ |
|
|
Sim |
Um erro é reportado se a função encontrar um dígito não hexadecimal. |
|
|
Não |
/ |
Funções de data
Nome da função | Suportada | Limitações |
| Sim | Se o valor retornado exceder o intervalo de valores de dados do tipo tempo para a instância analítica baseada em DuckDB, ocorrerão resultados inconsistentes. |
| Sim |
|
| Não | / |
| Sim | Anos maiores que 9999 não são suportados. |
| Sim | Anos maiores que 9999 não são suportados. |
| Sim | Se o valor retornado exceder o intervalo de valores do tipo de dados tempo para a instância analítica baseada em DuckDB, poderão ocorrer resultados inconsistentes. |
| Sim |
|
| Sim | Se o valor retornado estiver fora do intervalo de valores de dados do tipo tempo para uma instância analítica baseada em DuckDB, poderão ocorrer resultados inconsistentes. |
| Sim | O formato DAY TIME não é suportado. Por exemplo: |
| Não | / |
Funções JSON
|
Nome da função |
Suportada? |
Limitações |
|
|
Não |
/ |
|
|
Não |
/ |
|
|
Não |
/ |
|
|
Não |
/ |
|
|
Sim |
A ordem dos campos no objeto JSON mesclado pode ser diferente daquela no MySQL. |
|
|
Não |
/ |
|
|
Não |
/ |
|
|
Não |
/ |
|
|
Não |
/ |
|
|
Não |
/ |
|
|
Não |
/ |
|
|
Não |
/ |
|
|
Não |
/ |
|
|
Não |
/ |
|
|
Não |
/ |
|
|
Não |
/ |
Funções de janela
|
Nome da função |
Suportada |
Limitações |
|
|
Não |
/ |
|
|
Não |
/ |