Extension Model
The provided languages are built on the same public extension points that are available to you, so you can add behavior at every level, from a single function to an entire language, without forking the engine.
| You want to add... | Do this | Guide |
|---|---|---|
| a function, operator, aggregate, or cast | bundle it as an extension | Functions & Aggregates |
| a way to read a differently-shaped source | write a data adapter | Data Adapters |
| a specialized access structure | write an index type | Custom Index Types |
| a plan rewrite | write an optimizer rule | Optimizer Rules |
| a whole query language | write a language plug-in | Authoring a Language |
Bundle it as an extension
The lightest extension point is an
Extension: a
bundle of operators, functions, aggregates, and castables that you pass to the
engine.
new DortDB({
mainLang: SQL(),
optimizer: { rules: defaultRules },
extensions: [datetime, myExtension],
});
Two optional fields shape what the bundle contributes:
scope
limits it to specific languages (for aggregates that only make sense in Cypher,
say), and
schema
namespaces every member under a prefix. Note that only some languages support
user-defined operators, SQL among them.
Adding to the algebra
The deeper extension points, new index types, new optimizer rules, and new languages, often involve new plan operators. Because the core dispatches plan traversal through per-language visitors, a new operator can be introduced entirely inside your own package: you implement the visitor methods for it and the core stays untouched.
The catch is that every pass over the plan must know about your operator. Plan Visitors lists those passes and what each one needs from you; the formal description of the operators themselves is in the Formalism section.