dsl

package
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 22, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package dsl implements the v1 named-query DSL of the graph-backend adapter contract (graph-backend-adapter-contract §5). It is the only query interface for adapter named queries, materialized views, and impact-radius operations.

The package has two halves:

  • Parse + validate (parser.go, lexer.go, validate.go): turn a DSL string into a typed *Query AST, rejecting every forbidden construct (§5.2) at parse/load time. The conformance catalog (§5.5, tests T1–T39) is the normative behavior; see dsl_conformance_test.go.
  • Evaluate (eval.go): run a parsed *Query against an sdk.NamespaceView (the notes+edges of one adapter namespace) and produce result rows. This is what makes the hand-written dogfood runners (the t3 #168 SDK Query stand-ins) expressible declaratively.

Schema-aware validation (ref depth cap §5.4.1, untyped-ref rejection, derivation flags §7.3, variable-length bound against max_depth) keys off a SchemaInfo the caller supplies (compiled from a registry.Schema). The DSL package never imports the registry, so it stays a leaf the registry, SDK, and adapters can all depend on.

Index

Constants

View Source
const (
	KindTimeAfter = "time_after"
	KindWebhook   = "webhook"
)

Predicate kind constants (§7.2).

Variables

This section is empty.

Functions

func ApplyEnvTrigger

func ApplyEnvTrigger(preds []EnvPredicate, notes []sdk.Note, trig EnvTrigger) ([]sdk.Note, error)

ApplyEnvTrigger evaluates a fired trigger against the declared predicates and returns the notes that should be tagged stale, each carrying the §7.3 structured stale payload `{ reason: "environmental", because, fired_at }`. It does not mutate the store — the caller (a bootstrap skill via the SDK, or the scoped-KG driver bus in production) persists the tagged notes. This keeps the env-predicate logic a pure function the conformance tests pin directly.

func Eval

func Eval(q *Query, view sdk.NamespaceView, params map[string]any) ([]sdk.Row, error)

Eval executes a parsed query against one namespace's notes+edges and the caller's params, producing result rows. This is the runtime that makes the hand-written dogfood runners (the t3 #168 SDK Query stand-ins) expressible declaratively: a compiled *Query plus an sdk.NamespaceView yields the same rows the bespoke Go runners did.

Eval implements the v1 semantics the conformance catalog pins: ref-join resolution (§5.4.1), OPTIONAL+WHERE lowering (§5.4.2), variable-length BFS with hop_count (§5.1), and the stale-tag selectors (§7.3). It operates over the in-memory NamespaceView the SDK hands a query runner, so it needs no SQL backend — the lowering rules are honored by construction, not by emitting SQL. Eval returns (rows, error). The in-memory evaluator's execution is total — every query was schema-validated at parse, so evaluation never fails — but the error return is retained as the stable contract a future storage-backed executor (§2.7) needs without re-touching every caller.

Types

type EdgeInfo

type EdgeInfo struct {
	From       string
	To         string
	Derivation bool
}

EdgeInfo is one edge type's endpoint metadata.

type EdgePattern

type EdgePattern struct {
	Alias  string
	Type   string
	VarMin int
	VarMax int
}

EdgePattern is the `-[alias?:type]->` segment of a MATCH (§5.1). VarMin/ VarMax model the variable-length form `[:type*min..max]`; when VarMax is 0 the pattern is a single fixed hop.

func (EdgePattern) IsVarLength

func (e EdgePattern) IsVarLength() bool

IsVarLength reports whether the edge is a variable-length pattern `*min..max`.

type EdgeTypeDecl

type EdgeTypeDecl struct {
	Name       string
	From       string
	To         string
	Derivation bool
}

EdgeTypeDecl is the declarative form of an edge type (§4).

type EnvPredicate

type EnvPredicate struct {
	// NoteType is the note type the predicate is declared on.
	NoteType string
	// Kind is one of time_after | webhook | module_version | custom (§7.2).
	Kind string
	// Field is the date field a time_after predicate observes.
	Field string
	// Endpoint is the webhook predicate's endpoint name.
	Endpoint string
}

EnvPredicate is a declared environmental-driver predicate on a note type (§7.1, §7.2). When an external trigger fires, matching notes are tagged `stale: { reason: "environmental" }`. v1 supports the time_after and webhook kinds; module_version and custom are declared-but-deferred.

type EnvTrigger

type EnvTrigger struct {
	// Kind selects which predicates fire (time_after | webhook).
	Kind string
	// Now is the clock observation a time_after trigger compares against. A
	// note is tagged when its predicate field is a date <= Now.
	Now time.Time
	// Endpoint is the webhook endpoint that fired (webhook kind). All notes
	// whose webhook predicate names this endpoint are tagged.
	Endpoint string
	// Targets optionally restricts the fire to specific note ids. When empty,
	// every note whose predicate matches the trigger is tagged; when set, only
	// the listed notes are tagged (a webhook fired for one policy, say). This
	// models the §8.4.1 declare_predicate_fired arg surface where a receiver
	// fires for a specific resource.
	Targets []string
	// TriggerID is recorded in the stale tag's `because` provenance list.
	TriggerID string
}

EnvTrigger is one fired environmental observation: a clock crossing (time_after) or a webhook POST. It is the input to ApplyEnvTrigger, which tags matching notes stale.

type FieldDecl

type FieldDecl struct {
	Name       string
	Type       string
	Derivation bool
}

FieldDecl is one field declaration (§4). For a `ref<type>` field, Type is the raw declaration text (e.g. "ref<policy>") which NewSchemaInfo parses into a RefType.

type FieldInfo

type FieldInfo struct {
	Type       string
	RefType    string
	Derivation bool
}

FieldInfo is one field's type metadata. RefType is the target note type for a `ref<type>` field (empty for scalar fields). Derivation mirrors the §7.3 flag on ref fields.

func (FieldInfo) IsRef

func (f FieldInfo) IsRef() bool

IsRef reports whether the field is a typed ref.

type FieldRef

type FieldRef struct {
	Alias string
	// Path is the field/ref selectors after the alias, in order. For
	// `c.stated_location.region` this is ["stated_location", "region"].
	Path []string
}

FieldRef is a chained field access `alias.part.part...` (§5.4 ref-joins). Path[0] is always a bound alias; subsequent parts are ref-field hops ending in a scalar field or a structured `stale.<sub>` selector (§7.3).

func (FieldRef) IsBareAlias

func (f FieldRef) IsBareAlias() bool

IsBareAlias reports whether the ref is just `alias` with no field path (a bare ref id read, §5.4.1 rule 1).

type FuncCall

type FuncCall struct {
	Name string
	Args []ValueExpr
}

FuncCall is an allowed-function application (§5.1.1). Args are themselves ValueExprs so coalesce can nest params and literals.

type MatchClause

type MatchClause struct {
	Optional bool
	// Nodes are the node patterns in the clause: one (bare node) or two
	// (an edge hop a-[..]->b).
	Nodes []NodePattern
	// Edge is the edge pattern joining Nodes[0]→Nodes[1] when len(Nodes)==2;
	// nil for a bare single-node MATCH.
	Edge *EdgePattern
}

MatchClause is one MATCH or OPTIONAL MATCH (§5.1). v1 supports a single node pattern or a single edge hop between two node patterns; the optional flag carries left-join semantics.

type NodePattern

type NodePattern struct {
	Alias string
	Type  string
}

NodePattern is `(alias:type)` (§5.1). Alias may be empty only for an anonymous end node, but v1 requires aliases for returned/filtered nodes.

type NoteTypeDecl

type NoteTypeDecl struct {
	Name   string
	Fields []FieldDecl
}

NoteTypeDecl is the declarative form of a note type used to build a SchemaInfo (§4). It mirrors the registry's NoteType without importing it, so the dsl package stays a leaf. Fields lists the note's fields in declaration order.

type Predicate

type Predicate struct {
	// Op is the comparison operator, one of the closed §5.1 set
	// {=, !=, <, <=, >, >=, IN} or the STARTS_WITH function form.
	Op string
	// Left is the field reference (alias + ref/field path) the predicate
	// filters on.
	Left FieldRef
	// Right is the value expression compared against Left.
	Right ValueExpr
	// Func names a WHERE-side function wrapping the whole predicate
	// (STARTS_WITH). Empty for a plain comparison.
	Func string
}

Predicate is one WHERE comparison (§5.1). The left side is always a field reference on a bound alias (possibly through a ref chain); the right side is a parameter, literal, or allowed-function call on params/literals (§5.1.1).

type Query

type Query struct {
	// Matches are the MATCH / OPTIONAL MATCH clauses in source order. The
	// first match binds the driving alias.
	Matches []MatchClause
	// Where are the conjuncted WHERE predicates (an empty slice means no
	// filter). v1 has no OR; predicates AND together.
	Where []Predicate
	// Returns are the RETURN items in source order.
	Returns []ReturnItem
	// contains filtered or unexported fields
}

Query is the parsed, validated form of a DSL string (§5). It is produced once at adapter load (Parse / ParseWithSchema) and reused for every invocation; the AST carries everything Eval needs, so no re-parse happens per call (§5.3).

func Parse

func Parse(src string) (*Query, error)

Parse turns a DSL string into a validated *Query without schema-aware checks (ref depth cap, untyped-ref rejection, max_depth bound). Use ParseWithSchema when an adapter SchemaInfo is available so the §5.4 / §7.3 schema rules also run. Parse alone enforces every grammar-level rule (§5.1, §5.2).

func ParseWithSchema

func ParseWithSchema(src string, info SchemaInfo) (*Query, error)

ParseWithSchema parses a DSL string and then runs the schema-aware checks (§5.4 ref-join rules, §5.1 variable-length bound, edge-intrinsic restriction, untyped-ref rejection). Grammar-level rejections (§5.2) happen in Parse; this adds the rules that need the adapter schema to evaluate.

type ReturnItem

type ReturnItem struct {
	// Ref is the field reference when the item is a plain projection; its
	// Alias is empty when the item is a pure intrinsic (hop_count/count).
	Ref FieldRef
	// Func is the aggregate/intrinsic function name (count, min, max,
	// hop_count, coalesce) or empty for a plain field projection.
	Func string
	// FuncArgs are the arguments to Func (e.g. min(c.field) has one ref arg).
	FuncArgs []ReturnItem
	// Alias is the output column name. Defaults to the source text when the
	// query omits an explicit AS.
	Alias string
}

ReturnItem is one RETURN element (§5.1): a field ref, an aggregate/intrinsic (count(*), hop_count, min/max, coalesce), or an edge intrinsic (e.id/e.kind).

type SchemaInfo

type SchemaInfo struct {
	// NoteFields maps note-type → field name → field metadata.
	NoteFields map[string]map[string]FieldInfo
	// Edges maps edge-type → endpoints/derivation metadata.
	Edges map[string]EdgeInfo
	// MaxDepth bounds variable-length edge patterns (§4 / §5.1). A query whose
	// `*1..N` exceeds MaxDepth is rejected (T37). Zero means "unset" and the
	// check is skipped (Parse without a declared bound).
	MaxDepth int
}

SchemaInfo is the slice of an adapter schema (§4) the DSL needs for schema-aware validation and ref resolution. The caller compiles it from a registry.Schema (see NewSchemaInfo) so the dsl package never imports the registry — it stays a leaf dependency.

func NewSchemaInfo

func NewSchemaInfo(notes []NoteTypeDecl, edges []EdgeTypeDecl, maxDepth int) (SchemaInfo, error)

NewSchemaInfo compiles a SchemaInfo from declarative note/edge declarations, parsing `ref<type>` field types into typed refs and rejecting the untyped `ref` form (§5.4, T11). maxDepth bounds variable-length patterns (§5.1).

type ValueExpr

type ValueExpr struct {
	// Param is the parameter name (without the leading $) when this is a param
	// reference.
	Param string
	// Literal holds a string/number/bool literal value.
	Literal any
	// IsLiteral disambiguates a nil/zero Literal from "not a literal".
	IsLiteral bool
	// Call is a coalesce(...) call over params/literals (the only WHERE-side
	// allowed function on the value side, §5.1.1). nil when not a call.
	Call *FuncCall
}

ValueExpr is the right-hand side of a predicate: a param ($x), a literal, or an allowed-function call on params/literals (§5.1.1). Exactly one of Param, Literal, or Call is set.

Directories

Path Synopsis
Package crossnamespace executes a cross-adapter materialized view: a single v1 DSL query (internal/kg/dsl) that joins a consumer adapter's namespace with one or more reads_from dependency namespaces (graph-backend-adapter-contract §8.3).
Package crossnamespace executes a cross-adapter materialized view: a single v1 DSL query (internal/kg/dsl) that joins a consumer adapter's namespace with one or more reads_from dependency namespaces (graph-backend-adapter-contract §8.3).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL