Catalogs
On this page
Presenting a worker as a database — schemas, tables, views, and macros — configured through the catalog interface.
type AttachOpaqueData
Section titled “type AttachOpaqueData”export type AttachOpaqueData = Uint8Array;interface AttachOptionSpec
Section titled “interface AttachOptionSpec”export interface AttachOptionSpecDescription
Declarative spec for a single attach-time option.
The catalog’s catalogsInfo() emits these (serialized) in
CatalogInfo.attach_option_specs so the DuckDB extension can validate
user-supplied ATTACH options and cast them to the declared type before
forwarding to the worker’s catalog_attach handler.
Fields
namestringOption name — matches the key users pass in the ATTACH statement.
descriptionstringHuman-readable description (shown in discovery UIs).
typeVgiDataTypeArrow data type the extension should cast user input to.
defaultunknownoptionalDefault value used when the user omits this option. Passed through to the worker’s catalog_attach handler as-is if no override is given. Use
nullfor “no default” (an unset option will then be absent from the options dict delivered to attach()).requiredbooleanoptionalThe caller must supply this option at ATTACH time. A catalog that cannot be attached without it advertises that fact at discovery, so a client can say so before attempting the attach rather than surfacing a failure that reads like an empty catalog.
Mutually exclusive with
default— an option that falls back to a value is by definition satisfiable without the caller.
type AttachOptionValue
Section titled “type AttachOptionValue”export type AttachOptionValue = string | number | bigint | boolean | null | Uint8Array;Description
Values supported in a CatalogAttach options map. The client infers an Arrow type per value:
string → Utf8 bigint → Int64 number → Float64 (JS numbers are doubles — safe for small ints too) boolean → Bool Uint8Array → Binary null → Null (column with no concrete type; value is null)
If you need types this can’t express (Decimal, Timestamp, Int32 vs Int64,
nested structs), drop down to optionsBytes on CatalogAttachOptions and
build the RecordBatch yourself.
function buildScanBranchesResult
Section titled “function buildScanBranchesResult”export function buildScanBranchesResult(branches: ScanBranchInput[],requiredExtensions: string[] = [],): { branches: Uint8Array[]; required_extensions: string[] }Description
Build a multi-branch ScanBranchesResult wire dict from explicit branch
definitions. Each branch becomes its own 1-row ScanBranchSchema IPC
stream carried in the branches list<binary> column. Mirrors vgi-python’s
ScanBranchesResult construction in the test fixture’s
table_scan_branches_get.
An empty branches list is serialized verbatim — the C++ side loud-fails
on it (that asymmetry is exercised by multi_branch_empty_branches.test).
interface CatalogAttachResult
Section titled “interface CatalogAttachResult”export interface CatalogAttachResultFields
attach_opaque_dataUint8Arraysupports_transactionsbooleansupports_time_travelbooleancatalog_version_frozenbooleancatalog_versionnumberattach_opaque_data_requiredbooleandefault_schemastringsettingsUint8Array[]secret_typesUint8Array[]attach_catalogsUint8Array[]tagsRecord<string, string>supports_column_statisticsbooleanglobal_functionsUint8Array[]global_function_prefixstringcommentstring | nulloptionalresolved_data_versionstring | nulloptionalresolved_implementation_versionstring | nulloptional
interface CatalogDescriptor
Section titled “interface CatalogDescriptor”export interface CatalogDescriptorFields
namestringschemasSchemaDescriptor[]defaultSchemastringoptionalsettingsSettingDescriptor[]optionalsecretTypesSecretTypeDescriptor[]optionalattachCatalogsAttachCatalogInfo[]optionalCompanion catalogs (lakehouse federation) the client should ATTACH when this VGI catalog attaches. Surfaced via
catalog_attach.attach_catalogs.commentstringoptionaltagsRecord<string, string>optionalsourceUrlstringoptionalHomepage for this catalog — repo, docs, or dataset landing page. Surfaced through the
catalog_catalogsdiscovery record asCatalogInfo.source_url, which DuckDB exposes viaduckdb_databases(). Optional; omitted/undefinedadvertises a nullsource_url.globalFunctionsVgiFunction[]optionalFunctions this catalog asks the client to additionally publish into its global (DuckDB
system.main) function namespace, on top of the normal schema-qualified registration. Surfaced as IPC-serializedFunctionInforecords oncatalog_attach.global_functions.Every entry must also be declared in exactly one of this catalog’s schemas — the
FunctionInfo.schema_nameit carries is the bind-dispatch key, not a sentinel. Mirrors vgi-python’sCatalog.global_functions.globalFunctionPrefixstringoptionalPrefix applied client-side to every
globalFunctionsentry’s name when it is published globally (e.g. prefixvgi_example+global_scalar→vgi_example_global_scalar). The advertisedFunctionInfo.namestays unprefixed. Surfaced ascatalog_attach.global_function_prefix.
interface CatalogInfo
Section titled “interface CatalogInfo”export interface CatalogInfoFields
namestringattach_option_specsUint8Array[]releasesCatalogDataVersionRelease[]implementation_versionstring | nulloptionaldata_version_specstring | nulloptionalsource_urlstring | nulloptional
class CatalogInterface
Section titled “class CatalogInterface”export abstract class CatalogInterfaceMethods
method catalogNameForAttach
Section titled “method catalogNameForAttach”catalogNameForAttach(_attachOpaqueData: Uint8Array): string | nullWhich catalog an attach_opaque_data belongs to, or null if unknown.
Two catalogs served by one worker may declare the same schema and
function name, in which case the attachment is the only thing that tells
them apart — the bind path uses this to scope function resolution. The
default answers from catalogs() when this interface owns exactly one,
which is right for every single-catalog implementation; the composite
overrides it to route by its backend index byte.
method attach
Section titled “method attach”abstract attach( name: string, options?: Record<string, unknown>, dataVersionSpec?: string | null, implementationVersion?: string | null,): Awaitable<CatalogAttachResult>;Attach this catalog. The framework already validates ATTACH options
(name + type) against the specs the worker advertises in
catalogsInfo().attach_option_specs, so options arrives as a
validated, decoded {name: value} dict with typed column values.
Use {} if no options were supplied.
method catalogsInfo
Section titled “method catalogsInfo”catalogsInfo?(): Awaitable<import(“../generated/vgi-client.js”).CatalogInfo[]>;List the catalogs this worker exposes with their version metadata. The
implementation_version / data_version_spec come from the CatalogInfo
returned by the read-only catalogs() signature below — a versioned worker
overrides catalogs() / catalogsInfo() to advertise real values; the
default derives them from the registered descriptor(s).
method detach
Section titled “method detach”abstract detach(attachOpaqueData: AttachOpaqueData): Awaitable<void>;method version
Section titled “method version”abstract version( attachOpaqueData: AttachOpaqueData, transactionOpaqueData?: TransactionOpaqueData): Awaitable<number>;method schemas
Section titled “method schemas”abstract schemas( attachOpaqueData: AttachOpaqueData, transactionOpaqueData?: TransactionOpaqueData): Awaitable<SchemaInfo[]>;method create
Section titled “method create”create(name: string, onConflict: string, options?: any): Awaitable<void>method schemaGet
Section titled “method schemaGet”schemaGet( attachOpaqueData: AttachOpaqueData, name: string, transactionOpaqueData?: TransactionOpaqueData): Awaitable<SchemaInfo | null>method schemaCreate
Section titled “method schemaCreate”schemaCreate( attachOpaqueData: AttachOpaqueData, name: string, comment?: string | null, tags?: any, transactionOpaqueData?: TransactionOpaqueData): Awaitable<void>method schemaDrop
Section titled “method schemaDrop”schemaDrop( attachOpaqueData: AttachOpaqueData, name: string, ignoreNotFound?: boolean, cascade?: boolean, transactionOpaqueData?: TransactionOpaqueData): Awaitable<void>method schemaContentsTables
Section titled “method schemaContentsTables”schemaContentsTables( attachOpaqueData: AttachOpaqueData, name: string, transactionOpaqueData?: TransactionOpaqueData): Awaitable<TableInfo[]>method schemaContentsViews
Section titled “method schemaContentsViews”schemaContentsViews( attachOpaqueData: AttachOpaqueData, name: string, transactionOpaqueData?: TransactionOpaqueData): Awaitable<ViewInfo[]>method schemaContentsFunctions
Section titled “method schemaContentsFunctions”schemaContentsFunctions( attachOpaqueData: AttachOpaqueData, name: string, type: string, transactionOpaqueData?: TransactionOpaqueData): Awaitable<FunctionInfo[]>method tableGet
Section titled “method tableGet”tableGet( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, atUnit?: string, atValue?: string, transactionOpaqueData?: TransactionOpaqueData): Awaitable<TableInfo | null>method tableCreate
Section titled “method tableCreate”tableCreate( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, columns: Uint8Array, onConflict: string, notNullConstraints?: number[], uniqueConstraints?: number[][], checkConstraints?: string[], transactionOpaqueData?: TransactionOpaqueData): Awaitable<void>method tableDrop
Section titled “method tableDrop”tableDrop( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, ignoreNotFound?: boolean, transactionOpaqueData?: TransactionOpaqueData): Awaitable<void>method tableScanFunctionGet
Section titled “method tableScanFunctionGet”tableScanFunctionGet( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, atUnit?: string, atValue?: string, transactionOpaqueData?: TransactionOpaqueData): Awaitable<any>method tableScanBranchesGet
Section titled “method tableScanBranchesGet”tableScanBranchesGet( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, atUnit?: string, atValue?: string, transactionOpaqueData?: TransactionOpaqueData): Awaitable<any>Return the scan branches for a (possibly multi-source) table. Default
delegates to tableScanFunctionGet and wraps the single result as a
one-branch list, so every single-source catalog is compatible with the
branches-aware C++ extension. Override for genuine multi-source tables.
method tableColumnStatisticsGet
Section titled “method tableColumnStatisticsGet”tableColumnStatisticsGet( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, transactionOpaqueData?: TransactionOpaqueData,): Awaitable<Return serialized column statistics for a table, or null if none are
available. The result is the IPC bytes of a ColumnStatistics RecordBatch
(see src/util/statistics.ts for the schema) wrapped with an optional
cache TTL. Callers typically override this to pull stats from a
descriptor. Returning null signals “no stats” so DuckDB falls back to
the function-level table_function_statistics path.
method tableCommentSet
Section titled “method tableCommentSet”tableCommentSet( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, comment?: string | null, ignoreNotFound?: boolean, transactionOpaqueData?: TransactionOpaqueData): Awaitable<void>method tableRename
Section titled “method tableRename”tableRename( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, newName: string, ignoreNotFound?: boolean, transactionOpaqueData?: TransactionOpaqueData): Awaitable<void>method tableColumnAdd
Section titled “method tableColumnAdd”tableColumnAdd( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, columnName: string, columnType: string, defaultValue?: string, ignoreNotFound?: boolean, transactionOpaqueData?: TransactionOpaqueData): Awaitable<void>method tableColumnDrop
Section titled “method tableColumnDrop”tableColumnDrop( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, columnName: string, ignoreNotFound?: boolean, transactionOpaqueData?: TransactionOpaqueData): Awaitable<void>method tableColumnRename
Section titled “method tableColumnRename”tableColumnRename( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, columnName: string, newName: string, ignoreNotFound?: boolean, transactionOpaqueData?: TransactionOpaqueData): Awaitable<void>method tableColumnDefaultSet
Section titled “method tableColumnDefaultSet”tableColumnDefaultSet( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, columnName: string, defaultValue: string, ignoreNotFound?: boolean, transactionOpaqueData?: TransactionOpaqueData): Awaitable<void>method tableColumnDefaultDrop
Section titled “method tableColumnDefaultDrop”tableColumnDefaultDrop( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, columnName: string, ignoreNotFound?: boolean, transactionOpaqueData?: TransactionOpaqueData): Awaitable<void>method tableColumnTypeChange
Section titled “method tableColumnTypeChange”tableColumnTypeChange( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, columnName: string, newType: string, ignoreNotFound?: boolean, transactionOpaqueData?: TransactionOpaqueData): Awaitable<void>method tableNotNullSet
Section titled “method tableNotNullSet”tableNotNullSet( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, columnName: string, ignoreNotFound?: boolean, transactionOpaqueData?: TransactionOpaqueData): Awaitable<void>method tableNotNullDrop
Section titled “method tableNotNullDrop”tableNotNullDrop( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, columnName: string, ignoreNotFound?: boolean, transactionOpaqueData?: TransactionOpaqueData): Awaitable<void>method viewGet
Section titled “method viewGet”viewGet( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, transactionOpaqueData?: TransactionOpaqueData): Awaitable<ViewInfo | null>method viewCreate
Section titled “method viewCreate”viewCreate( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, definition: string, onConflict: string, transactionOpaqueData?: TransactionOpaqueData): Awaitable<void>method viewDrop
Section titled “method viewDrop”viewDrop( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, ignoreNotFound?: boolean, transactionOpaqueData?: TransactionOpaqueData): Awaitable<void>method viewRename
Section titled “method viewRename”viewRename( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, newName: string, ignoreNotFound?: boolean, transactionOpaqueData?: TransactionOpaqueData): Awaitable<void>method viewCommentSet
Section titled “method viewCommentSet”viewCommentSet( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, comment?: string | null, ignoreNotFound?: boolean, transactionOpaqueData?: TransactionOpaqueData): Awaitable<void>method macroGet
Section titled “method macroGet”macroGet( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, transactionOpaqueData?: TransactionOpaqueData): Awaitable<MacroInfo | null>method macroCreate
Section titled “method macroCreate”macroCreate( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, macroType: MacroType, parameters: string[], definition: string, onConflict: string, parameterDefaultValues?: Uint8Array | null, /** * Optional Arrow schema (one nullable field per parameter, in `parameters` * order) serialized as IPC bytes, carrying per-parameter descriptions via themethod macroDrop
Section titled “method macroDrop”macroDrop( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, ignoreNotFound?: boolean, transactionOpaqueData?: TransactionOpaqueData): Awaitable<void>method schemaContentsMacros
Section titled “method schemaContentsMacros”schemaContentsMacros( attachOpaqueData: AttachOpaqueData, name: string, type: string, transactionOpaqueData?: TransactionOpaqueData): Awaitable<MacroInfo[]>method schemaContentsIndexes
Section titled “method schemaContentsIndexes”schemaContentsIndexes( attachOpaqueData: AttachOpaqueData, name: string, transactionOpaqueData?: TransactionOpaqueData): Awaitable<IndexInfo[]>method indexGet
Section titled “method indexGet”indexGet( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, transactionOpaqueData?: TransactionOpaqueData): Awaitable<IndexInfo | null>method copyFromFormats
Section titled “method copyFromFormats”copyFromFormats( attachOpaqueData: AttachOpaqueData, transactionOpaqueData?: TransactionOpaqueData,): Awaitable<CopyFromFormatInfo[]>List custom COPY ... FROM formats advertised by this catalog. Catalog-level
(not schema-scoped). The default returns an empty list, so catalogs that
don’t define COPY formats are unaffected. The VGI extension treats an empty
list (or a not-implemented method) as “no custom formats”. Mirrors
vgi-python’s CatalogInterface.copy_from_formats.
method transactionBegin
Section titled “method transactionBegin”transactionBegin(attachOpaqueData: AttachOpaqueData): Awaitable<Uint8Array | null>method transactionCommit
Section titled “method transactionCommit”transactionCommit( attachOpaqueData: AttachOpaqueData, transactionOpaqueData: TransactionOpaqueData): Awaitable<void>method transactionRollback
Section titled “method transactionRollback”transactionRollback( attachOpaqueData: AttachOpaqueData, transactionOpaqueData: TransactionOpaqueData): Awaitable<void>class CompositeCatalogInterface
Section titled “class CompositeCatalogInterface”export class CompositeCatalogInterface extends CatalogInterfaceMethods
method catalogNameForAttach
Section titled “method catalogNameForAttach”override catalogNameForAttach(attachOpaqueData: Uint8Array): string | nullRoute to the owning backend and ask it, so the answer is per-attachment.
method catalogsInfo
Section titled “method catalogsInfo”async catalogsInfo(): Promise<CatalogInfo[]>List the catalogs this worker exposes with their version metadata. The
implementation_version / data_version_spec come from the CatalogInfo
returned by the read-only catalogs() signature below — a versioned worker
overrides catalogs() / catalogsInfo() to advertise real values; the
default derives them from the registered descriptor(s).
method attach
Section titled “method attach”async attach( name: string, options?: Record<string, unknown>, dataVersionSpec?: string | null, implementationVersion?: string | null,): Promise<CatalogAttachResult>Attach this catalog. The framework already validates ATTACH options
(name + type) against the specs the worker advertises in
catalogsInfo().attach_option_specs, so options arrives as a
validated, decoded {name: value} dict with typed column values.
Use {} if no options were supplied.
method detach
Section titled “method detach”async detach(attachOpaqueData: AttachOpaqueData): Promise<void>method version
Section titled “method version”async version(attachOpaqueData: AttachOpaqueData, transactionOpaqueData?: TransactionOpaqueData): Promise<number>method schemas
Section titled “method schemas”async schemas(attachOpaqueData: AttachOpaqueData, transactionOpaqueData?: TransactionOpaqueData): Promise<SchemaInfo[]>method schemaGet
Section titled “method schemaGet”override async schemaGet(attachOpaqueData: AttachOpaqueData, name: string, transactionOpaqueData?: TransactionOpaqueData): Promise<SchemaInfo | null>method schemaContentsTables
Section titled “method schemaContentsTables”override async schemaContentsTables(attachOpaqueData: AttachOpaqueData, name: string, transactionOpaqueData?: TransactionOpaqueData): Promise<TableInfo[]>method schemaContentsViews
Section titled “method schemaContentsViews”override async schemaContentsViews(attachOpaqueData: AttachOpaqueData, name: string, transactionOpaqueData?: TransactionOpaqueData): Promise<ViewInfo[]>method schemaContentsFunctions
Section titled “method schemaContentsFunctions”override async schemaContentsFunctions(attachOpaqueData: AttachOpaqueData, name: string, type: string, transactionOpaqueData?: TransactionOpaqueData): Promise<FunctionInfo[]>method schemaContentsMacros
Section titled “method schemaContentsMacros”override async schemaContentsMacros(attachOpaqueData: AttachOpaqueData, name: string, type: string, transactionOpaqueData?: TransactionOpaqueData): Promise<MacroInfo[]>method schemaContentsIndexes
Section titled “method schemaContentsIndexes”override async schemaContentsIndexes(attachOpaqueData: AttachOpaqueData, name: string, transactionOpaqueData?: TransactionOpaqueData): Promise<IndexInfo[]>method indexGet
Section titled “method indexGet”override async indexGet(attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, transactionOpaqueData?: TransactionOpaqueData): Promise<IndexInfo | null>method tableGet
Section titled “method tableGet”override async tableGet(attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, atUnit?: string, atValue?: string, transactionOpaqueData?: TransactionOpaqueData): Promise<TableInfo | null>method tableScanFunctionGet
Section titled “method tableScanFunctionGet”override async tableScanFunctionGet(attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, atUnit?: string, atValue?: string, transactionOpaqueData?: TransactionOpaqueData): Promise<any>method tableScanBranchesGet
Section titled “method tableScanBranchesGet”override async tableScanBranchesGet(attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, atUnit?: string, atValue?: string, transactionOpaqueData?: TransactionOpaqueData): Promise<any>Return the scan branches for a (possibly multi-source) table. Default
delegates to tableScanFunctionGet and wraps the single result as a
one-branch list, so every single-source catalog is compatible with the
branches-aware C++ extension. Override for genuine multi-source tables.
method tableColumnStatisticsGet
Section titled “method tableColumnStatisticsGet”override async tableColumnStatisticsGet(attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, transactionOpaqueData?: TransactionOpaqueData): Promise<Return serialized column statistics for a table, or null if none are
available. The result is the IPC bytes of a ColumnStatistics RecordBatch
(see src/util/statistics.ts for the schema) wrapped with an optional
cache TTL. Callers typically override this to pull stats from a
descriptor. Returning null signals “no stats” so DuckDB falls back to
the function-level table_function_statistics path.
method viewGet
Section titled “method viewGet”override async viewGet(attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, transactionOpaqueData?: TransactionOpaqueData): Promise<ViewInfo | null>method macroGet
Section titled “method macroGet”override async macroGet(attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, transactionOpaqueData?: TransactionOpaqueData): Promise<MacroInfo | null>method copyFromFormats
Section titled “method copyFromFormats”override async copyFromFormats(attachOpaqueData: AttachOpaqueData, transactionOpaqueData?: TransactionOpaqueData): Promise<CopyFromFormatInfo[]>List custom COPY ... FROM formats advertised by this catalog. Catalog-level
(not schema-scoped). The default returns an empty list, so catalogs that
don’t define COPY formats are unaffected. The VGI extension treats an empty
list (or a not-implemented method) as “no custom formats”. Mirrors
vgi-python’s CatalogInterface.copy_from_formats.
method transactionBegin
Section titled “method transactionBegin”override async transactionBegin(attachOpaqueData: AttachOpaqueData): Promise<Uint8Array | null>method transactionCommit
Section titled “method transactionCommit”override async transactionCommit(attachOpaqueData: AttachOpaqueData, transactionOpaqueData: TransactionOpaqueData): Promise<void>method transactionRollback
Section titled “method transactionRollback”override async transactionRollback(attachOpaqueData: AttachOpaqueData, transactionOpaqueData: TransactionOpaqueData): Promise<void>interface CopyFromFormatInfo
Section titled “interface CopyFromFormatInfo”export interface CopyFromFormatInfoFields
tagsRecord<string, string>Function/format tags.
format_namestringThe
FORMATidentifier users type (single global namespace).handlerstringRegistered name of the worker function that performs the read.
optionsUint8ArraySerialized Arrow schema of the format’s options (same encoding as
FunctionInfo.arguments), each field carrying type /vgi_docdescription.directionstring"from"/"to"/"both"— the COPY direction this format serves.descriptionstringIntrinsic documentation from the handler’s description.
orderedbooleanCOPY … TO only — when true the writer requires rows in source order, so the extension uses a single-threaded sink (
REGULAR_COPY_TO_FILE) instead of the default parallel sharded write. Set viaMeta.sinkOrderDependenton a CopyToFunction; always false for readers. Mirrors vgi-python’sCopyFromFormatInfo.ordered.commentstring | nulloptionalFree-text comment (CopyFromFunction’s
copyFromComment).
function decodeCatalogInfo
Section titled “function decodeCatalogInfo”const decodeCatalogInfo = (b: Uint8Array): CatalogInfo => decodeASD<CatalogInfo>(CatalogInfoSchema, b)function decodeFunctionInfo
Section titled “function decodeFunctionInfo”const decodeFunctionInfo = (b: Uint8Array): FunctionInfo => decodeASD<FunctionInfo>(FunctionInfoSchema, b)function decodeMacroInfo
Section titled “function decodeMacroInfo”const decodeMacroInfo = (b: Uint8Array): MacroInfo => decodeASD<MacroInfo>(MacroInfoSchema, b)function decodeSchemaInfo
Section titled “function decodeSchemaInfo”const decodeSchemaInfo = (b: Uint8Array): SchemaInfo => decodeASD<SchemaInfo>(SchemaInfoSchema, b)function decodeTableInfo
Section titled “function decodeTableInfo”const decodeTableInfo = (b: Uint8Array): TableInfo => decodeASD<TableInfo>(TableInfoSchema, b)function decodeViewInfo
Section titled “function decodeViewInfo”const decodeViewInfo = (b: Uint8Array): ViewInfo => decodeASD<ViewInfo>(ViewInfoSchema, b)type DefaultValue
Section titled “type DefaultValue”export type DefaultValue = string | number | boolean | null;function deserializeAttachOptionSpec
Section titled “function deserializeAttachOptionSpec”export function deserializeAttachOptionSpec(bytes: Uint8Array,): AttachOptionSpecDescription
Deserialize one AttachOptionSpec from the wire format above.
Reads by column name, so a spec written by a peer that predates the
required column deserializes with required: false rather than failing —
the same tolerance the Python and C++ readers have.
function deserializeAttachOptionSpecs
Section titled “function deserializeAttachOptionSpecs”export function deserializeAttachOptionSpecs(specs: Iterable<Uint8Array>,): AttachOptionSpec[]Description
Deserialize many specs — the shape CatalogInfo.attach_option_specs holds.
function encodeCatalogInfo
Section titled “function encodeCatalogInfo”const encodeCatalogInfo = (v: CatalogInfo): Uint8Array => encodeASD(CatalogInfoSchema, v)function encodeCopyFromFormatInfo
Section titled “function encodeCopyFromFormatInfo”const encodeCopyFromFormatInfoDescription
Encode a CopyFromFormatInfo to Arrow IPC bytes (single-row batch).
function encodeFunctionInfo
Section titled “function encodeFunctionInfo”const encodeFunctionInfo = (v: FunctionInfo): Uint8Array => encodeASD(FunctionInfoSchema, v)function encodeMacroInfo
Section titled “function encodeMacroInfo”const encodeMacroInfo = (v: MacroInfo): Uint8Array => encodeASD(MacroInfoSchema, v)function encodeSchemaInfo
Section titled “function encodeSchemaInfo”const encodeSchemaInfo = (v: SchemaInfo): Uint8Array => encodeASD(SchemaInfoSchema, v)function encodeTableInfo
Section titled “function encodeTableInfo”const encodeTableInfo = (v: TableInfo): Uint8Array => encodeASD(TableInfoSchema, v)function encodeViewInfo
Section titled “function encodeViewInfo”const encodeViewInfo = (v: ViewInfo): Uint8Array => encodeASD(ViewInfoSchema, v)interface ForeignKeyDef
Section titled “interface ForeignKeyDef”export interface ForeignKeyDefFields
columnsstring[]referencedTablestringreferencedColumnsstring[]referencedSchemastringoptional
interface FunctionInfo
Section titled “interface FunctionInfo”export interface FunctionInfoFields
tagsRecord<string, string>namestringschema_namestringfunction_typeFunctionTypeargumentsUint8Arrayoutput_schemaUint8ArraydescriptionstringexamplesCatalogExample[]categoriesstring[]supported_expression_filtersstring[]supports_batch_indexbooleanpartition_kindPartitionKindorder_dependentOrderDependencedistinct_dependentDistinctDependencesupports_windowbooleanstreaming_partitionedbooleanhas_finalizebooleansource_order_dependentbooleansink_order_dependentbooleanrequires_input_batch_indexbooleaninput_from_argsbooleanrequired_settingsstring[]required_secretsSecretLookupEntry[]commentstring | nulloptionalstabilityFunctionStability | nulloptionalnull_handlingNullHandling | nulloptionalprojection_pushdownboolean | nulloptionalfilter_pushdownboolean | nulloptionalsampling_pushdownboolean | nulloptionallate_materializationboolean | nulloptionalorder_preservationOrderPreservation | nulloptionalmax_workersnumber | nulloptional
type FunctionInfoOptions
Section titled “type FunctionInfoOptions”export type FunctionInfoOptions = FunctionInfo;Deprecated — Use the FunctionInfo interface (snake_case) directly.
interface MacroDescriptor
Section titled “interface MacroDescriptor”export interface MacroDescriptorFields
namestringmacroType“scalar” | “table”parametersstring[]definitionstringparameterDefaultValuesUint8Array | nulloptionalparameterDocsRecord<string, string>optionalOptional mapping of parameter name to a human/agent-facing description. Keys must appear in
parameters. Descriptions flow over the wire via the macroarguments_schema’svgi_docfield metadata (the same channel functions use for per-argument docs), so the DuckDB extension’svgi_function_arguments()can surface them. Empty/omitted = no docs.commentstringoptionaltagsRecord<string, string>optional
interface MacroInfo
Section titled “interface MacroInfo”export interface MacroInfoFields
tagsRecord<string, string>namestringschema_namestringmacro_typeMacroTypeparametersstring[]definitionstringcommentstring | nulloptionalparameter_default_values/** @record-batch */ Uint8Array | nulloptionalarguments_schema/** @arrow-schema */ Uint8Array | nulloptional
class ReadOnlyCatalogInterface
Section titled “class ReadOnlyCatalogInterface”export class ReadOnlyCatalogInterface extends CatalogInterfaceMethods
method attachOptionSpecs
Section titled “method attachOptionSpecs”attachOptionSpecs(_name: string): AttachOptionSpec[]Attach-time options this catalog declares, for the named catalog.
Empty by default — the declarative descriptor path carries no attach
options. A subclass that advertises specs in catalogsInfo() should
return the same specs here so attach() enforces the required ones it
advertised. Takes the catalog name because one interface may serve
several catalogs with different option sets.
method catalogsInfo
Section titled “method catalogsInfo”override catalogsInfo(): CatalogInfo[]List the catalogs this worker exposes with their version metadata. The
implementation_version / data_version_spec come from the CatalogInfo
returned by the read-only catalogs() signature below — a versioned worker
overrides catalogs() / catalogsInfo() to advertise real values; the
default derives them from the registered descriptor(s).
method attach
Section titled “method attach”attach( name: string, options?: Record<string, unknown>, dataVersionSpec?: string | null, implementationVersion?: string | null,): CatalogAttachResult | Promise<CatalogAttachResult>Attach this catalog. The framework already validates ATTACH options
(name + type) against the specs the worker advertises in
catalogsInfo().attach_option_specs, so options arrives as a
validated, decoded {name: value} dict with typed column values.
Use {} if no options were supplied.
method version
Section titled “method version”version(attachOpaqueData: AttachOpaqueData, transactionOpaqueData?: TransactionOpaqueData): number | Promise<number>method schemas
Section titled “method schemas”schemas(attachOpaqueData: AttachOpaqueData, transactionOpaqueData?: TransactionOpaqueData): SchemaInfo[]method schemaGet
Section titled “method schemaGet”override schemaGet( attachOpaqueData: AttachOpaqueData, name: string, transactionOpaqueData?: TransactionOpaqueData): SchemaInfo | nullmethod schemaContentsTables
Section titled “method schemaContentsTables”override async schemaContentsTables( attachOpaqueData: AttachOpaqueData, name: string, transactionOpaqueData?: TransactionOpaqueData): Promise<TableInfo[]>method tableColumnStatisticsGet
Section titled “method tableColumnStatisticsGet”override tableColumnStatisticsGet( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, transactionOpaqueData?: TransactionOpaqueData,):Return serialized column statistics for a table, or null if none are
available. The result is the IPC bytes of a ColumnStatistics RecordBatch
(see src/util/statistics.ts for the schema) wrapped with an optional
cache TTL. Callers typically override this to pull stats from a
descriptor. Returning null signals “no stats” so DuckDB falls back to
the function-level table_function_statistics path.
method schemaContentsViews
Section titled “method schemaContentsViews”override schemaContentsViews( attachOpaqueData: AttachOpaqueData, name: string, transactionOpaqueData?: TransactionOpaqueData): ViewInfo[]method schemaContentsFunctions
Section titled “method schemaContentsFunctions”override schemaContentsFunctions( attachOpaqueData: AttachOpaqueData, name: string, type: string, transactionOpaqueData?: TransactionOpaqueData): FunctionInfo[]method schemaContentsMacros
Section titled “method schemaContentsMacros”override schemaContentsMacros( attachOpaqueData: AttachOpaqueData, name: string, type: string, transactionOpaqueData?: TransactionOpaqueData): MacroInfo[]method schemaContentsIndexes
Section titled “method schemaContentsIndexes”override schemaContentsIndexes( attachOpaqueData: AttachOpaqueData, name: string, transactionOpaqueData?: TransactionOpaqueData): IndexInfo[]method indexGet
Section titled “method indexGet”override indexGet( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, transactionOpaqueData?: TransactionOpaqueData): IndexInfo | nullmethod macroGet
Section titled “method macroGet”override macroGet( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, transactionOpaqueData?: TransactionOpaqueData): MacroInfo | nullmethod tableScanFunctionGet
Section titled “method tableScanFunctionGet”override tableScanFunctionGet( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, atUnit?: string, atValue?: string, transactionOpaqueData?: TransactionOpaqueData): anymethod tableGet
Section titled “method tableGet”override async tableGet( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, atUnit?: string, atValue?: string, transactionOpaqueData?: TransactionOpaqueData): Promise<TableInfo | null>method viewGet
Section titled “method viewGet”override viewGet( attachOpaqueData: AttachOpaqueData, schemaName: string, name: string, transactionOpaqueData?: TransactionOpaqueData): ViewInfo | nullmethod copyFromFormats
Section titled “method copyFromFormats”override copyFromFormats( attachOpaqueData: AttachOpaqueData, transactionOpaqueData?: TransactionOpaqueData,): CopyFromFormatInfo[]List custom COPY ... FROM formats advertised by this catalog. Catalog-level
(not schema-scoped). The default returns an empty list, so catalogs that
don’t define COPY formats are unaffected. The VGI extension treats an empty
list (or a not-implemented method) as “no custom formats”. Mirrors
vgi-python’s CatalogInterface.copy_from_formats.
interface ScanBranchInput
Section titled “interface ScanBranchInput”export interface ScanBranchInputDescription
One physical source backing a multi-branch scan, in the shape the
buildScanBranchesResult helper consumes. Mirrors vgi-python’s
ScanBranch (catalog_interface.py).
Each scalar argument carries an explicit Arrow type so the nested
arguments batch is built with the wire type the C++ binder expects
(e.g. utf8 for file paths, int64 for counts).
Fields
functionNamestringDuckDB function to call for this branch (e.g. “sequence”, “read_parquet”).
positionalArguments{ value: unknown; type: VgiDataType }[]optionalPositional scalar arguments, each with its Arrow type.
namedArgumentsRecord<string, { value: unknown; type: VgiDataType }>optionalNamed scalar arguments, each with its Arrow type.
branchFilterstring | nulloptionalOptional SQL filter text AND’d into every scan of this branch.
writablebooleanoptionalDeclares this branch as the INSERT target (at most one per table).
sourceCatalogstring | nulloptionalCatalog-table branch (lakehouse federation): leave
functionNameempty and set these to scan the base tablesourceCatalog.sourceSchema.sourceTablein a companion catalog instead of calling a table function.sourceSchemastring | nulloptionalsourceTablestring | nulloptional
interface SchemaDescriptor
Section titled “interface SchemaDescriptor”export interface SchemaDescriptorFields
namestringtablesTableDescriptor[]optionalviewsViewDescriptor[]optionalmacrosMacroDescriptor[]optionalfunctionsVgiFunction[]optionalindexesIndexDescriptor[]optionalcommentstringoptionaltagsRecord<string, string>optional
interface SchemaInfo
Section titled “interface SchemaInfo”export interface SchemaInfoFields
tagsRecord<string, string>attach_opaque_dataUint8Arraynamestringcommentstring | nulloptionalestimated_object_countRecord<string, number> | nulloptional
interface SecretTypeDescriptor
Section titled “interface SecretTypeDescriptor”export interface SecretTypeDescriptorFields
namestringdescriptionstringschemaVgiSchema
function serializeAttachOptionSpec
Section titled “function serializeAttachOptionSpec”export function serializeAttachOptionSpec(spec: AttachOptionSpec): Uint8ArrayDescription
Serialize an AttachOptionSpec to the wire format the extension expects (one IPC-serialized RecordBatch with a single row).
function serializeAttachOptionSpecs
Section titled “function serializeAttachOptionSpecs”export function serializeAttachOptionSpecs(specs: Iterable<AttachOptionSpec>,): Uint8Array[]Description
Convenience: serialize many specs at once for CatalogInfo.attach_option_specs.
interface SettingDescriptor
Section titled “interface SettingDescriptor”export interface SettingDescriptorFields
namestringdescriptionstringtypeVgiDataTypedefaultValuestring | number | bigint | booleanoptionalMust be a JS primitive compatible with
type(string, number, bigint, boolean).
interface TableDescriptor
Section titled “interface TableDescriptor”export interface TableDescriptorFields
namestringcolumnsVgiSchemaoptionalfunctionVgiFunctionoptionalargumentsArgumentsoptionalnotNullstring[]optionaluniquestring[][]optionalcheckstring[]optionalprimaryKeystring[][]optionalforeignKeyForeignKeyDef[]optionaldefaultsRecord<string, DefaultValue>optionalcolumnCommentsRecord<string, string>optionalPer-column comment strings, applied as field metadata
comment.generatedColumnsRecord<string, string>optionalGenerated (virtual) columns: map of column name → SQL expression computed from other physical columns. Applied as Arrow field metadata
generated_expression, which the DuckDB VGI extension reads at table registration. The backing scan function should not return these columns — DuckDB evaluates the expressions client-side.statisticsRecord<string, ColumnStatistics>optionalPer-column statistics for the optimizer. Keys are column names; values are ColumnStatistics records with typed min/max and Arrow type info. DuckDB uses these for plan-time filter elimination and join reordering via the
catalog_table_column_statistics_getRPC.statisticsCacheMaxAgeSecondsnumber | nulloptionalCache TTL for this table’s column statistics. DuckDB caches the result of
catalog_table_column_statistics_getfor up to this many seconds.undefined/null means cache indefinitely;0means never cache (always re-fetch).requiredFiltersstring[][]optionalRequired WHERE-filter groups in conjunctive normal form — an AND (outer list) of OR-groups (inner lists) of dotted-path column references that MUST appear in a WHERE expression for any scan of this table. A group is satisfied when any one of its paths has a filter; every group must be satisfied. So
[["accession_number"], ["ticker", "cik"]]means “accession_number AND one of (ticker, cik)”; a single-path group[["country"]]is a plain mandatory filter. Paths are top-level names ("country") or struct subfields ("bbox.xmin","nested.outer.inner"). Empty/undefined (default) means no enforcement — the zero-cost fast path for every existing table.Satisfaction is prefix-based: a present filter on a shorter path satisfies any required path it is a prefix of. So a whole-struct filter on
bboxsatisfies all ofbbox.xmin/.xmax/.ymin/.ymax. The VGI DuckDB extension’s optimizer pass consults this at bind time and throws aBinderExceptionlisting any unsatisfied groups.supportsTimeTravelbooleanoptionalinlinedCardinality{ estimate: bigint; max: bigint }optionalInline cardinality estimate/max surfaced through TableInfo. When set, the C++ extension uses these directly and skips the per-bind table_function_cardinality RPC. Only meaningful for function-backed tables; static-column tables don’t have a function to call.
commentstringoptionaltagsRecord<string, string>optional
interface TableInfo
Section titled “interface TableInfo”export interface TableInfoFields
tagsRecord<string, string>namestringschema_namestringcolumnsUint8Arraynot_null_constraintsnumber[]unique_constraintsnumber[][]check_constraintsstring[]primary_key_constraintsnumber[][]foreign_key_constraintsUint8Array[]supports_insertbooleansupports_updatebooleansupports_deletebooleansupports_returningbooleansupports_column_statisticsbooleanrequired_filtersstring[][]commentstring | nulloptionalscan_functionUint8Array | nulloptionalinsert_functionUint8Array | nulloptionalupdate_functionUint8Array | nulloptionaldelete_functionUint8Array | nulloptionalcardinality_estimatenumber | nulloptionalcardinality_maxnumber | nulloptionalcolumn_statisticsUint8Array | nulloptionalbind_resultUint8Array | nulloptional
type TransactionOpaqueData
Section titled “type TransactionOpaqueData”export type TransactionOpaqueData = Uint8Array;interface ViewDescriptor
Section titled “interface ViewDescriptor”export interface ViewDescriptorFields
namestringdefinitionstringcommentstringoptionalcolumnCommentsRecord<string, string>optionalPer-column comments keyed by the view’s output column name. Unlike tables (whose column comments ride along as Arrow field metadata), a view ships only its SQL
definition, so column comments need their own channel. The C++ extension aligns these by name against the bound output columns and feeds them intoCreateViewInfo.column_comments_map; names that don’t match a bound column are ignored.tagsRecord<string, string>optional
interface ViewInfo
Section titled “interface ViewInfo”export interface ViewInfoFields
tagsRecord<string, string>namestringschema_namestringdefinitionstringcolumn_commentsRecord<string, string>commentstring | nulloptional