pst

Read and edit in place Microsoft PST files with rich schemas for common MAPI types (emails, contacts, appointments, tasks)

Maintainer(s): mach-kernel

Installing and Loading

INSTALL pst FROM community;
LOAD pst;

Example

-- Count all messages across PST files (supports globs)
D SELECT count(*) FROM read_pst_messages('enron/*.pst');
┌────────────────┐
│ count_star() │
│ int64 │
├────────────────┤
1227193
└────────────────┘
-- Query contacts (supports remote URIs)
D SELECT given_name, surname FROM read_pst_contacts('https://example.com/outlook.pst');
┌────────────┬─────────┐
│ given_name │ surname │
varcharvarchar
├────────────┼─────────┤
│ John │ Doe │
│ Jane │ Smith │
└────────────┴─────────┘
-- Read messages with limit (applied during planning for large files)
D SELECT subject, sender_email_address, message_delivery_time
FROM read_pst_messages('*.pst', read_limit=100);
-- Preview an in-place delete. Without `really := true` the call
-- opens read-only and reports what it would do per row.
D SELECT status, count(*) FROM delete_pst_messages(
SELECT pst_path, node_id FROM read_pst_messages('/tmp/hr.pst')
WHERE sender_email_address = '[email protected]'
) GROUP BY status;
┌───────────┬──────────────┐
status │ count_star() │
varchar │ int64 │
├───────────┼──────────────┤
│ PREVIEWED │ 17
└───────────┴──────────────┘

About pst

A DuckDB extension for reading and editing in place Microsoft PST files, with rich schemas for common MAPI types. Built on Microsoft’s official PST SDK. Query emails, contacts, appointments, and more. Use it to analyze PST data in-place (locally or on object storage), import to DuckDB tables, export to Parquet, or delete from a store in place to scrub PII, drop out-of-scope custodian mail before a production, or strip attachments.

Table Functions

Function MAPI Class Description
read_pst_folders * Folder hierarchy
read_pst_messages * All messages with base IPM.Note schema
read_pst_notes IPM.Note Email messages
read_pst_contacts IPM.Contact Contacts with 78+ fields
read_pst_distribution_lists IPM.DistList Distribution lists with members
read_pst_appointments IPM.Appointment Calendar appointments and meetings
read_pst_sticky_notes IPM.StickyNote Sticky note items
read_pst_tasks IPM.Task Task items

In-place Deletion

Function Input Table Deletes
delete_pst_messages (pst_path VARCHAR, node_id UINTEGER) One message, and its attachments
delete_pst_folders (pst_path VARCHAR, node_id UINTEGER) A folder, its subfolders and everything in them
delete_pst_attachments (pst_path VARCHAR, message_node_id UINTEGER, attachment_node_id UINTEGER) One attachment, leaving the message
wipe_pst_free_space a path or glob Overwrites bytes no node points at

Gated behind SET pst_allow_delete = true (session) plus really := true per call. Without really the call opens read-only, resolves every target, and reports PREVIEWED or FAILED per row. Bind errors abort the statement; anything found later is reported per row so a mid-statement throw cannot leave already-committed deletes with no record of what went. Node IDs are checked against the mode, so delete_pst_messages refuses a folder or the store’s root.

Performance Features

  • Query pushdown: projection and statistics pushdown
  • Concurrent planning: parallel partition planning for directories with many PST files
  • Late materialization: filter on virtual columns before expanding full projections

Parameters

Parameter Default Description
read_body_size_bytes 1000000 Max bytes to read into body/body_html (0 for unlimited)
read_attachment_body false Whether to read attachment bytes
read_limit NULL Max items to read (applied during planning)

For full schema documentation and usage examples, see the GitHub repository.

Added Functions

function_name function_type description comment examples
delete_pst_attachments table NULL NULL
delete_pst_folders table NULL NULL
delete_pst_messages table NULL NULL
read_pst_appointments table NULL NULL
read_pst_contacts table NULL NULL
read_pst_distribution_lists table NULL NULL
read_pst_folders table NULL NULL
read_pst_messages table NULL NULL
read_pst_notes table NULL NULL
read_pst_sticky_notes table NULL NULL
read_pst_tasks table NULL NULL
wipe_pst_free_space table NULL NULL

Overloaded Functions

This extension does not add any function overloads.

Added Types

This extension does not add any types.

Added Settings

name description input_type scope aliases
pst_allow_delete Allow delete_pst_* and wipe_pst_free_space to edit PST files in place. Deletion cannot be undone. BOOLEAN GLOBAL []