Aankondiging DuckDB 2.0.0 LTS “Cinnamon Teal”
TL;DR: Het DuckDB-team kondigt met trots de release aan van DuckDB versie 2.0.0 LTS, codenaam “Cinnamon Teal” (Spatula cyanoptera). Dit is de grootste feature-release tot nu toe. De update bevat een gepolijste versie van het Quack-protocol, asynchrone I/O, een eersteklas VARIANT-type, agent-modus, triggers, een uitbreidbare SQL-parser en meer. Deze release is het resultaat van bijna 20.000 commits sinds DuckDB 1.5.
DuckDB 2.0 is vernoemd naar de Spatula cyanoptera, een opvallende roodbruine eend uit de westelijke Amerika's. Waar DuckDB 1.0 primair gericht was op stabiliteit en achterwaartse compatibiliteit, is DuckDB 2.0 in de eerste plaats een feature-release.
Ondersteuning en Versies
Er zijn momenteel drie DuckDB-lijnen beschikbaar:
- DuckDB 2.0: Een long-term support (LTS) release met ondersteuning tot ten minste oktober 2027.
- DuckDB 1.4: De vorige LTS-release, ondersteund tot eind november 2026.
- DuckDB 1.5: De ondersteuningsperiode is verlengd tot maart 2027, waardoor dit effectief ook een LTS-release is geworden om een soepele overgang te faciliteren.
---
DuckDB als Server
DuckDB is vanaf het begin een in-process database geweest. In DuckDB 1.5.3 werd het Quack-protocol geïntroduceerd, waarmee DuckDB in een traditionele client-serveropstelling kan draaien via de quack-extensie.
Quack en CONNECT
DuckDB 2.0.0 bevat een gepolijste versie van het Quack-protocol met aanzienlijke verbeteringen in prestaties en stabiliteit. Daarnaast is het nieuwe CONNECT-statement geïntroduceerd, waarmee men in één commando kan koppelen aan en overschakelen naar een externe database.
Voorbeeld: DuckDB server
CALL quack_serve(token = 'my_token');
CREATE TABLE events (date DATE, name VARCHAR);
INSERT INTO events VALUES ('2027-04-07', 'DuckCon #8');
Voorbeeld: DuckDB client
ATTACH 'quack:localhost' AS qk (TOKEN 'my_token');
CONNECT qk;
SELECT * FROM events;
Voor eenvoud draait dit voorbeeld de server en client op dezelfde machine. Standaard luistert de server alleen op localhost. Om verbindingen van andere machines te accepteren, dient de server achter een TLS-terminerende reverse proxy te worden geplaatst. De optie allowotherhostname is uitsluitend bedoeld voor tests.
Het CONNECT-statement is niet beperkt tot Quack; het werkt met elke externe database die dit ondersteunt, inclusief PostgreSQL en MySQL. Hiervoor is een nieuwe remote pushdown optimizer toegevoegd die queries direct naar de externe server stuurt in plaats van tabellen over het netwerk te halen.
Quack in de CLI
De CLI heeft nu shortcuts voor het opzetten van een Quack client-server paar via de argumenten -serve en -connect.
CLI server:
duckdb -serve
CREATE TABLE t AS SELECT 42 AS x;
CLI client:
duckdb -connect
FROM t;
---
Prestaties
Asynchrone I/O
DuckDB 2.0 introduceert asynchrone I/O voor het lezen van Parquet- en CSV-bestanden. De I/O-laag schaalt nu onafhankelijk van de query-verwerkingslaag, waarbij leesacties op de achtergrond worden uitgevoerd en meerdere verzoeken gelijktijdig openstaan. Dit resulteert in veel meer parallellisme voor externe leesacties en aanzienlijk snellere queries op objectopslag zoals s3://.
Het VARIANT-type als eersteklas burger
Het VARIANT-type slaat semi-gestructureerde, schema-loze data op (zoals JSON), terwijl de prestaties van kolomgebaseerde uitvoering behouden blijven. Je kunt het zien als "JSON op steroïden": een VARIANT-kolom kan in elke rij data van een andere vorm opslaan, maar in tegenstelling tot JSON is het geen tekstformaat.
In DuckDB 2.0 is dit type volledig geïntegreerd. DuckDB detecteert de gemeenschappelijke structuur in de data en "shredt" deze, wat zorgt voor betere compressie en snellere uitvoering.
Voorbeeld:
CREATE TABLE events (payload VARIANT);
INSERT INTO events
VALUES
('{"user": {"id": 42, "tags": ["a", "b"]}}'::JSON::VARIANT),
('{"event": "click", "x": 10, "y": 20}'::JSON::VARIANT);
SELECT variant_type(payload), variant_keys(payload)
FROM events;
Agent-modus in de CLI
Coding-agents zoals Claude Code, Codex en Cursor bedienen steeds vaker de DuckDB CLI. De 2.0 CLI detecteert wanneer deze door een agent wordt uitgevoerd en schakelt over naar de agent-modus:
- Compacte Markdown-tabellen in plaats van gepadded boxen.
- Duidelijke meldingen wanneer een resultaat is afgekapt.
- Vroegtijdig stoppen van runaway-queries.
- Foutmeldingen in JSON-formaat.
- Rapportage van verwachte kosten bij langdurige SQL-queries, zodat de agent kan beslissen of hij moet wachten.
De agent-modus kan handmatig worden geactiveerd met de -agent flag of uitgeschakeld met -no-agent.
---
Uitbreidbaarheid
Een volledig nieuwe SQL-parser
DuckDB stapt over op een eigen, moderne en uitbreidbare PEG-gebaseerde parser als standaard. Extensies kunnen nu direct inbreken in de grammatica, wat in de toekomst extensies mogelijk maakt die geheel nieuwe SQL-syntaxis introduceren. Foutmeldingen bevatten nu precieze locatiegegevens.
De nieuwe parser is ontworpen om compatibel te zijn met de oude. Indien nodig kan de oude parser worden geactiveerd via de legacyparser extensie: SET enablelegacy_parser = true;.
Het voordeel van de PEG-grammatica ten opzichte van de oude YACC/Bison-parser is dat het toevoegen van nieuwe syntaxis geen risico meer vormt voor het breken van niet-gerelateerde regels (geen shift/reduce-conflicten).
Extensies schrijven en zelf hosten
DuckDB 2.0 introduceert een vernieuwde C API v2, die krachtiger is en componenten zoals bestandssystemen en tabelfuncties blootstelt aan extensies.
Organisaties kunnen nu hun eigen vertrouwde extensie-repositories registreren en hosten:
SET allow_extension_repositories = 'allowed';
CREATE EXTENSION REPOSITORY my_repo WITH PREFIX 'https://extensions.example.org';
INSTALL AND LOAD my_ext FROM my_repo;
Een repository bestaat uit een naam, een URL-prefix en één of meerdere RSA-publieke sleutels.
Updates voor kernextensies
Enkele hoogtepunten van de kernextensies:
- DuckLake 1.1: Nieuwe specificatie en referentie-implementatie.
- Iceberg: Toevoeging van REST catalog
ATTACHopties om tabellocaties af te leiden van de namespace of metadata-locatiebestanden. - Delta: Mogelijkheid om Delta-tabellen te maken met
CREATE TABLE(inclusief partitionering), ondersteuning voor time travel en verbeterdeVARIANT-ondersteuning.
---
SQL-functionaliteiten
Triggers
DuckDB 2.0 introduceert triggers via het CREATE TRIGGER statement. Ondersteund worden:
BEFOREenAFTERtriggers.FOR EACH ROWenFOR EACH STATEMENT.- Transitietabellen via
REFERENCING OLD/NEW TABLE. - Meerdere triggers per event.
RETURNINGop getriggerde tabellen enDROP TRIGGER.
Voorbeeld: Audit-tabel
CREATE TRIGGER trg_audit
AFTER UPDATE ON target
REFERENCING OLD TABLE AS o NEW TABLE AS n
FOR EACH STATEMENT
INSERT INTO audit
SELECT n.id, o.val, n.val
FROM o JOIN n ON o.id = n.id;
Triggers kunnen ook worden gebruikt om gematerialiseerde views incrementeel bij te houden. Hieronder een voorbeeld waarbij de gemiddelde leeftijd per nationaliteit wordt bijgehouden in een tabel age_statistics.
Setup:
CREATE TABLE people (name VARCHAR, nationality VARCHAR, age INTEGER);
CREATE TABLE age_statistics (
nationality VARCHAR PRIMARY KEY,
sum_age INTEGER,
num_people INTEGER,
average_age DOUBLE
);
Trigger bij invoeging:
CREATE TRIGGER people_insert
AFTER INSERT ON people
REFERENCING NEW TABLE AS n
FOR EACH STATEMENT
MERGE INTO age_statistics s
USING (
SELECT nationality, sum(age) AS sum_age, count(*) AS num_people
FROM n
GROUP BY nationality
) d
ON s.nationality = d.nationality
WHEN MATCHED THEN UPDATE SET
sum_age = s.sum_age + d.sum_age,
num_people = s.num_people + d.num_people,
average_age = (s.sum_age + d.sum_age) / (s.num_people + d.num_people)
WHEN NOT MATCHED THEN INSERT
VALUES (d.nationality, d.sum_age, d.num_people, d.sum_age / d.num_people);
Trigger bij verwijdering:
CREATE TRIGGER people_delete
AFTER DELETE ON people
REFERENCING OLD TABLE AS o
FOR EACH STATEMENT
MERGE INTO age_statistics s
USING (
SELECT nationality, sum(age) AS sum_age, count(*) AS num_people
FROM o
GROUP BY nationality
) d
ON s.nationality = d.nationality
WHEN MATCHED AND s.num_people = d.num_people THEN DELETE
WHEN MATCHED THEN UPDATE SET
sum_age = s.sum_age - d.sum_age,
num_people = s.num_people - d.num_people,
average_age = (s.sum_age - d.sum_age) / (s.num_people - d.num_people);
Toevoegingen aan het SQL-dialect
$variableshorthand: Gebruik$xin plaats vangetvariable('x').- Data-modifying CTE's:
INSERT,UPDATE,DELETEenCOPYkunnen nu als pipeline-stappen in CTE's worden gebruikt. - NEAREST joins: Maakt top-k similarity search mogelijk via een join-clause, nuttig voor vector- en embedding-workloads.
- Nested schemas: Ondersteuning voor schema's binnen schema's (bijv.
CREATE SCHEMA finance.reports). - JSON mutatiefuncties:
jsonset,jsoninsert,jsonreplaceenjsonremoveretourneren gemodificeerde kopieën van JSON-documenten. - Overig: Ondersteuning voor SQL-standaard
FETCH FIRSTenUNNESTin deGROUP BYclause.
---
Migreren naar 2.0
DuckDB 2.0 bevat enkele breaking changes. Voor de meeste gebruikers is de upgrade eenvoudig, maar complexe deployments vereisen zorg.
Belangrijk: Het opslagformaat is gewijzigd. DuckDB-versies vóór 2.0 kunnen geen databasebestanden lezen die zijn aangemaakt door DuckDB 2.0. DuckDB 2.0 kan bestaande bestanden van oudere versies nog wel lezen en beschrijven. Het wordt aangeraden om 2.0.0 eerst op een schaduwsysteem te testen voordat productie wordt omgezet.
---
Internals en Deprecations
Compilervereisten
DuckDB 2.0 vereist nu een C++17 compiler. Daarnaast is Clang de standaardcompiler geworden voor release-builds op Linux, macOS en (voor de CLI) Windows.
Tijdzones, kalenders en collaties zonder ICU
De ICU-bibliotheek is volledig verwijderd. De icu-extensie implementeert nu zelf tijdzones, kalenders en collaties, waarbij de tijdzonedata direct is gebouwd vanuit de IANA-database en is gecomprimeerd tot ongeveer 45 kB. Dit is sneller en behoudt dezelfde functionaliteit.
Deprecations (Verouderde functies)
- Lambda Syntaxis: De oude single-arrow syntaxis (
x -> x + 1) is standaard uitgeschakeld. Gebruik de Python-stijl syntaxis:
SELECT listtransform([1, 2, 3], lambda x: x + 1); De oude syntaxis kan tijdelijk worden geactiveerd met SET lambdasyntax = 'enablesinglearrow';, maar wordt in v2.1 volledig verwijderd.
- Amalgamation Builds: De amalgamation build (waarbij de broncode in één header- en bronbestand wordt gebundeld) is deprecated omdat deze te groot is geworden.
- macOS x8664: Ondersteuning voor
osxamd64wordt geleidelijk uitgefaseerd. Community-extensies worden hier niet meer voor gebouwd en DuckDB 2.1 zal deze architectuur volledig stopzetten.
---
Samenvatting
DuckDB 2.0 is een enorme stap voorwaarts met bijna 20.000 commits sinds versie 1.5. Naast de grote nieuwe features zijn er talloze kleine verbeteringen in prestaties en gebruiksvriendelijkheid doorgevoerd. De volledige release notes zijn beschikbaar op GitHub.
Groetjes,