firebird
Föderierter Nur-Lese-Zugriff auf Firebird-Datenbanken (3.0/4.0/5.0) aus DuckDB, mit Projektions- und Filter-Pushdown, Unterstützung für INT128 / DECIMAL(38) / TIMESTAMP_TZ, nativem ATTACH und Behandlung von CHARACTER SET NONE (Standard win1252; außerdem strict / iso8859_1 / blob) mit korrektem Filter-Pushdown auf transkodierten Spalten.
Maintainer: flozer
Installation und Laden
INSTALL firebird FROM community;LOAD firebird;Beispiel
LOAD firebird;
-- 1. Live scan against a Firebird server.SELECT * FROM firebird_scan( 'firebird://APP_READONLY:secret@db.host:3050/srv:/data/prod.fdb?charset=UTF8', 'EMPLOYEE') LIMIT 10;
-- 2. Projection + filter pushdown — only EMP_NO, FIRST_NAME and the-- WHERE predicate are sent to Firebird.SELECT EMP_NO, FIRST_NAME FROM firebird_scan('firebird://…', 'EMPLOYEE') WHERE DEPT_NO = '600' AND HIRE_DATE > DATE '2020-01-01';
-- 3. Discover the schema.SELECT * FROM firebird_tables('firebird://…');
-- 4. Native ATTACH — every Firebird table reachable through DuckDB's catalog.ATTACH 'firebird://APP_READONLY:secret@host/path/db.fdb' AS fb (TYPE firebird);SELECT * FROM fb.main.EMPLOYEE WHERE DEPT_NO = '600';
-- 5. Firebird-native diagnostics (v0.6).SELECT * FROM firebird_profile_table('fb.main.EMPLOYEE');SELECT * FROM firebird_pool_stats('fb');
-- 6. Federated JOIN — Firebird ⋈ Parquet.SELECT e.dept_no, COUNT(*), AVG(e.salary) FROM firebird_scan('firebird://…', 'EMPLOYEE') e JOIN read_parquet('s3://lake/departments/*.parquet') d ON e.dept_no = d.dept_no GROUP BY e.dept_no;
-- 7. Legacy database declared CHARACTER SET NONE. Firebird does-- NOT transliterate NONE columns to UTF-8 on the wire; pick-- the encoding the writing application used.SELECT * FROM firebird_scan( 'C:/legacy/company.fdb', 'TABENTRADASAIDA', none_encoding='win1252');Über firebird
duckdb-firebird stellt Firebird-Tabellen als DuckDB-Tabellen bereit; der DuckDB-Optimierer reicht Projektions- und Filterprädikate an den Firebird-Server weiter. Große Aggregationen laufen weiterhin in DuckDBs vektorisiertem Executor; Sie müssen nur keine parallele ETL- Pipeline mehr pflegen, um Firebird-Daten zuerst nach Parquet zu exportieren.
Oberfläche
firebird_scan(conn, table [, named params])— Scan einer einzelnen Tabelle mit Projektions- und Filter-Pushdown und optionalem parallelem PK-Bereichsscan.firebird_tables(conn)— listet Benutzertabellen (und Sichten, externe Tabellen, GTTs) mit PK-Informationen auf.firebird_attach_sql(conn[, schema])— gibt das DDL für ein leichtgewichtiges, sichtbasiertes Attach aus, wenn Sie nicht die volle Lebensdauer derStorageExtensionwollen.ATTACH 'firebird://…' AS fb (TYPE firebird)— nativer schreibgeschützter Katalog mitSELECT * FROM fb.main.TABLE, föderierten Joins,DESCRIBE, groß-/kleinschreibungsunabhängiger Suche und Connection Pooling.firebird_profile_table('fb.main.TABLE')— faktische Diagnostik v0.6 zu PKs, Indizes, Filter-/Wasserzeichen-Kandidaten, Sicht-Risiko und empfohlenen Partitionen.firebird_pool_stats('fb')— Connection-Pool-Zähler v0.6 für einen angehängten Firebird-Katalog.
Pushdown
- Projektion: nur angeforderte Spalten gehen über die Leitung.
- Filter:
=, <>, <, >, <=, >=, IS [NOT] NULL, BETWEEN, IN, AND/OR, LIKE 'prefix%'werden in Firebird-SQL übersetzt. Alles andere bleibt in DuckDB oberhalb des Scans. - Paralleler PK-Bereichsscan: Opt-in über den benannten Parameter
partitions=N— empfohlen für entfernte / Classic-Firebird-Server, bei denen Parallelität günstig ist. - Manuelles
row_limit=N: gibt FirebirdsROWS Ndirekt aus.
Typabbildung
Kompatibilität mit Firebird-3-+-4-+-5-Servern:
INTEGER,BIGINT,SMALLINT,CHAR(N),VARCHAR(N),NUMERIC/DECIMAL(p, s)(bis 38 Stellen),FLOAT,DOUBLE,DATE,TIME,TIMESTAMP,BOOLEAN— exakte Abbildung.INT128→HUGEINT;DECIMAL(p > 18, s)→DECIMAL(38, s).TIMESTAMP WITH TIME ZONE(einschließlich der erweiterten TZ-Form von FB4) → DuckDBTIMESTAMP WITH TIME ZONE(UTC-Zeitpunkt bleibt erhalten).TIME WITH TIME ZONE→ DuckDBTIME WITH TIME ZONE.BLOB SUB_TYPE 1(Text) →VARCHAR; andere BLOBs →BLOB.DECFLOAT(16)/DECFLOAT(34)→ verlustfreiesVARCHARüber serverseitigesCAST(... AS VARCHAR(64))(v0.6).
Verbindungszeichenfolgen
firebird://USER:PASS@HOST:PORT/DB_PATH?charset=UTF8&dialect=3&role=…user=APP_READONLY;password=secret;database=server:/data/db.fdb;charset=UTF8Ein bloßer Pfad (/var/lib/firebird/test.fdb, C:/data/prod.fdb) wird
für lokale Datenbanken ebenfalls akzeptiert.
Benutzer / Passwort / Zeichensatz / Rolle / Dialekt / Partitionen / row_limit können zur Aufrufzeit über benannte Parameter überschrieben werden.
Zeichensatzbehandlung
DuckDB speichert Zeichenketten intern als UTF-8. Die Erweiterung akzeptiert
für den Client-Zeichensatz nur UTF8, UTF-8, NONE oder OCTETS;
alles andere wird zur Bind-Zeit zurückgewiesen.
Datenbanken mit einem echten Zeichensatz (WIN1252, ISO8859_1,
UTF8, …) durchlaufen den Roundtrip unter dem Standard charset=UTF8 sauber:
Firebird transliteriert serverseitig, sodass São Paulo, Açúcar,
Coração ohne Extra-Konfiguration als gültiges UTF-8 ankommen.
Datenbanken (oder einzelne Spalten) mit CHARACTER SET NONE
sind anders: Firebird liefert die Rohbytes zurück, die die schreibende
Anwendung gespeichert hat, ohne Transliteration. Der
Standardmodus win1252 der Erweiterung dekodiert die Bytes, die viele ältere brasilianische
und westeuropäische ERP-Systeme verwenden. Der Aufrufer kann weiterhin die Kodierung wählen, die
die Quellanwendung verwendet hat:
none_encoding='win1252'(Standard) — Bytes als Windows-1252 → UTF-8 dekodieren.none_encoding='strict'— nur gültiges UTF-8 akzeptieren.none_encoding='iso8859_1'(Alias'latin1') — Bytes als ISO-8859-1 → UTF-8 dekodieren.none_encoding='blob'— NONE-Textspalten als DuckDB-BLOB(Rohbytes) bereitstellen.
Die Option wird sowohl von firebird_scan(…) als auch von der
Form ATTACH ... (TYPE firebird, none_encoding 'win1252') akzeptiert. Solange
none_encoding != 'strict', ist Filter-Pushdown auf NONE-Textspalten
bewusst deaktiviert — das SQL-Literal, das wir senden würden, ist UTF-8
und würde serverseitig nicht zu den Rohbytes passen. DuckDB wendet
den Textfilter nach der Transkodierung oberhalb des Scans an.
Verifiziert gegen
- Firebird 3.0 (apt
firebird3.0-server, CI-Fixture) - Firebird 4.0.x (
firebirdsql/firebird:4-noble) - Firebird 5.0.4 (Windows lokal +
firebirdsql/firebird:5-noble) - DuckDB v1.5.3 - v1.5.5 (
StorageExtension::Register-API)
Hinzugefügte Funktionen
| function_name | function_type | description | comment | examples |
|---|---|---|---|---|
| firebird_attach_sql | table | NULL | NULL | |
| firebird_comments | table | NULL | NULL | |
| firebird_computed_columns | table | NULL | NULL | |
| firebird_dependencies | table | NULL | NULL | |
| firebird_domains | table | NULL | NULL | |
| firebird_explain_pushdown | table | NULL | NULL | |
| firebird_foreign_keys | table | NULL | NULL | |
| firebird_generate_dbt_sources | table | NULL | NULL | |
| firebird_generators | table | NULL | NULL | |
| firebird_health | table | NULL | NULL | |
| firebird_index_profile | table | NULL | NULL | |
| firebird_indexes | table | NULL | NULL | |
| firebird_last_query | table | NULL | NULL | |
| firebird_pool_stats | table | NULL | NULL | |
| firebird_profile_table | table | NULL | NULL | |
| firebird_query_log | table | NULL | NULL | |
| firebird_scan | table | NULL | NULL | |
| firebird_tables | table | NULL | NULL | |
| firebird_type_audit | table | NULL | NULL |
Überladene Funktionen
Diese Erweiterung fügt keine Funktionsüberladungen hinzu.
Hinzugefügte Typen
Diese Erweiterung fügt keine Typen hinzu.
Hinzugefügte Einstellungen
| name | description | input_type | scope | aliases |
|---|---|---|---|---|
| firebird_pool_enabled | Enable the per-ATTACH FirebirdConnectionPool. When false, every Acquire opens a fresh connection and Release destroys it. | BOOLEAN | GLOBAL | [] |
| firebird_pool_idle_timeout_ms | How long (in milliseconds) a released connection may sit in the idle queue before it is discarded on the next Acquire. 0 = no expiry (default). Clock starts at Release(). | BIGINT | GLOBAL | [] |
| firebird_pool_max_size | Maximum number of idle connections kept in the pool. 0 = unlimited (default). Caps the idle queue, not active leases. | BIGINT | GLOBAL | [] |
| firebird_query_log_size | Maximum entries kept by firebird_query_log() per session. 0 disables the log (default). | BIGINT | GLOBAL | [] |