Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Virtual Schema

The SQL engine exposes three virtual tables backed directly by the in-memory store; there is no separate schema to migrate.

SELECT id, path, title, tags FROM documents;

SELECT id, document_id, block_type, content, pre, post,
       depth, lang, properties FROM blocks;

documents

ColumnTypeDescription
idintegerDocument ID (matches blocks.document_id)
pathtextSource file path, or NULL for in-memory-only documents
titletextFront-matter / first-heading title, if any
tagstextFront-matter tags, as a JSON array
block_countintegerNumber of blocks in the document
max_heading_depthintegerDeepest heading level
code_languagestextCode fence languages, as a sorted JSON array
frontmatter_keystextTop-level front-matter keys, as a sorted JSON array
propertiestextTop-level front-matter as a JSON object, readable without loading blocks
SELECT path FROM documents
WHERE json_extract(properties, 'owner') = 'alice';

One row per link or image, including those inside lists, tables and block quotes.

ColumnTypeDescription
document_idintegerOwning document ID
block_idintegerblocks.id of the block containing the link
kindtext'link', 'image', 'ref' (reference link) or 'image_ref'
urltextDestination URL, or the reference label for ref/image_ref
texttextLink text, or image alt text
titletextLink title, or empty
-- Most linked-to URLs
SELECT url, COUNT(*) AS n FROM links WHERE kind = 'link' GROUP BY url ORDER BY n DESC;

blocks

ColumnTypeDescription
idintegerBlock ID
document_idintegerOwning document ID
block_typetext'heading', 'paragraph', 'code', 'list', 'blockquote', 'table_cell', 'table_row', 'table_align', 'yaml', 'toml', 'html', 'horizontal_rule', 'math', 'definition', 'footnote'
contenttextRaw block content
preintegerInterval-index pre-order boundary
postintegerInterval-index post-order boundary
depthintegerHeading depth (1–6); NULL/0 for non-headings
langtextCode fence language, when block_type = 'code'
propertiestextRemaining block-type-specific properties as JSON
content_hashtext64 hex digits of SHA-256 over the block type, a NUL byte and the content. Equal for equal content wherever it appears, so it is a stable key for derived data such as embeddings
anchortextLocation that survives edits elsewhere in the document: a heading is its slug path (guide/install, a repeated sibling gets -2), any other block is <section path>::<type>:<n> (guide/install::code:1). Unique within a document

id is the block’s position across the whole store, so it shifts when an earlier document gains or loses blocks. Key long-lived data on (documents.path, anchor) or on content_hash instead.

pre/post are the Nested-Set interval-index boundaries described in Index Layers; they encode heading hierarchy as a pure integer range, which is what the under() function operates on.