@prisma/query-plan-executor 7.10.0-dev.21 → 7.10.0-dev.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +102 -82
- package/dist/index.js +265 -23
- package/package.json +6 -6
package/dist/index.d.ts
CHANGED
|
@@ -1645,6 +1645,21 @@ declare interface HTTPResponseError extends Error {
|
|
|
1645
1645
|
|
|
1646
1646
|
declare type IfAnyThenEmptyObject<T> = 0 extends 1 & T ? {} : T;
|
|
1647
1647
|
|
|
1648
|
+
/**
|
|
1649
|
+
* Query plan nodes that perform database I/O: individual queries and statements,
|
|
1650
|
+
* and subtrees executed within a transaction.
|
|
1651
|
+
*/
|
|
1652
|
+
declare type ImpureQueryPlanNode = {
|
|
1653
|
+
type: 'query';
|
|
1654
|
+
args: QueryPlanDbQuery;
|
|
1655
|
+
} | {
|
|
1656
|
+
type: 'execute';
|
|
1657
|
+
args: QueryPlanDbQuery;
|
|
1658
|
+
} | {
|
|
1659
|
+
type: 'transaction';
|
|
1660
|
+
args: QueryPlanNode;
|
|
1661
|
+
};
|
|
1662
|
+
|
|
1648
1663
|
/**
|
|
1649
1664
|
* Logs an informational message using the active logger.
|
|
1650
1665
|
*
|
|
@@ -1690,13 +1705,6 @@ declare type IsInvalid<T> = T extends InvalidJSONValue ? true : false;
|
|
|
1690
1705
|
|
|
1691
1706
|
declare type IsolationLevel = 'READ UNCOMMITTED' | 'READ COMMITTED' | 'REPEATABLE READ' | 'SNAPSHOT' | 'SERIALIZABLE';
|
|
1692
1707
|
|
|
1693
|
-
declare type JoinExpression = {
|
|
1694
|
-
child: QueryPlanNode;
|
|
1695
|
-
on: [left: string, right: string][];
|
|
1696
|
-
parentField: string;
|
|
1697
|
-
isRelationUnique: boolean;
|
|
1698
|
-
};
|
|
1699
|
-
|
|
1700
1708
|
declare type JSONArray = (JSONPrimitive | JSONObject | JSONArray)[];
|
|
1701
1709
|
|
|
1702
1710
|
declare type JSONObject = {
|
|
@@ -2403,57 +2411,23 @@ declare type PropsForRenderer = [...Required<Parameters<Renderer>>] extends [unk
|
|
|
2403
2411
|
declare type Provider = 'mysql' | 'postgres' | 'sqlite' | 'sqlserver';
|
|
2404
2412
|
|
|
2405
2413
|
/**
|
|
2406
|
-
*
|
|
2407
|
-
*
|
|
2408
|
-
*
|
|
2409
|
-
*
|
|
2410
|
-
*
|
|
2414
|
+
* Query plan nodes that are free of side effects and can be interpreted synchronously
|
|
2415
|
+
* without touching the database. The `Rest` parameter controls what other nodes may
|
|
2416
|
+
* appear in child positions: with the default `never` the tree is fully pure, while
|
|
2417
|
+
* `PureQueryPlanNode<ImpureQueryPlanNode>` describes a tree of pure nodes that may
|
|
2418
|
+
* contain impure nodes anywhere inside.
|
|
2411
2419
|
*/
|
|
2412
|
-
declare
|
|
2413
|
-
|
|
2414
|
-
declare interface Queryable<Query, Result> extends AdapterInfo {
|
|
2415
|
-
/**
|
|
2416
|
-
* Execute a query and return its result.
|
|
2417
|
-
*/
|
|
2418
|
-
queryRaw(params: Query): Promise<Result>;
|
|
2419
|
-
/**
|
|
2420
|
-
* Execute a query and return the number of affected rows.
|
|
2421
|
-
*/
|
|
2422
|
-
executeRaw(params: Query): Promise<number>;
|
|
2423
|
-
}
|
|
2424
|
-
|
|
2425
|
-
declare type QueryEvent = {
|
|
2426
|
-
timestamp: Date;
|
|
2427
|
-
query: string;
|
|
2428
|
-
params: readonly unknown[];
|
|
2429
|
-
duration: number;
|
|
2430
|
-
};
|
|
2431
|
-
|
|
2432
|
-
declare type QueryPlanBinding = {
|
|
2433
|
-
name: string;
|
|
2434
|
-
expr: QueryPlanNode;
|
|
2435
|
-
};
|
|
2436
|
-
|
|
2437
|
-
declare type QueryPlanDbQuery = {
|
|
2438
|
-
type: 'rawSql';
|
|
2439
|
-
sql: string;
|
|
2440
|
-
args: PrismaValue[];
|
|
2441
|
-
argTypes: ArgType[];
|
|
2442
|
-
} | {
|
|
2443
|
-
type: 'templateSql';
|
|
2444
|
-
fragments: Fragment[];
|
|
2445
|
-
placeholderFormat: PlaceholderFormat;
|
|
2446
|
-
args: PrismaValue[];
|
|
2447
|
-
argTypes: DynamicArgType[];
|
|
2448
|
-
chunkable: boolean;
|
|
2449
|
-
};
|
|
2450
|
-
|
|
2451
|
-
declare type QueryPlanNode = {
|
|
2420
|
+
declare type PureQueryPlanNode<Rest = never> = {
|
|
2452
2421
|
type: 'value';
|
|
2453
2422
|
args: PrismaValue;
|
|
2423
|
+
/**
|
|
2424
|
+
* Present when this node is the result of evaluating an impure node during
|
|
2425
|
+
* query plan purification. Never produced by the query compiler.
|
|
2426
|
+
*/
|
|
2427
|
+
lastInsertId?: string;
|
|
2454
2428
|
} | {
|
|
2455
2429
|
type: 'seq';
|
|
2456
|
-
args:
|
|
2430
|
+
args: (PureQueryPlanNode<Rest> | Rest)[];
|
|
2457
2431
|
} | {
|
|
2458
2432
|
type: 'get';
|
|
2459
2433
|
args: {
|
|
@@ -2462,101 +2436,147 @@ declare type QueryPlanNode = {
|
|
|
2462
2436
|
} | {
|
|
2463
2437
|
type: 'let';
|
|
2464
2438
|
args: {
|
|
2465
|
-
bindings:
|
|
2466
|
-
|
|
2439
|
+
bindings: {
|
|
2440
|
+
name: string;
|
|
2441
|
+
expr: PureQueryPlanNode<Rest> | Rest;
|
|
2442
|
+
}[];
|
|
2443
|
+
expr: PureQueryPlanNode<Rest> | Rest;
|
|
2467
2444
|
};
|
|
2468
2445
|
} | {
|
|
2469
2446
|
type: 'getFirstNonEmpty';
|
|
2470
2447
|
args: {
|
|
2471
2448
|
names: string[];
|
|
2472
2449
|
};
|
|
2473
|
-
} | {
|
|
2474
|
-
type: 'query';
|
|
2475
|
-
args: QueryPlanDbQuery;
|
|
2476
|
-
} | {
|
|
2477
|
-
type: 'execute';
|
|
2478
|
-
args: QueryPlanDbQuery;
|
|
2479
2450
|
} | {
|
|
2480
2451
|
type: 'reverse';
|
|
2481
|
-
args:
|
|
2452
|
+
args: PureQueryPlanNode<Rest> | Rest;
|
|
2482
2453
|
} | {
|
|
2483
2454
|
type: 'sum';
|
|
2484
|
-
args:
|
|
2455
|
+
args: (PureQueryPlanNode<Rest> | Rest)[];
|
|
2485
2456
|
} | {
|
|
2486
2457
|
type: 'concat';
|
|
2487
|
-
args:
|
|
2458
|
+
args: (PureQueryPlanNode<Rest> | Rest)[];
|
|
2488
2459
|
} | {
|
|
2489
2460
|
type: 'unique';
|
|
2490
|
-
args:
|
|
2461
|
+
args: PureQueryPlanNode<Rest> | Rest;
|
|
2491
2462
|
} | {
|
|
2492
2463
|
type: 'required';
|
|
2493
|
-
args:
|
|
2464
|
+
args: PureQueryPlanNode<Rest> | Rest;
|
|
2494
2465
|
} | {
|
|
2495
2466
|
type: 'join';
|
|
2496
2467
|
args: {
|
|
2497
|
-
parent:
|
|
2498
|
-
children:
|
|
2468
|
+
parent: PureQueryPlanNode<Rest> | Rest;
|
|
2469
|
+
children: {
|
|
2470
|
+
child: PureQueryPlanNode<Rest> | Rest;
|
|
2471
|
+
on: [left: string, right: string][];
|
|
2472
|
+
parentField: string;
|
|
2473
|
+
isRelationUnique: boolean;
|
|
2474
|
+
}[];
|
|
2499
2475
|
canAssumeStrictEquality: boolean;
|
|
2500
2476
|
};
|
|
2501
2477
|
} | {
|
|
2502
2478
|
type: 'mapField';
|
|
2503
2479
|
args: {
|
|
2504
2480
|
field: string;
|
|
2505
|
-
records:
|
|
2481
|
+
records: PureQueryPlanNode<Rest> | Rest;
|
|
2506
2482
|
};
|
|
2507
|
-
} | {
|
|
2508
|
-
type: 'transaction';
|
|
2509
|
-
args: QueryPlanNode;
|
|
2510
2483
|
} | {
|
|
2511
2484
|
type: 'dataMap';
|
|
2512
2485
|
args: {
|
|
2513
|
-
expr:
|
|
2486
|
+
expr: PureQueryPlanNode<Rest> | Rest;
|
|
2514
2487
|
structure: ResultNode;
|
|
2515
2488
|
enums: Record<string, Record<string, string>>;
|
|
2516
2489
|
};
|
|
2517
2490
|
} | {
|
|
2518
2491
|
type: 'validate';
|
|
2519
2492
|
args: {
|
|
2520
|
-
expr:
|
|
2493
|
+
expr: PureQueryPlanNode<Rest> | Rest;
|
|
2521
2494
|
rules: DataRule[];
|
|
2522
2495
|
} & ValidationError;
|
|
2523
2496
|
} | {
|
|
2524
2497
|
type: 'if';
|
|
2525
2498
|
args: {
|
|
2526
|
-
value:
|
|
2499
|
+
value: PureQueryPlanNode<Rest> | Rest;
|
|
2527
2500
|
rule: DataRule;
|
|
2528
|
-
then:
|
|
2529
|
-
else:
|
|
2501
|
+
then: PureQueryPlanNode<Rest> | Rest;
|
|
2502
|
+
else: PureQueryPlanNode<Rest> | Rest;
|
|
2530
2503
|
};
|
|
2531
2504
|
} | {
|
|
2532
2505
|
type: 'unit';
|
|
2533
2506
|
} | {
|
|
2534
2507
|
type: 'diff';
|
|
2535
2508
|
args: {
|
|
2536
|
-
from:
|
|
2537
|
-
to:
|
|
2509
|
+
from: PureQueryPlanNode<Rest> | Rest;
|
|
2510
|
+
to: PureQueryPlanNode<Rest> | Rest;
|
|
2538
2511
|
fields: string[];
|
|
2539
2512
|
};
|
|
2540
2513
|
} | {
|
|
2541
2514
|
type: 'initializeRecord';
|
|
2542
2515
|
args: {
|
|
2543
|
-
expr:
|
|
2516
|
+
expr: PureQueryPlanNode<Rest> | Rest;
|
|
2544
2517
|
fields: Record<string, FieldInitializer>;
|
|
2545
2518
|
};
|
|
2546
2519
|
} | {
|
|
2547
2520
|
type: 'mapRecord';
|
|
2548
2521
|
args: {
|
|
2549
|
-
expr:
|
|
2522
|
+
expr: PureQueryPlanNode<Rest> | Rest;
|
|
2550
2523
|
fields: Record<string, FieldOperation>;
|
|
2551
2524
|
};
|
|
2552
2525
|
} | {
|
|
2553
2526
|
type: 'process';
|
|
2554
2527
|
args: {
|
|
2555
|
-
expr:
|
|
2528
|
+
expr: PureQueryPlanNode<Rest> | Rest;
|
|
2556
2529
|
operations: InMemoryOps;
|
|
2557
2530
|
};
|
|
2558
2531
|
};
|
|
2559
2532
|
|
|
2533
|
+
/**
|
|
2534
|
+
* Logs a database query event using the active logger.
|
|
2535
|
+
*
|
|
2536
|
+
* @param message The message to log
|
|
2537
|
+
* @param attributes Optional key-value pairs to include with the log event
|
|
2538
|
+
* @throws {Error} if no active logger is found
|
|
2539
|
+
*/
|
|
2540
|
+
declare function query(message: string, attributes?: ExtendedAttributes): void;
|
|
2541
|
+
|
|
2542
|
+
declare interface Queryable<Query, Result> extends AdapterInfo {
|
|
2543
|
+
/**
|
|
2544
|
+
* Execute a query and return its result.
|
|
2545
|
+
*/
|
|
2546
|
+
queryRaw(params: Query): Promise<Result>;
|
|
2547
|
+
/**
|
|
2548
|
+
* Execute a query and return the number of affected rows.
|
|
2549
|
+
*/
|
|
2550
|
+
executeRaw(params: Query): Promise<number>;
|
|
2551
|
+
}
|
|
2552
|
+
|
|
2553
|
+
declare type QueryEvent = {
|
|
2554
|
+
timestamp: Date;
|
|
2555
|
+
query: string;
|
|
2556
|
+
params: readonly unknown[];
|
|
2557
|
+
duration: number;
|
|
2558
|
+
};
|
|
2559
|
+
|
|
2560
|
+
declare type QueryPlanDbQuery = {
|
|
2561
|
+
type: 'rawSql';
|
|
2562
|
+
sql: string;
|
|
2563
|
+
args: PrismaValue[];
|
|
2564
|
+
argTypes: ArgType[];
|
|
2565
|
+
} | {
|
|
2566
|
+
type: 'templateSql';
|
|
2567
|
+
fragments: Fragment[];
|
|
2568
|
+
placeholderFormat: PlaceholderFormat;
|
|
2569
|
+
args: PrismaValue[];
|
|
2570
|
+
argTypes: DynamicArgType[];
|
|
2571
|
+
chunkable: boolean;
|
|
2572
|
+
};
|
|
2573
|
+
|
|
2574
|
+
/**
|
|
2575
|
+
* A query plan as emitted by the query compiler: a tree of pure nodes that may
|
|
2576
|
+
* contain impure nodes anywhere inside.
|
|
2577
|
+
*/
|
|
2578
|
+
declare type QueryPlanNode = ImpureQueryPlanNode | PureQueryPlanNode<ImpureQueryPlanNode>;
|
|
2579
|
+
|
|
2560
2580
|
declare type RedirectStatusCode = 300 | 301 | 302 | 303 | 304 | DeprecatedStatusCode | 307 | 308;
|
|
2561
2581
|
|
|
2562
2582
|
declare type RemoveBlankRecord<T> = T extends Record<infer K, unknown> ? (K extends string ? T : never) : never;
|
package/dist/index.js
CHANGED
|
@@ -93473,7 +93473,7 @@ __export(index_exports, {
|
|
|
93473
93473
|
module.exports = __toCommonJS(index_exports);
|
|
93474
93474
|
|
|
93475
93475
|
// package.json
|
|
93476
|
-
var version = "7.10.0-dev.
|
|
93476
|
+
var version = "7.10.0-dev.23";
|
|
93477
93477
|
|
|
93478
93478
|
// ../../node_modules/.pnpm/temporal-polyfill@0.3.0/node_modules/temporal-polyfill/chunks/internal.js
|
|
93479
93479
|
function clampProp(e2, n2, t2, o2, r2) {
|
|
@@ -103126,17 +103126,27 @@ var QueryInterpreter = class _QueryInterpreter {
|
|
|
103126
103126
|
});
|
|
103127
103127
|
}
|
|
103128
103128
|
async run(queryPlan, options) {
|
|
103129
|
-
const
|
|
103130
|
-
|
|
103131
|
-
|
|
103132
|
-
|
|
103129
|
+
const generators = this.#generators.snapshot();
|
|
103130
|
+
const context4 = { ...options, generators };
|
|
103131
|
+
const purified = purifyQueryPlan(queryPlan, (node) => this.interpretNode(node, context4))?.catch(
|
|
103132
|
+
(e2) => rethrowAsUserFacing(e2)
|
|
103133
|
+
);
|
|
103134
|
+
if (purified) {
|
|
103135
|
+
try {
|
|
103136
|
+
return this.#interpretPureNode(await purified, context4.scope, generators).value;
|
|
103137
|
+
} catch (e2) {
|
|
103138
|
+
rethrowAsUserFacing(e2);
|
|
103139
|
+
}
|
|
103140
|
+
}
|
|
103141
|
+
const { value } = await this.interpretNode(queryPlan, context4).catch((e2) => rethrowAsUserFacing(e2));
|
|
103133
103142
|
return value;
|
|
103134
103143
|
}
|
|
103135
103144
|
async interpretNode(node, context4) {
|
|
103136
103145
|
switch (node.type) {
|
|
103137
103146
|
case "value": {
|
|
103138
103147
|
return {
|
|
103139
|
-
value: evaluateArg(node.args, context4.scope, context4.generators)
|
|
103148
|
+
value: evaluateArg(node.args, context4.scope, context4.generators),
|
|
103149
|
+
lastInsertId: node.lastInsertId
|
|
103140
103150
|
};
|
|
103141
103151
|
}
|
|
103142
103152
|
case "seq": {
|
|
@@ -103146,9 +103156,6 @@ var QueryInterpreter = class _QueryInterpreter {
|
|
|
103146
103156
|
}
|
|
103147
103157
|
return result ?? { value: void 0 };
|
|
103148
103158
|
}
|
|
103149
|
-
case "get": {
|
|
103150
|
-
return { value: context4.scope[node.args.name] };
|
|
103151
|
-
}
|
|
103152
103159
|
case "let": {
|
|
103153
103160
|
const nestedScope = Object.create(context4.scope);
|
|
103154
103161
|
for (const binding of node.args.bindings) {
|
|
@@ -103157,15 +103164,6 @@ var QueryInterpreter = class _QueryInterpreter {
|
|
|
103157
103164
|
}
|
|
103158
103165
|
return this.interpretNode(node.args.expr, { ...context4, scope: nestedScope });
|
|
103159
103166
|
}
|
|
103160
|
-
case "getFirstNonEmpty": {
|
|
103161
|
-
for (const name6 of node.args.names) {
|
|
103162
|
-
const value = context4.scope[name6];
|
|
103163
|
-
if (!isEmpty(value)) {
|
|
103164
|
-
return { value };
|
|
103165
|
-
}
|
|
103166
|
-
}
|
|
103167
|
-
return { value: [] };
|
|
103168
|
-
}
|
|
103169
103167
|
case "concat": {
|
|
103170
103168
|
const parts = await Promise.all(
|
|
103171
103169
|
node.args.map((arg) => this.interpretNode(arg, context4).then((res) => res.value))
|
|
@@ -103292,9 +103290,6 @@ var QueryInterpreter = class _QueryInterpreter {
|
|
|
103292
103290
|
return await this.interpretNode(node.args.else, context4);
|
|
103293
103291
|
}
|
|
103294
103292
|
}
|
|
103295
|
-
case "unit": {
|
|
103296
|
-
return { value: void 0 };
|
|
103297
|
-
}
|
|
103298
103293
|
case "diff": {
|
|
103299
103294
|
const { value: from } = await this.interpretNode(node.args.from, context4);
|
|
103300
103295
|
const { value: to2 } = await this.interpretNode(node.args.to, context4);
|
|
@@ -103324,6 +103319,139 @@ var QueryInterpreter = class _QueryInterpreter {
|
|
|
103324
103319
|
}
|
|
103325
103320
|
return { value: record2, lastInsertId };
|
|
103326
103321
|
}
|
|
103322
|
+
default:
|
|
103323
|
+
return this.#interpretPureNode(node, context4.scope, context4.generators);
|
|
103324
|
+
}
|
|
103325
|
+
}
|
|
103326
|
+
#interpretPureNode(node, scope, generators) {
|
|
103327
|
+
switch (node.type) {
|
|
103328
|
+
case "value": {
|
|
103329
|
+
return { value: evaluateArg(node.args, scope, generators), lastInsertId: node.lastInsertId };
|
|
103330
|
+
}
|
|
103331
|
+
case "seq": {
|
|
103332
|
+
let result;
|
|
103333
|
+
for (const arg of node.args) {
|
|
103334
|
+
result = this.#interpretPureNode(arg, scope, generators);
|
|
103335
|
+
}
|
|
103336
|
+
return result ?? { value: void 0 };
|
|
103337
|
+
}
|
|
103338
|
+
case "get": {
|
|
103339
|
+
return { value: scope[node.args.name] };
|
|
103340
|
+
}
|
|
103341
|
+
case "let": {
|
|
103342
|
+
const nestedScope = Object.create(scope);
|
|
103343
|
+
for (const binding of node.args.bindings) {
|
|
103344
|
+
const { value } = this.#interpretPureNode(binding.expr, nestedScope, generators);
|
|
103345
|
+
nestedScope[binding.name] = value;
|
|
103346
|
+
}
|
|
103347
|
+
return this.#interpretPureNode(node.args.expr, nestedScope, generators);
|
|
103348
|
+
}
|
|
103349
|
+
case "getFirstNonEmpty": {
|
|
103350
|
+
for (const name6 of node.args.names) {
|
|
103351
|
+
const value = scope[name6];
|
|
103352
|
+
if (!isEmpty(value)) {
|
|
103353
|
+
return { value };
|
|
103354
|
+
}
|
|
103355
|
+
}
|
|
103356
|
+
return { value: [] };
|
|
103357
|
+
}
|
|
103358
|
+
case "concat": {
|
|
103359
|
+
const parts = node.args.map((arg) => this.#interpretPureNode(arg, scope, generators).value);
|
|
103360
|
+
return {
|
|
103361
|
+
value: parts.length > 0 ? parts.reduce((acc, part) => acc.concat(asList(part)), []) : []
|
|
103362
|
+
};
|
|
103363
|
+
}
|
|
103364
|
+
case "sum": {
|
|
103365
|
+
const parts = node.args.map((arg) => this.#interpretPureNode(arg, scope, generators).value);
|
|
103366
|
+
return {
|
|
103367
|
+
value: parts.length > 0 ? parts.reduce((acc, part) => asNumber2(acc) + asNumber2(part)) : 0
|
|
103368
|
+
};
|
|
103369
|
+
}
|
|
103370
|
+
case "reverse": {
|
|
103371
|
+
const { value, lastInsertId } = this.#interpretPureNode(node.args, scope, generators);
|
|
103372
|
+
return { value: Array.isArray(value) ? value.reverse() : value, lastInsertId };
|
|
103373
|
+
}
|
|
103374
|
+
case "unique": {
|
|
103375
|
+
const { value, lastInsertId } = this.#interpretPureNode(node.args, scope, generators);
|
|
103376
|
+
if (!Array.isArray(value)) {
|
|
103377
|
+
return { value, lastInsertId };
|
|
103378
|
+
}
|
|
103379
|
+
if (value.length > 1) {
|
|
103380
|
+
throw new Error(`Expected zero or one element, got ${value.length}`);
|
|
103381
|
+
}
|
|
103382
|
+
return { value: value[0] ?? null, lastInsertId };
|
|
103383
|
+
}
|
|
103384
|
+
case "required": {
|
|
103385
|
+
const { value, lastInsertId } = this.#interpretPureNode(node.args, scope, generators);
|
|
103386
|
+
if (isEmpty(value)) {
|
|
103387
|
+
throw new Error("Required value is empty");
|
|
103388
|
+
}
|
|
103389
|
+
return { value, lastInsertId };
|
|
103390
|
+
}
|
|
103391
|
+
case "mapField": {
|
|
103392
|
+
const { value, lastInsertId } = this.#interpretPureNode(node.args.records, scope, generators);
|
|
103393
|
+
return { value: mapField2(value, node.args.field), lastInsertId };
|
|
103394
|
+
}
|
|
103395
|
+
case "join": {
|
|
103396
|
+
const { value: parent, lastInsertId } = this.#interpretPureNode(node.args.parent, scope, generators);
|
|
103397
|
+
if (parent === null) {
|
|
103398
|
+
return { value: null, lastInsertId };
|
|
103399
|
+
}
|
|
103400
|
+
const children = node.args.children.map((joinExpr) => ({
|
|
103401
|
+
joinExpr,
|
|
103402
|
+
childRecords: this.#interpretPureNode(joinExpr.child, scope, generators).value
|
|
103403
|
+
}));
|
|
103404
|
+
return { value: attachChildrenToParents(parent, children, node.args.canAssumeStrictEquality), lastInsertId };
|
|
103405
|
+
}
|
|
103406
|
+
case "dataMap": {
|
|
103407
|
+
const { value, lastInsertId } = this.#interpretPureNode(node.args.expr, scope, generators);
|
|
103408
|
+
return { value: applyDataMap(value, node.args.structure, node.args.enums), lastInsertId };
|
|
103409
|
+
}
|
|
103410
|
+
case "validate": {
|
|
103411
|
+
const { value, lastInsertId } = this.#interpretPureNode(node.args.expr, scope, generators);
|
|
103412
|
+
performValidation(value, node.args.rules, node.args);
|
|
103413
|
+
return { value, lastInsertId };
|
|
103414
|
+
}
|
|
103415
|
+
case "if": {
|
|
103416
|
+
const { value } = this.#interpretPureNode(node.args.value, scope, generators);
|
|
103417
|
+
if (doesSatisfyRule(value, node.args.rule)) {
|
|
103418
|
+
return this.#interpretPureNode(node.args.then, scope, generators);
|
|
103419
|
+
} else {
|
|
103420
|
+
return this.#interpretPureNode(node.args.else, scope, generators);
|
|
103421
|
+
}
|
|
103422
|
+
}
|
|
103423
|
+
case "unit": {
|
|
103424
|
+
return { value: void 0 };
|
|
103425
|
+
}
|
|
103426
|
+
case "diff": {
|
|
103427
|
+
const { value: from } = this.#interpretPureNode(node.args.from, scope, generators);
|
|
103428
|
+
const { value: to2 } = this.#interpretPureNode(node.args.to, scope, generators);
|
|
103429
|
+
const keyGetter = (item) => item !== null ? getRecordKey(asRecord(item), node.args.fields) : null;
|
|
103430
|
+
const toSet = new Set(asList(to2).map(keyGetter));
|
|
103431
|
+
return { value: asList(from).filter((item) => !toSet.has(keyGetter(item))) };
|
|
103432
|
+
}
|
|
103433
|
+
case "process": {
|
|
103434
|
+
const { value, lastInsertId } = this.#interpretPureNode(node.args.expr, scope, generators);
|
|
103435
|
+
const ops = cloneObject(node.args.operations);
|
|
103436
|
+
evaluateProcessingParameters(ops, scope, generators);
|
|
103437
|
+
return { value: processRecords(value, ops), lastInsertId };
|
|
103438
|
+
}
|
|
103439
|
+
case "initializeRecord": {
|
|
103440
|
+
const { lastInsertId } = this.#interpretPureNode(node.args.expr, scope, generators);
|
|
103441
|
+
const record2 = {};
|
|
103442
|
+
for (const [key, initializer3] of Object.entries(node.args.fields)) {
|
|
103443
|
+
record2[key] = evalFieldInitializer(initializer3, lastInsertId, scope, generators);
|
|
103444
|
+
}
|
|
103445
|
+
return { value: record2, lastInsertId };
|
|
103446
|
+
}
|
|
103447
|
+
case "mapRecord": {
|
|
103448
|
+
const { value, lastInsertId } = this.#interpretPureNode(node.args.expr, scope, generators);
|
|
103449
|
+
const record2 = value === null ? {} : asRecord(value);
|
|
103450
|
+
for (const [key, entry] of Object.entries(node.args.fields)) {
|
|
103451
|
+
record2[key] = evalFieldOperation(entry, record2[key], scope, generators);
|
|
103452
|
+
}
|
|
103453
|
+
return { value: record2, lastInsertId };
|
|
103454
|
+
}
|
|
103327
103455
|
default:
|
|
103328
103456
|
assertNever(node, `Unexpected node type: ${node.type}`);
|
|
103329
103457
|
}
|
|
@@ -103501,6 +103629,112 @@ function evalFieldOperation(op, value, scope, generators) {
|
|
|
103501
103629
|
assertNever(op, `Unexpected field operation type: ${op["type"]}`);
|
|
103502
103630
|
}
|
|
103503
103631
|
}
|
|
103632
|
+
function purifyQueryPlan(node, evalNode) {
|
|
103633
|
+
const impureNode = findUniqueUnconditionalImpureNode(node);
|
|
103634
|
+
if (!impureNode) {
|
|
103635
|
+
return void 0;
|
|
103636
|
+
}
|
|
103637
|
+
return evalNode(impureNode).then((result) => {
|
|
103638
|
+
const evaluated = {
|
|
103639
|
+
type: "value",
|
|
103640
|
+
args: result.value,
|
|
103641
|
+
lastInsertId: result.lastInsertId
|
|
103642
|
+
};
|
|
103643
|
+
const purified = replaceImpureNode(node, impureNode, evaluated);
|
|
103644
|
+
if (!purified) {
|
|
103645
|
+
throw new Error("Could not substitute the evaluated impure node into the query plan");
|
|
103646
|
+
}
|
|
103647
|
+
return purified;
|
|
103648
|
+
});
|
|
103649
|
+
}
|
|
103650
|
+
function replaceImpureNode(node, target, replacement) {
|
|
103651
|
+
if (node === target) {
|
|
103652
|
+
return replacement;
|
|
103653
|
+
}
|
|
103654
|
+
switch (node.type) {
|
|
103655
|
+
case "seq":
|
|
103656
|
+
case "sum":
|
|
103657
|
+
case "concat": {
|
|
103658
|
+
for (let i2 = 0; i2 < node.args.length; i2++) {
|
|
103659
|
+
const child = replaceImpureNode(node.args[i2], target, replacement);
|
|
103660
|
+
if (child) {
|
|
103661
|
+
return { ...node, args: node.args.map((arg, j2) => j2 === i2 ? child : arg) };
|
|
103662
|
+
}
|
|
103663
|
+
}
|
|
103664
|
+
return void 0;
|
|
103665
|
+
}
|
|
103666
|
+
case "dataMap":
|
|
103667
|
+
case "validate":
|
|
103668
|
+
case "initializeRecord":
|
|
103669
|
+
case "mapRecord":
|
|
103670
|
+
case "process": {
|
|
103671
|
+
const expr = replaceImpureNode(node.args.expr, target, replacement);
|
|
103672
|
+
return expr && { ...node, args: { ...node.args, expr } };
|
|
103673
|
+
}
|
|
103674
|
+
case "mapField": {
|
|
103675
|
+
const records = replaceImpureNode(node.args.records, target, replacement);
|
|
103676
|
+
return records && { ...node, args: { ...node.args, records } };
|
|
103677
|
+
}
|
|
103678
|
+
case "reverse":
|
|
103679
|
+
case "unique":
|
|
103680
|
+
case "required": {
|
|
103681
|
+
const args = replaceImpureNode(node.args, target, replacement);
|
|
103682
|
+
return args && { ...node, args };
|
|
103683
|
+
}
|
|
103684
|
+
default:
|
|
103685
|
+
return void 0;
|
|
103686
|
+
}
|
|
103687
|
+
}
|
|
103688
|
+
function findUniqueUnconditionalImpureNode(node) {
|
|
103689
|
+
switch (node.type) {
|
|
103690
|
+
case "query":
|
|
103691
|
+
case "execute":
|
|
103692
|
+
return node;
|
|
103693
|
+
case "seq":
|
|
103694
|
+
case "sum":
|
|
103695
|
+
case "concat": {
|
|
103696
|
+
let found = void 0;
|
|
103697
|
+
for (const child of node.args) {
|
|
103698
|
+
const childFound = findUniqueUnconditionalImpureNode(child);
|
|
103699
|
+
if (childFound === null) {
|
|
103700
|
+
return null;
|
|
103701
|
+
}
|
|
103702
|
+
if (childFound) {
|
|
103703
|
+
if (found) {
|
|
103704
|
+
return null;
|
|
103705
|
+
}
|
|
103706
|
+
found = childFound;
|
|
103707
|
+
}
|
|
103708
|
+
}
|
|
103709
|
+
return found;
|
|
103710
|
+
}
|
|
103711
|
+
case "dataMap":
|
|
103712
|
+
case "validate":
|
|
103713
|
+
case "initializeRecord":
|
|
103714
|
+
case "mapRecord":
|
|
103715
|
+
case "process":
|
|
103716
|
+
return findUniqueUnconditionalImpureNode(node.args.expr);
|
|
103717
|
+
case "mapField":
|
|
103718
|
+
return findUniqueUnconditionalImpureNode(node.args.records);
|
|
103719
|
+
case "reverse":
|
|
103720
|
+
case "unique":
|
|
103721
|
+
case "required":
|
|
103722
|
+
return findUniqueUnconditionalImpureNode(node.args);
|
|
103723
|
+
case "let":
|
|
103724
|
+
case "join":
|
|
103725
|
+
case "diff":
|
|
103726
|
+
case "if":
|
|
103727
|
+
case "transaction":
|
|
103728
|
+
return null;
|
|
103729
|
+
case "value":
|
|
103730
|
+
case "get":
|
|
103731
|
+
case "getFirstNonEmpty":
|
|
103732
|
+
case "unit":
|
|
103733
|
+
return void 0;
|
|
103734
|
+
default:
|
|
103735
|
+
assertNever(node, `Unexpected node type: ${node.type}`);
|
|
103736
|
+
}
|
|
103737
|
+
}
|
|
103504
103738
|
function applyComments(query2, sqlCommenter) {
|
|
103505
103739
|
if (!sqlCommenter || sqlCommenter.plugins.length === 0) {
|
|
103506
103740
|
return query2;
|
|
@@ -108164,10 +108398,18 @@ function mapDriverError3(error44) {
|
|
|
108164
108398
|
message: error44.message
|
|
108165
108399
|
};
|
|
108166
108400
|
case "23505": {
|
|
108167
|
-
|
|
108401
|
+
let constraint;
|
|
108402
|
+
if (error44.constraint) {
|
|
108403
|
+
constraint = { index: error44.constraint };
|
|
108404
|
+
} else {
|
|
108405
|
+
const fields = error44.detail?.match(/Key \(([^)]+)\)/)?.at(1)?.split(", ");
|
|
108406
|
+
if (fields !== void 0) {
|
|
108407
|
+
constraint = { fields };
|
|
108408
|
+
}
|
|
108409
|
+
}
|
|
108168
108410
|
return {
|
|
108169
108411
|
kind: "UniqueConstraintViolation",
|
|
108170
|
-
constraint
|
|
108412
|
+
constraint
|
|
108171
108413
|
};
|
|
108172
108414
|
}
|
|
108173
108415
|
case "23502": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma/query-plan-executor",
|
|
3
|
-
"version": "7.10.0-dev.
|
|
3
|
+
"version": "7.10.0-dev.23",
|
|
4
4
|
"description": "This package is intended for Prisma's internal use",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
"hono": "^4.12.23",
|
|
20
20
|
"temporal-polyfill": "0.3.0",
|
|
21
21
|
"zod": "4.1.3",
|
|
22
|
-
"@prisma/adapter-pg": "7.10.0-dev.
|
|
23
|
-
"@prisma/adapter-mssql": "7.10.0-dev.
|
|
24
|
-
"@prisma/adapter-mariadb": "7.10.0-dev.
|
|
25
|
-
"@prisma/client-engine-runtime": "7.10.0-dev.
|
|
26
|
-
"@prisma/driver-adapter-utils": "7.10.0-dev.
|
|
22
|
+
"@prisma/adapter-pg": "7.10.0-dev.23",
|
|
23
|
+
"@prisma/adapter-mssql": "7.10.0-dev.23",
|
|
24
|
+
"@prisma/adapter-mariadb": "7.10.0-dev.23",
|
|
25
|
+
"@prisma/client-engine-runtime": "7.10.0-dev.23",
|
|
26
|
+
"@prisma/driver-adapter-utils": "7.10.0-dev.23"
|
|
27
27
|
},
|
|
28
28
|
"files": [
|
|
29
29
|
"dist"
|