@sixb/sqlite 0.1.15 → 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +67 -21
- package/dist/index.js.map +6 -6
- package/dist/objects/query-compiler.d.ts +3 -0
- package/dist/objects/query-compiler.d.ts.map +1 -1
- package/dist/objects/read-scope.d.ts +2 -0
- package/dist/objects/read-scope.d.ts.map +1 -1
- package/dist/objects/reader.d.ts +1 -0
- package/dist/objects/reader.d.ts.map +1 -1
- package/dist/objects/rows.d.ts +1 -0
- package/dist/objects/rows.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/objects/README.md +19 -0
- package/src/objects/query-compiler.ts +44 -7
- package/src/objects/read-scope.ts +10 -8
- package/src/objects/reader.ts +43 -8
- package/src/objects/rows.ts +1 -0
|
@@ -11,6 +11,9 @@ export interface CompiledObjectQuery {
|
|
|
11
11
|
sql: string;
|
|
12
12
|
args: SqliteValue[];
|
|
13
13
|
limit: number;
|
|
14
|
+
/** Maximum returned rows and total before the outermost limit, respectively. */
|
|
15
|
+
rowLimit: number;
|
|
16
|
+
totalLimit: number;
|
|
14
17
|
};
|
|
15
18
|
sql: string;
|
|
16
19
|
args: SqliteValue[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-compiler.d.ts","sourceRoot":"","sources":["../../src/objects/query-compiler.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EAKjB,MAAM,YAAY,CAAA;AASnB,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,UAAU,CAAA;AAEhF,MAAM,WAAW,wBAAwB;IACvC,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE;
|
|
1
|
+
{"version":3,"file":"query-compiler.d.ts","sourceRoot":"","sources":["../../src/objects/query-compiler.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,6 +15,8 @@ export interface SqliteSelectedObjectReadSource extends SqliteObjectQuerySource
|
|
|
15
15
|
* CROSS JOIN keeps authorized parents/grants before indexed edge/object lookups, even when
|
|
16
16
|
* statistics would otherwise make SQLite rescan all grants for every stored object.
|
|
17
17
|
* Property grants are grouped only after path-sensitive reachability has been resolved.
|
|
18
|
+
* Expose identities from grants/visible, so flattened joins can seek those relations by key
|
|
19
|
+
* before loading stored values. Exposing stored identities makes traversal rescan grants per edge.
|
|
18
20
|
*/
|
|
19
21
|
export declare function compileSqliteSelectedObjectReadSource(projectId: string, scope: CompiledSelectedObjectReadScope, maxTraversalFacts: number): SqliteSelectedObjectReadSource;
|
|
20
22
|
//# sourceMappingURL=read-scope.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-scope.d.ts","sourceRoot":"","sources":["../../src/objects/read-scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,oBAAoB,CAAA;AACzE,OAAO,EAEL,KAAK,uBAAuB,EAC5B,KAAK,WAAW,EAEjB,MAAM,kBAAkB,CAAA;AAEzB,MAAM,WAAW,8BAA+B,SAAQ,uBAAuB;IAC7E,QAAQ,CAAC,8BAA8B,EAAE,MAAM,CAAA;IAC/C,QAAQ,CAAC,cAAc,EAAE;QACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;QACpB,QAAQ,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,CAAA;KACtC,CAAA;CACF;AAED
|
|
1
|
+
{"version":3,"file":"read-scope.d.ts","sourceRoot":"","sources":["../../src/objects/read-scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,oBAAoB,CAAA;AACzE,OAAO,EAEL,KAAK,uBAAuB,EAC5B,KAAK,WAAW,EAEjB,MAAM,kBAAkB,CAAA;AAEzB,MAAM,WAAW,8BAA+B,SAAQ,uBAAuB;IAC7E,QAAQ,CAAC,8BAA8B,EAAE,MAAM,CAAA;IAC/C,QAAQ,CAAC,cAAc,EAAE;QACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;QACpB,QAAQ,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,CAAA;KACtC,CAAA;CACF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qCAAqC,CACnD,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,+BAA+B,EACtC,iBAAiB,EAAE,MAAM,GACxB,8BAA8B,CAoDhC"}
|
package/dist/objects/reader.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export declare class SqliteObjectReader {
|
|
|
9
9
|
constructor(db: Database, source: SqliteObjectQuerySource | SqliteSelectedObjectReadSource);
|
|
10
10
|
private assertVectorSearch;
|
|
11
11
|
queryObjects(params: QueryObjectsInput): QueryObjectsResult;
|
|
12
|
+
private vectorResultTotal;
|
|
12
13
|
countObjects(params: CountObjectsInput): CountObjectsResult;
|
|
13
14
|
existsObjects(params: ExistsObjectsInput): ExistsObjectsResult;
|
|
14
15
|
facetObjects(params: FacetObjectsInput): FacetObjectsResult;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../../src/objects/reader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAG1C,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,cAAc,EAEd,aAAa,EACb,iBAAiB,EACjB,SAAS,EACT,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAGL,KAAK,uBAAuB,EAE7B,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAA;AAWlE,qGAAqG;AACrG,qBAAa,kBAAkB;IAE3B,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,uBAAuB,GAAG,8BAA8B;IAGnF,OAAO,CAAC,kBAAkB;
|
|
1
|
+
{"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../../src/objects/reader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAG1C,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,EACZ,aAAa,EACb,cAAc,EAEd,aAAa,EACb,iBAAiB,EACjB,SAAS,EACT,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAGL,KAAK,uBAAuB,EAE7B,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAA;AAWlE,qGAAqG;AACrG,qBAAa,kBAAkB;IAE3B,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,uBAAuB,GAAG,8BAA8B;IAGnF,OAAO,CAAC,kBAAkB;IAY1B,YAAY,CAAC,MAAM,EAAE,iBAAiB,GAAG,kBAAkB;IA8B3D,OAAO,CAAC,iBAAiB;IAoBzB,YAAY,CAAC,MAAM,EAAE,iBAAiB,GAAG,kBAAkB;IAa3D,aAAa,CAAC,MAAM,EAAE,kBAAkB,GAAG,mBAAmB;IAS9D,YAAY,CAAC,MAAM,EAAE,iBAAiB,GAAG,kBAAkB;IAc3D,cAAc,CAAC,MAAM,EAAE;QACrB,SAAS,EAAE,MAAM,CAAA;QACjB,YAAY,EAAE,MAAM,CAAA;QACpB,SAAS,EAAE,MAAM,CAAA;KAClB,GAAG,SAAS,GAAG,IAAI;IAYpB,uBAAuB,CACrB,MAAM,EAAE,UAAU,CAAC,iBAAiB,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,CAAC,GAClE,SAAS,OAAO,EAAE;IA8BrB,SAAS,CAAC,MAAM,EAAE;QAChB,SAAS,EAAE,MAAM,CAAA;QACjB,YAAY,EAAE,MAAM,CAAA;QACpB,QAAQ,EAAE,MAAM,CAAA;QAChB,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,SAAS,CAAC,EAAE,aAAa,CAAA;KAC1B,GAAG,SAAS,aAAa,EAAE;IAgC5B,mBAAmB,CAAC,MAAM,EAAE;QAC1B,SAAS,EAAE,MAAM,CAAA;QACjB,KAAK,EAAE,SAAS;YAAE,YAAY,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,EAAE,CAAA;KAC9D,GAAG,GAAG,CAAC,cAAc,EAAE,SAAS,CAAC;IA4BlC,cAAc,CAAC,MAAM,EAAE;QACrB,SAAS,EAAE,MAAM,CAAA;QACjB,SAAS,CAAC,EAAE,aAAa,CAAA;QACzB,KAAK,EAAE,SAAS;YAAE,YAAY,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,EAAE,CAAA;KAC7E,GAAG,GAAG,CAAC,YAAY,EAAE,aAAa,EAAE,CAAC;IA+CtC,UAAU,CAAC,MAAM,EAAE,qBAAqB,GAAG,sBAAsB;IAiFjE,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG;QACtD,OAAO,EAAE,SAAS,SAAS,EAAE,CAAA;QAC7B,OAAO,EAAE,OAAO,CAAA;QAChB,KAAK,EAAE,MAAM,CAAA;KACd;CA6EF;AAYD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAIxD"}
|
package/dist/objects/rows.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export interface DatabaseRow {
|
|
|
14
14
|
last_commit_id: string;
|
|
15
15
|
}
|
|
16
16
|
export interface ObjectQueryDatabaseRow extends DatabaseRow {
|
|
17
|
+
_vector_candidate_count?: number;
|
|
17
18
|
_vector_score?: number;
|
|
18
19
|
_cursor_properties?: string;
|
|
19
20
|
/** `json_object(linkId, value, ...)` serialized text from an `expand` pushdown; absent otherwise. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rows.d.ts","sourceRoot":"","sources":["../../src/objects/rows.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,aAAa,EACb,SAAS,EAEV,MAAM,oBAAoB,CAAA;AAE3B,wBAAgB,WAAW,CAAC,GAAG,EAAE,WAAW,GAAG,SAAS,CAWvD;AAED,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,sBAAsB,GAAG,SAAS,CAOvE;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,eAAe,GAAG,aAAa,CAa7D;AAqDD,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,sBAAuB,SAAQ,WAAW;IACzD,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,qGAAqG;IACrG,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;CACvB"}
|
|
1
|
+
{"version":3,"file":"rows.d.ts","sourceRoot":"","sources":["../../src/objects/rows.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,aAAa,EACb,SAAS,EAEV,MAAM,oBAAoB,CAAA;AAE3B,wBAAgB,WAAW,CAAC,GAAG,EAAE,WAAW,GAAG,SAAS,CAWvD;AAED,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,sBAAsB,GAAG,SAAS,CAOvE;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,eAAe,GAAG,aAAa,CAa7D;AAqDD,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,sBAAuB,SAAQ,WAAW;IACzD,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,qGAAqG;IACrG,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,EAAE,MAAM,CAAA;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;CACvB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sixb/sqlite",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.16",
|
|
4
4
|
"description": "SQLite storage provider for Sixb",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sixb",
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
"prepack": "bun run build"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
|
-
"@sixb/core": "0.1.
|
|
40
|
+
"@sixb/core": "0.1.16"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@sixb/core": "0.1.
|
|
43
|
+
"@sixb/core": "0.1.16",
|
|
44
44
|
"@types/bun": "latest",
|
|
45
45
|
"typescript": "^5.7.0"
|
|
46
46
|
},
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Object reads
|
|
2
|
+
|
|
3
|
+
`read-scope.ts` derives visible objects, links and property grants from the selected roots and
|
|
4
|
+
paths. The selected reader holds its traversal-budget probe and terminal statements on one WAL
|
|
5
|
+
snapshot. SQL must filter by those relations before ranking or limiting results.
|
|
6
|
+
|
|
7
|
+
SQLite flattens CTEs. Expose identity columns from the grant/visible relation and put authorized
|
|
8
|
+
parents before indexed lookups with `CROSS JOIN`; exposing stored identities can cause a full
|
|
9
|
+
grant scan per traversed edge. The query-plan regression test checks those lookups.
|
|
10
|
+
|
|
11
|
+
Vector `list()` materializes at most the candidate budget plus one identity/vector pair per
|
|
12
|
+
eligible object. Its count controls distance evaluation and travels with the ranked rows, so
|
|
13
|
+
admission, total and ranking share one scan. Returned objects are hydrated after top-k; candidate
|
|
14
|
+
filters and traversals may still evaluate masked properties while deciding eligibility.
|
|
15
|
+
Overflow fails before exposing rows; it never silently ranks a truncated candidate set.
|
|
16
|
+
|
|
17
|
+
An outer zero limit can suppress the count row; that case uses the separate bounded probe.
|
|
18
|
+
Count, existence and facet terminals also retain that probe. Totals count the top-k set before
|
|
19
|
+
the outer limit, and all candidates must grant every profile source property.
|
|
@@ -24,7 +24,14 @@ export interface SqliteObjectQueryPageRow {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export interface CompiledObjectQuery {
|
|
27
|
-
vectorProbe?: {
|
|
27
|
+
vectorProbe?: {
|
|
28
|
+
sql: string
|
|
29
|
+
args: SqliteValue[]
|
|
30
|
+
limit: number
|
|
31
|
+
/** Maximum returned rows and total before the outermost limit, respectively. */
|
|
32
|
+
rowLimit: number
|
|
33
|
+
totalLimit: number
|
|
34
|
+
}
|
|
28
35
|
sql: string
|
|
29
36
|
args: SqliteValue[]
|
|
30
37
|
totalSql: string
|
|
@@ -98,7 +105,7 @@ export function compileObjectQuery(
|
|
|
98
105
|
if (hasVectorProfile(query) && !isVectorProfileQuery(query)) {
|
|
99
106
|
throw new ObjectQueryExecutionError(
|
|
100
107
|
"unsupported_vector_composition",
|
|
101
|
-
"Vector search supports one profile with filters before ranking and limit/project after."
|
|
108
|
+
"Vector search supports one profile with filters, traversals or sets before ranking and limit/project after."
|
|
102
109
|
)
|
|
103
110
|
}
|
|
104
111
|
const source = options.source ?? DEFAULT_OBJECT_QUERY_SOURCE
|
|
@@ -231,9 +238,31 @@ function compileVector(
|
|
|
231
238
|
{ kind: "column", column: "_vector_score", direction: "desc" },
|
|
232
239
|
...identityOrderFields().map((field) => ({ ...field, binary: true })),
|
|
233
240
|
])
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
241
|
+
const rankedOrder = compileOrder(order.fields, "ranked")
|
|
242
|
+
// Materialize only bounded, authorized candidates once. CASE prevents distance evaluation
|
|
243
|
+
// above the envelope; the reader rejects the count before exposing any rows or scores.
|
|
244
|
+
const sql = `SELECT stored.project_id, stored.object_type_id, stored.primary_id,
|
|
245
|
+
stored.properties, stored.properties AS _cursor_properties,
|
|
246
|
+
stored.created_at, stored.updated_at, stored.version, stored.last_commit_id,
|
|
247
|
+
ranked._vector_candidate_count, ranked._vector_score
|
|
248
|
+
FROM (
|
|
249
|
+
WITH _sixb_vector_candidates AS MATERIALIZED (
|
|
250
|
+
SELECT input.project_id, input.object_type_id, input.primary_id,
|
|
251
|
+
vectors.embedding AS _vector_embedding ${candidates} LIMIT ?
|
|
252
|
+
), _sixb_vector_budget AS (
|
|
253
|
+
SELECT COUNT(*) AS _vector_candidate_count FROM _sixb_vector_candidates
|
|
254
|
+
)
|
|
255
|
+
SELECT input.project_id, input.object_type_id, input.primary_id, budget._vector_candidate_count,
|
|
256
|
+
CASE WHEN budget._vector_candidate_count <= ?
|
|
257
|
+
THEN max(-1, min(1, 1 - vec_distance_cosine(input._vector_embedding, ?)))
|
|
258
|
+
END AS _vector_score
|
|
259
|
+
FROM _sixb_vector_candidates AS input CROSS JOIN _sixb_vector_budget AS budget
|
|
260
|
+
ORDER BY ${order.sql} LIMIT ?
|
|
261
|
+
) AS ranked CROSS JOIN ${ctx.source.objectsTable} AS stored
|
|
262
|
+
ON stored.project_id = ranked.project_id AND stored.object_type_id = ranked.object_type_id
|
|
263
|
+
AND stored.primary_id = ranked.primary_id
|
|
264
|
+
ORDER BY ${rankedOrder.sql}`
|
|
265
|
+
const args = [...candidateArgs, limit + 1, limit, encodeSqliteVector(values), query.k]
|
|
237
266
|
return {
|
|
238
267
|
sql,
|
|
239
268
|
args,
|
|
@@ -245,6 +274,8 @@ function compileVector(
|
|
|
245
274
|
sql: `SELECT COUNT(*) AS total FROM (SELECT 1 ${candidates} LIMIT ?) AS candidates`,
|
|
246
275
|
args: [...candidateArgs, limit + 1],
|
|
247
276
|
limit,
|
|
277
|
+
rowLimit: query.k,
|
|
278
|
+
totalLimit: query.k,
|
|
248
279
|
},
|
|
249
280
|
hasMore: () => false,
|
|
250
281
|
trimRows: identityRows,
|
|
@@ -451,7 +482,13 @@ function compileLimit(
|
|
|
451
482
|
FROM (${input.sql}) AS input
|
|
452
483
|
`,
|
|
453
484
|
totalArgs: input.args,
|
|
454
|
-
vectorProbe: input.vectorProbe
|
|
485
|
+
vectorProbe: input.vectorProbe
|
|
486
|
+
? {
|
|
487
|
+
...input.vectorProbe,
|
|
488
|
+
rowLimit: Math.min(input.vectorProbe.rowLimit, rowLimit),
|
|
489
|
+
totalLimit: input.vectorProbe.rowLimit,
|
|
490
|
+
}
|
|
491
|
+
: undefined,
|
|
455
492
|
order: input.order,
|
|
456
493
|
hasMore: (rowCount, total) =>
|
|
457
494
|
total === undefined ? ctx.probeLimit && rowCount > limit : limit < total,
|
|
@@ -852,7 +889,7 @@ function compileProject(
|
|
|
852
889
|
input.created_at,
|
|
853
890
|
input.updated_at,
|
|
854
891
|
input.version,
|
|
855
|
-
input.last_commit_id${input.vectorProbe ? ", input._vector_score" : ""}
|
|
892
|
+
input.last_commit_id${input.vectorProbe ? ", input._vector_score, input._vector_candidate_count" : ""}
|
|
856
893
|
FROM (${input.sql}) AS input
|
|
857
894
|
ORDER BY ${inputOrder.sql}
|
|
858
895
|
`,
|
|
@@ -22,6 +22,8 @@ export interface SqliteSelectedObjectReadSource extends SqliteObjectQuerySource
|
|
|
22
22
|
* CROSS JOIN keeps authorized parents/grants before indexed edge/object lookups, even when
|
|
23
23
|
* statistics would otherwise make SQLite rescan all grants for every stored object.
|
|
24
24
|
* Property grants are grouped only after path-sensitive reachability has been resolved.
|
|
25
|
+
* Expose identities from grants/visible, so flattened joins can seek those relations by key
|
|
26
|
+
* before loading stored values. Exposing stored identities makes traversal rescan grants per edge.
|
|
25
27
|
*/
|
|
26
28
|
export function compileSqliteSelectedObjectReadSource(
|
|
27
29
|
projectId: string,
|
|
@@ -105,7 +107,7 @@ function compileSelectedReadScopeCte(scopeJson: string, projectId: string): Comp
|
|
|
105
107
|
_sixb_scope_root_facts(project_id, root_id, node_id, object_type_id, primary_id) AS (
|
|
106
108
|
SELECT anchor.project_id, root.root_id, root.node_id, root.object_type_id, root.primary_id
|
|
107
109
|
FROM _sixb_scope_roots AS root
|
|
108
|
-
JOIN objects AS anchor
|
|
110
|
+
CROSS JOIN objects AS anchor
|
|
109
111
|
ON anchor.project_id = ?
|
|
110
112
|
AND anchor.object_type_id = root.object_type_id
|
|
111
113
|
AND anchor.primary_id = root.primary_id
|
|
@@ -187,7 +189,7 @@ function compileSelectedReadScopeCte(scopeJson: string, projectId: string): Comp
|
|
|
187
189
|
GROUP BY reachable.project_id, reachable.object_type_id, reachable.primary_id
|
|
188
190
|
),
|
|
189
191
|
_sixb_scope_objects AS (
|
|
190
|
-
SELECT
|
|
192
|
+
SELECT grants.project_id, grants.object_type_id, grants.primary_id,
|
|
191
193
|
COALESCE((
|
|
192
194
|
SELECT json_group_object(property.key, ${sqliteJsonEachValue("property")})
|
|
193
195
|
FROM json_each(stored.properties) AS property
|
|
@@ -277,12 +279,12 @@ function compileSelectedReadScopeCte(scopeJson: string, projectId: string): Comp
|
|
|
277
279
|
),
|
|
278
280
|
_sixb_scope_links AS (
|
|
279
281
|
SELECT
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
282
|
+
visible.project_id,
|
|
283
|
+
visible.source_type_id,
|
|
284
|
+
visible.source_id,
|
|
285
|
+
visible.link_id,
|
|
286
|
+
visible.target_type_id,
|
|
287
|
+
visible.target_id,
|
|
286
288
|
CASE
|
|
287
289
|
WHEN stored.properties IS NULL THEN NULL
|
|
288
290
|
ELSE NULLIF(
|
package/src/objects/reader.ts
CHANGED
|
@@ -54,23 +54,23 @@ export class SqliteObjectReader {
|
|
|
54
54
|
ensureSqliteVectorSearch(this.db)
|
|
55
55
|
const probe = compiled.vectorProbe
|
|
56
56
|
const row = this.db.query<{ total: number }, SqliteValue[]>(probe.sql).get(...probe.args)
|
|
57
|
-
|
|
58
|
-
throw new ObjectQueryExecutionError(
|
|
59
|
-
"vector_work_limit_exceeded",
|
|
60
|
-
`Exact vector search supports at most ${probe.limit} eligible vectors at this dimension. Narrow the query filters.`
|
|
61
|
-
)
|
|
62
|
-
}
|
|
57
|
+
assertVectorCandidateCount(row?.total, probe.limit)
|
|
63
58
|
}
|
|
64
59
|
|
|
65
60
|
queryObjects(params: QueryObjectsInput): QueryObjectsResult {
|
|
66
|
-
this.assertVectorSearch(params)
|
|
67
61
|
const source = this.source
|
|
68
62
|
const compiled = compileObjectQuery(params.projectId, params.query, {
|
|
69
63
|
includeTotal: params.includeTotal,
|
|
70
64
|
source,
|
|
71
65
|
})
|
|
72
|
-
|
|
66
|
+
if (compiled.vectorProbe) ensureSqliteVectorSearch(this.db)
|
|
67
|
+
const ordinaryTotal =
|
|
68
|
+
params.includeTotal === false || compiled.vectorProbe
|
|
69
|
+
? undefined
|
|
70
|
+
: readTotal(this.db, compiled)
|
|
73
71
|
const rawRows = this.db.query(compiled.sql).all(...compiled.args) as ObjectQueryDatabaseRow[]
|
|
72
|
+
const vectorTotal = this.vectorResultTotal(compiled, rawRows)
|
|
73
|
+
const total = params.includeTotal === false ? undefined : (vectorTotal ?? ordinaryTotal)
|
|
74
74
|
const rows = compiled.trimRows(rawRows) as readonly ObjectQueryDatabaseRow[]
|
|
75
75
|
const hasMore =
|
|
76
76
|
total === undefined && compiled.hasMoreProbe
|
|
@@ -87,6 +87,26 @@ export class SqliteObjectReader {
|
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
private vectorResultTotal(
|
|
91
|
+
compiled: CompiledObjectQuery,
|
|
92
|
+
rows: readonly ObjectQueryDatabaseRow[]
|
|
93
|
+
): number | undefined {
|
|
94
|
+
const probe = compiled.vectorProbe
|
|
95
|
+
if (!probe) return undefined
|
|
96
|
+
|
|
97
|
+
// A zero outer limit can hide the count row. Keep admission and total semantics for that
|
|
98
|
+
// uncommon case, without rescanning candidates for ordinary vector queries.
|
|
99
|
+
let count = rows[0]?._vector_candidate_count
|
|
100
|
+
if (rows.length === 0) {
|
|
101
|
+
count =
|
|
102
|
+
probe.rowLimit === 0
|
|
103
|
+
? this.db.query<{ total: number }, SqliteValue[]>(probe.sql).get(...probe.args)?.total
|
|
104
|
+
: 0
|
|
105
|
+
}
|
|
106
|
+
assertVectorCandidateCount(count, probe.limit)
|
|
107
|
+
return Math.min(count, probe.totalLimit)
|
|
108
|
+
}
|
|
109
|
+
|
|
90
110
|
countObjects(params: CountObjectsInput): CountObjectsResult {
|
|
91
111
|
this.assertVectorSearch(params)
|
|
92
112
|
const source = this.source
|
|
@@ -519,6 +539,21 @@ function sqliteFacetValue(valueType: string | null, value: unknown): unknown {
|
|
|
519
539
|
return value
|
|
520
540
|
}
|
|
521
541
|
|
|
542
|
+
function assertVectorCandidateCount(count: unknown, limit: number): asserts count is number {
|
|
543
|
+
if (typeof count !== "number" || !Number.isSafeInteger(count) || count < 0) {
|
|
544
|
+
throw new ObjectQueryExecutionError(
|
|
545
|
+
"invalid_vector_candidate_count",
|
|
546
|
+
"Storage did not return a valid vector candidate count."
|
|
547
|
+
)
|
|
548
|
+
}
|
|
549
|
+
if (count > limit) {
|
|
550
|
+
throw new ObjectQueryExecutionError(
|
|
551
|
+
"vector_work_limit_exceeded",
|
|
552
|
+
`Exact vector search supports at most ${limit} eligible vectors at this dimension. Narrow the query filters.`
|
|
553
|
+
)
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
522
557
|
function existsProbeQuery(query: ObjectQuery): ObjectQuery {
|
|
523
558
|
return { kind: "limit", limit: 1, input: stripOuterRowShape(query) }
|
|
524
559
|
}
|
package/src/objects/rows.ts
CHANGED
|
@@ -107,6 +107,7 @@ export interface DatabaseRow {
|
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
export interface ObjectQueryDatabaseRow extends DatabaseRow {
|
|
110
|
+
_vector_candidate_count?: number
|
|
110
111
|
_vector_score?: number
|
|
111
112
|
_cursor_properties?: string
|
|
112
113
|
/** `json_object(linkId, value, ...)` serialized text from an `expand` pushdown; absent otherwise. */
|