@bjornpagen/bumbledb 0.5.0 → 0.7.0
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/COOKBOOK.md +140 -136
- package/README.md +24 -11
- package/dist/closed.d.ts +7 -5
- package/dist/closed.d.ts.map +1 -1
- package/dist/closed.js +4 -1
- package/dist/closed.js.map +1 -1
- package/dist/count.js +1 -1
- package/dist/count.js.map +1 -1
- package/dist/db.d.ts +110 -73
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +172 -116
- package/dist/db.js.map +1 -1
- package/dist/exhume.d.ts +22 -10
- package/dist/exhume.d.ts.map +1 -1
- package/dist/exhume.js +42 -9
- package/dist/exhume.js.map +1 -1
- package/dist/face.d.ts +10 -6
- package/dist/face.d.ts.map +1 -1
- package/dist/face.js.map +1 -1
- package/dist/fields.d.ts +38 -16
- package/dist/fields.d.ts.map +1 -1
- package/dist/fields.js +33 -8
- package/dist/fields.js.map +1 -1
- package/dist/index.d.ts +9 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/lower.d.ts +9 -9
- package/dist/lower.d.ts.map +1 -1
- package/dist/lower.js +17 -12
- package/dist/lower.js.map +1 -1
- package/dist/marshal.d.ts +17 -7
- package/dist/marshal.d.ts.map +1 -1
- package/dist/marshal.js +32 -10
- package/dist/marshal.js.map +1 -1
- package/dist/native.d.ts +60 -9
- package/dist/native.d.ts.map +1 -1
- package/dist/native.js.map +1 -1
- package/dist/query/atom.d.ts +199 -203
- package/dist/query/atom.d.ts.map +1 -1
- package/dist/query/atom.js +39 -48
- package/dist/query/atom.js.map +1 -1
- package/dist/query/find.d.ts +116 -0
- package/dist/query/find.d.ts.map +1 -0
- package/dist/query/{select.js → find.js} +22 -22
- package/dist/query/find.js.map +1 -0
- package/dist/query/lower.d.ts +131 -158
- package/dist/query/lower.d.ts.map +1 -1
- package/dist/query/lower.js +505 -494
- package/dist/query/lower.js.map +1 -1
- package/dist/query/predicate.d.ts +22 -14
- package/dist/query/predicate.d.ts.map +1 -1
- package/dist/query/predicate.js +35 -42
- package/dist/query/predicate.js.map +1 -1
- package/dist/query/run.d.ts +8 -8
- package/dist/query/run.d.ts.map +1 -1
- package/dist/query/run.js +16 -21
- package/dist/query/run.js.map +1 -1
- package/dist/query/scope.d.ts +139 -74
- package/dist/query/scope.d.ts.map +1 -1
- package/dist/query/scope.js +80 -33
- package/dist/query/scope.js.map +1 -1
- package/dist/relation.d.ts.map +1 -1
- package/dist/relation.js +3 -1
- package/dist/relation.js.map +1 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +12 -2
- package/dist/schema.js.map +1 -1
- package/dist/spec.d.ts +20 -10
- package/dist/spec.d.ts.map +1 -1
- package/dist/spec.js.map +1 -1
- package/dist/statements.d.ts +22 -2
- package/dist/statements.d.ts.map +1 -1
- package/dist/statements.js +26 -5
- package/dist/statements.js.map +1 -1
- package/package.json +3 -3
- package/src/closed.ts +13 -7
- package/src/count.ts +1 -1
- package/src/db.ts +293 -177
- package/src/exhume.ts +48 -11
- package/src/face.ts +13 -6
- package/src/fields.ts +51 -15
- package/src/index.ts +12 -8
- package/src/lower.ts +17 -12
- package/src/marshal.ts +38 -13
- package/src/native.ts +59 -8
- package/src/query/atom.ts +297 -275
- package/src/query/find.ts +212 -0
- package/src/query/lower.ts +692 -724
- package/src/query/predicate.ts +37 -45
- package/src/query/run.ts +17 -22
- package/src/query/scope.ts +184 -90
- package/src/relation.ts +3 -1
- package/src/schema.ts +14 -2
- package/src/spec.ts +21 -9
- package/src/statements.ts +30 -6
- package/dist/query/select.d.ts +0 -128
- package/dist/query/select.d.ts.map +0 -1
- package/dist/query/select.js.map +0 -1
- package/src/query/select.ts +0 -215
package/src/schema.ts
CHANGED
|
@@ -13,11 +13,11 @@ import * as errors from "@superbuilders/errors"
|
|
|
13
13
|
import type { AnyClosed } from "#closed.ts"
|
|
14
14
|
import { isClosedMember, sealedFieldOf } from "#closed.ts"
|
|
15
15
|
import type { FaceData } from "#face.ts"
|
|
16
|
-
import { assertDeclarationOrderKey, rosterOf } from "#fields.ts"
|
|
16
|
+
import { assertDeclarationOrderKey, assertDeclarationRecord, rosterOf } from "#fields.ts"
|
|
17
17
|
import { type ClassesOf, classesComplete, computeClasses, type LawfulStatements, type SchemaClasses } from "#law.ts"
|
|
18
18
|
import type { AnyRelation } from "#relation.ts"
|
|
19
19
|
import type { LiteralSetSpec, LiteralSpec } from "#spec.ts"
|
|
20
|
-
import { renderStatement, type Statement } from "#statements.ts"
|
|
20
|
+
import { isStatement, renderStatement, type Statement } from "#statements.ts"
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Validates the relation record and collects the implied keys: the
|
|
@@ -27,6 +27,7 @@ import { renderStatement, type Statement } from "#statements.ts"
|
|
|
27
27
|
* single spelling authority.
|
|
28
28
|
*/
|
|
29
29
|
function collectImplied(name: string, relations: SchemaRelations): Set<string> {
|
|
30
|
+
assertDeclarationRecord(`schema ${name} relations`, relations)
|
|
30
31
|
const implied = new Set<string>()
|
|
31
32
|
for (const [recordKey, member] of Object.entries(relations)) {
|
|
32
33
|
assertDeclarationOrderKey(`schema ${name} relation`, recordKey)
|
|
@@ -297,6 +298,17 @@ function schema<const Rels extends SchemaRelations, const Stmts extends readonly
|
|
|
297
298
|
const implied = collectImplied(name, relations)
|
|
298
299
|
const seen = new Set<string>()
|
|
299
300
|
for (const statement of statements) {
|
|
301
|
+
/**
|
|
302
|
+
* The untyped caller's half of the admission brand: the type tier
|
|
303
|
+
* already refuses an unbranded structural literal, and this probe
|
|
304
|
+
* refuses the same forgery at runtime — a statement that skipped the
|
|
305
|
+
* construction-time arity and roster walls never enters the theory.
|
|
306
|
+
*/
|
|
307
|
+
if (!isStatement(statement)) {
|
|
308
|
+
throw errors.new(
|
|
309
|
+
`schema ${name}: a statement is minted only by key/contained/mirrors/window — a structural literal skips the construction-time arity and roster walls`
|
|
310
|
+
)
|
|
311
|
+
}
|
|
300
312
|
const rendered = renderStatement(statement)
|
|
301
313
|
verifyMembership(name, relations, statement, rendered)
|
|
302
314
|
if (implied.has(rendered)) {
|
package/src/spec.ts
CHANGED
|
@@ -118,19 +118,30 @@ interface RowSpec {
|
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
/**
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
* `` `${name}.id` `` — the same label every referencing field
|
|
127
|
-
* law),
|
|
121
|
+
* A relation's closedness as ONE sum (ruled 2026-07-23, R7): the handle
|
|
122
|
+
* newtype and the ground axioms travel together — the two illegal states
|
|
123
|
+
* (a roster without its newtype, a newtype without its roster) are
|
|
124
|
+
* unspellable on the wire exactly as they are unrepresentable in the
|
|
125
|
+
* fused Rust `RelationSpec`. `newtype` is the id's law-computed generator
|
|
126
|
+
* class (`` `${name}.id` `` — the same label every referencing field
|
|
127
|
+
* carries by law), which is how the engine resolves a handle literal back
|
|
128
|
+
* to its roster.
|
|
129
|
+
*/
|
|
130
|
+
interface ClosedSpec {
|
|
131
|
+
readonly newtype: string
|
|
132
|
+
readonly rows: readonly RowSpec[]
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* One relation. A present `closed` declares it closed (the option is the
|
|
137
|
+
* kind, one sum — R7); a closed relation's `fields` are its declared
|
|
138
|
+
* intrinsic columns only — the synthetic (`id`, u64) handle field is
|
|
139
|
+
* materialized by the engine's schema validation.
|
|
128
140
|
*/
|
|
129
141
|
interface RelationSpec {
|
|
130
142
|
readonly name: string
|
|
131
|
-
readonly newtype: string | undefined
|
|
132
143
|
readonly fields: readonly FieldSpec[]
|
|
133
|
-
readonly
|
|
144
|
+
readonly closed: ClosedSpec | undefined
|
|
134
145
|
}
|
|
135
146
|
|
|
136
147
|
/**
|
|
@@ -313,6 +324,7 @@ function renderWindow(window: WindowSpec): string {
|
|
|
313
324
|
}
|
|
314
325
|
|
|
315
326
|
export type {
|
|
327
|
+
ClosedSpec,
|
|
316
328
|
FieldSpec,
|
|
317
329
|
LiteralSetSpec,
|
|
318
330
|
LiteralSpec,
|
package/src/statements.ts
CHANGED
|
@@ -74,9 +74,33 @@ interface WindowData<Tgt extends FaceData = FaceData, Src extends FaceData = Fac
|
|
|
74
74
|
/** One statement's runtime description, tagged by form. */
|
|
75
75
|
type StatementData = KeyData<AnyRelation, readonly string[]> | ContainmentData | WindowData
|
|
76
76
|
|
|
77
|
-
/**
|
|
77
|
+
/**
|
|
78
|
+
* The admission brand — a module-private symbol, deliberately unexported
|
|
79
|
+
* (the `count.ts` pattern): `Statement` is a public structural type, so
|
|
80
|
+
* without this brand a forged plain object of the right shape would walk
|
|
81
|
+
* past the construction-time arity and roster walls into `schema()` — and
|
|
82
|
+
* the roster wall is the one the engine cannot backstop (the wire carries
|
|
83
|
+
* plain u64s, no rosters). The symbol makes the four constructors the ONLY
|
|
84
|
+
* mints, so a statement that skipped the walls is unspellable.
|
|
85
|
+
*/
|
|
86
|
+
const admitted: unique symbol = Symbol("bumbledb.statement.admitted")
|
|
87
|
+
|
|
88
|
+
/** An opaque statement value — what `schema()` assembles into a theory. Only the four constructors produce one. */
|
|
78
89
|
interface Statement {
|
|
79
90
|
readonly data: StatementData
|
|
91
|
+
readonly [admitted]: true
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Narrows any value to an admitted statement — the probe is the
|
|
96
|
+
* module-private {@link admitted} brand only the four constructors set, so
|
|
97
|
+
* no host-built value (fact cells are structurally OPEN — an interval with
|
|
98
|
+
* an excess `kind` property is a legal cell) can ever be misread as one.
|
|
99
|
+
* The keyed-get selector dispatch and `schema()`'s admission both judge
|
|
100
|
+
* through here.
|
|
101
|
+
*/
|
|
102
|
+
function isStatement(value: unknown): value is Statement {
|
|
103
|
+
return typeof value === "object" && value !== null && admitted in value
|
|
80
104
|
}
|
|
81
105
|
|
|
82
106
|
/**
|
|
@@ -188,7 +212,7 @@ function key<
|
|
|
188
212
|
owner: relation,
|
|
189
213
|
projection: Object.freeze(fields)
|
|
190
214
|
})
|
|
191
|
-
return Object.freeze({ data })
|
|
215
|
+
return Object.freeze({ data, [admitted]: true as const })
|
|
192
216
|
}
|
|
193
217
|
|
|
194
218
|
/**
|
|
@@ -210,7 +234,7 @@ function contained<A extends AnyFace, B extends AnyFace>(
|
|
|
210
234
|
target: target.data,
|
|
211
235
|
bidirectional: false
|
|
212
236
|
})
|
|
213
|
-
const statement = Object.freeze({ data })
|
|
237
|
+
const statement = Object.freeze({ data, [admitted]: true as const })
|
|
214
238
|
assertArityAgreement(data.source, data.target, statement)
|
|
215
239
|
assertRosterAgreement(data.source, data.target, statement)
|
|
216
240
|
return statement
|
|
@@ -235,7 +259,7 @@ function mirrors<A extends AnyFace, B extends AnyFace>(
|
|
|
235
259
|
target: target.data,
|
|
236
260
|
bidirectional: true
|
|
237
261
|
})
|
|
238
|
-
const statement = Object.freeze({ data })
|
|
262
|
+
const statement = Object.freeze({ data, [admitted]: true as const })
|
|
239
263
|
assertArityAgreement(data.source, data.target, statement)
|
|
240
264
|
assertRosterAgreement(data.source, data.target, statement)
|
|
241
265
|
return statement
|
|
@@ -262,7 +286,7 @@ function window<B extends AnyFace, A extends AnyFace>(
|
|
|
262
286
|
window: count.window,
|
|
263
287
|
source: source.data
|
|
264
288
|
})
|
|
265
|
-
const statement = Object.freeze({ data })
|
|
289
|
+
const statement = Object.freeze({ data, [admitted]: true as const })
|
|
266
290
|
assertArityAgreement(data.source, data.target, statement)
|
|
267
291
|
assertRosterAgreement(data.source, data.target, statement)
|
|
268
292
|
return statement
|
|
@@ -302,4 +326,4 @@ export type {
|
|
|
302
326
|
WindowData,
|
|
303
327
|
WindowStatement
|
|
304
328
|
}
|
|
305
|
-
export { contained, key, mirrors, renderStatement, window }
|
|
329
|
+
export { contained, isStatement, key, mirrors, renderStatement, window }
|
package/dist/query/select.d.ts
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Select entries and aggregates, STRUCTURAL edition — the head vocabulary,
|
|
3
|
-
* mirroring the IR's aggregate roster exactly
|
|
4
|
-
* (`bumbledb/crates/bumbledb/src/ir.rs` `AggOp`/`FindTerm`;
|
|
5
|
-
* `docs/architecture/20-query-ir.md` § aggregation): `count` (nullary),
|
|
6
|
-
* `countDistinct`, `sum`/`min`/`max` (over an orderable variable or the
|
|
7
|
-
* measure), `argMax`/`argMin` (arg-restriction: carried value + orderable
|
|
8
|
-
* key; a tie yields every attaining row), and `pack` (the coalescing fold —
|
|
9
|
-
* RELATION-SHAPED: one answer row per (group, maximal segment), the result
|
|
10
|
-
* position interval-typed). Aggregates name their variables — `r.sum("m")`
|
|
11
|
-
* — and are typed by the rule environment at `.select`. Grouping is
|
|
12
|
-
* implicit: the non-aggregate select entries are the group key; over empty
|
|
13
|
-
* input an all-aggregate select yields the EMPTY SET, never a zero row.
|
|
14
|
-
* The creation quarantine is representational: a head position is a var
|
|
15
|
-
* name, the measure, or an aggregate — no minting or arithmetic term
|
|
16
|
-
* exists to spell (permanent law).
|
|
17
|
-
*/
|
|
18
|
-
import type { Infer } from "#fields.ts";
|
|
19
|
-
import type { IntervalVarOk, OrderVarOk } from "#query/atom.ts";
|
|
20
|
-
import type { Duration, EnvShape, ShapeOf } from "#query/scope.ts";
|
|
21
|
-
/** One aggregate operator name of the select vocabulary. */
|
|
22
|
-
type AggOpName = "count" | "countDistinct" | "sum" | "min" | "max" | "argMax" | "argMin" | "pack";
|
|
23
|
-
/**
|
|
24
|
-
* One aggregate select VALUE: the op, the variable name (or measure) it
|
|
25
|
-
* folds, and — for the Arg forms — the orderable key's variable name. The
|
|
26
|
-
* runtime representation carries the types; the rule environment types the
|
|
27
|
-
* result at `.select`.
|
|
28
|
-
*/
|
|
29
|
-
interface Agg<Op extends AggOpName, Over extends string | Duration<string> | undefined, Key extends string | undefined = undefined> {
|
|
30
|
-
readonly agg: Op;
|
|
31
|
-
readonly over: Over;
|
|
32
|
-
readonly key: Key;
|
|
33
|
-
}
|
|
34
|
-
/** Any aggregate select value. */
|
|
35
|
-
type AnyAgg = Agg<AggOpName, string | Duration<string> | undefined, string | undefined>;
|
|
36
|
-
/** One select entry: a projected var name, the measure, or an aggregate. */
|
|
37
|
-
type SelectEntry = string | Duration<string> | AnyAgg;
|
|
38
|
-
/** Nullary count: |the group's set of distinct full bindings|, `bigint`; the answer column is named `count`. */
|
|
39
|
-
declare function count(): Agg<"count", undefined>;
|
|
40
|
-
/** |the distinct values of the named variable across the group|, `bigint`; legal over every type. */
|
|
41
|
-
declare function countDistinct<const N extends string>(over: N): Agg<"countDistinct", N>;
|
|
42
|
-
/**
|
|
43
|
-
* Exact checked sum over an orderable (u64/i64) variable — wide
|
|
44
|
-
* accumulator, one finalize range check; overflow is the engine's typed
|
|
45
|
-
* runtime error, never a wrap — or over the measure
|
|
46
|
-
* (`r.sum(r.duration("w"))`).
|
|
47
|
-
*/
|
|
48
|
-
declare function sum<const N extends string | Duration<string>>(over: N): Agg<"sum", N>;
|
|
49
|
-
/** Minimum over an orderable variable or the measure (orderable types only). */
|
|
50
|
-
declare function min<const N extends string | Duration<string>>(over: N): Agg<"min", N>;
|
|
51
|
-
/** Maximum over an orderable variable or the measure (orderable types only). */
|
|
52
|
-
declare function max<const N extends string | Duration<string>>(over: N): Agg<"max", N>;
|
|
53
|
-
/**
|
|
54
|
-
* Arg-restriction toward the maximum of `key` (`ir::AggOp::ArgMax`): the
|
|
55
|
-
* group's binding set is restricted to the bindings attaining the extreme
|
|
56
|
-
* of the orderable key, and `value` is the carried payload — a tie yields
|
|
57
|
-
* every attaining row. All Arg entries of one query share one key and one
|
|
58
|
-
* direction; Arg and fold aggregates never mix (both the engine's typed
|
|
59
|
-
* rules).
|
|
60
|
-
*/
|
|
61
|
-
declare function argMax<const V extends string, const K extends string>(value: V, key: K): Agg<"argMax", V, K>;
|
|
62
|
-
/** Arg-restriction toward the minimum of `key`; rules as {@link argMax}. */
|
|
63
|
-
declare function argMin<const V extends string, const K extends string>(value: V, key: K): Agg<"argMin", V, K>;
|
|
64
|
-
/**
|
|
65
|
-
* The coalescing fold (Snodgrass coalesce, `ir::AggOp::Pack`): per group,
|
|
66
|
-
* the maximal disjoint half-open segments of the union of the group's
|
|
67
|
-
* interval point sets — RELATION-SHAPED, one answer row per (group,
|
|
68
|
-
* maximal segment), the result position carrying one interval of the
|
|
69
|
-
* input's element type. At most one `pack` per select, never beside a
|
|
70
|
-
* fold or an Arg entry (the engine's typed rules).
|
|
71
|
-
*/
|
|
72
|
-
declare function pack<const N extends string>(over: N): Agg<"pack", N>;
|
|
73
|
-
/** A fold input's judgment: an orderable variable, or the measure of an interval variable. */
|
|
74
|
-
type FoldOverOk<Env extends EnvShape, O> = O extends string ? OrderVarOk<Env, O> : O extends Duration<infer N extends string> ? IntervalVarOk<Env, N> : false;
|
|
75
|
-
/**
|
|
76
|
-
* One select entry's judgment against the rule environment: projected
|
|
77
|
-
* names must be bound, the measure and `pack` demand interval-typed
|
|
78
|
-
* variables, folds and Arg keys demand orderable ones.
|
|
79
|
-
*/
|
|
80
|
-
type SelectEntryOk<Env extends EnvShape, E> = E extends string ? E extends keyof Env ? true : false : E extends Duration<infer N extends string> ? IntervalVarOk<Env, N> : E extends Agg<"count", undefined> ? true : E extends Agg<"countDistinct", infer O extends string> ? O extends keyof Env ? true : false : E extends Agg<"sum" | "min" | "max", infer O> ? FoldOverOk<Env, O> : E extends Agg<"argMax" | "argMin", infer O extends string, infer K extends string> ? [O extends keyof Env ? true : false, OrderVarOk<Env, K>] extends [true, true] ? true : false : E extends Agg<"pack", infer O extends string> ? IntervalVarOk<Env, O> : false;
|
|
81
|
-
/** The validated select tuple (intersect with the inferred entries — errors land on the offending argument). */
|
|
82
|
-
type CheckSelect<Env extends EnvShape, S> = {
|
|
83
|
-
readonly [I in keyof S]: SelectEntryOk<Env, S[I]> extends true ? S[I] : never;
|
|
84
|
-
};
|
|
85
|
-
/** The validated names-only select tuple of a RECURSIVE rule (aggregates and the measure are unwritable there). */
|
|
86
|
-
type CheckNameSelect<Env extends EnvShape, S> = {
|
|
87
|
-
readonly [I in keyof S]: S[I] extends keyof Env ? S[I] : never;
|
|
88
|
-
};
|
|
89
|
-
/**
|
|
90
|
-
* One select entry's answer-column fragment: the column is named by the
|
|
91
|
-
* variable it projects or folds (`count` names its column `count`), and
|
|
92
|
-
* its type reflects the entry — `count`/`countDistinct` are `bigint`
|
|
93
|
-
* whatever they counted, folds carry their input's type, the measure is
|
|
94
|
-
* `bigint`, the Arg forms carry the payload's type, `pack` its interval
|
|
95
|
-
* type.
|
|
96
|
-
*/
|
|
97
|
-
type SelectEntryRow<Env extends EnvShape, E> = E extends string ? {
|
|
98
|
-
readonly [K in E]: Infer<Env[E & keyof Env]["field"]>;
|
|
99
|
-
} : E extends Duration<infer N extends string> ? {
|
|
100
|
-
readonly [K in N]: bigint;
|
|
101
|
-
} : E extends Agg<"count", undefined> ? {
|
|
102
|
-
readonly count: bigint;
|
|
103
|
-
} : E extends Agg<"countDistinct", infer O extends string> ? {
|
|
104
|
-
readonly [K in O]: bigint;
|
|
105
|
-
} : E extends Agg<"sum" | "min" | "max", infer O> ? O extends string ? {
|
|
106
|
-
readonly [K in O]: Infer<Env[O & keyof Env]["field"]>;
|
|
107
|
-
} : O extends Duration<infer N extends string> ? {
|
|
108
|
-
readonly [K in N]: bigint;
|
|
109
|
-
} : never : E extends Agg<"argMax" | "argMin", infer O extends string, string> ? {
|
|
110
|
-
readonly [K in O]: Infer<Env[O & keyof Env]["field"]>;
|
|
111
|
-
} : E extends Agg<"pack", infer O extends string> ? {
|
|
112
|
-
readonly [K in O]: Infer<Env[O & keyof Env]["field"]>;
|
|
113
|
-
} : never;
|
|
114
|
-
/** The inferred answer-row object type of a select tuple. */
|
|
115
|
-
type RowOfSelect<Env extends EnvShape, S extends readonly SelectEntry[]> = ShapeOf<SelectEntryRow<Env, S[number]>>;
|
|
116
|
-
/**
|
|
117
|
-
* One projected name's answer-column fragment — a NAKED parameter, so the
|
|
118
|
-
* judgment distributes per name (the union of a multi-name select never
|
|
119
|
-
* smears into one column's type), mirroring {@link SelectEntryRow}.
|
|
120
|
-
*/
|
|
121
|
-
type NameSelectRow<Env extends EnvShape, N> = N extends string ? {
|
|
122
|
-
readonly [K in N]: Infer<Env[K & keyof Env]["field"]>;
|
|
123
|
-
} : never;
|
|
124
|
-
/** The inferred answer-row object type of a names-only (recursive-rule) select tuple. */
|
|
125
|
-
type RowOfNameSelect<Env extends EnvShape, S extends readonly string[]> = ShapeOf<NameSelectRow<Env, S[number]>>;
|
|
126
|
-
export type { Agg, AggOpName, AnyAgg, CheckNameSelect, CheckSelect, RowOfNameSelect, RowOfSelect, SelectEntry, SelectEntryOk, SelectEntryRow };
|
|
127
|
-
export { argMax, argMin, count, countDistinct, max, min, pack, sum };
|
|
128
|
-
//# sourceMappingURL=select.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../src/query/select.ts"],"names":[],"mappings":"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"}
|
package/dist/query/select.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"select.js","sourceRoot":"","sources":["../../src/query/select.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AA+BH,kCAAkC;AAClC,SAAS,SAAS,CAIhB,EAAM,EAAE,IAAU,EAAE,GAAQ;IAC7B,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAA;AAC7C,CAAC;AAED,gHAAgH;AAChH,SAAS,KAAK;IACb,OAAO,SAAS,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC,CAAA;AAChD,CAAC;AAED,qGAAqG;AACrG,SAAS,aAAa,CAAyB,IAAO;IACrD,OAAO,SAAS,CAAC,eAAe,EAAE,IAAI,EAAE,SAAS,CAAC,CAAA;AACnD,CAAC;AAED;;;;;GAKG;AACH,SAAS,GAAG,CAA4C,IAAO;IAC9D,OAAO,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,CAAA;AACzC,CAAC;AAED,gFAAgF;AAChF,SAAS,GAAG,CAA4C,IAAO;IAC9D,OAAO,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,CAAA;AACzC,CAAC;AAED,gFAAgF;AAChF,SAAS,GAAG,CAA4C,IAAO;IAC9D,OAAO,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,CAAA;AACzC,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,MAAM,CAAiD,KAAQ,EAAE,GAAM;IAC/E,OAAO,SAAS,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,CAAA;AACvC,CAAC;AAED,4EAA4E;AAC5E,SAAS,MAAM,CAAiD,KAAQ,EAAE,GAAM;IAC/E,OAAO,SAAS,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,CAAA;AACvC,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,IAAI,CAAyB,IAAO;IAC5C,OAAO,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,CAAA;AAC1C,CAAC;AAqGD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,CAAA"}
|
package/src/query/select.ts
DELETED
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Select entries and aggregates, STRUCTURAL edition — the head vocabulary,
|
|
3
|
-
* mirroring the IR's aggregate roster exactly
|
|
4
|
-
* (`bumbledb/crates/bumbledb/src/ir.rs` `AggOp`/`FindTerm`;
|
|
5
|
-
* `docs/architecture/20-query-ir.md` § aggregation): `count` (nullary),
|
|
6
|
-
* `countDistinct`, `sum`/`min`/`max` (over an orderable variable or the
|
|
7
|
-
* measure), `argMax`/`argMin` (arg-restriction: carried value + orderable
|
|
8
|
-
* key; a tie yields every attaining row), and `pack` (the coalescing fold —
|
|
9
|
-
* RELATION-SHAPED: one answer row per (group, maximal segment), the result
|
|
10
|
-
* position interval-typed). Aggregates name their variables — `r.sum("m")`
|
|
11
|
-
* — and are typed by the rule environment at `.select`. Grouping is
|
|
12
|
-
* implicit: the non-aggregate select entries are the group key; over empty
|
|
13
|
-
* input an all-aggregate select yields the EMPTY SET, never a zero row.
|
|
14
|
-
* The creation quarantine is representational: a head position is a var
|
|
15
|
-
* name, the measure, or an aggregate — no minting or arithmetic term
|
|
16
|
-
* exists to spell (permanent law).
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
import type { Infer } from "#fields.ts"
|
|
20
|
-
import type { IntervalVarOk, OrderVarOk } from "#query/atom.ts"
|
|
21
|
-
import type { Duration, EnvShape, ShapeOf } from "#query/scope.ts"
|
|
22
|
-
|
|
23
|
-
/** One aggregate operator name of the select vocabulary. */
|
|
24
|
-
type AggOpName = "count" | "countDistinct" | "sum" | "min" | "max" | "argMax" | "argMin" | "pack"
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* One aggregate select VALUE: the op, the variable name (or measure) it
|
|
28
|
-
* folds, and — for the Arg forms — the orderable key's variable name. The
|
|
29
|
-
* runtime representation carries the types; the rule environment types the
|
|
30
|
-
* result at `.select`.
|
|
31
|
-
*/
|
|
32
|
-
interface Agg<
|
|
33
|
-
Op extends AggOpName,
|
|
34
|
-
Over extends string | Duration<string> | undefined,
|
|
35
|
-
Key extends string | undefined = undefined
|
|
36
|
-
> {
|
|
37
|
-
readonly agg: Op
|
|
38
|
-
readonly over: Over
|
|
39
|
-
readonly key: Key
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/** Any aggregate select value. */
|
|
43
|
-
type AnyAgg = Agg<AggOpName, string | Duration<string> | undefined, string | undefined>
|
|
44
|
-
|
|
45
|
-
/** One select entry: a projected var name, the measure, or an aggregate. */
|
|
46
|
-
type SelectEntry = string | Duration<string> | AnyAgg
|
|
47
|
-
|
|
48
|
-
/** Builds one aggregate value. */
|
|
49
|
-
function aggregate<
|
|
50
|
-
Op extends AggOpName,
|
|
51
|
-
Over extends string | Duration<string> | undefined,
|
|
52
|
-
Key extends string | undefined
|
|
53
|
-
>(op: Op, over: Over, key: Key): Agg<Op, Over, Key> {
|
|
54
|
-
return Object.freeze({ agg: op, over, key })
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/** Nullary count: |the group's set of distinct full bindings|, `bigint`; the answer column is named `count`. */
|
|
58
|
-
function count(): Agg<"count", undefined> {
|
|
59
|
-
return aggregate("count", undefined, undefined)
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/** |the distinct values of the named variable across the group|, `bigint`; legal over every type. */
|
|
63
|
-
function countDistinct<const N extends string>(over: N): Agg<"countDistinct", N> {
|
|
64
|
-
return aggregate("countDistinct", over, undefined)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Exact checked sum over an orderable (u64/i64) variable — wide
|
|
69
|
-
* accumulator, one finalize range check; overflow is the engine's typed
|
|
70
|
-
* runtime error, never a wrap — or over the measure
|
|
71
|
-
* (`r.sum(r.duration("w"))`).
|
|
72
|
-
*/
|
|
73
|
-
function sum<const N extends string | Duration<string>>(over: N): Agg<"sum", N> {
|
|
74
|
-
return aggregate("sum", over, undefined)
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/** Minimum over an orderable variable or the measure (orderable types only). */
|
|
78
|
-
function min<const N extends string | Duration<string>>(over: N): Agg<"min", N> {
|
|
79
|
-
return aggregate("min", over, undefined)
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/** Maximum over an orderable variable or the measure (orderable types only). */
|
|
83
|
-
function max<const N extends string | Duration<string>>(over: N): Agg<"max", N> {
|
|
84
|
-
return aggregate("max", over, undefined)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Arg-restriction toward the maximum of `key` (`ir::AggOp::ArgMax`): the
|
|
89
|
-
* group's binding set is restricted to the bindings attaining the extreme
|
|
90
|
-
* of the orderable key, and `value` is the carried payload — a tie yields
|
|
91
|
-
* every attaining row. All Arg entries of one query share one key and one
|
|
92
|
-
* direction; Arg and fold aggregates never mix (both the engine's typed
|
|
93
|
-
* rules).
|
|
94
|
-
*/
|
|
95
|
-
function argMax<const V extends string, const K extends string>(value: V, key: K): Agg<"argMax", V, K> {
|
|
96
|
-
return aggregate("argMax", value, key)
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/** Arg-restriction toward the minimum of `key`; rules as {@link argMax}. */
|
|
100
|
-
function argMin<const V extends string, const K extends string>(value: V, key: K): Agg<"argMin", V, K> {
|
|
101
|
-
return aggregate("argMin", value, key)
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* The coalescing fold (Snodgrass coalesce, `ir::AggOp::Pack`): per group,
|
|
106
|
-
* the maximal disjoint half-open segments of the union of the group's
|
|
107
|
-
* interval point sets — RELATION-SHAPED, one answer row per (group,
|
|
108
|
-
* maximal segment), the result position carrying one interval of the
|
|
109
|
-
* input's element type. At most one `pack` per select, never beside a
|
|
110
|
-
* fold or an Arg entry (the engine's typed rules).
|
|
111
|
-
*/
|
|
112
|
-
function pack<const N extends string>(over: N): Agg<"pack", N> {
|
|
113
|
-
return aggregate("pack", over, undefined)
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/** A fold input's judgment: an orderable variable, or the measure of an interval variable. */
|
|
117
|
-
type FoldOverOk<Env extends EnvShape, O> = O extends string
|
|
118
|
-
? OrderVarOk<Env, O>
|
|
119
|
-
: O extends Duration<infer N extends string>
|
|
120
|
-
? IntervalVarOk<Env, N>
|
|
121
|
-
: false
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* One select entry's judgment against the rule environment: projected
|
|
125
|
-
* names must be bound, the measure and `pack` demand interval-typed
|
|
126
|
-
* variables, folds and Arg keys demand orderable ones.
|
|
127
|
-
*/
|
|
128
|
-
type SelectEntryOk<Env extends EnvShape, E> = E extends string
|
|
129
|
-
? E extends keyof Env
|
|
130
|
-
? true
|
|
131
|
-
: false
|
|
132
|
-
: E extends Duration<infer N extends string>
|
|
133
|
-
? IntervalVarOk<Env, N>
|
|
134
|
-
: E extends Agg<"count", undefined>
|
|
135
|
-
? true
|
|
136
|
-
: E extends Agg<"countDistinct", infer O extends string>
|
|
137
|
-
? O extends keyof Env
|
|
138
|
-
? true
|
|
139
|
-
: false
|
|
140
|
-
: E extends Agg<"sum" | "min" | "max", infer O>
|
|
141
|
-
? FoldOverOk<Env, O>
|
|
142
|
-
: E extends Agg<"argMax" | "argMin", infer O extends string, infer K extends string>
|
|
143
|
-
? [O extends keyof Env ? true : false, OrderVarOk<Env, K>] extends [true, true]
|
|
144
|
-
? true
|
|
145
|
-
: false
|
|
146
|
-
: E extends Agg<"pack", infer O extends string>
|
|
147
|
-
? IntervalVarOk<Env, O>
|
|
148
|
-
: false
|
|
149
|
-
|
|
150
|
-
/** The validated select tuple (intersect with the inferred entries — errors land on the offending argument). */
|
|
151
|
-
type CheckSelect<Env extends EnvShape, S> = {
|
|
152
|
-
readonly [I in keyof S]: SelectEntryOk<Env, S[I]> extends true ? S[I] : never
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/** The validated names-only select tuple of a RECURSIVE rule (aggregates and the measure are unwritable there). */
|
|
156
|
-
type CheckNameSelect<Env extends EnvShape, S> = {
|
|
157
|
-
readonly [I in keyof S]: S[I] extends keyof Env ? S[I] : never
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* One select entry's answer-column fragment: the column is named by the
|
|
162
|
-
* variable it projects or folds (`count` names its column `count`), and
|
|
163
|
-
* its type reflects the entry — `count`/`countDistinct` are `bigint`
|
|
164
|
-
* whatever they counted, folds carry their input's type, the measure is
|
|
165
|
-
* `bigint`, the Arg forms carry the payload's type, `pack` its interval
|
|
166
|
-
* type.
|
|
167
|
-
*/
|
|
168
|
-
type SelectEntryRow<Env extends EnvShape, E> = E extends string
|
|
169
|
-
? { readonly [K in E]: Infer<Env[E & keyof Env]["field"]> }
|
|
170
|
-
: E extends Duration<infer N extends string>
|
|
171
|
-
? { readonly [K in N]: bigint }
|
|
172
|
-
: E extends Agg<"count", undefined>
|
|
173
|
-
? { readonly count: bigint }
|
|
174
|
-
: E extends Agg<"countDistinct", infer O extends string>
|
|
175
|
-
? { readonly [K in O]: bigint }
|
|
176
|
-
: E extends Agg<"sum" | "min" | "max", infer O>
|
|
177
|
-
? O extends string
|
|
178
|
-
? { readonly [K in O]: Infer<Env[O & keyof Env]["field"]> }
|
|
179
|
-
: O extends Duration<infer N extends string>
|
|
180
|
-
? { readonly [K in N]: bigint }
|
|
181
|
-
: never
|
|
182
|
-
: E extends Agg<"argMax" | "argMin", infer O extends string, string>
|
|
183
|
-
? { readonly [K in O]: Infer<Env[O & keyof Env]["field"]> }
|
|
184
|
-
: E extends Agg<"pack", infer O extends string>
|
|
185
|
-
? { readonly [K in O]: Infer<Env[O & keyof Env]["field"]> }
|
|
186
|
-
: never
|
|
187
|
-
|
|
188
|
-
/** The inferred answer-row object type of a select tuple. */
|
|
189
|
-
type RowOfSelect<Env extends EnvShape, S extends readonly SelectEntry[]> = ShapeOf<SelectEntryRow<Env, S[number]>>
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* One projected name's answer-column fragment — a NAKED parameter, so the
|
|
193
|
-
* judgment distributes per name (the union of a multi-name select never
|
|
194
|
-
* smears into one column's type), mirroring {@link SelectEntryRow}.
|
|
195
|
-
*/
|
|
196
|
-
type NameSelectRow<Env extends EnvShape, N> = N extends string
|
|
197
|
-
? { readonly [K in N]: Infer<Env[K & keyof Env]["field"]> }
|
|
198
|
-
: never
|
|
199
|
-
|
|
200
|
-
/** The inferred answer-row object type of a names-only (recursive-rule) select tuple. */
|
|
201
|
-
type RowOfNameSelect<Env extends EnvShape, S extends readonly string[]> = ShapeOf<NameSelectRow<Env, S[number]>>
|
|
202
|
-
|
|
203
|
-
export type {
|
|
204
|
-
Agg,
|
|
205
|
-
AggOpName,
|
|
206
|
-
AnyAgg,
|
|
207
|
-
CheckNameSelect,
|
|
208
|
-
CheckSelect,
|
|
209
|
-
RowOfNameSelect,
|
|
210
|
-
RowOfSelect,
|
|
211
|
-
SelectEntry,
|
|
212
|
-
SelectEntryOk,
|
|
213
|
-
SelectEntryRow
|
|
214
|
-
}
|
|
215
|
-
export { argMax, argMin, count, countDistinct, max, min, pack, sum }
|