turbine-orm 0.33.0 → 0.35.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/README.md +2 -2
- package/dist/cjs/client.js +26 -4
- package/dist/cjs/dialect.js +1 -0
- package/dist/cjs/errors.js +41 -1
- package/dist/cjs/index-advisor.js +0 -0
- package/dist/cjs/index.js +4 -2
- package/dist/cjs/mssql.js +5 -0
- package/dist/cjs/mysql.js +4 -0
- package/dist/cjs/optional-peer-import.cjs +28 -0
- package/dist/cjs/powdb-introspect.js +222 -0
- package/dist/cjs/powdb.js +592 -72
- package/dist/cjs/powql.js +998 -134
- package/dist/cjs/query/builder.js +72 -1
- package/dist/cjs/schema-builder.js +16 -0
- package/dist/cjs/schema-metadata.js +81 -10
- package/dist/cjs/sqlite.js +3 -0
- package/dist/client.d.ts +32 -5
- package/dist/client.js +26 -4
- package/dist/dialect.d.ts +13 -0
- package/dist/dialect.js +1 -0
- package/dist/errors.d.ts +36 -0
- package/dist/errors.js +39 -0
- package/dist/index-advisor.d.ts +15 -1
- package/dist/index-advisor.js +0 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/mssql.js +5 -0
- package/dist/mysql.js +4 -0
- package/dist/optional-peer-import.cjs +28 -0
- package/dist/optional-peer-import.d.cts +19 -0
- package/dist/powdb-introspect.d.ts +84 -0
- package/dist/powdb-introspect.js +219 -0
- package/dist/powdb.d.ts +361 -19
- package/dist/powdb.js +585 -72
- package/dist/powql.d.ts +245 -8
- package/dist/powql.js +1001 -137
- package/dist/query/builder.d.ts +36 -1
- package/dist/query/builder.js +72 -1
- package/dist/query/deferred.d.ts +6 -2
- package/dist/query/types.d.ts +49 -12
- package/dist/schema-builder.d.ts +46 -1
- package/dist/schema-builder.js +15 -0
- package/dist/schema-metadata.d.ts +13 -7
- package/dist/schema-metadata.js +82 -11
- package/dist/schema.d.ts +25 -0
- package/dist/sqlite.js +3 -0
- package/package.json +3 -3
package/dist/powql.d.ts
CHANGED
|
@@ -53,13 +53,20 @@ export declare class PowqlInterface<T extends object = Record<string, unknown>>
|
|
|
53
53
|
private readonly defaultLimit?;
|
|
54
54
|
private readonly warnOnUnlimited;
|
|
55
55
|
private readonly onQuery?;
|
|
56
|
-
private currentAction;
|
|
57
56
|
private warnedUnlimited;
|
|
58
57
|
constructor(pool: PowdbPool, table: string, schema: SchemaMetadata, middlewares?: MiddlewareFn[], options?: QueryInterfaceOptions);
|
|
59
58
|
/** Resolve a camelCase field name (or raw snake) to its column metadata. */
|
|
60
59
|
private column;
|
|
61
|
-
/**
|
|
60
|
+
/**
|
|
61
|
+
* PowQL column reference for a field. Unqualified it is a dotted field
|
|
62
|
+
* reference (`.snake_name`), which bypasses keyword lookup. When an `alias`
|
|
63
|
+
* is supplied (the F2 join path) it is qualified (`alias.snake_name`) and the
|
|
64
|
+
* column name is backtick-quoted if it is a reserved word (a qualified
|
|
65
|
+
* `p.order` does NOT bypass keyword lookup, unlike the dotted `.order`).
|
|
66
|
+
*/
|
|
62
67
|
private ref;
|
|
68
|
+
/** Render a raw column name as a PowQL reference, qualified with `alias` when given. */
|
|
69
|
+
private colRefName;
|
|
63
70
|
/**
|
|
64
71
|
* Push a value into the param array and return its `$N` placeholder. When the
|
|
65
72
|
* value targets a `float` column it is wrapped in {@link PowdbFloatParam} so
|
|
@@ -81,15 +88,67 @@ export declare class PowqlInterface<T extends object = Record<string, unknown>>
|
|
|
81
88
|
*/
|
|
82
89
|
private writeRef;
|
|
83
90
|
private isFloatCol;
|
|
91
|
+
/**
|
|
92
|
+
* The bound pool's {@link PowdbCapabilities}. Falls back to the trusted-caller
|
|
93
|
+
* default (all feature gates on, `nativeRaw` off) when a directly-constructed
|
|
94
|
+
* pool did not carry them, matching {@link PowdbPool}'s own constructor
|
|
95
|
+
* default so a hand-built test pool never crashes the version gates.
|
|
96
|
+
*/
|
|
97
|
+
private get capabilities();
|
|
84
98
|
/** A predicate that is always false — the empty-`in` / contradiction sentinel. */
|
|
85
99
|
private alwaysFalse;
|
|
86
100
|
/**
|
|
87
101
|
* Compile a {@link WhereClause} into a PowQL filter expression, pushing every
|
|
88
102
|
* value as a positional `$N` param. Returns `''` when there are no conditions.
|
|
103
|
+
*
|
|
104
|
+
* When `alias` is supplied (the F2 native-join path) every field reference is
|
|
105
|
+
* qualified with it (`.col` → `alias.col`, JSON path bases too); params bind
|
|
106
|
+
* exactly as in the unqualified path. The caller only ever passes an alias for
|
|
107
|
+
* an already-RESOLVED where (relation filters pre-resolved to literal in-lists
|
|
108
|
+
* by {@link resolveRelationFilters}): the relation-key branch below still
|
|
109
|
+
* throws, so an unresolved relation filter can never leak into a join.
|
|
89
110
|
*/
|
|
90
111
|
private buildWhere;
|
|
91
112
|
/** Build a single `field: value | operator` condition. */
|
|
92
113
|
private buildFieldCondition;
|
|
114
|
+
/**
|
|
115
|
+
* PowQL JSON path expression `.col->$a->$b…`, binding EVERY path segment as a
|
|
116
|
+
* positional param (a string segment as a `str` token, an integer index as an
|
|
117
|
+
* `int` token). `->` binds tighter than every operator, so no parens are
|
|
118
|
+
* needed around the path in a comparison. Segments are bound (never inlined)
|
|
119
|
+
* to keep {@link materializePowql}'s `$N`-scan invariant intact: a segment
|
|
120
|
+
* that literally contained `$1` would otherwise be rewritten. Shared by the
|
|
121
|
+
* F1 where-filter path and the F2 orderBy / groupBy path emitters.
|
|
122
|
+
*
|
|
123
|
+
* A digit-only STRING segment (`'0'`) binds as an `int` array index, matching
|
|
124
|
+
* the SQL engines: `JsonFilter.path` is typed `string[]`, so an array index
|
|
125
|
+
* can only be expressed as a digit string, and the SQL builder converts it the
|
|
126
|
+
* same way (`/^\d+$/ → [n]`, query/builder.ts). Without this, PowDB's typed
|
|
127
|
+
* `->` treats `'0'` as a string KEY and silently matches nothing on an array
|
|
128
|
+
* (a wrong result, not an error). Same object-key-`'0'` caveat SQL accepts: a
|
|
129
|
+
* json object whose key is literally `"0"` is addressed as an array index.
|
|
130
|
+
*/
|
|
131
|
+
private jsonPathExpr;
|
|
132
|
+
/**
|
|
133
|
+
* Compile a {@link JsonFilter} on a json document column into a PowQL filter
|
|
134
|
+
* (≥ 0.12). Operators PowQL cannot express EXACTLY throw a per-operator E017
|
|
135
|
+
* (never a wrong result): containment (`contains`, and `equals` without a
|
|
136
|
+
* `path`) has no PowQL operator. The mapped shapes:
|
|
137
|
+
* - `{ path, equals: v }` → `P = $n` (typed: string→str, bool→bool,
|
|
138
|
+
* integral number→int, fractional→float; NOT stringified)
|
|
139
|
+
* - `{ path, equals: null }` → `P is null` (matches JSON null AND a missing
|
|
140
|
+
* key, a deliberate divergence from the PG driver, documented on
|
|
141
|
+
* {@link JsonFilter})
|
|
142
|
+
* - `{ path, gt|gte|lt|lte: v }` → `P > $n` … (range ops require `path`; the
|
|
143
|
+
* engine coerces int/float numerically)
|
|
144
|
+
* - `{ hasKey: k }` → `json_type(.col->$n) is not null` (top-level key test,
|
|
145
|
+
* ignoring `path`, mirroring PG `col ? key`; includes keys holding JSON
|
|
146
|
+
* null)
|
|
147
|
+
* A bare `{ path }` with no operators compiles to zero clauses (byte-parity
|
|
148
|
+
* with SQL), so a mutation whose only `where` is a bare `{ path }` is refused
|
|
149
|
+
* by the empty-where guard.
|
|
150
|
+
*/
|
|
151
|
+
private buildJsonPathCondition;
|
|
93
152
|
/** Bind a value, lowercasing for case-insensitive comparisons. */
|
|
94
153
|
private bind;
|
|
95
154
|
/** Bind a LIKE pattern (already escaped), lowercasing for insensitive mode. */
|
|
@@ -120,23 +179,99 @@ export declare class PowqlInterface<T extends object = Record<string, unknown>>
|
|
|
120
179
|
private projectedColumns;
|
|
121
180
|
/** `{ .c1, .c2, … }` projection clause. */
|
|
122
181
|
private projection;
|
|
123
|
-
/**
|
|
182
|
+
/**
|
|
183
|
+
* `order .c1 asc, .c2 desc` clause (empty string when no orderBy). Supports,
|
|
184
|
+
* besides a plain direction:
|
|
185
|
+
* - {@link JsonPathOrderBy} on a json column (≥ 0.12): `{ data: { path: […],
|
|
186
|
+
* type?, direction? } }` → `order .data->$n asc` (or
|
|
187
|
+
* `cast(.data->$n, "float")` for `type: 'numeric'`);
|
|
188
|
+
* - {@link OrderBySpec} `{ sort, nulls }`: `nulls: 'last'` is accepted as a
|
|
189
|
+
* no-op (PowDB is always nulls-last), `nulls: 'first'` throws E017.
|
|
190
|
+
*
|
|
191
|
+
* PowDB orders missing / JSON-null keys LAST in BOTH directions (an engine
|
|
192
|
+
* contract): for identical cross-engine results pass `nulls: 'last'`
|
|
193
|
+
* explicitly on Postgres, which defaults nulls-first for `desc`.
|
|
194
|
+
*/
|
|
124
195
|
private buildOrder;
|
|
125
|
-
/**
|
|
196
|
+
/** Compile one {@link JsonPathOrderBy} entry to `order .col->$n asc` (+ optional numeric cast). */
|
|
197
|
+
private buildJsonPathOrder;
|
|
198
|
+
/**
|
|
199
|
+
* Run PowQL with optional timeout, emitting a query event either way. The
|
|
200
|
+
* `action` is passed PER CALL (never read from shared instance state) so the
|
|
201
|
+
* retry-eligibility and the emitted event action stay correct even when a
|
|
202
|
+
* concurrent operation runs on the same cached interface: a WRITE statement
|
|
203
|
+
* carries a write action and can therefore never be mistaken for a replayable
|
|
204
|
+
* read. Read statements pass a read-shaped action from {@link POWQL_READ_ACTIONS}.
|
|
205
|
+
*/
|
|
126
206
|
private exec;
|
|
207
|
+
/** Build the E018 refusal for a write / `begin` on a read-only pool. */
|
|
208
|
+
private readOnlyError;
|
|
209
|
+
/**
|
|
210
|
+
* Execute one statement, with the opt-in single stale-frame READ replay. When
|
|
211
|
+
* `retryStaleReads` is on and a first-statement READ fails with the stale-wire
|
|
212
|
+
* {@link isStaleFramePowdbError} ConnectionError (a socket idle-gap "received
|
|
213
|
+
* unexpected frame" that the client cannot recover), the statement is retried
|
|
214
|
+
* exactly once on a fresh pooled connection (the broken one was destroyed).
|
|
215
|
+
* The replay is refused for writes (an ambiguous mutation reply is unsafe to
|
|
216
|
+
* replay) and inside a transaction (a mid-tx statement cannot move connection),
|
|
217
|
+
* so only the read-shaped actions in {@link POWQL_READ_ACTIONS}, outside a
|
|
218
|
+
* `_txScoped` interface, are eligible. `action` is a per-call argument (never
|
|
219
|
+
* `this`-state), so a concurrent op flipping instance fields cannot turn a
|
|
220
|
+
* write into a retryable read.
|
|
221
|
+
*/
|
|
222
|
+
private execOnce;
|
|
223
|
+
/** Is `err` a replayable stale-frame failure for THIS (per-call) read-shaped, non-tx action? */
|
|
224
|
+
private shouldRetryStaleRead;
|
|
127
225
|
private emit;
|
|
128
226
|
/** Run a method body through the middleware chain (mirrors QueryInterface). */
|
|
129
227
|
private withMiddleware;
|
|
130
|
-
/** Map raw rows to typed entities.
|
|
228
|
+
/** Map raw rows to typed entities. `native` is the wire that ACTUALLY served
|
|
229
|
+
* this result (threaded from {@link execOnce}, not the pool-level capability),
|
|
230
|
+
* so cells that arrived pre-typed over `queryNativeRaw` (F3) skip the legacy
|
|
231
|
+
* string coercion (a genuine str `"null"` stays `"null"` instead of collapsing
|
|
232
|
+
* to null) while a per-call legacy fallback on a native-capable pool still
|
|
233
|
+
* coerces its string cells correctly. Defaults to the pool capability for the
|
|
234
|
+
* rare caller with no per-result flag (hand-built test pools). */
|
|
131
235
|
private shape;
|
|
132
236
|
findMany(args?: FindManyArgs<T>): Promise<T[]>;
|
|
133
|
-
/**
|
|
237
|
+
/**
|
|
238
|
+
* Compile the flat findMany select into PowQL (no execution), pushing values
|
|
239
|
+
* into `params`. Returns the query plus the RESOLVED where (relation filters
|
|
240
|
+
* already collapsed to literal in-lists) so the F2 join path can re-emit the
|
|
241
|
+
* exact parent predicate alias-qualified, and so {@link explain} can wrap it.
|
|
242
|
+
*/
|
|
243
|
+
private buildFind;
|
|
244
|
+
/** Build + run the flat findMany select; returns raw rows, the serving wire, and the resolved where. */
|
|
134
245
|
private runFind;
|
|
246
|
+
/**
|
|
247
|
+
* Diagnostic surface: compile the same PowQL {@link findMany} would run for
|
|
248
|
+
* `args` (no cache) and return the engine's plan as one string per line.
|
|
249
|
+
*
|
|
250
|
+
* Runs as a READ (`explain <query>`), so it is safe on a read-only pool and
|
|
251
|
+
* eligible for the stale-read replay. The line content is engine-owned and is
|
|
252
|
+
* NOT covered by semver (match plan node names / tree shape, never exact
|
|
253
|
+
* bytes; mirrors PowDB's own `explain` contract).
|
|
254
|
+
*
|
|
255
|
+
* Does NOT run through the middleware chain: plan text is a diagnostic, not
|
|
256
|
+
* entity rows, and `QueryInterface.explain` deliberately bypasses middleware
|
|
257
|
+
* too, so both engines agree.
|
|
258
|
+
*/
|
|
259
|
+
explain(args?: FindManyArgs<T>): Promise<string[]>;
|
|
135
260
|
findUnique(args: FindUniqueArgs<T>): Promise<T | null>;
|
|
136
261
|
findFirst(args?: FindManyArgs<T>): Promise<T | null>;
|
|
137
262
|
findUniqueOrThrow(args: FindUniqueArgs<T>): Promise<T>;
|
|
138
263
|
findFirstOrThrow(args?: FindManyArgs<T>): Promise<T>;
|
|
139
|
-
/**
|
|
264
|
+
/**
|
|
265
|
+
* Load each requested relation for `parents` and attach it onto each row.
|
|
266
|
+
*
|
|
267
|
+
* `parent` is supplied ONLY by the top-level {@link findMany} (its args +
|
|
268
|
+
* resolved where). When the effective `relationLoadStrategy` resolves to an
|
|
269
|
+
* explicit `'join'` and the pool advertises `serverJoins`, an eligible
|
|
270
|
+
* top-level relation is loaded with a native PowQL join instead of the keyed
|
|
271
|
+
* loaders (F2); everything else (nested `with` levels, ineligible shapes, and
|
|
272
|
+
* the default `'batched'` strategy) keeps the loaders. Output is byte-equal
|
|
273
|
+
* either way (the join reuses the same stitch / shape helpers).
|
|
274
|
+
*/
|
|
140
275
|
private loadRelations;
|
|
141
276
|
/**
|
|
142
277
|
* manyToMany nested read — a three-hop batched loader (no `json_agg`/join
|
|
@@ -147,6 +282,88 @@ export declare class PowqlInterface<T extends object = Record<string, unknown>>
|
|
|
147
282
|
* (composite junction keys would need PowQL tuple-`in`, which it lacks).
|
|
148
283
|
*/
|
|
149
284
|
private loadManyToMany;
|
|
285
|
+
/**
|
|
286
|
+
* Resolve the effective relation-load strategy: the per-query arg wins, then
|
|
287
|
+
* the client config, then the PowDB default of `'batched'` (the keyed
|
|
288
|
+
* loaders). PowDB deliberately does NOT inherit the SQL-side implicit `'join'`
|
|
289
|
+
* default (that would silently flip every existing PowDB user onto brand-new
|
|
290
|
+
* join generation). Only a value the user actually set to `'join'` activates it.
|
|
291
|
+
*/
|
|
292
|
+
private resolveStrategy;
|
|
293
|
+
/**
|
|
294
|
+
* Per-relation eligibility for the join path (checked before the serverJoins
|
|
295
|
+
* capability). Any `false` here is a SILENT fallback to the keyed loaders (it
|
|
296
|
+
* is never an error), so an off-page or nested-`with` shape still returns
|
|
297
|
+
* correct rows:
|
|
298
|
+
* - the parent query must not be paged (`limit`/`offset`/`take`, including the
|
|
299
|
+
* configured `defaultLimit`): a parent-filter join under a page would scan
|
|
300
|
+
* children of off-page parents, where the loaders are strictly better;
|
|
301
|
+
* - the relation must not request a nested `with` (its subtree stays on the
|
|
302
|
+
* loaders this round) or a `distinct`;
|
|
303
|
+
* - single-column relation keys only (a composite key falls to the loader,
|
|
304
|
+
* which throws the same E017 as today);
|
|
305
|
+
* - the PARENT-SIDE correlation column must be a single-column PK or unique
|
|
306
|
+
* column, or the INNER join would re-emit one child copy per matching
|
|
307
|
+
* parent row (a non-unique correlation key produces duplicate children the
|
|
308
|
+
* loader never would). For hasMany/hasOne/m2m that column is the relation's
|
|
309
|
+
* `referenceKey` on THIS (fetched) table; for belongsTo it is the
|
|
310
|
+
* `referenceKey` on the TARGET table (the join's non-fetched side);
|
|
311
|
+
* - m2m keeps any `orderBy`/`limit`/`offset` on the loader (the junction-order
|
|
312
|
+
* stitch can't be reproduced by the 3-table join deterministically);
|
|
313
|
+
* - a to-one relation `limit`/`offset` (meaningless) stays on the loader, as
|
|
314
|
+
* does a to-many relation `limit`/`offset` when the parent set spills past
|
|
315
|
+
* one loader chunk (the loader limits per chunk, the join once globally).
|
|
316
|
+
*/
|
|
317
|
+
private joinEligible;
|
|
318
|
+
/**
|
|
319
|
+
* True when `col` is a single-column unique key of `tableMeta`: the sole
|
|
320
|
+
* primary-key column, a single-column entry in `uniqueColumns` (where a
|
|
321
|
+
* per-column `unique: true` and an introspected single-column unique constraint
|
|
322
|
+
* both land), or a single-column unique index. Used by {@link joinEligible} to
|
|
323
|
+
* keep the INNER-join path off relations whose parent-side correlation column
|
|
324
|
+
* can repeat (which would duplicate children).
|
|
325
|
+
*/
|
|
326
|
+
private isSingleColumnUnique;
|
|
327
|
+
/** Dispatch one eligible relation to the correct native-join loader. */
|
|
328
|
+
private loadRelationViaJoin;
|
|
329
|
+
/**
|
|
330
|
+
* manyToMany via chained joins: the target (alias `t`) → junction (alias `j`)
|
|
331
|
+
* → the already-fetched side (alias `p`), correlating `__tpk` from the
|
|
332
|
+
* junction's source key. Always a list, stitched exactly like the loader.
|
|
333
|
+
*/
|
|
334
|
+
private loadManyToManyViaJoin;
|
|
335
|
+
/**
|
|
336
|
+
* The target column list to project through the join (honouring select/omit),
|
|
337
|
+
* with a loud guard: a real column named `__tpk` would collide with the
|
|
338
|
+
* reserved correlation alias, so refuse rather than silently mis-stitch.
|
|
339
|
+
*/
|
|
340
|
+
private joinChildCols;
|
|
341
|
+
/**
|
|
342
|
+
* `{ __tpk: <tpkExpr>, <col>: <childAlias>.<col>, … }`. Each child column is
|
|
343
|
+
* ALIASED to its bare name (a bare qualified ref `c.col` would come back named
|
|
344
|
+
* `c.col`, not `col`) so the stitched rows shape identically to a flat select.
|
|
345
|
+
*/
|
|
346
|
+
private joinProjection;
|
|
347
|
+
/**
|
|
348
|
+
* `filter <parentWhere qualified p> [and <relationWhere qualified childAlias>]`.
|
|
349
|
+
* The parent where is the ALREADY-RESOLVED predicate (relation filters collapsed
|
|
350
|
+
* to literal in-lists before the base query ran); the relation where is resolved
|
|
351
|
+
* on the target the same way before qualifying, so a nested relation filter in
|
|
352
|
+
* the relation `where` never reaches the join unresolved. Params bind in order.
|
|
353
|
+
*/
|
|
354
|
+
private joinFilter;
|
|
355
|
+
/** Group join rows by their (normalized) `__tpk`, stripping it and shaping each child. */
|
|
356
|
+
private bucketByTpk;
|
|
357
|
+
/**
|
|
358
|
+
* Normalize a correlation key to a stable string map key so a parent's key
|
|
359
|
+
* value (a shaped entity field) and a child row's `__tpk` cell match across
|
|
360
|
+
* wires and column types. A `Date` maps to microseconds
|
|
361
|
+
* (`getTime()` ms times 1000), because a datetime correlation cell arrives as
|
|
362
|
+
* raw micros (bigint on the native wire, a micros string on the legacy wire),
|
|
363
|
+
* never as ms. bigint / number / string all stringify to the same digits, so
|
|
364
|
+
* an int key matches whether it came back typed or as text.
|
|
365
|
+
*/
|
|
366
|
+
private joinKey;
|
|
150
367
|
/** Split `data` into scalar assignments; reject relation (nested-write) keys. */
|
|
151
368
|
private scalarData;
|
|
152
369
|
/**
|
|
@@ -192,8 +409,28 @@ export declare class PowqlInterface<T extends object = Record<string, unknown>>
|
|
|
192
409
|
count(args?: CountArgs<T>): Promise<number>;
|
|
193
410
|
aggregate(args: AggregateArgs<T>): Promise<AggregateResult<T>>;
|
|
194
411
|
groupBy(args: GroupByArgs<T>): Promise<Record<string, unknown>[]>;
|
|
195
|
-
/**
|
|
412
|
+
/** Validate a JSON-path target (group key / aggregate target): non-empty array of keys/indexes. */
|
|
413
|
+
private assertJsonPath;
|
|
414
|
+
/**
|
|
415
|
+
* `having <expr>` over group aggregates. `_count` compares `count(*)` (parity
|
|
416
|
+
* with the projection); a per-field aggregate re-emits its inner expression
|
|
417
|
+
* (from `aggInner` when the field is a requested aggregate, so a JSON-path
|
|
418
|
+
* aggregate reuses its bound placeholders, else `.field` for a plain column).
|
|
419
|
+
*/
|
|
196
420
|
private buildHaving;
|
|
421
|
+
/**
|
|
422
|
+
* Compile a groupBy `orderBy` into a PowQL `order` body over the group RESULT
|
|
423
|
+
* columns (by-fields, JSON group-key aliases, and requested aggregates). PowQL
|
|
424
|
+
* cannot re-emit an aggregate EXPRESSION in `order` (engine error), but CAN
|
|
425
|
+
* order by a projection alias on a grouped query (probed), so each key maps to
|
|
426
|
+
* its projected alias (`.agg_N` / `.gk_N` / `.col`). Semantics and error
|
|
427
|
+
* surface mirror the SQL `buildGroupByOrderBy` (0.32.2 R3-1): an aggregate not
|
|
428
|
+
* requested in this call, or an unknown by-key, throws E003 listing the valid
|
|
429
|
+
* keys. `nulls: 'first'` stays E017 (PowDB has no NULLS placement grammar).
|
|
430
|
+
*/
|
|
431
|
+
private buildGroupOrder;
|
|
432
|
+
/** Resolve a groupBy order direction, refusing `nulls: 'first'` (E017); `nulls: 'last'` is a no-op. */
|
|
433
|
+
private groupOrderDir;
|
|
197
434
|
findManyStream(): AsyncGenerator<T>;
|
|
198
435
|
/** Reselect a single row by its single-column primary key value. */
|
|
199
436
|
private reselectByPk;
|