Search Shortcut cmd + k | ctrl + k

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/…).

Maintainer(s): asubbarao

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.

Readread_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.

Inspectpdf_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.

Convertpdf_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 & writepdf_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.