Skip to main content

Extension Model

Extensibility is a core goal of DortDB: the provided languages are built on the same public extension points that are available to you. You can add behavior at several levels, from a single function to an entire language, without forking the engine.

You want to add...Do thisGuide
a function, operator, aggregate, or castbundle it as an extensionFunctions & Aggregates
a way to read a differently-shaped sourcewrite a data adapterData Sources & Adapters
a specialized access structurewrite an index typeCustom Index Types
a plan rewritewrite an optimizer ruleOptimizer Rules
a whole query languagewrite a language plug-inAuthoring a Language

Extensions

The lightest extension point is an extension: a bundle of operators, functions, aggregates, and castables that you register on the engine.

interface Extension {
schema?: string; // name prefix applied to everything in the bundle
operators?: Operator[];
functions?: Fn[];
aggregates?: AggregateFn[];
castables?: Castable[];
scope?: string[]; // limit the bundle to specific languages
}

You pass extensions when constructing the engine:

new DortDB({
mainLang: SQL(),
optimizer: { rules: defaultRules },
extensions: [datetime, myExtension],
});

Use scope to make a bundle available only to certain languages (e.g. aggregates that only make sense in Cypher), and schema to namespace its members. Note that only some languages support user-defined operators, SQL among them.

Extending the algebra

The deeper extension points (new index types, new optimizer rules, and new languages) often involve new plan operators. The core processes plans with an extended visitor pattern: a plan operator's accept() takes a dictionary of visitors keyed by language, and each operator is dispatched to the visitor of the language that instantiated it. A language implements the full visitor interface, typically by subclassing the core visitor and overriding only its own operators, which is what lets the algebra grow without changes to the core. See Plan Visitors for the passes a language must handle. The formal description of the operators lives in the Formalism section.