Saltar al contingut

La superfície de query (OSL-SQL)

POST /osl/query és l’únic endpoint de consum. L’analítica estructurada, les mètriques, el retrieval vectorial governat i la travessa de grafs s’expressen tots aquí — no aprens cinc superfícies per llegir un domini.

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

El body és una de tres formes mútuament excloents (barrejar-les és 400 E0513); totes tres passen per la mateixa junta governada i comparteixen un request_id:

Body Què és
{ "osql": "…" } OSL-SQL — el dialecte SQL semàntic (la superfície canònica)
{ "sql": "…" } Un SELECT de només lectura sobre l’allowlist del tenant (el slice SQL)
{ "metrics": […], "group_by": […], … } Query de mètriques a l’estil MetricFlow

osql és un dialecte SQL semàntic. Anomena només objectes semàntics — osl.entities.<model> i columnes declarades, o les funcions de taula RETRIEVE(...) / TRAVERSE(...). Mai anomena una taula física ni una columna crua.

El motor parseja osql (via sqlglot, dialecte trino) i el baixa a una IR d’operadors tancada — l’escala determinista sobre la qual aplica el model de governança. El lowering és total i default-deny: qualsevol construcció que no baixi a un node d’IR conegut es refusa.

lower() classifica cada query en exactament una forma i valida la seva gramàtica:

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

Baixa a to_trino() → la junta SQL governada. Els joins entre entitats estructurades només s’admeten com un equijoin de clau segellada (vegeu més avall).

L’únic node cross-relacional és un equijoin l’ON del qual és una igualtat escalar sobre una clau d’entitat segellada (les entity_key_columns del model, o el camp scalar_indexed d’una faceta) a totes dues potes. Qualsevol altre JOIN … ON400 E0514.

No hi ha cap sintaxi que passi un segon argument relacional a un operador de similitud o LLM — un join semàntic relació×relació en temps de query (el no-objectiu R3) és una propietat estructural de la gramàtica, no una blocklist a mantenir.

X JOIN RETRIEVE(...) ON X.k = R.k no és un join relacional de dues taules físiques. S’executa així:

  1. RETRIEVE (governat) → passatges, cadascun portant la seva clau desnormalitzada.
  2. Porta en clar → els valors de clau, o refusa (403 E0515).
  3. Prefiltre estructurat: … WHERE k IN (<keys>)to_trino → SQL governat (la llista IN es construeix amb la conversió de literals de sqlglot — segura contra injecció).
  4. Hash join in-cell sobre la clau segellada, projectant les columnes de cada pota.

A la forma RETRIEVE, <op>(col) al SELECT és un operador de projecció (RFC 0004). Són mapes unaris — mai un join.

Classe Operadors Corre sobre Si falta
Encoder (determinista) SIMILARITY, CLASSIFY, TAG, RANK, DEDUP, OUTLIER, CLUSTER Embeddings ja presents al chunk
Decoder (inferència) requereix LLM EXTRACT, SUMMARIZE, SCORE, GENERATE, COMPLETE Un backend LLM 503 E0521

{ "sql": "<SELECT>" } és un SELECT de només lectura validat contra l’allowlist del tenant amb el punt d’aplicació de polítiques aplicat (row filters + projection des de l’snapshot compost). { "metrics": …, "group_by": … } segueix la semàntica de MetricFlow. Tots dos comparteixen la mateixa junta governada que osql.

Codi Significat
200 Èxit
400 Malformat / fora de gramàtica (E0511), objecte no declarat (E0512), el body barreja formes (E0513), JOIN sense clau segellada (E0514), sql buit (E0246)
403 Deny de la PDP (E2101/E2102), clau cross-modal no en clar (E0515), objecte fora de l’allowlist (E0512)
422 Vàlid però no resoluble — p. ex. MetricFlow encara no implementat (E1001)
503 Falta l’snapshot de la PDP (E2001, fail-closed), op decoder sense backend LLM (E0521)
502 Fallada d’execució de Trino (E0510)

Vegeu Errors i codis d’estat per a l’envelope complet.