VKL Language Reference
VKL (the Veezoo Knowledge Language) is the modelling language for a Veezoo knowledge graph - the semantic model Veezoo uses to understand a question and generate the SQL that answers it. A knowledge graph is a set of .vkl files.
This page documents VKL's syntax and the concepts shared across the language. For the specific constructs you model - classes, entities, relationships, charts, and so on - see the other pages in this section.
Statements and blocks
A .vkl file is a sequence of statements. A statement is one of:
- a declaration - an optional type keyword, an identifier, and a block, e.g.
class Order { ... }declares the classOrder, while a barekb { ... }opens thekbnamespace; - a property assignment -
name: value, one per line; - an import - see Imports.
Blocks nest to build the graph, and a dotted declaration is shorthand for nesting - kb.Order { ... } means kb { Order { ... } }:
kb {
class Order {
name.en: "Order"
}
}
Statements are separated by a newline or a semicolon (;); properties take no commas between them.
Identifiers
Identifiers name resources (classes, attributes, relationships, etc.) and are split into segments by dots, e.g. kb.Order.Amount.
An unquoted identifier may not start with a digit or -, and may not contain whitespace, dots, or the special characters used by VKL syntax ({ } [ ] ( ) = , # : ; " \ @ and the backtick). Wrap an identifier in backticks to use a name that is otherwise valid but starts with a digit (or -) or clashes with a reserved keyword (import, true, false):
class `2024_Revenue` {
name.en: "2024 Revenue"
}
Backticks only relax the leading-digit/- and keyword rules; the name between them must still consist solely of identifier characters (no whitespace, dots, or special characters).
Namespaces
The first segment of an identifier is a namespace prefix identifying the layer the resource lives in:
kb- the knowledge base (classes, attributes, relationships, ...)db- the database (tables and columns)onto- the shared ontologymeta- the Veezoo meta-schemacb- computations
For example kb.Order or db.postgres.movie_db.public.CUSTOMER.
Built-ins - the meta-schema types (class, entity, measure, ...), computations, and similar - are referenced by their short name, e.g. tag: measure. Their explicit form is vkl.<name> (for example vkl.measure); you only need it when the short name is shadowed by another name in scope. Referencing vkl.<name> for something that is not a built-in is an error.
Two namespaces are reserved:
vkl- the built-in namespace described above; you cannot define your own resources in it.veezoo- reserved for Veezoo-managed system variables such asveezoo.Tenant.Id. Avoid defining your own resources under it.
Values
A property value is either a reference to another resource or a literal. The two are distinguished syntactically, so the same property can take either with no ambiguity.
References
An unquoted value is a reference to another resource: tag: measure, to: kb.Language. See Namespaces for how a reference resolves.
Strings
A quoted value is a string literal. VKL has single-line and multi-line strings.
Single-line strings are enclosed in double quotes and use standard backslash escapes (\n, \t, \", \\, \uXXXX), e.g. name.en: "Order".
Multi-line strings are enclosed in triple quotes and behave like Java text blocks, with one deviation (the trailing newline, below). The canonical form places the quotes on their own lines, with the content aligned one indentation level in:
description:
"""
first line
second line
"""
The opening """ must be on its own line - content may not start on the opening line - and the line break right after it is not part of the value. Incidental whitespace is then removed: the common indentation shared by all lines - the left margin is the smallest indentation among the content lines and the closing """, so content indented further than the margin keeps the extra indentation - and trailing whitespace from each line.
Unlike Java text blocks, a closing """ on its own line is not part of the value, so the example above is exactly "first line\nsecond line" (no trailing newline). To add a trailing newline, leave a blank line before the closing """. Use \s to keep a trailing space or a whitespace-only line, and \" for a quote that would otherwise form the closing triple quote.
Numbers, booleans, and lists
- numbers -
42(integer) and1.5(decimal); - booleans -
trueandfalse; - lists -
["a", "b", "c"](for most properties the elements are an unordered set, so order and duplicates are not preserved).
Typed literals
Typed literals are written as a constructor call, e.g. date("2024-01-01"). The available constructors are date, number, periodicity, and xsd.decimal.
Anonymous objects
A value can itself be a block - an anonymous, inline resource - used by properties that nest further structure:
default_filter: {
...
}
Comments
Comments start with # or // and run to the end of the line. They may be on their own line or follow a statement:
# A standalone comment
class Order {
name.en: "Order" // a trailing comment
}
Imports
The import statement references database tables that can then be used within the kb block. Unused imports are removed automatically on save, so always include the matching usage in the same edit.
import db.postgres.movie_db.public.CUSTOMER
kb {
class Customer {
name.en: "Customer"
from_table: CUSTOMER
sql: "${CUSTOMER.id}"
}
}