@prisma-next/sql-orm-lane 0.3.0-pr.95.1 → 0.3.0-pr.98.1
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/{chunk-C4EECZ4E.js → chunk-3DNKIXXB.js} +119 -106
- package/dist/chunk-3DNKIXXB.js.map +1 -0
- package/dist/exports/orm.js +1 -1
- package/dist/index.js +1 -1
- package/dist/orm/state.d.ts +3 -3
- package/dist/orm/state.d.ts.map +1 -1
- package/dist/plan/plan-assembly.d.ts.map +1 -1
- package/dist/relations/include-plan.d.ts.map +1 -1
- package/dist/selection/predicates.d.ts.map +1 -1
- package/dist/selection/projection.d.ts +4 -4
- package/dist/selection/projection.d.ts.map +1 -1
- package/dist/selection/select-builder.d.ts +4 -4
- package/dist/selection/select-builder.d.ts.map +1 -1
- package/package.json +9 -9
- package/src/orm/state.ts +3 -3
- package/src/plan/plan-assembly.ts +80 -95
- package/src/relations/include-plan.ts +5 -5
- package/src/selection/predicates.ts +41 -25
- package/src/selection/projection.ts +10 -16
- package/src/selection/select-builder.ts +24 -22
- package/dist/chunk-C4EECZ4E.js.map +0 -1
|
@@ -4,22 +4,21 @@ import type { SqlContract, SqlStorage } from '@prisma-next/sql-contract/types';
|
|
|
4
4
|
import type {
|
|
5
5
|
BinaryExpr,
|
|
6
6
|
ExistsExpr,
|
|
7
|
-
Expression,
|
|
8
7
|
LoweredStatement,
|
|
8
|
+
OperationExpr,
|
|
9
9
|
SelectAst,
|
|
10
10
|
TableRef,
|
|
11
11
|
} from '@prisma-next/sql-relational-core/ast';
|
|
12
12
|
import { compact } from '@prisma-next/sql-relational-core/ast';
|
|
13
13
|
import type {
|
|
14
|
-
|
|
14
|
+
AnyColumnBuilder,
|
|
15
15
|
AnyOrderBuilder,
|
|
16
16
|
BinaryBuilder,
|
|
17
17
|
} from '@prisma-next/sql-relational-core/types';
|
|
18
18
|
import {
|
|
19
19
|
collectColumnRefs,
|
|
20
|
+
getColumnInfo,
|
|
20
21
|
getColumnMeta,
|
|
21
|
-
isColumnBuilder,
|
|
22
|
-
isExpressionBuilder,
|
|
23
22
|
isOperationExpr,
|
|
24
23
|
} from '@prisma-next/sql-relational-core/utils/guards';
|
|
25
24
|
import type { IncludeState } from '../relations/include-plan';
|
|
@@ -36,66 +35,29 @@ export interface MetaBuildArgs {
|
|
|
36
35
|
readonly paramCodecs?: Record<string, string>;
|
|
37
36
|
}
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const allRefs = collectColumnRefs(source.expr);
|
|
49
|
-
for (const ref of allRefs) {
|
|
50
|
-
// Skip empty table/column (placeholders for includes)
|
|
51
|
-
if (ref.table && ref.column) {
|
|
38
|
+
export function buildMeta(args: MetaBuildArgs): PlanMeta {
|
|
39
|
+
const refsColumns = new Map<string, { table: string; column: string }>();
|
|
40
|
+
const refsTables = new Set<string>([args.table.name]);
|
|
41
|
+
|
|
42
|
+
for (const column of args.projection.columns) {
|
|
43
|
+
const operationExpr = (column as { _operationExpr?: OperationExpr })._operationExpr;
|
|
44
|
+
if (operationExpr) {
|
|
45
|
+
const allRefs = collectColumnRefs(operationExpr);
|
|
46
|
+
for (const ref of allRefs) {
|
|
52
47
|
refsColumns.set(`${ref.table}.${ref.column}`, {
|
|
53
48
|
table: ref.table,
|
|
54
49
|
column: ref.column,
|
|
55
50
|
});
|
|
56
51
|
}
|
|
52
|
+
} else {
|
|
53
|
+
const col = column as unknown as { table?: string; column?: string };
|
|
54
|
+
if (col.table && col.column) {
|
|
55
|
+
refsColumns.set(`${col.table}.${col.column}`, {
|
|
56
|
+
table: col.table,
|
|
57
|
+
column: col.column,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
57
60
|
}
|
|
58
|
-
} else if (isColumnBuilder(source)) {
|
|
59
|
-
const col = source as unknown as { table: string; column: string };
|
|
60
|
-
// Skip empty table/column (placeholders for includes)
|
|
61
|
-
if (col.table && col.column) {
|
|
62
|
-
refsColumns.set(`${col.table}.${col.column}`, {
|
|
63
|
-
table: col.table,
|
|
64
|
-
column: col.column,
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Extracts column references from an Expression (AST node).
|
|
72
|
-
*/
|
|
73
|
-
function collectRefsFromExpression(
|
|
74
|
-
expr: Expression,
|
|
75
|
-
refsColumns: Map<string, { table: string; column: string }>,
|
|
76
|
-
): void {
|
|
77
|
-
if (isOperationExpr(expr)) {
|
|
78
|
-
const allRefs = collectColumnRefs(expr);
|
|
79
|
-
for (const ref of allRefs) {
|
|
80
|
-
refsColumns.set(`${ref.table}.${ref.column}`, {
|
|
81
|
-
table: ref.table,
|
|
82
|
-
column: ref.column,
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
} else if (expr.kind === 'col') {
|
|
86
|
-
refsColumns.set(`${expr.table}.${expr.column}`, {
|
|
87
|
-
table: expr.table,
|
|
88
|
-
column: expr.column,
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export function buildMeta(args: MetaBuildArgs): PlanMeta {
|
|
94
|
-
const refsColumns = new Map<string, { table: string; column: string }>();
|
|
95
|
-
const refsTables = new Set<string>([args.table.name]);
|
|
96
|
-
|
|
97
|
-
for (const column of args.projection.columns) {
|
|
98
|
-
collectRefsFromExpressionSource(column, refsColumns);
|
|
99
61
|
}
|
|
100
62
|
|
|
101
63
|
if (args.includes) {
|
|
@@ -123,21 +85,32 @@ export function buildMeta(args: MetaBuildArgs): PlanMeta {
|
|
|
123
85
|
}
|
|
124
86
|
}
|
|
125
87
|
if (include.childWhere) {
|
|
126
|
-
|
|
127
|
-
|
|
88
|
+
const colInfo = getColumnInfo(include.childWhere.left);
|
|
89
|
+
refsColumns.set(`${colInfo.table}.${colInfo.column}`, {
|
|
90
|
+
table: colInfo.table,
|
|
91
|
+
column: colInfo.column,
|
|
92
|
+
});
|
|
128
93
|
}
|
|
129
94
|
if (include.childOrderBy) {
|
|
130
|
-
|
|
131
|
-
|
|
95
|
+
const orderBy = include.childOrderBy as unknown as {
|
|
96
|
+
expr?: AnyColumnBuilder | OperationExpr;
|
|
97
|
+
};
|
|
98
|
+
if (orderBy.expr) {
|
|
99
|
+
const colInfo = getColumnInfo(orderBy.expr);
|
|
100
|
+
refsColumns.set(`${colInfo.table}.${colInfo.column}`, {
|
|
101
|
+
table: colInfo.table,
|
|
102
|
+
column: colInfo.column,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
132
105
|
}
|
|
133
106
|
}
|
|
134
107
|
}
|
|
135
108
|
|
|
136
109
|
if (args.where) {
|
|
137
|
-
|
|
138
|
-
const
|
|
139
|
-
if (
|
|
140
|
-
const allRefs = collectColumnRefs(
|
|
110
|
+
const whereLeft = args.where.left;
|
|
111
|
+
const operationExpr = (whereLeft as { _operationExpr?: OperationExpr })._operationExpr;
|
|
112
|
+
if (operationExpr) {
|
|
113
|
+
const allRefs = collectColumnRefs(operationExpr);
|
|
141
114
|
for (const ref of allRefs) {
|
|
142
115
|
refsColumns.set(`${ref.table}.${ref.column}`, {
|
|
143
116
|
table: ref.table,
|
|
@@ -145,31 +118,39 @@ export function buildMeta(args: MetaBuildArgs): PlanMeta {
|
|
|
145
118
|
});
|
|
146
119
|
}
|
|
147
120
|
} else {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
table
|
|
151
|
-
|
|
152
|
-
|
|
121
|
+
const colBuilder = whereLeft as unknown as { table?: string; column?: string };
|
|
122
|
+
if (colBuilder.table && colBuilder.column) {
|
|
123
|
+
refsColumns.set(`${colBuilder.table}.${colBuilder.column}`, {
|
|
124
|
+
table: colBuilder.table,
|
|
125
|
+
column: colBuilder.column,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
153
128
|
}
|
|
154
129
|
}
|
|
155
130
|
|
|
156
131
|
if (args.orderBy) {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
132
|
+
const orderBy = args.orderBy as unknown as {
|
|
133
|
+
expr?: AnyColumnBuilder | OperationExpr;
|
|
134
|
+
};
|
|
135
|
+
const orderByExpr = orderBy.expr;
|
|
136
|
+
if (orderByExpr) {
|
|
137
|
+
if (isOperationExpr(orderByExpr)) {
|
|
138
|
+
const allRefs = collectColumnRefs(orderByExpr);
|
|
139
|
+
for (const ref of allRefs) {
|
|
140
|
+
refsColumns.set(`${ref.table}.${ref.column}`, {
|
|
141
|
+
table: ref.table,
|
|
142
|
+
column: ref.column,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
} else {
|
|
146
|
+
const colBuilder = orderByExpr as unknown as { table?: string; column?: string };
|
|
147
|
+
if (colBuilder.table && colBuilder.column) {
|
|
148
|
+
refsColumns.set(`${colBuilder.table}.${colBuilder.column}`, {
|
|
149
|
+
table: colBuilder.table,
|
|
150
|
+
column: colBuilder.column,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
166
153
|
}
|
|
167
|
-
} else {
|
|
168
|
-
// orderByExpr is ColumnRef
|
|
169
|
-
refsColumns.set(`${orderByExpr.table}.${orderByExpr.column}`, {
|
|
170
|
-
table: orderByExpr.table,
|
|
171
|
-
column: orderByExpr.column,
|
|
172
|
-
});
|
|
173
154
|
}
|
|
174
155
|
}
|
|
175
156
|
|
|
@@ -183,14 +164,18 @@ export function buildMeta(args: MetaBuildArgs): PlanMeta {
|
|
|
183
164
|
if (!column) {
|
|
184
165
|
throw planInvalid(`Missing column for alias ${alias} at index ${index}`);
|
|
185
166
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
167
|
+
const col = column as unknown as {
|
|
168
|
+
table?: string;
|
|
169
|
+
column?: string;
|
|
170
|
+
_operationExpr?: OperationExpr;
|
|
171
|
+
};
|
|
191
172
|
if (!col.table || !col.column) {
|
|
192
173
|
return [alias, `include:${alias}`];
|
|
193
174
|
}
|
|
175
|
+
const operationExpr = col._operationExpr;
|
|
176
|
+
if (operationExpr) {
|
|
177
|
+
return [alias, `operation:${operationExpr.method}`];
|
|
178
|
+
}
|
|
194
179
|
return [alias, `${col.table}.${col.column}`];
|
|
195
180
|
}),
|
|
196
181
|
);
|
|
@@ -205,8 +190,8 @@ export function buildMeta(args: MetaBuildArgs): PlanMeta {
|
|
|
205
190
|
if (!col) {
|
|
206
191
|
continue;
|
|
207
192
|
}
|
|
208
|
-
|
|
209
|
-
|
|
193
|
+
const operationExpr = (col as { _operationExpr?: OperationExpr })._operationExpr;
|
|
194
|
+
if (operationExpr) {
|
|
210
195
|
if (operationExpr.returns.kind === 'typeId') {
|
|
211
196
|
projectionTypes[alias] = operationExpr.returns.type;
|
|
212
197
|
} else if (operationExpr.returns.kind === 'builtin') {
|
|
@@ -231,8 +216,8 @@ export function buildMeta(args: MetaBuildArgs): PlanMeta {
|
|
|
231
216
|
if (!column) {
|
|
232
217
|
continue;
|
|
233
218
|
}
|
|
234
|
-
|
|
235
|
-
|
|
219
|
+
const operationExpr = (column as { _operationExpr?: OperationExpr })._operationExpr;
|
|
220
|
+
if (operationExpr) {
|
|
236
221
|
if (operationExpr.returns.kind === 'typeId') {
|
|
237
222
|
projectionCodecs[alias] = operationExpr.returns.type;
|
|
238
223
|
}
|
|
@@ -19,7 +19,6 @@ import type {
|
|
|
19
19
|
BuildOptions,
|
|
20
20
|
NestedProjection,
|
|
21
21
|
} from '@prisma-next/sql-relational-core/types';
|
|
22
|
-
import { isExpressionBuilder } from '@prisma-next/sql-relational-core/utils/guards';
|
|
23
22
|
import { checkIncludeCapabilities } from '../orm/capabilities';
|
|
24
23
|
import type { OrmIncludeState, RelationFilter } from '../orm/state';
|
|
25
24
|
import { buildJoinOnExpr } from '../selection/join';
|
|
@@ -176,11 +175,12 @@ export function buildIncludeAsts(input: BuildIncludeAstsInput): {
|
|
|
176
175
|
if (!column) {
|
|
177
176
|
errorMissingColumn(alias, i);
|
|
178
177
|
}
|
|
179
|
-
|
|
180
|
-
|
|
178
|
+
const operationExpr = (column as { _operationExpr?: OperationExpr })._operationExpr;
|
|
179
|
+
if (operationExpr) {
|
|
180
|
+
childProjectionItems.push({ alias, expr: operationExpr });
|
|
181
181
|
} else {
|
|
182
|
-
|
|
183
|
-
childProjectionItems.push({ alias, expr: column
|
|
182
|
+
const col = column as { table: string; column: string };
|
|
183
|
+
childProjectionItems.push({ alias, expr: createColumnRef(col.table, col.column) });
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
186
|
|
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import type { ParamDescriptor } from '@prisma-next/contract/types';
|
|
2
2
|
import type { SqlContract, SqlStorage, StorageColumn } from '@prisma-next/sql-contract/types';
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
BinaryExpr,
|
|
5
|
+
ColumnRef,
|
|
6
|
+
OperationExpr,
|
|
7
|
+
ParamRef,
|
|
8
|
+
} from '@prisma-next/sql-relational-core/ast';
|
|
4
9
|
import { augmentDescriptorWithColumnMeta } from '@prisma-next/sql-relational-core/plan';
|
|
5
10
|
import type { BinaryBuilder, ParamPlaceholder } from '@prisma-next/sql-relational-core/types';
|
|
6
11
|
import {
|
|
12
|
+
getColumnInfo,
|
|
13
|
+
getColumnMeta,
|
|
14
|
+
getOperationExpr,
|
|
7
15
|
isColumnBuilder,
|
|
8
|
-
isExpressionBuilder,
|
|
9
16
|
isParamPlaceholder,
|
|
10
17
|
} from '@prisma-next/sql-relational-core/utils/guards';
|
|
11
|
-
import { createBinaryExpr, createParamRef } from '../utils/ast';
|
|
18
|
+
import { createBinaryExpr, createColumnRef, createParamRef } from '../utils/ast';
|
|
12
19
|
import {
|
|
13
20
|
errorFailedToBuildWhereClause,
|
|
14
21
|
errorMissingParameter,
|
|
@@ -26,17 +33,16 @@ export function buildWhereExpr(
|
|
|
26
33
|
codecId?: string;
|
|
27
34
|
paramName: string;
|
|
28
35
|
} {
|
|
29
|
-
let leftExpr:
|
|
36
|
+
let leftExpr: ColumnRef | OperationExpr;
|
|
30
37
|
let codecId: string | undefined;
|
|
31
|
-
let rightExpr:
|
|
38
|
+
let rightExpr: ColumnRef | ParamRef;
|
|
32
39
|
let paramName: string;
|
|
33
40
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const { table, column } = leftExpr;
|
|
41
|
+
const operationExpr = getOperationExpr(where.left);
|
|
42
|
+
if (operationExpr) {
|
|
43
|
+
leftExpr = operationExpr;
|
|
44
|
+
} else if (isColumnBuilder(where.left)) {
|
|
45
|
+
const { table, column } = getColumnInfo(where.left);
|
|
40
46
|
|
|
41
47
|
const contractTable = contract.storage.tables[table];
|
|
42
48
|
if (!contractTable) {
|
|
@@ -49,9 +55,12 @@ export function buildWhereExpr(
|
|
|
49
55
|
if (columnMeta) {
|
|
50
56
|
codecId = columnMeta.codecId;
|
|
51
57
|
}
|
|
58
|
+
leftExpr = createColumnRef(table, column);
|
|
59
|
+
} else {
|
|
60
|
+
errorFailedToBuildWhereClause();
|
|
52
61
|
}
|
|
53
62
|
|
|
54
|
-
// Handle where.right - can be ParamPlaceholder or
|
|
63
|
+
// Handle where.right - can be ParamPlaceholder or AnyColumnBuilder
|
|
55
64
|
if (isParamPlaceholder(where.right)) {
|
|
56
65
|
// Handle param placeholder (existing logic)
|
|
57
66
|
const placeholder: ParamPlaceholder = where.right;
|
|
@@ -64,35 +73,42 @@ export function buildWhereExpr(
|
|
|
64
73
|
const value = paramsMap[paramName];
|
|
65
74
|
const index = values.push(value);
|
|
66
75
|
|
|
67
|
-
// Construct descriptor
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (leftExpr.kind === 'col') {
|
|
71
|
-
const { table, column } = leftExpr;
|
|
76
|
+
// Construct descriptor if where.left is a ColumnBuilder
|
|
77
|
+
if (isColumnBuilder(where.left)) {
|
|
78
|
+
const { table, column } = getColumnInfo(where.left);
|
|
72
79
|
const contractTable = contract.storage.tables[table];
|
|
73
80
|
const columnMeta = contractTable?.columns[column];
|
|
81
|
+
const builderColumnMeta = getColumnMeta(where.left);
|
|
74
82
|
|
|
75
83
|
descriptors.push({
|
|
76
84
|
name: paramName,
|
|
77
85
|
source: 'dsl',
|
|
78
86
|
refs: { table, column },
|
|
79
|
-
...(
|
|
80
|
-
? { nullable:
|
|
87
|
+
...(typeof builderColumnMeta?.nullable === 'boolean'
|
|
88
|
+
? { nullable: builderColumnMeta.nullable }
|
|
81
89
|
: {}),
|
|
82
90
|
});
|
|
83
91
|
|
|
84
92
|
augmentDescriptorWithColumnMeta(descriptors, columnMeta);
|
|
85
93
|
}
|
|
86
|
-
// For OperationExpr, we don't create descriptors since we can't reliably extract column info
|
|
87
94
|
|
|
88
95
|
rightExpr = createParamRef(index, paramName);
|
|
89
|
-
} else if (isColumnBuilder(where.right)
|
|
90
|
-
// Handle
|
|
91
|
-
|
|
92
|
-
|
|
96
|
+
} else if (isColumnBuilder(where.right)) {
|
|
97
|
+
// Handle column builder on the right
|
|
98
|
+
const { table, column } = getColumnInfo(where.right);
|
|
99
|
+
|
|
100
|
+
const contractTable = contract.storage.tables[table];
|
|
101
|
+
if (!contractTable) {
|
|
102
|
+
errorUnknownTable(table);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// If column not found in contract, still build expression
|
|
106
|
+
// This allows flexibility when columnMeta is available on the column builder
|
|
107
|
+
rightExpr = createColumnRef(table, column);
|
|
108
|
+
// Use a placeholder paramName for column references (not used for params)
|
|
93
109
|
paramName = '';
|
|
94
110
|
} else {
|
|
95
|
-
// where.right is neither ParamPlaceholder nor
|
|
111
|
+
// where.right is neither ParamPlaceholder nor ColumnBuilder - invalid state
|
|
96
112
|
errorFailedToBuildWhereClause();
|
|
97
113
|
}
|
|
98
114
|
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import type { TableRef } from '@prisma-next/sql-relational-core/ast';
|
|
2
2
|
import type {
|
|
3
3
|
AnyBinaryBuilder,
|
|
4
|
-
|
|
4
|
+
AnyColumnBuilder,
|
|
5
5
|
AnyOrderBuilder,
|
|
6
6
|
JoinOnPredicate,
|
|
7
7
|
NestedProjection,
|
|
8
8
|
} from '@prisma-next/sql-relational-core/types';
|
|
9
|
-
import {
|
|
10
|
-
isColumnBuilder,
|
|
11
|
-
isExpressionBuilder,
|
|
12
|
-
} from '@prisma-next/sql-relational-core/utils/guards';
|
|
9
|
+
import { isColumnBuilder } from '@prisma-next/sql-relational-core/utils/guards';
|
|
13
10
|
import {
|
|
14
11
|
errorAliasCollision,
|
|
15
12
|
errorAliasPathEmpty,
|
|
@@ -21,10 +18,10 @@ import {
|
|
|
21
18
|
|
|
22
19
|
export interface ProjectionState {
|
|
23
20
|
readonly aliases: string[];
|
|
24
|
-
readonly columns:
|
|
21
|
+
readonly columns: AnyColumnBuilder[];
|
|
25
22
|
}
|
|
26
23
|
|
|
27
|
-
export type ProjectionInput = Record<string,
|
|
24
|
+
export type ProjectionInput = Record<string, AnyColumnBuilder | boolean | NestedProjection>;
|
|
28
25
|
|
|
29
26
|
function generateAlias(path: string[]): string {
|
|
30
27
|
if (path.length === 0) {
|
|
@@ -61,14 +58,14 @@ export function flattenProjection(
|
|
|
61
58
|
projection: NestedProjection,
|
|
62
59
|
tracker: AliasTracker,
|
|
63
60
|
currentPath: string[] = [],
|
|
64
|
-
): { aliases: string[]; columns:
|
|
61
|
+
): { aliases: string[]; columns: AnyColumnBuilder[] } {
|
|
65
62
|
const aliases: string[] = [];
|
|
66
|
-
const columns:
|
|
63
|
+
const columns: AnyColumnBuilder[] = [];
|
|
67
64
|
|
|
68
65
|
for (const [key, value] of Object.entries(projection)) {
|
|
69
66
|
const path = [...currentPath, key];
|
|
70
67
|
|
|
71
|
-
if (isColumnBuilder(value)
|
|
68
|
+
if (isColumnBuilder(value)) {
|
|
72
69
|
const alias = tracker.register(path);
|
|
73
70
|
aliases.push(alias);
|
|
74
71
|
columns.push(value);
|
|
@@ -99,7 +96,7 @@ export function buildProjectionState(
|
|
|
99
96
|
): ProjectionState {
|
|
100
97
|
const tracker = new AliasTracker();
|
|
101
98
|
const aliases: string[] = [];
|
|
102
|
-
const columns:
|
|
99
|
+
const columns: AnyColumnBuilder[] = [];
|
|
103
100
|
|
|
104
101
|
for (const [key, value] of Object.entries(projection)) {
|
|
105
102
|
if (value === true) {
|
|
@@ -117,11 +114,8 @@ export function buildProjectionState(
|
|
|
117
114
|
codecId: 'core/json@1',
|
|
118
115
|
nullable: true,
|
|
119
116
|
},
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
},
|
|
123
|
-
} as AnyExpressionSource);
|
|
124
|
-
} else if (isColumnBuilder(value) || isExpressionBuilder(value)) {
|
|
117
|
+
} as AnyColumnBuilder);
|
|
118
|
+
} else if (isColumnBuilder(value)) {
|
|
125
119
|
const alias = tracker.register([key]);
|
|
126
120
|
aliases.push(alias);
|
|
127
121
|
columns.push(value);
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
BinaryExpr,
|
|
3
|
+
ColumnRef,
|
|
3
4
|
Direction,
|
|
4
5
|
ExistsExpr,
|
|
5
|
-
Expression,
|
|
6
6
|
IncludeAst,
|
|
7
7
|
IncludeRef,
|
|
8
|
+
OperationExpr,
|
|
8
9
|
SelectAst,
|
|
9
10
|
TableRef,
|
|
10
11
|
} from '@prisma-next/sql-relational-core/ast';
|
|
11
|
-
import { isExpressionBuilder } from '@prisma-next/sql-relational-core/utils/guards';
|
|
12
12
|
import type { IncludeState } from '../relations/include-plan';
|
|
13
|
-
import { createSelectAst, createTableRef } from '../utils/ast';
|
|
13
|
+
import { createColumnRef, createSelectAst, createTableRef } from '../utils/ast';
|
|
14
14
|
import { errorInvalidColumn, errorMissingAlias, errorMissingColumn } from '../utils/errors';
|
|
15
15
|
import type { ProjectionState } from './projection';
|
|
16
16
|
|
|
17
17
|
export function buildProjectionItems(
|
|
18
18
|
projectionState: ProjectionState,
|
|
19
19
|
includesForMeta: ReadonlyArray<IncludeState>,
|
|
20
|
-
): Array<{ alias: string; expr:
|
|
21
|
-
const projectEntries: Array<{ alias: string; expr:
|
|
20
|
+
): Array<{ alias: string; expr: ColumnRef | IncludeRef | OperationExpr }> {
|
|
21
|
+
const projectEntries: Array<{ alias: string; expr: ColumnRef | IncludeRef | OperationExpr }> = [];
|
|
22
22
|
for (let i = 0; i < projectionState.aliases.length; i++) {
|
|
23
23
|
const alias = projectionState.aliases[i];
|
|
24
24
|
if (!alias) {
|
|
@@ -35,23 +35,25 @@ export function buildProjectionItems(
|
|
|
35
35
|
alias,
|
|
36
36
|
expr: { kind: 'includeRef', alias },
|
|
37
37
|
});
|
|
38
|
-
} else if (isExpressionBuilder(column)) {
|
|
39
|
-
// ExpressionBuilder (operation result) - use its expr
|
|
40
|
-
projectEntries.push({
|
|
41
|
-
alias,
|
|
42
|
-
expr: column.expr,
|
|
43
|
-
});
|
|
44
38
|
} else {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
39
|
+
const operationExpr = (column as { _operationExpr?: OperationExpr })._operationExpr;
|
|
40
|
+
if (operationExpr) {
|
|
41
|
+
projectEntries.push({
|
|
42
|
+
alias,
|
|
43
|
+
expr: operationExpr,
|
|
44
|
+
});
|
|
45
|
+
} else {
|
|
46
|
+
const col = column as { table: string; column: string };
|
|
47
|
+
const tableName = col.table;
|
|
48
|
+
const columnName = col.column;
|
|
49
|
+
if (!tableName || !columnName) {
|
|
50
|
+
errorInvalidColumn(alias, i);
|
|
51
|
+
}
|
|
52
|
+
projectEntries.push({
|
|
53
|
+
alias,
|
|
54
|
+
expr: createColumnRef(tableName, columnName),
|
|
55
|
+
});
|
|
50
56
|
}
|
|
51
|
-
projectEntries.push({
|
|
52
|
-
alias,
|
|
53
|
-
expr,
|
|
54
|
-
});
|
|
55
57
|
}
|
|
56
58
|
}
|
|
57
59
|
return projectEntries;
|
|
@@ -59,11 +61,11 @@ export function buildProjectionItems(
|
|
|
59
61
|
|
|
60
62
|
export function buildSelectAst(params: {
|
|
61
63
|
table: TableRef;
|
|
62
|
-
projectEntries: Array<{ alias: string; expr:
|
|
64
|
+
projectEntries: Array<{ alias: string; expr: ColumnRef | IncludeRef | OperationExpr }>;
|
|
63
65
|
includesAst?: ReadonlyArray<IncludeAst>;
|
|
64
66
|
whereExpr?: BinaryExpr | ExistsExpr;
|
|
65
67
|
orderByClause?: ReadonlyArray<{
|
|
66
|
-
expr:
|
|
68
|
+
expr: ColumnRef | OperationExpr;
|
|
67
69
|
dir: Direction;
|
|
68
70
|
}>;
|
|
69
71
|
limit?: number;
|