10 poin oleh GN⁺ 2025-10-16 | 2 komentar | Bagikan ke WhatsApp
  • SQLite dikembangkan dalam bahasa C sejak awal (tahun 2000) karena alasan kinerja, kompatibilitas, dependensi yang minim, dan stabilitas
  • C dapat digunakan di hampir semua OS dan bahasa, serta sangat mendukung operasi cepat terutama sebagai library tingkat rendah
  • Alasan memilih C alih-alih bahasa berorientasi objek adalah skalabilitas, kemudahan dipanggil dari berbagai bahasa, serta ketidakmatangan C++ dan Java pada saat pengembangan dimulai
  • SQLite memiliki struktur satu berkas dengan hampir tanpa dependensi, dan hanya memakai fungsi minimum dari pustaka standar C
  • Ada pembahasan tentang penulisan ulang dalam "bahasa aman" seperti Rust dan Go, tetapi dari sisi pengelolaan kualitas, kinerja, dan kemudahan dipanggil sebagai library, C masih unggul

1. Mengapa C adalah pilihan terbaik

  • SQLite tetap dipertahankan dalam bahasa C sejak pertama kali dikembangkan pada 29 Mei 2000 hingga sekarang
    • Saat ini belum ada rencana untuk menulis ulang ke bahasa lain
  • C memiliki kendali yang dekat dengan perangkat keras sekaligus portabilitas yang sangat baik, sehingga sering disebut sebagai “bahasa assembly yang portabel”
  • Bahasa lain boleh saja mengklaim “secepat C”, tetapi tidak ada bahasa yang mengklaim lebih cepat dari C

1.1. Kinerja

  • Library tingkat rendah seperti SQLite sering dipanggil, sehingga harus mampu berjalan sangat cepat
  • Bahasa C cocok untuk menulis kode yang cepat, dengan portabilitas tinggi sambil tetap memungkinkan akses yang dekat ke perangkat keras
  • Bahasa modern lain juga mengklaim ‘secepat C’, tetapi dalam pemrograman umum tidak ada bahasa yang dengan yakin dapat disebut lebih cepat dari C
  • C memungkinkan kontrol rinci atas memori dan sumber daya CPU, sehingga kadang dapat menunjukkan kinerja 35% lebih cepat daripada sistem berkas

1.2. Kompatibilitas

  • Hampir semua sistem dapat memanggil library yang ditulis dalam C
  • Misalnya, bahkan di Android (berbasis Java), SQLite bisa digunakan melalui adaptor
  • Jika SQLite ditulis dalam Java, maka di iPhone (Objective-C, Swift) SQLite tidak akan bisa dipakai, sehingga sifat serbagunanya akan sangat berkurang

1.3. Dependensi rendah

  • Karena dikembangkan sebagai library C, dependensi runtime-nya sangat sedikit
  • Pada konfigurasi minimum, SQLite hanya menggunakan fungsi-fungsi paling dasar dari pustaka standar C (memcmp(), memcpy(), memmove(), memset(), strcmp(), strlen(), strncmp())
  • Bahkan pada build yang lebih lengkap, dependensinya tetap hanya sedikit, seperti malloc(), free(), dan input/output berkas
  • Bahasa modern sering kali membutuhkan runtime besar dalam jumlah banyak dan ribuan antarmuka

1.4. Stabilitas

  • C adalah bahasa lama, membosankan, dan jarang berubah, tetapi justru itu berarti dapat diprediksi dan stabil
  • Untuk membuat mesin basis data yang kecil, cepat, dan andal seperti SQLite, bahasa yang spesifikasinya tidak sering berubah lebih cocok
  • Jika spesifikasi atau implementasi bahasa sering berubah, hal itu merugikan stabilitas SQLite

2. Mengapa tidak ditulis dengan bahasa berorientasi objek

  • Sebagian pengembang menganggap sistem kompleks seperti SQLite sulit diimplementasikan tanpa paradigma berorientasi objek, tetapi dibanding C, library yang dibuat dengan C++ atau Java lebih sulit dipanggil dari bahasa lain
  • Demi mendukung berbagai bahasa seperti Haskell, Java, dan lainnya, pilihan library C adalah keputusan yang masuk akal
  • Berorientasi objek adalah pola desain, bukan bahasa, sehingga tidak terbatas pada bahasa tertentu
    • Bahkan di C, pola berorientasi objek bisa diimplementasikan dengan struct dan function pointer
  • Berorientasi objek tidak selalu merupakan struktur terbaik; kode prosedural kadang lebih jelas, lebih mudah dikelola, dan bisa menghasilkan performa yang lebih baik
  • Pada masa awal pengembangan SQLite (sekitar tahun 2000)
    • Java masih belum matang
    • C++ memiliki masalah kompatibilitas yang serius antar-compiler
      → Saat itu, C adalah pilihan yang paling praktis dan aman
  • Bahkan sekarang pun, manfaat untuk menulis ulang SQLite masih belum cukup besar

3. Mengapa tidak ditulis dalam "bahasa aman"

  • Belakangan minat terhadap bahasa pemrograman aman seperti Rust dan Go memang meningkat, tetapi pada saat SQLite pertama kali dikembangkan (bahkan selama 10 tahun pertamanya), bahasa-bahasa itu belum ada
  • Jika ditulis ulang dalam Go atau Rust, ada kemungkinan bug justru lebih banyak muncul atau kinerjanya menurun
  • Bahasa-bahasa ini menyisipkan kode percabangan (branch) tambahan untuk pengecekan memori dan sebagainya, sementara dalam strategi kualitas SQLite, branch coverage 100% sangat penting, dan bagian ini belum terpenuhi
  • Bahasa aman umumnya menghentikan program saat terjadi kondisi out-of-memory, sedangkan SQLite dirancang agar bisa pulih bahkan dalam kondisi kekurangan memori
  • Rust, Go, dan bahasa sejenisnya masih merupakan bahasa yang relatif baru dan masih memerlukan pengembangan berkelanjutan
  • Karena itu, tim pengembang SQLite mendukung perkembangan bahasa aman, tetapi untuk implementasi SQLite mereka tetap mengutamakan stabilitas C yang telah teruji

Meski begitu, suatu hari nanti kemungkinan ditulis ulang dalam Rust tetap ada. Kemungkinan ditulis dalam Go rendah karena Go tidak menyukai assert()

  • Namun, ada prasyarat agar dapat ditulis dalam Rust:
    • Rust harus menjadi lebih matang, dengan siklus perubahan yang lebih lambat, hingga menjadi “bahasa lama dan membosankan”
    • Harus terbukti bisa membuat library umum yang dapat dipanggil dari berbagai bahasa
    • Harus bisa menghasilkan object code yang berjalan bahkan pada perangkat tanpa OS seperti sistem embedded
    • Harus tersedia alat uji branch coverage 100% untuk biner hasil kompilasi
    • Harus dapat pulih dari error OOM (kehabisan memori)
    • Rust harus mampu melakukan semua hal yang ditangani C di SQLite tanpa penurunan kinerja
  • Jika seorang penggemar Rust (rustacean) menganggap syarat-syarat di atas sebenarnya sudah terpenuhi dan SQLite memang perlu ditulis ulang dalam Rust, ia dianjurkan untuk langsung menghubungi pengembang SQLite dan menyampaikan pendapatnya

2 komentar

 
GN⁺ 2025-10-16
Komentar Hacker News
  • Meskipun bahasa pemrograman yang aman belum ada pada 10 tahun pertama, saya pikir jika SQLite diimplementasikan ulang dalam Go atau Rust, kemungkinan besar justru akan menimbulkan lebih banyak bug daripada yang bisa diperbaiki, dan mungkin juga lebih lambat. Jika kode yang nyaris tanpa bug sudah selesai setelah melalui waktu dan pengujian yang luar biasa besar, maka dalam situasi dengan tingkat perubahan yang rendah, tidak terlalu penting kode itu ditulis dalam bahasa apa. Bahkan kalaupun assembly, rasanya tetap tidak masalah
    • Poin bahwa “jika tingkat perubahan rendah maka masalahnya lebih sedikit” juga dijelaskan di Google Security Blog. Argumennya adalah bahwa sebagian besar masalah keamanan memori muncul di kode baru, dan kode menjadi lebih aman seiring waktu tautan terkait
    • Di kubu Rust, proyek seperti Turso bergerak cukup aktif Turso
    • Ada juga yang berpendapat bahwa utilitas dasar Linux tidak perlu ditulis ulang dalam Rust. Perangkat lunak yang sudah dipakai puluhan tahun dan sebagian besar bug-nya sudah dihilangkan dianggap tidak perlu ditulis ulang
    • Saya pikir Zig bagus untuk menggantikan sebagian kode C. Ia juga cocok dengan Python dan biner C yang sudah ada. Filosofi Go memang bagus, tetapi ada keterbatasan karena sulit dioptimalkan dan membutuhkan pengembang yang sangat mahir. Rust juga bisa dipakai, tetapi jauh lebih mudah tetap memakai C yang ada sambil memperkenalkan Zig secara bertahap. Kami tidak bisa sepenuhnya menghilangkan bug dari kode C, tetapi rasanya beralih ke Rust secara realistis memang sulit
    • Sudah ada implementasi sqlite yang di-port ke Go cznic/sqlite
  • Selain alasan bahwa C adalah pilihan terbaik saat SQLite pertama kali dikembangkan dan keunggulannya saat ini, saya rasa memang tidak ada alasan khusus untuk menulis ulang SQLite dalam bahasa lain. Mengimplementasikan database SQL ringan itu bisa dilakukan siapa saja, jadi Anda bisa membuat implementasi baru dalam Rust, C++, Go, Lisp, atau bahasa apa pun yang diinginkan. Rasanya tidak perlu membuang implementasi C yang sudah berjalan baik, lalu memaksa para pengembang yang telah merawat SQLite dalam C selama lebih dari 25 tahun untuk belajar bahasa baru dan membuatnya ulang dari nol
    • Saya merasa di banyak fandom bahasa ada kecenderungan memaksakan preferensi sendiri kepada orang lain, dan adopsi bahasa kadang berubah menjadi semacam pertarungan zero-sum. Jika suatu proyek dikembangkan dalam bahasa tertentu, hanya dengan tidak memakai bahasa itu saja orang bisa mulai mempertanyakan perlunya bahasa lain. Padahal pada kenyataannya pilihannya jauh lebih beragam, dan sekalipun ditulis ulang dalam bahasa lain, opsinya tetap banyak seperti Rust, Go, D, Lisp, Julia, dan lain-lain
    • Sebenarnya para pengembang SQLite terbuka terhadap rewrite ke Rust. Jika Rust memenuhi prasyarat yang dibutuhkan, ada kemungkinan SQLite akan dibuat ulang. Bahkan ada anjuran agar para penggemar Rust menghubungi langsung pengembang SQLite
    • Sudah ada proyek seperti rqlite dan turso yang diimplementasikan dalam Rust
    • Ada adapter yang ditulis dalam Go, sehingga sqlite bisa dipakai dari golang tanpa cgo. Kini sqlite bukan hanya library C, tetapi juga format file database. Ke depan mungkin akan muncul implementasi pure Rust, dan suatu saat itu bisa menjadi implementasi utama
    • Saya merasa kesal dengan kecenderungan belakangan ini yang menganggap teknologi berusia lebih dari 5 tahun sebagai sesuatu yang kuno. Menurut saya, teknologi yang telah dipoles dalam waktu lama pantas mendapat lebih banyak penghormatan
  • Bahasa yang aman menghasilkan branch tambahan untuk memeriksa batas saat mengakses array, tetapi pada kode yang benar branch seperti itu sebenarnya tidak pernah dijalankan. Artinya, mencapai branch test 100% jadi sulit, dan ini berkaitan dengan strategi kualitas SQLite. Menarik mendengar logika baru seperti ini
    • Jika kita bisa yakin bahwa branch kode itu tidak akan pernah dijalankan, bukankah bagian itu memang tidak perlu diuji? Rasanya seperti mengorbankan keamanan demi cakupan pengujian 100%
    • Dalam bahasa aman, compiler otomatis menambahkan kode pertahanan seperti if (i >= array_length) panic("index out of bounds"), dan saya rasa kode itu sendiri sudah diuji dengan baik oleh compiler Rust, jadi tidak perlu dikhawatirkan. Saya penasaran apakah saya memahami logika ini dengan benar
    • Untuk pakar seperti Dr Hipp dan proyek seperti sqlite, saya rasa argumen ini juga ada masuk akalnya
    • Dengan memakai cara seperti get_unchecked() di Rust, akses tanpa bounds check juga dimungkinkan, sehingga keamanan tetap terjaga sambil meningkatkan performa dokumentasi get_unchecked
    • Saya penasaran apakah masalah ini bisa dikurangi dengan tidak mewajibkan coverage untuk branch yang secara kondisional berujung panic
  • SQLite membuka kemungkinan untuk suatu hari ditulis ulang dalam Rust, sementara Go tampaknya kecil kemungkinannya karena keterbatasan terkait assert(). Menurut saya, untuk pindah ke Rust diperlukan prasyarat seperti berikut: Rust harus jauh lebih lama berada dalam fase perubahan rendah, harus cocok untuk penulisan library umum, harus bisa berjalan pada embedded tanpa OS, harus ada tooling untuk branch coverage 100%, harus ada mekanisme penanganan error OOM, dan harus bisa menggantikan peran C tanpa penurunan performa
    • Sejak Rust 1.0, Rust telah berubah selama lebih dari 10 tahun dengan tetap menjaga kompatibilitas. Ada perbedaan antara orang yang ingin perubahan berhenti total dan orang yang menerima bahwa perubahan masih boleh terjadi. Pengembangan library umum sudah terbukti, dan dukungan embedded tanpa OS juga jelas memungkinkan. Untuk branch coverage saya kurang paham karena bukan ahli, tetapi pekerjaan terkait sedang dilakukan di Ferrocene dan lainnya. Bahasa Rust itu sendiri tidak melakukan alokasi memori, jadi penanganan OOM bisa diputuskan di tingkat standard library. Soal performa bisa ditafsirkan berbeda tergantung bagaimana mendefinisikannya
    • Saya penasaran apakah di Go juga tidak bisa memakai sintaks if condition { panic(err) } sebagai semacam fungsi assert
  • Sebagian besar argumen terdengar meyakinkan pada awalnya, tetapi jika diperiksa dengan teliti rasanya tidak sepenuhnya sempurna. Jika alasan memilih C sekitar tahun 2000 bisa dijelaskan dengan jelas, bukankah sekarang kita tinggal menerima bahwa ini adalah codebase yang sudah matang. Argumen tambahannya terasa masih bisa dibantah
    • Saya ingin mendengar argumen mana yang secara spesifik bisa dibantah
    • Argumen yang diajukan bisa dipakai untuk mempertahankan codebase lama, tetapi jika ingin mendorong pengembang baru memilih C alih-alih bahasa yang lebih kompleks, diperlukan dasar yang lebih kuat
    • (Dokumen tersebut ditulis pada 2017)
    • Saya menduga dokumen yang panjang dan detail itu dibuat untuk menanggapi begitu banyak pertanyaan “mengapa tidak ditulis ulang ke X” selama bertahun-tahun
  • Proyek yang memindahkan SQLite ke Go lewat otomasi sudah aktif didistribusikan sejak beberapa tahun lalu modernc.org/sqlite. Ia juga lulus test suite yang sama dengan baik. Namun versi Go memang jauh lebih lambat, dan dalam banyak situasi yang lebih penting daripada performa adalah kenyamanan port native Go. Kesimpulannya, menurut saya pendekatan yang realistis bukan menulis ulang SQLite ke Go, Rust, Zig, Nim, Swift, dan sebagainya, melainkan menerjemahkannya secara otomatis dari C
    • Ia memang lulus test suite publik, tetapi saya dengar SQLite juga punya test suite internal yang jauh lebih ketat
    • Lulus test suite tidak berarti bebas bug, jadi edge case baru atau masalah performa tetap bisa tersisa
  • “Mengapa SQLite dikembangkan dalam C” dijelaskan dengan baik dalam dokumen resmi, tetapi ketika mendengar pertanyaan “mengapa bukan Rust”, yang justru pertama terlintas adalah “mengapa harus Rust?”
    • Ada pendapat bahwa ini akibat judul yang dibingkai seperti itu
    • Sudah ada proyek rewrite Rust seperti ini: tursodatabase/turso dan ada juga pembahasan tentang Why di posting blog
    • Nuansanya seperti bertanya mengapa SQLite ditulis dalam C dan bukan BASIC
  • Semakin banyak saya melihat tulisan tentang coding, penggunaan perangkat lunak, dan rewrite, satu masalahnya adalah jika rewrite dilakukan hanya demi “kesetaraan fitur”, maka banyak penanganan pengecualian dan patch yang terakumulasi selama ini mudah terlewat. Akibatnya perangkat lunak bisa kembali rusak, atau hal-hal yang dulu berjalan baik menjadi bermasalah. Rewrite semacam ini perlu sangat ditekankan dan dilakukan dengan hati-hati, dan saya rasa reproduksi 100% itu sulit. Hal yang sama berlaku untuk library penting seperti SDL. Saya membayangkan akan ada rilis yang berulang kali bermasalah dan keluhan pengguna. Saya pikir C akan tetap bertahan lama bahkan setelah Rust menjadi arus utama. Rewrite tidak seharusnya menjadi pilihan default
  • Fakta bahwa DuckDB ditulis dalam C++ alih-alih Rust justru lebih menarik; DuckDB adalah proyek baru yang muncul pada 2019, jadi tampaknya ia bisa saja memilih Rust tetapi akhirnya tetap memilih C++. DuckDB masih baru, dan codebase-nya juga jauh lebih kecil daripada SQLite
    • Saya dengar tim DuckDB memilihnya karena mereka percaya diri dengan C++ dan mempercayai kemampuan auto-vectorization compiler. Pada saat itu (2019), Rust belum punya dukungan SIMD tingkat tinggi yang jelas. Mereka tidak ingin memelihara kode SIMD buatan tangan
    • Jika targetnya adalah performa maksimum, saya pikir C++ dapat menghasilkan biner yang lebih cepat dengan kode yang lebih sedikit. C++ modern juga punya lebih banyak keamanan saat compile time, sehingga cocok untuk kode seperti DB
    • Saya rasa jika ditulis dengan C++ modern, itu tidak masalah
  • Perdebatan soal rewrite SQLite sudah sering terjadi sebelumnya 2021, 2018
    • Komentar tptacek menarik; di dokumen lama ada paragraf tentang security, tetapi di dokumen terbaru itu sudah hilang. C jelas merupakan kerentanan keamanan bagi SQLite juga. Di versi sebelumnya ada penjelasan bahwa ‘SQLite bukan library yang terlalu sensitif terhadap keamanan’. Menjalankan SQL yang tidak tepercaya sendiri sudah merupakan isu yang lebih besar, sedangkan untuk impor file eksternal, masalah dicegah dengan kode pertahanan dan pengujian yang kuat, dan juga ada rutinitas pra-validasi dokumen web archive 2021
 
aer0700 2025-10-16

Frasa bahwa C juga merupakan risiko keamanan bagi SQLite, apakah itu tetap berlaku bahkan jika pengujian ditulis dengan sangat baik dan pengembangnya sangat berpengalaman? Logika dan proses pengembangan mungkin bisa menjadi masalah, tetapi sulit dipahami bahwa bahasanya sendiri merupakan kerentanan keamanan. Faktanya, hampir tidak ada program yang tidak bergantung pada infrastruktur yang ditulis dalam C.