Topik ini menjelaskan kompatibilitas instans analitis berbasis DuckDB yang disediakan oleh ApsaraDB RDS for MySQL.
Catatan kompatibilitas berikut berlaku hanya jika parameter duckdb_sql_normalization diaktifkan.
Tipe data yang didukung
Tabel berikut mencantumkan hanya tipe data yang perilakunya berbeda antara instans analitis berbasis DuckDB dan MySQL.
Type | Tipe data MySQL | Kompatibilitas |
String types |
| Hanya set karakter dan collation UTF-8 yang didukung. |
Time types |
| Instans analitis berbasis DuckDB mendukung rentang MySQL mendukung rentang |
| Instans analitis berbasis DuckDB mendukung rentang dari Untuk rentang | |
| Rentang yang didukung untuk instans analitis berbasis DuckDB adalah Untuk data dalam rentang | |
Spatial data types |
| Tidak kompatibel |
Batasan pada pernyataan SELECT
Konversi set karakter
Untuk fungsi konversi set karakter, terlepas dari set karakter target, semua konversi distandarkan ke set karakter
utf8mb4dan diteruskan ke DuckDB untuk dieksekusi. Contohnya:SELECT convert(id using gbk) FROM t1; SELECT cast(id AS CHAR CHARACTER SET utf8mb4) FROM t1;Unit interval
Unit interval berikut tidak didukung:
YEAR_MONTH, DAY_HOUR, HOUR_MINUTE, DAY_MINUTE, HOUR_SECOND, DAY_SECOND, SECOND_MICROSECOND, HOUR_MICROSECOND, DAY_MICROSECOND, MINUTE_SECOND, MINUTE_MICROSECOND, SQL_TSI_HOURSubkueri
Subkueri non-skalar dengan kondisi kesamaan tidak didukung. Contoh:
SELECT * FROM t1 WHERE (id, col1) = (SELECT id, col1 FROM t1);Konversi tipe BINARY(num)
Konversi eksplisit ke tipe data
BINARY(num)tidak didukung, dan panjang bit yang ditentukan akan diabaikan. Contoh:SELECT CAST('abc' AS binary(1));Konversi tipe UNSIGNED
Konversi eksplisit ke tipe data
UNSIGNEDtidak didukung. Contohnya:SELECT CAST(1 AS UNSIGNED);
Masalah konversi tipe data
Untuk efisiensi eksekusi optimal, instans analitis berbasis DuckDB menerapkan batasan tipe yang ketat selama eksekusi. Saat kueri dieksekusi, sistem secara otomatis melakukan konversi tipe berdasarkan konteks—proses ini disebut konversi tipe implisit. Pada skenario di mana konversi tidak dapat diselesaikan secara implisit, Anda harus menggunakan fungsi CAST atau CONVERT untuk menentukan konversi tipe secara eksplisit guna memastikan kueri dieksekusi dengan benar.
Aturan untuk konversi tipe implisit dalam fungsi
/ menunjukkan bahwa tidak ada konversi implisit yang terlibat. ✔️ menunjukkan bahwa konversi implisit didukung. ✖️ menunjukkan bahwa konversi implisit tidak didukung.
Tipe string reguler mengacu pada tipe data MySQL berikut:
CHAR,VARCHAR,TINYTEXT,TEXT,MEDIUMTEXT,LONGTEXT,JSON,SET, danENUM.Tipe string biner mengacu pada tipe data MySQL berikut:
BINARY,VARBINARY,BIT,TINYBLOB,BLOB,MEDIUMBLOB, danLONGBLOB.Konversi dari tipe integer dengan rentang nilai lebih besar ke tipe integer dengan rentang nilai lebih kecil tidak didukung.
Konversi ke tipe skalar dasar
Tipe sumber | Konversi implisit ke tipe skalar dasar | ||
Literal string | Literal numerik | ||
Skalar dasar | Literal string | / | ✖️ |
Literal numerik | ✖️ | / | |
Nilai | BOOLEAN | ✖️ | ✖️ |
Tipe integer | ✖️ | ✖️ | |
FLOAT | ✖️ | ✖️ | |
DOUBLE | ✖️ | ✖️ | |
DECIMAL | ✖️ | ✖️ | |
String | String reguler | ✖️ | ✖️ |
String biner | ✖️ | ✖️ | |
Tanggal dan waktu | YEAR | ✖️ | ✖️ |
DATE | ✖️ | ✖️ | |
TIME | ✖️ | ✖️ | |
DATETIME | ✖️ | ✖️ | |
TIMESTAMP | ✖️ | ✖️ | |
Konversi ke tipe numerik
Tipe sumber | Konversi implisit ke tipe numerik | |||||
BOOLEAN | Tipe integer | FLOAT | DOUBLE | DECIMAL | ||
Skalar dasar | Literal string | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ |
Literal numerik | ✖️ | ✔️ | ✔️ | ✔️ | ✔️ | |
Numerik | BOOLEAN | / | ✖️ | ✖️ | ✖️ | ✖️ |
Tipe integer | ✖️ | / | ✔️ | ✔️ | ✔️ | |
FLOAT | ✖️ | ✔️: Hanya konversi ke BIGINT yang didukung. | / | ✔️ | ✖️ | |
DOUBLE | ✖️ | ✔️: Hanya konversi ke BIGINT yang didukung. | ✖️ | / | ✖️ | |
DECIMAL | ✖️ | ✔️ | ✔️ | ✔️ | / | |
String | String reguler | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ |
String biner | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
Tanggal dan waktu | YEAR | ✖️ | ✔️ | ✔️ | ✔️ | ✔️ |
DATE | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ | |
TIME | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ | |
DATETIME | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ | |
TIMESTAMP | ✖️ | ✖️ | ✖️ | ✔️ | ✖️ | |
Konversi ke tipe string
Tipe sumber | Konversi implisit ke tipe string | ||
String reguler | String biner | ||
Skalar dasar | String literal | ✔️ | ✖️ |
Literal numerik | ✖️ | ✖️ | |
Numerik | BOOLEAN | ✖️ | ✖️ |
Tipe integer | ✔️ | ✖️ | |
FLOAT | ✔️ | ✖️ | |
DOUBLE | ✔️ | ✖️ | |
DECIMAL | ✔️ | ✖️ | |
String | String reguler | / | ✖️ |
String biner | ✖️ | / | |
Tanggal dan waktu | YEAR | ✔️ | ✖️ |
DATE | ✔️ | ✖️ | |
TIME | ✔️ | ✖️ | |
DATETIME | ✔️ | ✖️ | |
TIMESTAMP | ✔️ | ✖️ | |
Konversi ke tipe tanggal dan waktu
Tipe sumber | Konversi implisit ke tipe tanggal dan waktu | |||||
YEAR | DATE | TIME | DATETIME | TIMESTAMP | ||
Skalar dasar | Literal string | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ |
Literal numerik | ✔️ | ✖️ | ✖️ | ✖️ | ✖️ | |
nilai | BOOLEAN | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ |
Tipe integer | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
FLOAT | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
DOUBLE | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
DECIMAL | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
String | String reguler | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ |
String biner | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
Tanggal dan waktu | YEAR | / | ✖️ | ✖️ | ✖️ | ✖️ |
DATE | ✖️ | / | ✖️ | ✔️ | ✔️ | |
TIME | ✖️ | ✖️ | / | ✔️ | ✔️ | |
DATETIME | ✖️ | ✖️ | ✖️ | / | ✔️ | |
TIMESTAMP | ✖️ | ✖️ | ✖️ | ✔️ | / | |
Aturan untuk konversi tipe implisit dalam perbandingan
Instans analitis berbasis DuckDB menerapkan aturan yang lebih ketat dan konsisten untuk konversi dan perbandingan tipe. Namun, perilaku ini mungkin berbeda dari MySQL dalam beberapa skenario:
Konversi implisit dari string ke tanggal: Ketika string dikonversi secara implisit ke tanggal, jika format string tidak dapat diurai menjadi nilai tanggal yang valid, kueri SQL gagal dan melaporkan error.
Aturan perbandingan antar tipe integer: Saat tipe integer yang berbeda dibandingkan, instans analitis berbasis DuckDB mengonversinya ke tipe integer dengan rentang nilai lebih besar.
Urutan konversi tipe untuk ekspresi multi-operan: Untuk ekspresi multi-operan seperti
col1 in (col2, col3, col4, ...), col1 between col2 and col3, coalesce(col1, col2, col3, ...), konversi tipe dilakukan secara berurutan.Perbedaan kompatibilitas untuk tipe YEAR: Dalam instans analitis berbasis DuckDB, tipe YEAR dikonversi ke tipe INTEGER untuk perbandingan, yang dapat menyebabkan ketidakkompatibilitas dengan MySQL. Contoh:
CREATE TABLE t1 (id YEAR PRIMARY KEY); INSERT INTO t1 VALUES (1980); SELECT * FROM t1 WHERE id BETWEEN 70 AND 90; # Hasil kueri MySQL +------+ | id | +------+ | 1980 | +------+ # Hasil kueri instans analitis berbasis DuckDB Empty set.Aturan konversi string untuk tipe Boolean: Instans analitis berbasis DuckDB mendukung konversi enam string (
'1','0','yes','no','true', dan'false') ke tipe BOOLEAN. Upaya mengonversi string lainnya menghasilkan error. Sebaliknya, MySQL mengonversi'1'ketruedan semua string lainnya kefalse. Oleh karena itu, pernyataan SQL berikut mungkin menghasilkan hasil yang tidak konsisten:CREATE TABLE t1 (id INT PRIMARY KEY); INSERT INTO t1 VALUES (1); SELECT id FROM t1 WHERE 'true'; # Hasil kueri MySQL Empty set # Hasil kueri instans analitis berbasis DuckDB +------+ | id | +------+ | 1 | +------+
Ketika data dengan tipe berbeda dibandingkan, sistem mengonversi data tersebut ke tipe umum untuk perbandingan berdasarkan aturan dalam tabel berikut. Jika perbandingan antar tipe tidak didukung (✖️), error dilaporkan.
Tipe string reguler mengacu pada tipe data MySQL berikut:
CHAR,VARCHAR,TINYTEXT,TEXT,MEDIUMTEXT,LONGTEXT,JSON,SET, danENUM.Tipe string biner mengacu pada tipe data MySQL berikut:
BINARY,VARBINARY,BIT,TINYBLOB,BLOB,MEDIUMBLOB, danLONGBLOB.
Perbandingan dengan tipe skalar dasar
Tipe sumber | Perbandingan dengan tipe skalar dasar | ||
Literal string | Literal numerik | ||
Skalar dasar | Literal string | String | Literal numerik |
Literal numerik | Literal numerik | Tipe numerik dengan rentang lebih besar | |
Nilai | BOOLEAN | BOOLEAN | Tipe numerik dengan rentang lebih besar |
Tipe integer | Tipe integer | Tipe numerik dengan rentang lebih besar | |
FLOAT | FLOAT | Tipe numerik dengan rentang lebih besar | |
DOUBLE | DOUBLE | Tipe numerik dengan rentang lebih besar | |
DECIMAL | DECIMAL | Tipe numerik dengan rentang lebih besar | |
String | String reguler | String reguler | Literal numerik |
String biner | String biner | ✖️ | |
Tanggal dan waktu | YEAR | YEAR | Tipe numerik dengan rentang lebih besar |
DATE | DATETIME | ✖️ | |
TIME | TIME | ✖️ | |
DATETIME | DATETIME | ✖️ | |
TIMESTAMP | TIMESTAMP | ✖️ | |
Perbandingan dengan tipe numerik
Tipe sumber | Perbandingan dengan tipe numerik | |||||
BOOLEAN | Tipe integer | FLOAT | DOUBLE | DECIMAL | ||
Skalar dasar | Literal string | BOOLEAN | Tipe integer | FLOAT | DOUBLE | DECIMAL |
Literal numerik | Tipe numerik dengan rentang lebih besar | Tipe numerik dengan rentang lebih besar | Tipe numerik dengan rentang lebih besar | Tipe numerik dengan rentang lebih besar | Tipe numerik dengan rentang lebih besar | |
Numerik | BOOLEAN | BOOLEAN | Tipe integer | FLOAT (perbandingan ketidaksamaan ✖️) | DOUBLE (perbandingan ketidaksamaan ✖️) | DECIMAL (perbandingan ketidaksamaan ✖️) |
Tipe integer | Tipe integer | Tipe integer | FLOAT | DOUBLE | DECIMAL | |
FLOAT | FLOAT (perbandingan ketidaksamaan ✖️) | FLOAT | FLOAT | DOUBLE | FLOAT | |
DOUBLE | DOUBLE (perbandingan ketidaksamaan ✖️) | DOUBLE | DOUBLE | DOUBLE | DOUBLE | |
DECIMAL | DECIMAL (perbandingan ketidaksamaan ✖️) | DECIMAL | FLOAT | DOUBLE | DECIMAL | |
String | String reguler | BOOLEAN | Tipe integer | FLOAT | DOUBLE | DECIMAL |
String biner | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
Tanggal dan waktu | YEAR | INTEGER | Tipe integer dengan rentang lebih besar | FLOAT | DOUBLE | DECIMAL |
DATE | ✖️ | ✖️ | ✖️ | DOUBLE | ✖️ | |
TIME | ✖️ | ✖️ | ✖️ | DOUBLE | ✖️ | |
DATETIME | ✖️ | ✖️ | ✖️ | DOUBLE | ✖️ | |
TIMESTAMP | ✖️ | ✖️ | ✖️ | DOUBLE | ✖️ | |
Perbandingan dengan tipe string
Tipe sumber | Perbandingan dengan tipe string | ||
String reguler | String biner | ||
Skalar dasar | Literal string | String reguler | String biner |
Literal numerik | Literal numerik | ✖️ | |
Numerik | BOOLEAN | BOOLEAN | ✖️ |
Tipe integer | Tipe integer | ✖️ | |
FLOAT | FLOAT | ✖️ | |
DOUBLE | DOUBLE | ✖️ | |
DECIMAL | DECIMAL | ✖️ | |
String | String reguler | String reguler | String biner |
String biner | String biner | String biner | |
Tanggal dan waktu | YEAR | INTEGER | ✖️ |
DATE | DATE | ✖️ | |
TIME | TIME | ✖️ | |
DATETIME | DATETIME | ✖️ | |
TIMESTAMP | TIMESTAMP | ✖️ | |
Perbandingan dengan tipe tanggal dan waktu
Tipe sumber | Perbandingan dengan tipe tanggal dan waktu | |||||
YEAR | DATE | TIME | DATETIME | TIMESTAMP | ||
Skalar dasar | String literal | YEAR | DATETIME | TIME | DATETIME | TIMESTAMP |
Literal numerik | Tipe numerik dengan rentang lebih besar | ✖️ | ✖️ | ✖️ | ✖️ | |
Numerik | BOOLEAN | INTEGER | ✖️ | ✖️ | ✖️ | ✖️ |
Tipe integer | Tipe integer dengan rentang lebih besar | ✖️ | ✖️ | ✖️ | ✖️ | |
FLOAT | FLOAT | ✖️ | ✖️ | ✖️ | ✖️ | |
DOUBLE | DOUBLE | DOUBLE | DOUBLE | DOUBLE | DOUBLE | |
DECIMAL | DECIMAL | ✖️ | ✖️ | ✖️ | ✖️ | |
String | String reguler | INTEGER | DATE | TIME | DATETIME | TIMESTAMP |
String biner | ✖️ | ✖️ | ✖️ | ✖️ | ✖️ | |
Tanggal dan waktu | YEAR | INTEGER | ✖️ | ✖️ | ✖️ | ✖️ |
DATE | ✖️ | DATE | ✖️ | DATETIME | TIMESTAMP | |
TIME | ✖️ | ✖️ | TIME | ✖️ | ✖️ | |
DATETIME | ✖️ | DATETIME | ✖️ | DATETIME | DATETIME | |
TIMESTAMP | ✖️ | TIMESTAMP | ✖️ | DATETIME | TIMESTAMP | |
Potensi ketidakonsistenan dalam hasil kueri
Operasi numerik
Perbandingan bilangan titik mengambang mungkin tidak kompatibel. Contoh:
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; # Hasil kueri MySQL +------+ | id | +------+ | 1.23 | | 1.24 | +------+ # Hasil kueri instans analitis berbasis DuckDB +------+ | id | +------+ | 1.24 | +------+Hasil operasi kompleks pada bilangan titik mengambang mungkin tidak konsisten akibat error titik mengambang.
Ketika operasi dilakukan antara tipe integer dan DECIMAL, hasilnya tidak boleh melebihi rentang nilai tipe tersebut. Jika tidak, error overflow dapat menyebabkan eksekusi gagal.
CREATE TABLE t1 (id TINYINT PRIMARY KEY); INSERT INTO t1 VALUES (100); SELECT id * 2 FROM t1; # Hasil kueri MySQL +--------+ | id * 2 | +--------+ | 200 | +--------+ # Hasil kueri instans analitis berbasis DuckDB ERROR 7577 (HY000): [DuckDB] Out of Range Error: Overflow in multiplication of INT8 (100 * 2)!.
Hasil tidak konsisten akibat aturan collation
Collation seri utf8mb4_0900_xx tidak kompatibel saat membandingkan karakter simbol tertentu. Contohnya:
CREATE TABLE t1 ( id varchar(20) COLLATE utf8mb4_0900_ai_ci PRIMARY KEY );
INSERT INTO t1 VALUES ('!'), ('_');
SELECT * FROM t1 ORDER BY id;
# Hasil kueri MySQL
+----+
| id |
+----+
| _ |
| ! |
+----+
# Hasil kueri instans analitis berbasis DuckDB
+----+
| id |
+----+
| ! |
| _ |
+----+Penanganan nilai NULL dalam subkueri vektor dengan IN
Dalam instans analitis berbasis DuckDB, penanganan nilai NULL dalam subkueri vektor dengan IN mungkin tidak kompatibel dengan MySQL. Contoh:
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;
# Hasil kueri MySQL
+-----------------------------------------+
| (id, col1) in (select id, col1 from t2) |
+-----------------------------------------+
| NULL |
| 0 |
+-----------------------------------------+
# Hasil kueri instans analitis berbasis DuckDB
+-----------------------------------------+
| (id, col1) in (select id, col1 from t2) |
+-----------------------------------------+
| NULL |
| NULL |
+-----------------------------------------+Untuk data (2, 2), tidak ada item yang sesuai untuk awalan vektor dalam klausa IN. Dalam kasus ini, MySQL mengembalikan 0, sedangkan instans analitis berbasis DuckDB mengembalikan NULL.
Batasan pada fungsi
Tabel berikut mencantumkan hanya fungsi yang perilakunya berbeda antara instans analitis berbasis DuckDB dan MySQL.
Fungsi agregat
Nama fungsi | Didukung | Batasan |
| Ya | Tipe string, DECIMAL, dan tanggal tidak didukung. |
| Ya | Tipe string, DECIMAL, dan tanggal tidak didukung. |
| Ya | Tipe string, DECIMAL, dan tanggal tidak didukung. |
| Tidak | / |
Fungsi numerik
Fungsi numerik tidak mendukung tipe BOOLEAN.
Nama fungsi | Didukung | Batasan |
| Tidak | / |
| Tidak | / |
| Tidak | / |
Fungsi string
MySQL DuckDB secara ketat membedakan antara string biner (seperti BLOB dan VARBINARY) dan string (seperti VARCHAR, TEXT, dan JSON). Oleh karena itu, batasan penggunaan berikut untuk fungsi string hanya berlaku untuk input string, bukan input string biner. Beberapa fungsi yang dapat menerima string biner sebagai input meliputi: CONCAT(), CONCAT_WS(), LENGTH(), MID(), OCTET_LENGTH(), REPEAT(), dan TO_BASE64(). Kecuali dinyatakan lain, fungsi-fungsi ini tidak memiliki batasan penggunaan.
Nama fungsi | Didukung | Batasan |
| Ya | Di MySQL, |
| Tidak | / |
| Tidak | / |
| Tidak | / |
| Ya | Parameter pertama fungsi ini harus bertipe string. Tipe non-string dapat menghasilkan hasil yang tidak konsisten dengan MySQL. |
| Tidak | / |
| Ya | Fungsi ini melaporkan error jika dekode base64 gagal. |
| Ya |
|
| Tidak | / |
| Tidak | / |
| Tidak | / |
| Ya |
|
| Ya | Di MySQL, |
| Tidak | / |
| Tidak | / |
| Tidak | / |
| Ya | Error dilaporkan jika fungsi menemukan digit non-heksadesimal. |
| Tidak | / |
Fungsi tanggal
Nama fungsi | Didukung | Batasan |
| Ya | Jika nilai kembali melebihi rentang nilai data tipe waktu untuk instans analitis berbasis DuckDB, hasil yang tidak konsisten akan terjadi. |
| Ya |
|
| Tidak | / |
| Ya | Tahun lebih dari 9999 tidak didukung. |
| Ya | Tahun lebih dari 9999 tidak didukung. |
| Ya | Jika nilai kembali melebihi rentang nilai tipe data waktu untuk instans analitis berbasis DuckDB, hasil yang tidak konsisten mungkin terjadi. |
| Ya |
|
| Ya | Jika nilai kembali berada di luar rentang nilai data tipe waktu untuk instans analitis berbasis DuckDB, hasil yang tidak konsisten mungkin terjadi. |
| Ya | Format DAY TIME tidak didukung. Contohnya: |
| Tidak | / |
Fungsi JSON
Nama fungsi | Didukung? | Batasan |
| Tidak | / |
| Tidak | / |
| Tidak | / |
| Tidak | / |
| Ya | Urutan field dalam objek JSON yang digabungkan mungkin berbeda dari MySQL. |
| Tidak | / |
| Tidak | / |
| Tidak | / |
| Tidak | / |
| Tidak | / |
| Tidak | / |
| Tidak | / |
| Tidak | / |
| Tidak | / |
| Tidak | / |
| Tidak | / |
Fungsi window
Nama fungsi | Didukung | Batasan |
| Tidak | / |
| Tidak | / |