@prisma-next/sql-lane 0.3.0-dev.12 → 0.3.0-dev.122
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/LICENSE +201 -0
- package/README.md +18 -1
- package/dist/builder-DpxuiFO4.d.mts +118 -0
- package/dist/builder-DpxuiFO4.d.mts.map +1 -0
- package/dist/builder-MYJh5-Gn.mjs +1153 -0
- package/dist/builder-MYJh5-Gn.mjs.map +1 -0
- package/dist/exports/sql.d.mts +3 -0
- package/dist/exports/sql.mjs +3 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.mjs +3 -0
- package/package.json +26 -21
- package/src/raw.ts +9 -2
- package/src/sql/builder.ts +12 -9
- package/src/sql/context.ts +3 -3
- package/src/sql/include-builder.ts +109 -70
- package/src/sql/join-builder.ts +21 -11
- package/src/sql/mutation-builder.ts +94 -107
- package/src/sql/plan.ts +88 -128
- package/src/sql/predicate-builder.ts +74 -65
- package/src/sql/projection.ts +17 -12
- package/src/sql/select-builder.ts +64 -102
- package/src/types/internal.ts +6 -5
- package/src/utils/errors.ts +2 -2
- package/src/utils/state.ts +5 -6
- package/dist/chunk-AWSKRSFP.js +0 -1569
- package/dist/chunk-AWSKRSFP.js.map +0 -1
- package/dist/exports/sql.d.ts +0 -5
- package/dist/exports/sql.d.ts.map +0 -1
- package/dist/exports/sql.js +0 -11
- package/dist/exports/sql.js.map +0 -1
- package/dist/index.d.ts +0 -5
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -11
- package/dist/index.js.map +0 -1
- package/dist/raw.d.ts +0 -11
- package/dist/raw.d.ts.map +0 -1
- package/dist/sql/builder.d.ts +0 -11
- package/dist/sql/builder.d.ts.map +0 -1
- package/dist/sql/context.d.ts +0 -5
- package/dist/sql/context.d.ts.map +0 -1
- package/dist/sql/include-builder.d.ts +0 -35
- package/dist/sql/include-builder.d.ts.map +0 -1
- package/dist/sql/join-builder.d.ts +0 -4
- package/dist/sql/join-builder.d.ts.map +0 -1
- package/dist/sql/mutation-builder.d.ts +0 -64
- package/dist/sql/mutation-builder.d.ts.map +0 -1
- package/dist/sql/plan.d.ts +0 -4
- package/dist/sql/plan.d.ts.map +0 -1
- package/dist/sql/predicate-builder.d.ts +0 -11
- package/dist/sql/predicate-builder.d.ts.map +0 -1
- package/dist/sql/projection.d.ts +0 -18
- package/dist/sql/projection.d.ts.map +0 -1
- package/dist/sql/select-builder.d.ts +0 -35
- package/dist/sql/select-builder.d.ts.map +0 -1
- package/dist/types/internal.d.ts +0 -35
- package/dist/types/internal.d.ts.map +0 -1
- package/dist/types/public.d.ts +0 -18
- package/dist/types/public.d.ts.map +0 -1
- package/dist/utils/assertions.d.ts +0 -28
- package/dist/utils/assertions.d.ts.map +0 -1
- package/dist/utils/capabilities.d.ts +0 -4
- package/dist/utils/capabilities.d.ts.map +0 -1
- package/dist/utils/errors.d.ts +0 -30
- package/dist/utils/errors.d.ts.map +0 -1
- package/dist/utils/state.d.ts +0 -30
- package/dist/utils/state.d.ts.map +0 -1
|
@@ -1,27 +1,19 @@
|
|
|
1
|
-
import type { ParamDescriptor } from '@prisma-next/contract/types';
|
|
2
1
|
import type { SqlContract, SqlStorage, StorageColumn } from '@prisma-next/sql-contract/types';
|
|
3
|
-
import type {
|
|
4
|
-
BinaryExpr,
|
|
5
|
-
ColumnRef,
|
|
6
|
-
Direction,
|
|
7
|
-
IncludeAst,
|
|
8
|
-
IncludeRef,
|
|
9
|
-
JoinAst,
|
|
10
|
-
OperationExpr,
|
|
11
|
-
TableRef,
|
|
12
|
-
} from '@prisma-next/sql-relational-core/ast';
|
|
13
2
|
import {
|
|
14
|
-
createColumnRef,
|
|
15
3
|
createJoinOnBuilder,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
4
|
+
OrderByItem,
|
|
5
|
+
type ParamRef,
|
|
6
|
+
ProjectionItem,
|
|
7
|
+
SelectAst,
|
|
8
|
+
type TableRef,
|
|
9
|
+
TableSource,
|
|
19
10
|
} from '@prisma-next/sql-relational-core/ast';
|
|
20
11
|
import type { SqlQueryPlan } from '@prisma-next/sql-relational-core/plan';
|
|
21
|
-
import type {
|
|
12
|
+
import type { ExecutionContext } from '@prisma-next/sql-relational-core/query-lane-context';
|
|
22
13
|
import type {
|
|
23
14
|
AnyBinaryBuilder,
|
|
24
15
|
AnyOrderBuilder,
|
|
16
|
+
AnyUnaryBuilder,
|
|
25
17
|
BinaryBuilder,
|
|
26
18
|
BuildOptions,
|
|
27
19
|
InferNestedProjectionRow,
|
|
@@ -30,10 +22,11 @@ import type {
|
|
|
30
22
|
NestedProjection,
|
|
31
23
|
OrderBuilder,
|
|
32
24
|
SqlBuilderOptions,
|
|
25
|
+
UnaryBuilder,
|
|
33
26
|
} from '@prisma-next/sql-relational-core/types';
|
|
34
|
-
import {
|
|
27
|
+
import { isExpressionBuilder } from '@prisma-next/sql-relational-core/utils/guards';
|
|
28
|
+
import { ifDefined } from '@prisma-next/utils/defined';
|
|
35
29
|
import type { ProjectionInput } from '../types/internal';
|
|
36
|
-
import { assertColumnBuilder } from '../utils/assertions';
|
|
37
30
|
import { checkIncludeCapabilities } from '../utils/capabilities';
|
|
38
31
|
import {
|
|
39
32
|
errorChildProjectionEmpty,
|
|
@@ -41,14 +34,13 @@ import {
|
|
|
41
34
|
errorIncludeAliasCollision,
|
|
42
35
|
errorLimitMustBeNonNegativeInteger,
|
|
43
36
|
errorMissingAlias,
|
|
44
|
-
errorMissingColumnForAlias,
|
|
45
37
|
errorSelectMustBeCalled,
|
|
46
38
|
errorSelfJoinNotSupported,
|
|
47
39
|
errorUnknownTable,
|
|
48
40
|
} from '../utils/errors';
|
|
49
41
|
import type { BuilderState, IncludeState, JoinState, ProjectionState } from '../utils/state';
|
|
50
42
|
import {
|
|
51
|
-
|
|
43
|
+
buildIncludeJoinArtifact,
|
|
52
44
|
type IncludeChildBuilder,
|
|
53
45
|
IncludeChildBuilderImpl,
|
|
54
46
|
} from './include-builder';
|
|
@@ -57,6 +49,18 @@ import { buildMeta } from './plan';
|
|
|
57
49
|
import { buildWhereExpr } from './predicate-builder';
|
|
58
50
|
import { buildProjectionState } from './projection';
|
|
59
51
|
|
|
52
|
+
function deriveParamsFromAst(ast: { collectParamRefs(): ParamRef[] }) {
|
|
53
|
+
const collected = [...new Set(ast.collectParamRefs())];
|
|
54
|
+
return {
|
|
55
|
+
paramValues: collected.map((p) => p.value),
|
|
56
|
+
paramDescriptors: collected.map((p) => ({
|
|
57
|
+
...ifDefined('name', p.name),
|
|
58
|
+
source: 'dsl' as const,
|
|
59
|
+
...ifDefined('codecId', p.codecId),
|
|
60
|
+
})),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
60
64
|
export class SelectBuilderImpl<
|
|
61
65
|
TContract extends SqlContract<SqlStorage> = SqlContract<SqlStorage>,
|
|
62
66
|
Row = unknown,
|
|
@@ -64,14 +68,12 @@ export class SelectBuilderImpl<
|
|
|
64
68
|
Includes extends Record<string, unknown> = Record<string, never>,
|
|
65
69
|
> {
|
|
66
70
|
private readonly contract: TContract;
|
|
67
|
-
private readonly
|
|
68
|
-
private readonly context: QueryLaneContext<TContract>;
|
|
71
|
+
private readonly context: ExecutionContext<TContract>;
|
|
69
72
|
private state: BuilderState = {};
|
|
70
73
|
|
|
71
74
|
constructor(options: SqlBuilderOptions<TContract>, state?: BuilderState) {
|
|
72
75
|
this.context = options.context;
|
|
73
76
|
this.contract = options.context.contract;
|
|
74
|
-
this.codecTypes = options.context.contract.mappings.codecTypes as CodecTypes;
|
|
75
77
|
if (state) {
|
|
76
78
|
this.state = state;
|
|
77
79
|
}
|
|
@@ -146,7 +148,6 @@ export class SelectBuilderImpl<
|
|
|
146
148
|
// Build child builder
|
|
147
149
|
const childBuilderImpl = new IncludeChildBuilderImpl<TContract, CodecTypes, unknown>(
|
|
148
150
|
this.contract,
|
|
149
|
-
this.codecTypes,
|
|
150
151
|
childTable,
|
|
151
152
|
);
|
|
152
153
|
const builtChild = childBuilder(
|
|
@@ -238,7 +239,9 @@ export class SelectBuilderImpl<
|
|
|
238
239
|
);
|
|
239
240
|
}
|
|
240
241
|
|
|
241
|
-
where(
|
|
242
|
+
where(
|
|
243
|
+
expr: AnyBinaryBuilder | AnyUnaryBuilder,
|
|
244
|
+
): SelectBuilderImpl<TContract, Row, CodecTypes, Includes> {
|
|
242
245
|
return new SelectBuilderImpl<TContract, Row, CodecTypes, Includes>(
|
|
243
246
|
{
|
|
244
247
|
context: this.context,
|
|
@@ -304,43 +307,28 @@ export class SelectBuilderImpl<
|
|
|
304
307
|
errorUnknownTable(table.name);
|
|
305
308
|
}
|
|
306
309
|
|
|
307
|
-
const paramDescriptors: ParamDescriptor[] = [];
|
|
308
|
-
const paramValues: unknown[] = [];
|
|
309
|
-
const paramCodecs: Record<string, string> = {};
|
|
310
|
-
|
|
311
310
|
const whereResult = this.state.where
|
|
312
|
-
? buildWhereExpr(this.contract, this.state.where, paramsMap
|
|
311
|
+
? buildWhereExpr(this.contract, this.state.where, paramsMap)
|
|
313
312
|
: undefined;
|
|
314
313
|
const whereExpr = whereResult?.expr;
|
|
315
314
|
|
|
316
|
-
if (whereResult?.codecId && whereResult.paramName) {
|
|
317
|
-
paramCodecs[whereResult.paramName] = whereResult.codecId;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
315
|
const orderByClause = this.state.orderBy
|
|
321
316
|
? (() => {
|
|
322
317
|
const orderBy = this.state.orderBy as OrderBuilder<string, StorageColumn, unknown>;
|
|
323
|
-
|
|
324
|
-
const operationExpr = getOperationExpr(orderExpr);
|
|
325
|
-
const expr: ColumnRef | OperationExpr = operationExpr
|
|
326
|
-
? operationExpr
|
|
327
|
-
: (() => {
|
|
328
|
-
const colBuilder = orderExpr as { table: string; column: string };
|
|
329
|
-
return createColumnRef(colBuilder.table, colBuilder.column);
|
|
330
|
-
})();
|
|
331
|
-
return [createOrderByItem(expr, orderBy.dir)];
|
|
318
|
+
return [new OrderByItem(orderBy.expr, orderBy.dir)];
|
|
332
319
|
})()
|
|
333
320
|
: undefined;
|
|
334
321
|
|
|
335
|
-
const joins = this.state.joins?.map((join) => buildJoinAst(join));
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
322
|
+
const joins = this.state.joins?.map((join) => buildJoinAst(join)) ?? [];
|
|
323
|
+
const includeArtifacts =
|
|
324
|
+
this.state.includes?.map((include) =>
|
|
325
|
+
buildIncludeJoinArtifact(include, this.contract, paramsMap),
|
|
326
|
+
) ?? [];
|
|
327
|
+
const includeProjectionByAlias = new Map(
|
|
328
|
+
includeArtifacts.map((artifact) => [artifact.projection.alias, artifact.projection]),
|
|
339
329
|
);
|
|
340
330
|
|
|
341
|
-
|
|
342
|
-
const projectEntries: Array<{ alias: string; expr: ColumnRef | IncludeRef | OperationExpr }> =
|
|
343
|
-
[];
|
|
331
|
+
const projectEntries: ProjectionItem[] = [];
|
|
344
332
|
for (let i = 0; i < projection.aliases.length; i++) {
|
|
345
333
|
const alias = projection.aliases[i];
|
|
346
334
|
if (!alias) {
|
|
@@ -348,57 +336,31 @@ export class SelectBuilderImpl<
|
|
|
348
336
|
}
|
|
349
337
|
const column = projection.columns[i];
|
|
350
338
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
if (
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
expr: { kind: 'includeRef', alias },
|
|
359
|
-
});
|
|
360
|
-
} else {
|
|
361
|
-
// Not an include - column must not be null
|
|
362
|
-
if (!column) {
|
|
363
|
-
errorMissingColumnForAlias(alias, i);
|
|
364
|
-
}
|
|
365
|
-
// Check if this column has an operation expression
|
|
366
|
-
const operationExpr = (column as { _operationExpr?: OperationExpr })._operationExpr;
|
|
367
|
-
if (operationExpr) {
|
|
368
|
-
projectEntries.push({
|
|
369
|
-
alias,
|
|
370
|
-
expr: operationExpr,
|
|
371
|
-
});
|
|
372
|
-
} else {
|
|
373
|
-
// This is a regular column
|
|
374
|
-
// TypeScript can't narrow ColumnBuilder properly
|
|
375
|
-
const col = column as { table: string; column: string };
|
|
376
|
-
assertColumnBuilder(col, 'projection column');
|
|
377
|
-
projectEntries.push({
|
|
378
|
-
alias,
|
|
379
|
-
expr: createColumnRef(col.table, col.column),
|
|
380
|
-
});
|
|
381
|
-
}
|
|
339
|
+
const includeProjection = includeProjectionByAlias.get(alias);
|
|
340
|
+
if (includeProjection) {
|
|
341
|
+
projectEntries.push(includeProjection);
|
|
342
|
+
} else if (column && isExpressionBuilder(column)) {
|
|
343
|
+
projectEntries.push(ProjectionItem.of(alias, column.expr));
|
|
344
|
+
} else if (column) {
|
|
345
|
+
projectEntries.push(ProjectionItem.of(alias, column.toExpr()));
|
|
382
346
|
}
|
|
383
347
|
}
|
|
384
348
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
limit?: number;
|
|
401
|
-
});
|
|
349
|
+
let ast = SelectAst.from(TableSource.named(table.name, table.alias))
|
|
350
|
+
.withProjection(projectEntries)
|
|
351
|
+
.withWhere(whereExpr);
|
|
352
|
+
const allJoins = [...joins, ...includeArtifacts.map((artifact) => artifact.join)];
|
|
353
|
+
if (allJoins.length > 0) {
|
|
354
|
+
ast = ast.withJoins(allJoins);
|
|
355
|
+
}
|
|
356
|
+
if (orderByClause) {
|
|
357
|
+
ast = ast.withOrderBy(orderByClause);
|
|
358
|
+
}
|
|
359
|
+
if (this.state.limit !== undefined) {
|
|
360
|
+
ast = ast.withLimit(this.state.limit);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
const { paramValues, paramDescriptors } = deriveParamsFromAst(ast);
|
|
402
364
|
|
|
403
365
|
const planMeta = buildMeta({
|
|
404
366
|
contract: this.contract,
|
|
@@ -407,19 +369,19 @@ export class SelectBuilderImpl<
|
|
|
407
369
|
joins: this.state.joins,
|
|
408
370
|
includes: this.state.includes,
|
|
409
371
|
paramDescriptors,
|
|
410
|
-
paramCodecs,
|
|
411
372
|
where: this.state.where,
|
|
412
373
|
orderBy: this.state.orderBy,
|
|
374
|
+
limit: this.state.limit,
|
|
413
375
|
} as {
|
|
414
376
|
contract: SqlContract<SqlStorage>;
|
|
415
377
|
table: TableRef;
|
|
416
378
|
projection: ProjectionState;
|
|
417
379
|
joins?: ReadonlyArray<JoinState>;
|
|
418
380
|
includes?: ReadonlyArray<IncludeState>;
|
|
419
|
-
where?: BinaryBuilder;
|
|
381
|
+
where?: BinaryBuilder | UnaryBuilder;
|
|
420
382
|
orderBy?: AnyOrderBuilder;
|
|
421
|
-
|
|
422
|
-
|
|
383
|
+
limit?: number;
|
|
384
|
+
paramDescriptors: typeof paramDescriptors;
|
|
423
385
|
});
|
|
424
386
|
|
|
425
387
|
const queryPlan: SqlQueryPlan<Row> = Object.freeze({
|
package/src/types/internal.ts
CHANGED
|
@@ -3,13 +3,14 @@ import type { SqlContract, SqlStorage } from '@prisma-next/sql-contract/types';
|
|
|
3
3
|
import type { TableRef } from '@prisma-next/sql-relational-core/ast';
|
|
4
4
|
import type {
|
|
5
5
|
AnyBinaryBuilder,
|
|
6
|
-
|
|
6
|
+
AnyExpressionSource,
|
|
7
7
|
AnyOrderBuilder,
|
|
8
|
+
AnyUnaryBuilder,
|
|
8
9
|
NestedProjection,
|
|
9
10
|
} from '@prisma-next/sql-relational-core/types';
|
|
10
11
|
import type { ProjectionState } from '../utils/state';
|
|
11
12
|
|
|
12
|
-
export type ProjectionInput = Record<string,
|
|
13
|
+
export type ProjectionInput = Record<string, AnyExpressionSource | boolean | NestedProjection>;
|
|
13
14
|
|
|
14
15
|
export interface MetaBuildArgs {
|
|
15
16
|
readonly contract: SqlContract<SqlStorage>;
|
|
@@ -31,11 +32,11 @@ export interface MetaBuildArgs {
|
|
|
31
32
|
readonly right: unknown;
|
|
32
33
|
};
|
|
33
34
|
readonly childProjection: ProjectionState;
|
|
34
|
-
readonly childWhere?: AnyBinaryBuilder;
|
|
35
|
+
readonly childWhere?: AnyBinaryBuilder | AnyUnaryBuilder;
|
|
35
36
|
readonly childOrderBy?: AnyOrderBuilder;
|
|
36
37
|
}>;
|
|
37
|
-
readonly where?: AnyBinaryBuilder;
|
|
38
|
+
readonly where?: AnyBinaryBuilder | AnyUnaryBuilder;
|
|
38
39
|
readonly orderBy?: AnyOrderBuilder;
|
|
40
|
+
readonly limit?: number;
|
|
39
41
|
readonly paramDescriptors: ParamDescriptor[];
|
|
40
|
-
readonly paramCodecs?: Record<string, string>;
|
|
41
42
|
}
|
package/src/utils/errors.ts
CHANGED
|
@@ -73,7 +73,7 @@ export function errorIncludeAliasCollision(alias: string, type: 'projection' | '
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
export function errorMissingColumnForAlias(alias: string, index: number): never {
|
|
76
|
-
throw planInvalid(`Missing column for alias ${alias
|
|
76
|
+
throw planInvalid(`Missing column for alias ${alias} at index ${index}`);
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
export function errorMissingAlias(index: number): never {
|
|
@@ -98,7 +98,7 @@ export function errorMissingParameter(paramName: string): never {
|
|
|
98
98
|
|
|
99
99
|
export function errorInvalidProjectionValue(path: string[]): never {
|
|
100
100
|
throw planInvalid(
|
|
101
|
-
`Invalid projection value at path ${path.join('.')}: expected ColumnBuilder or nested object`,
|
|
101
|
+
`Invalid projection value at path ${path.join('.')}: expected ExpressionSource (ColumnBuilder or ExpressionBuilder) or nested object`,
|
|
102
102
|
);
|
|
103
103
|
}
|
|
104
104
|
|
package/src/utils/state.ts
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import type { TableRef } from '@prisma-next/sql-relational-core/ast';
|
|
2
2
|
import type {
|
|
3
3
|
AnyBinaryBuilder,
|
|
4
|
-
|
|
4
|
+
AnyExpressionSource,
|
|
5
5
|
AnyOrderBuilder,
|
|
6
|
+
AnyUnaryBuilder,
|
|
6
7
|
JoinOnPredicate,
|
|
7
8
|
} from '@prisma-next/sql-relational-core/types';
|
|
8
9
|
|
|
9
10
|
export interface ProjectionState {
|
|
10
11
|
readonly aliases: string[];
|
|
11
|
-
|
|
12
|
-
// This maintains array alignment but avoids creating invalid ColumnBuilders
|
|
13
|
-
readonly columns: (AnyColumnBuilder | null)[];
|
|
12
|
+
readonly columns: AnyExpressionSource[];
|
|
14
13
|
}
|
|
15
14
|
|
|
16
15
|
export interface JoinState {
|
|
@@ -24,7 +23,7 @@ export interface IncludeState {
|
|
|
24
23
|
readonly table: TableRef;
|
|
25
24
|
readonly on: JoinOnPredicate;
|
|
26
25
|
readonly childProjection: ProjectionState;
|
|
27
|
-
readonly childWhere?: AnyBinaryBuilder;
|
|
26
|
+
readonly childWhere?: AnyBinaryBuilder | AnyUnaryBuilder;
|
|
28
27
|
readonly childOrderBy?: AnyOrderBuilder;
|
|
29
28
|
readonly childLimit?: number;
|
|
30
29
|
}
|
|
@@ -34,7 +33,7 @@ export interface BuilderState {
|
|
|
34
33
|
joins?: ReadonlyArray<JoinState>;
|
|
35
34
|
includes?: ReadonlyArray<IncludeState>;
|
|
36
35
|
projection?: ProjectionState;
|
|
37
|
-
where?: AnyBinaryBuilder;
|
|
36
|
+
where?: AnyBinaryBuilder | AnyUnaryBuilder;
|
|
38
37
|
orderBy?: AnyOrderBuilder;
|
|
39
38
|
limit?: number;
|
|
40
39
|
}
|