Zum Inhalt springen

Die Query-Oberfläche (OSL-SQL)

POST /osl/query ist der einzige Konsum-Endpoint. Strukturierte Analytik, Metriken, gesteuertes Vektor-Retrieval und Graph-Traversierung werden alle hier ausgedrückt — du lernst nicht fünf Oberflächen, um eine Domain zu lesen.

POST /osl/query
Authorization: Bearer <jwt> # attested delegation chain, see Authentication
Content-Type: application/json

Der Body ist eine von drei wechselseitig ausschließenden Formen (sie zu mischen ist 400 E0513); alle drei laufen durch dieselbe gesteuerte Naht und teilen sich eine request_id:

Body Was es ist
{ "osql": "…" } OSL-SQL — der semantische SQL-Dialekt (die kanonische Oberfläche)
{ "sql": "…" } Ein rohes read-only SELECT über die Allowlist des Tenants (der SQL-Slice)
{ "metrics": […], "group_by": […], … } MetricFlow-artige Metrik-Query

osql ist ein semantischer SQL-Dialekt. Er benennt nur semantische Objekte — osl.entities.<model> und deklarierte Spalten oder die Table-Functions RETRIEVE(...) / TRAVERSE(...). Er benennt niemals eine physische Tabelle oder eine rohe Spalte.

Die Engine parst osql (via sqlglot, trino-Dialekt) und senkt es zu einem geschlossenen Operator-IR ab — die deterministische Leiter, über die das Governance-Modell durchsetzt. Das Lowering ist total und default-deny: Jedes Konstrukt, das nicht zu einem bekannten IR-Knoten absenkt, wird abgelehnt.

lower() klassifiziert jede Query in genau eine Form und validiert ihre Grammatik:

SELECT segment, COUNT(*) AS n
FROM osl.entities.Customer
WHERE country IN ('ES','FR','DE')
GROUP BY segment
ORDER BY n DESC
LIMIT 100

Senkt zu to_trino() ab → die gesteuerte SQL-Naht. Joins zwischen strukturierten Entities sind nur als Equijoin auf versiegeltem Schlüssel erlaubt (siehe unten).

Der einzige cross-relationale Knoten ist ein Equijoin, dessen ON eine skalare Gleichheit auf einem versiegelten Entity-Schlüssel ist (die entity_key_columns des Modells oder das scalar_indexed-Feld einer Facette) auf beiden Beinen. Jedes andere JOIN … ON400 E0514.

Es gibt keine Syntax, die einem Ähnlichkeits- oder LLM-Operator ein zweites relationales Argument übergibt — ein relation×relation-semantischer Join zur Query-Zeit (das Nicht-Ziel R3) ist eine strukturelle Eigenschaft der Grammatik, keine zu pflegende Blocklist.

X JOIN RETRIEVE(...) ON X.k = R.k ist kein relationaler Join zweier physischer Tabellen. Er läuft als:

  1. RETRIEVE (gesteuert) → Passagen, jede trägt ihren denormalisierten Schlüssel.
  2. Klartext-Gate → die Schlüsselwerte, oder Ablehnung (403 E0515).
  3. Strukturierter Prefilter: … WHERE k IN (<keys>)to_trino → gesteuertes SQL (die IN-Liste wird mit sqlglot-Literal-Konvertierung gebaut — injection-sicher).
  4. In-Cell-Hash-Join auf dem versiegelten Schlüssel, projiziert die Spalten jedes Beins.

In der RETRIEVE-Form ist <op>(col) im SELECT ein Projektionsoperator (RFC 0004). Sie sind unäre Abbildungen — niemals ein Join.

Klasse Operatoren Läuft Falls fehlend
Encoder (deterministisch) SIMILARITY, CLASSIFY, TAG, RANK, DEDUP, OUTLIER, CLUSTER Auf Embeddings, die bereits im Chunk sind
Decoder (Inferenz) braucht LLM EXTRACT, SUMMARIZE, SCORE, GENERATE, COMPLETE Ein LLM-Backend 503 E0521

{ "sql": "<SELECT>" } ist ein read-only SELECT, validiert gegen die Allowlist des Tenants, mit angewandtem Policy Enforcement Point (Zeilenfilter + Projektion aus dem komponierten Snapshot). { "metrics": …, "group_by": … } folgt der MetricFlow-Semantik. Beide teilen sich dieselbe gesteuerte Naht wie osql.

Code Bedeutung
200 Erfolg
400 Fehlerhaft / außerhalb der Grammatik (E0511), nicht-deklariertes Objekt (E0512), Body mischt Formen (E0513), JOIN nicht auf versiegeltem Schlüssel (E0514), leeres sql (E0246)
403 PDP-Deny (E2101/E2102), cross-modaler Schlüssel nicht Klartext (E0515), Objekt außerhalb der Allowlist (E0512)
422 Gültig, aber nicht auflösbar — z. B. MetricFlow noch nicht implementiert (E1001)
503 PDP-Snapshot fehlt (E2001, fail-closed), Decoder-Op ohne LLM-Backend (E0521)
502 Trino-Ausführungsfehler (E0510)

Siehe Fehler & Statuscodes für das vollständige Envelope.