Skip to content

AI Quality Constraints

Data QualityAnomaly DetectionDDL
Beta Works · surface still evolving · usable surface, not yet in the stable configuration matrix

A plain CHECK constraint can only express static rules like salary > 0. It can’t say “this value looks suspicious given the last six months of data.” AI Quality Constraints fill that gap. You attach an AI_CHECK rule to a table; on ingest, each incoming row is scored against a learned model of the column’s own history. Rows that look like outliers are diverted into a quarantine table instead of corrupting your analytics.

The scoring model is lightweight (for example a streaming percentile sketch) — there’s no separate ML service to operate and no external feature store. You write the rule in SQL and the engine maintains the model.

flowchart LR
  classDef src fill:#1f2640,stroke:#9ca3af,color:#e8eaf0
  classDef chk fill:#1f2640,stroke:#7c5cff,color:#e8eaf0
  classDef ok  fill:#1f2640,stroke:#4ade80,color:#4ade80
  classDef dl  fill:#1f2640,stroke:#f87171,color:#f87171

  IN[Incoming rows]:::src
  AI[AI_CHECK<br/>score vs learned history]:::chk

  IN --> AI
  AI -->|normal| TGT[Target table]:::ok
  AI -->|anomalous| DLT[Dead-letter table]:::dl

Static CHECK constraints catch the impossible (salary > 0); they can’t catch the suspicious — a value that’s individually legal but wrong given the column’s recent history. AI_CHECK closes that gap at the door: dubious rows are diverted to quarantine instead of quietly skewing every downstream aggregate, and you declare the rule in SQL with no ML service to run.

  • Catches what CHECK can’t — outliers judged against the column’s own learned history, not a fixed threshold.
  • Quarantine, not corruption — suspect rows go to a side table you can review, rather than into your analytics.
  • No ML stack — the model is maintained by the engine; there’s no feature store or scoring service to operate.

Scoring uses a lightweight streaming sketch (e.g. a running percentile), so it runs inline at ingest with negligible overhead — you’re not paying a model-serving round trip on every insert.

Attach an AI_CHECK constraint to a numeric column. The engine builds and maintains the model automatically; you only declare the rule and where rejected rows go.

ALTER TABLE usage
ADD CONSTRAINT ck_traffic_anomaly
AI_CHECK (is_anomaly(traffic_volume) = FALSE)
WITH (
model = 'tdigest', -- 'tdigest' | 'isolation_forest' | 'zscore'
sensitivity = 0.995, -- reject above the 99.5th percentile of weirdness
DEAD LETTER usage_quarantine
);

The quarantine table is created automatically with extra columns describing why each row was rejected:

SELECT * FROM usage_quarantine LIMIT 5;
-- id | traffic_volume | observed_at | rejection_score | rejection_reason

Re-admitting a reviewed row is just an ordinary insert — no special “force ingest” command:

INSERT INTO usage SELECT * FROM usage_quarantine WHERE id = 12345;
DELETE FROM usage_quarantine WHERE id = 12345;
ConceptWhat it means
AI_CHECKA constraint that scores a row against a model during ingest validation.
SensitivityA 0–1 dial controlling how aggressive the rejection threshold is.
Dead-letter tableThe quarantine table holding rejected rows with their score and reason.