Read, inspect, transform, and write PDFs in SQL — text at every grain (page/line/word/element/chunk), OCR for scanned files, metadata, tables, images, and document surgery (merge/split/sign/redact/watermark/encrypt/…).
Installing and Loading
INSTALL pdf FROM community;
LOAD pdf;
Example
LOAD pdf;
-- One row per page; takes a file, a list, or a glob (parallel across files)
SELECT filename, page, text
FROM read_pdf('reports/*.pdf')
WHERE contains(lower(text), 'revenue');
-- One row per file: metadata, page count, size, encryption
SELECT file, title, author, page_count FROM pdf_info('reports/*.pdf');
-- Structured table extraction (digital and scanned PDFs)
SELECT * FROM read_pdf_tables('financial_report.pdf');
-- Retrieval-ready, section-aware chunks for RAG — one statement
CREATE TABLE chunks AS FROM pdf_chunks('reports/*.pdf');
-- Render a page to PNG bytes (vision-model input, thumbnails)
SELECT pdf_to_png('report.pdf', 1, 150) AS page_image;
-- Write page preview PNGs to disk (no pdftoppm): pages/<stem>/p1.png, …
SELECT * FROM pdf_write_page_images('reports/*.pdf', 'pages', dpi := 100);
-- Query result to a typeset PDF, no external tools
COPY (SELECT * FROM findings)
TO 'findings.pdf' (FORMAT pdf, TITLE 'Findings', FOOTER 'page {page}');
About pdf
Everything PDF, in SQL — built on Poppler (parsing/rendering), Tesseract (OCR), qpdf (document surgery), and libharu (native writing), all statically linked into the DuckDB process. Every function accepts a single path or a glob, so the natural unit of work is a folder of PDFs.
Read — read_pdf (pages), read_pdf_lines, read_pdf_words
(bounding boxes + OCR confidence), read_pdf_elements (layout elements in
reading order), read_pdf_tables (ruled and unruled tables, digital or
scanned), pdf_chunks (retrieval-ready chunks with section headings).
Shared named parameters cover password, page ranges, text layout, and
OCR knobs; ignore_errors := true skips unopenable files in a folder scan.
Inspect — pdf_info (full per-file census), pdf_outline
(bookmarks), pdf_attachments (embedded files as BLOBs),
pdf_form_fields, pdf_annotations (incl. hyperlink extraction),
pdf_revisions (incremental-update forensics: what changed after the
document was first written), pdf_signatures (digital signatures,
cryptographically verified with OpenSSL CMS over the signed byte ranges),
pdf_images (the stored raster XObjects — the JPEG a scanner wrote — as
BLOBs), and PDF/A identification columns on pdf_info.
Convert — pdf_to_text / pdf_to_markdown (layout-aware GitHub
markdown) / pdf_to_html / pdf_to_xml / pdf_to_svg / pdf_to_png /
pdf_write_page_images (write page preview PNGs to out_dir/<stem>/p{N}.png
without pdftoppm).
The render scalars also accept PDF bytes as a BLOB, so they compose with
read_blob and httpfs.
Transform & write — pdf_merge, pdf_split, pdf_split_blank
(split scanned batches at blank separator pages), pdf_rotate,
pdf_pages, pdf_compress, pdf_encrypt / pdf_decrypt;
pdf_watermark / pdf_bates (searchable text stamps), pdf_sign
(CMS digital signatures — verifies back through pdf_signatures),
pdf_redact (true raster redaction: boxed text destroyed, not covered);
write_pdf and COPY ... TO 'out.pdf' (FORMAT pdf) typeset text or query
results natively (libharu — no external tools); to_pdf converts office
documents (docx, odt, pptx, …) via a LibreOffice runtime shell-out.
OCR — pages with no text layer are OCR'd automatically. English
(eng) is bundled (tessdata_fast, extracted on first use) so scanned PDFs
work with zero host tessdata install. Other languages: install models the
normal way (brew install tesseract-lang, apt-get install tesseract-ocr-deu,
…) or pass tessdata_dir / TESSDATA_PREFIX. Pick languages with
ocr_language := 'deu'. Leptonica preprocess + confidence DPI retry by
default. Page text from read_pdf / pdf_to_text is trimmed once at
emit (no trailing form-feeds).
Scope — deterministic extraction, not ML document understanding: merged cells and borderless/sparse tables are out of scope (use docling / marker / a Document AI service for those). Full per-function docs, column lists, and recipes: https://github.com/asubbarao/duckdb-pdf
License — GPL-2.0-or-later (Poppler is GPL-2.0 and statically linked).
Added Functions
| function_name | function_type | description | comment | examples |
|---|---|---|---|---|
| pdf_annotations | table | NULL | NULL | |
| pdf_attachments | table | NULL | NULL | |
| pdf_bates | scalar | NULL | NULL | |
| pdf_chunks | table | NULL | NULL | |
| pdf_compress | scalar | NULL | NULL | |
| pdf_decrypt | scalar | NULL | NULL | |
| pdf_destinations | table | NULL | NULL | |
| pdf_encrypt | scalar | NULL | NULL | |
| pdf_fonts | table | NULL | NULL | |
| pdf_form_fields | table | NULL | NULL | |
| pdf_images | table | NULL | NULL | |
| pdf_info | table | NULL | NULL | |
| pdf_json | scalar | NULL | NULL | |
| pdf_merge | scalar | NULL | NULL | |
| pdf_outline | table | NULL | NULL | |
| pdf_page_images | table | NULL | NULL | |
| pdf_pages | scalar | NULL | NULL | |
| pdf_pages_info | table | NULL | NULL | |
| pdf_permissions | table | NULL | NULL | |
| pdf_qpdf_info | table | NULL | NULL | |
| pdf_redact | table | NULL | NULL | |
| pdf_redact_lateral | table | NULL | NULL | |
| pdf_repair | scalar | NULL | NULL | |
| pdf_revisions | table | NULL | NULL | |
| pdf_rotate | scalar | NULL | NULL | |
| pdf_sign | table | NULL | NULL | |
| pdf_signatures | table | NULL | NULL | |
| pdf_split | table | NULL | NULL | |
| pdf_split_blank | table | NULL | NULL | |
| pdf_to_html | scalar | NULL | NULL | |
| pdf_to_markdown | scalar | NULL | NULL | |
| pdf_to_png | scalar | NULL | NULL | |
| pdf_to_svg | scalar | NULL | NULL | |
| pdf_to_text | scalar | NULL | NULL | |
| pdf_to_xml | scalar | NULL | NULL | |
| pdf_watermark | scalar | NULL | NULL | |
| pdf_write_page_images | table | NULL | NULL | |
| read_pdf | table | NULL | NULL | |
| read_pdf_elements | table | NULL | NULL | |
| read_pdf_lines | table | NULL | NULL | |
| read_pdf_meta | table | NULL | NULL | |
| read_pdf_tables | table | NULL | NULL | |
| read_pdf_words | table | NULL | NULL | |
| to_pdf | scalar | NULL | NULL | |
| write_pdf | scalar | NULL | NULL |
Overloaded Functions
This extension does not add any function overloads.
Added Types
This extension does not add any types.
Added Settings
This extension does not add any settings.