You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Shared-scan graph projection: one scan per contract, declarative rule predicates (LLP 0095/0096) (#291)
* Shared-scan graph projection: one scan per contract, declarative predicates (LLP 0095/0096)
projectGraph ran every contract rule as an independent full SQL scan with
refresh:'always', and the LLP 0026 aux filter prepended `attributes` to each
rule and JSON-parsed it per rule per row. At 25 rules that meant 25 full
table sweeps per projection: ~35GB read and 45+ minutes for a ~1.3GB source
on a production hypaware-server deployment (LLP 0095).
- project.js: one shared scan per contract over the union of declarative
rules' columns; per-rule where predicates (eq/in/likePrefix, SQL null
semantics) evaluated in JS; raw-SQL rules stay supported, run standalone,
grouped by identical SQL text.
- Contract gains rowFilter, evaluated once per row on both paths; the
ai-gateway contract's aux filter moves there.
- ai-gateway-graph: 21 of 25 rules migrated to columns/where; the two
content_text prefix surfaces (x node+edge) stay raw SQL so the table's
largest column keeps its server-side pushdown.
- Registry validates the new shapes; equivalence test pins the JS evaluator
to the SQL engine's semantics over a fixture hitting every predicate.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Harden raw-rule column guard + cover likePrefix + @import types (neutral review, PR #291)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
// (project.js) and routes by `kind`, so a connector typo would otherwise
53
+
// surface as a confusing mid-projection failure (or silently route rows
54
+
// into the wrong target map) far from the contract that caused it.
55
+
// @ref LLP 0096#decision [implements]: exactly one read form per rule; `where` only rides `columns`; raw SQL must carry the rowFilter's columns itself
56
+
if(contract.rowFilter!==undefined){
57
+
constfilter=contract.rowFilter
58
+
constat=`'${contract.name}' rowFilter`
59
+
if(!filter||typeoffilter!=='object'){
60
+
thrownewTypeError(`registerContract: ${at} must be an object`)
0 commit comments