@prisma/query-plan-executor 7.3.0-dev.13 → 7.3.0-dev.15

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 CHANGED
@@ -36,12 +36,12 @@ declare class App {
36
36
  * Executes a query plan and returns the result.
37
37
  *
38
38
  * @param queryPlan - The query plan to execute
39
- * @param placeholderValues - Placeholder values for the query
39
+ * @param scope - Placeholder values for the query
40
40
  * @param comments - Pre-computed SQL commenter tags from the client
41
41
  * @param resourceLimits - Resource limits for the query
42
42
  * @param transactionId - Transaction ID if running within a transaction
43
43
  */
44
- query(queryPlan: QueryPlanNode, placeholderValues: Record<string, unknown>, comments: Record<string, string> | undefined, resourceLimits: ResourceLimits, transactionId: string | null): Promise<unknown>;
44
+ query(queryPlan: QueryPlanNode, scope: Record<string, unknown>, comments: Record<string, string> | undefined, resourceLimits: ResourceLimits, transactionId: string | null): Promise<unknown>;
45
45
  /**
46
46
  * Starts a new transaction.
47
47
  */
package/dist/index.js CHANGED
@@ -97773,7 +97773,7 @@ __export(index_exports, {
97773
97773
  module.exports = __toCommonJS(index_exports);
97774
97774
 
97775
97775
  // package.json
97776
- var version = "7.3.0-dev.13";
97776
+ var version = "7.3.0-dev.15";
97777
97777
 
97778
97778
  // ../../node_modules/.pnpm/temporal-polyfill@0.3.0/node_modules/temporal-polyfill/chunks/internal.js
97779
97779
  function clampProp(e2, n2, t2, o2, r2) {
@@ -107407,8 +107407,6 @@ function getErrorCode2(error44) {
107407
107407
  }
107408
107408
  }
107409
107409
  var QueryInterpreter = class _QueryInterpreter {
107410
- #transactionManager;
107411
- #placeholderValues;
107412
107410
  #onQuery;
107413
107411
  #generators = new GeneratorRegistry();
107414
107412
  #tracingHelper;
@@ -107416,76 +107414,66 @@ var QueryInterpreter = class _QueryInterpreter {
107416
107414
  #rawSerializer;
107417
107415
  #provider;
107418
107416
  #connectionInfo;
107419
- #sqlCommenter;
107420
107417
  constructor({
107421
- transactionManager,
107422
- placeholderValues,
107423
107418
  onQuery,
107424
107419
  tracingHelper,
107425
107420
  serializer,
107426
107421
  rawSerializer,
107427
107422
  provider,
107428
- connectionInfo,
107429
- sqlCommenter
107423
+ connectionInfo
107430
107424
  }) {
107431
- this.#transactionManager = transactionManager;
107432
- this.#placeholderValues = placeholderValues;
107433
107425
  this.#onQuery = onQuery;
107434
107426
  this.#tracingHelper = tracingHelper;
107435
107427
  this.#serializer = serializer;
107436
107428
  this.#rawSerializer = rawSerializer ?? serializer;
107437
107429
  this.#provider = provider;
107438
107430
  this.#connectionInfo = connectionInfo;
107439
- this.#sqlCommenter = sqlCommenter;
107440
107431
  }
107441
107432
  static forSql(options) {
107442
107433
  return new _QueryInterpreter({
107443
- transactionManager: options.transactionManager,
107444
- placeholderValues: options.placeholderValues,
107445
107434
  onQuery: options.onQuery,
107446
107435
  tracingHelper: options.tracingHelper,
107447
107436
  serializer: serializeSql,
107448
107437
  rawSerializer: serializeRawSql,
107449
107438
  provider: options.provider,
107450
- connectionInfo: options.connectionInfo,
107451
- sqlCommenter: options.sqlCommenter
107439
+ connectionInfo: options.connectionInfo
107452
107440
  });
107453
107441
  }
107454
- async run(queryPlan, queryable) {
107455
- const { value } = await this.interpretNode(
107456
- queryPlan,
107457
- queryable,
107458
- this.#placeholderValues,
107459
- this.#generators.snapshot()
107460
- ).catch((e2) => rethrowAsUserFacing(e2));
107442
+ async run(queryPlan, options) {
107443
+ const { value } = await this.interpretNode(queryPlan, {
107444
+ ...options,
107445
+ generators: this.#generators.snapshot()
107446
+ }).catch((e2) => rethrowAsUserFacing(e2));
107461
107447
  return value;
107462
107448
  }
107463
- async interpretNode(node, queryable, scope, generators) {
107449
+ async interpretNode(node, context2) {
107464
107450
  switch (node.type) {
107465
107451
  case "value": {
107466
- return { value: evaluateArg(node.args, scope, generators) };
107452
+ return {
107453
+ value: evaluateArg(node.args, context2.scope, context2.generators)
107454
+ };
107467
107455
  }
107468
107456
  case "seq": {
107469
107457
  let result;
107470
107458
  for (const arg of node.args) {
107471
- result = await this.interpretNode(arg, queryable, scope, generators);
107459
+ result = await this.interpretNode(arg, context2);
107472
107460
  }
107473
107461
  return result ?? { value: void 0 };
107474
107462
  }
107475
107463
  case "get": {
107476
- return { value: scope[node.args.name] };
107464
+ return { value: context2.scope[node.args.name] };
107477
107465
  }
107478
107466
  case "let": {
107479
- const nestedScope = Object.create(scope);
107467
+ const nestedScope = Object.create(context2.scope);
107480
107468
  for (const binding of node.args.bindings) {
107481
- const { value } = await this.interpretNode(binding.expr, queryable, nestedScope, generators);
107469
+ const { value } = await this.interpretNode(binding.expr, { ...context2, scope: nestedScope });
107482
107470
  nestedScope[binding.name] = value;
107483
107471
  }
107484
- return this.interpretNode(node.args.expr, queryable, nestedScope, generators);
107472
+ return this.interpretNode(node.args.expr, { ...context2, scope: nestedScope });
107485
107473
  }
107486
107474
  case "getFirstNonEmpty": {
107487
107475
  for (const name6 of node.args.names) {
107488
- const value = scope[name6];
107476
+ const value = context2.scope[name6];
107489
107477
  if (!isEmpty(value)) {
107490
107478
  return { value };
107491
107479
  }
@@ -107494,7 +107482,7 @@ var QueryInterpreter = class _QueryInterpreter {
107494
107482
  }
107495
107483
  case "concat": {
107496
107484
  const parts = await Promise.all(
107497
- node.args.map((arg) => this.interpretNode(arg, queryable, scope, generators).then((res) => res.value))
107485
+ node.args.map((arg) => this.interpretNode(arg, context2).then((res) => res.value))
107498
107486
  );
107499
107487
  return {
107500
107488
  value: parts.length > 0 ? parts.reduce((acc, part) => acc.concat(asList(part)), []) : []
@@ -107502,21 +107490,21 @@ var QueryInterpreter = class _QueryInterpreter {
107502
107490
  }
107503
107491
  case "sum": {
107504
107492
  const parts = await Promise.all(
107505
- node.args.map((arg) => this.interpretNode(arg, queryable, scope, generators).then((res) => res.value))
107493
+ node.args.map((arg) => this.interpretNode(arg, context2).then((res) => res.value))
107506
107494
  );
107507
107495
  return {
107508
107496
  value: parts.length > 0 ? parts.reduce((acc, part) => asNumber2(acc) + asNumber2(part)) : 0
107509
107497
  };
107510
107498
  }
107511
107499
  case "execute": {
107512
- const queries = renderQuery(node.args, scope, generators, this.#maxChunkSize());
107500
+ const queries = renderQuery(node.args, context2.scope, context2.generators, this.#maxChunkSize());
107513
107501
  let sum2 = 0;
107514
107502
  for (const query2 of queries) {
107515
- const commentedQuery = this.#applyComments(query2);
107503
+ const commentedQuery = applyComments(query2, context2.sqlCommenter);
107516
107504
  sum2 += await this.#withQuerySpanAndEvent(
107517
107505
  commentedQuery,
107518
- queryable,
107519
- () => queryable.executeRaw(commentedQuery).catch(
107506
+ context2.queryable,
107507
+ () => context2.queryable.executeRaw(commentedQuery).catch(
107520
107508
  (err) => node.args.type === "rawSql" ? rethrowAsUserFacingRawError(err) : rethrowAsUserFacing(err)
107521
107509
  )
107522
107510
  );
@@ -107524,14 +107512,14 @@ var QueryInterpreter = class _QueryInterpreter {
107524
107512
  return { value: sum2 };
107525
107513
  }
107526
107514
  case "query": {
107527
- const queries = renderQuery(node.args, scope, generators, this.#maxChunkSize());
107515
+ const queries = renderQuery(node.args, context2.scope, context2.generators, this.#maxChunkSize());
107528
107516
  let results;
107529
107517
  for (const query2 of queries) {
107530
- const commentedQuery = this.#applyComments(query2);
107518
+ const commentedQuery = applyComments(query2, context2.sqlCommenter);
107531
107519
  const result = await this.#withQuerySpanAndEvent(
107532
107520
  commentedQuery,
107533
- queryable,
107534
- () => queryable.queryRaw(commentedQuery).catch(
107521
+ context2.queryable,
107522
+ () => context2.queryable.queryRaw(commentedQuery).catch(
107535
107523
  (err) => node.args.type === "rawSql" ? rethrowAsUserFacingRawError(err) : rethrowAsUserFacing(err)
107536
107524
  )
107537
107525
  );
@@ -107548,11 +107536,11 @@ var QueryInterpreter = class _QueryInterpreter {
107548
107536
  };
107549
107537
  }
107550
107538
  case "reverse": {
107551
- const { value, lastInsertId } = await this.interpretNode(node.args, queryable, scope, generators);
107539
+ const { value, lastInsertId } = await this.interpretNode(node.args, context2);
107552
107540
  return { value: Array.isArray(value) ? value.reverse() : value, lastInsertId };
107553
107541
  }
107554
107542
  case "unique": {
107555
- const { value, lastInsertId } = await this.interpretNode(node.args, queryable, scope, generators);
107543
+ const { value, lastInsertId } = await this.interpretNode(node.args, context2);
107556
107544
  if (!Array.isArray(value)) {
107557
107545
  return { value, lastInsertId };
107558
107546
  }
@@ -107562,38 +107550,38 @@ var QueryInterpreter = class _QueryInterpreter {
107562
107550
  return { value: value[0] ?? null, lastInsertId };
107563
107551
  }
107564
107552
  case "required": {
107565
- const { value, lastInsertId } = await this.interpretNode(node.args, queryable, scope, generators);
107553
+ const { value, lastInsertId } = await this.interpretNode(node.args, context2);
107566
107554
  if (isEmpty(value)) {
107567
107555
  throw new Error("Required value is empty");
107568
107556
  }
107569
107557
  return { value, lastInsertId };
107570
107558
  }
107571
107559
  case "mapField": {
107572
- const { value, lastInsertId } = await this.interpretNode(node.args.records, queryable, scope, generators);
107560
+ const { value, lastInsertId } = await this.interpretNode(node.args.records, context2);
107573
107561
  return { value: mapField2(value, node.args.field), lastInsertId };
107574
107562
  }
107575
107563
  case "join": {
107576
- const { value: parent, lastInsertId } = await this.interpretNode(node.args.parent, queryable, scope, generators);
107564
+ const { value: parent, lastInsertId } = await this.interpretNode(node.args.parent, context2);
107577
107565
  if (parent === null) {
107578
107566
  return { value: null, lastInsertId };
107579
107567
  }
107580
107568
  const children = await Promise.all(
107581
107569
  node.args.children.map(async (joinExpr) => ({
107582
107570
  joinExpr,
107583
- childRecords: (await this.interpretNode(joinExpr.child, queryable, scope, generators)).value
107571
+ childRecords: (await this.interpretNode(joinExpr.child, context2)).value
107584
107572
  }))
107585
107573
  );
107586
107574
  return { value: attachChildrenToParents(parent, children), lastInsertId };
107587
107575
  }
107588
107576
  case "transaction": {
107589
- if (!this.#transactionManager.enabled) {
107590
- return this.interpretNode(node.args, queryable, scope, generators);
107577
+ if (!context2.transactionManager.enabled) {
107578
+ return this.interpretNode(node.args, context2);
107591
107579
  }
107592
- const transactionManager = this.#transactionManager.manager;
107580
+ const transactionManager = context2.transactionManager.manager;
107593
107581
  const transactionInfo = await transactionManager.startInternalTransaction();
107594
107582
  const transaction = await transactionManager.getTransaction(transactionInfo, "query");
107595
107583
  try {
107596
- const value = await this.interpretNode(node.args, transaction, scope, generators);
107584
+ const value = await this.interpretNode(node.args, { ...context2, queryable: transaction });
107597
107585
  await transactionManager.commitTransaction(transactionInfo.id);
107598
107586
  return value;
107599
107587
  } catch (e2) {
@@ -107602,49 +107590,49 @@ var QueryInterpreter = class _QueryInterpreter {
107602
107590
  }
107603
107591
  }
107604
107592
  case "dataMap": {
107605
- const { value, lastInsertId } = await this.interpretNode(node.args.expr, queryable, scope, generators);
107593
+ const { value, lastInsertId } = await this.interpretNode(node.args.expr, context2);
107606
107594
  return { value: applyDataMap(value, node.args.structure, node.args.enums), lastInsertId };
107607
107595
  }
107608
107596
  case "validate": {
107609
- const { value, lastInsertId } = await this.interpretNode(node.args.expr, queryable, scope, generators);
107597
+ const { value, lastInsertId } = await this.interpretNode(node.args.expr, context2);
107610
107598
  performValidation(value, node.args.rules, node.args);
107611
107599
  return { value, lastInsertId };
107612
107600
  }
107613
107601
  case "if": {
107614
- const { value } = await this.interpretNode(node.args.value, queryable, scope, generators);
107602
+ const { value } = await this.interpretNode(node.args.value, context2);
107615
107603
  if (doesSatisfyRule(value, node.args.rule)) {
107616
- return await this.interpretNode(node.args.then, queryable, scope, generators);
107604
+ return await this.interpretNode(node.args.then, context2);
107617
107605
  } else {
107618
- return await this.interpretNode(node.args.else, queryable, scope, generators);
107606
+ return await this.interpretNode(node.args.else, context2);
107619
107607
  }
107620
107608
  }
107621
107609
  case "unit": {
107622
107610
  return { value: void 0 };
107623
107611
  }
107624
107612
  case "diff": {
107625
- const { value: from } = await this.interpretNode(node.args.from, queryable, scope, generators);
107626
- const { value: to2 } = await this.interpretNode(node.args.to, queryable, scope, generators);
107613
+ const { value: from } = await this.interpretNode(node.args.from, context2);
107614
+ const { value: to2 } = await this.interpretNode(node.args.to, context2);
107627
107615
  const keyGetter = (item) => item !== null ? getRecordKey(asRecord(item), node.args.fields) : null;
107628
107616
  const toSet = new Set(asList(to2).map(keyGetter));
107629
107617
  return { value: asList(from).filter((item) => !toSet.has(keyGetter(item))) };
107630
107618
  }
107631
107619
  case "process": {
107632
- const { value, lastInsertId } = await this.interpretNode(node.args.expr, queryable, scope, generators);
107620
+ const { value, lastInsertId } = await this.interpretNode(node.args.expr, context2);
107633
107621
  return { value: processRecords(value, node.args.operations), lastInsertId };
107634
107622
  }
107635
107623
  case "initializeRecord": {
107636
- const { lastInsertId } = await this.interpretNode(node.args.expr, queryable, scope, generators);
107624
+ const { lastInsertId } = await this.interpretNode(node.args.expr, context2);
107637
107625
  const record2 = {};
107638
107626
  for (const [key, initializer3] of Object.entries(node.args.fields)) {
107639
- record2[key] = evalFieldInitializer(initializer3, lastInsertId, scope, generators);
107627
+ record2[key] = evalFieldInitializer(initializer3, lastInsertId, context2.scope, context2.generators);
107640
107628
  }
107641
107629
  return { value: record2, lastInsertId };
107642
107630
  }
107643
107631
  case "mapRecord": {
107644
- const { value, lastInsertId } = await this.interpretNode(node.args.expr, queryable, scope, generators);
107632
+ const { value, lastInsertId } = await this.interpretNode(node.args.expr, context2);
107645
107633
  const record2 = value === null ? {} : asRecord(value);
107646
107634
  for (const [key, entry] of Object.entries(node.args.fields)) {
107647
- record2[key] = evalFieldOperation(entry, record2[key], scope, generators);
107635
+ record2[key] = evalFieldOperation(entry, record2[key], context2.scope, context2.generators);
107648
107636
  }
107649
107637
  return { value: record2, lastInsertId };
107650
107638
  }
@@ -107689,22 +107677,6 @@ var QueryInterpreter = class _QueryInterpreter {
107689
107677
  onQuery: this.#onQuery
107690
107678
  });
107691
107679
  }
107692
- #applyComments(query2) {
107693
- if (!this.#sqlCommenter || this.#sqlCommenter.plugins.length === 0) {
107694
- return query2;
107695
- }
107696
- const comment = buildSqlComment(this.#sqlCommenter.plugins, {
107697
- query: this.#sqlCommenter.queryInfo,
107698
- sql: query2.sql
107699
- });
107700
- if (!comment) {
107701
- return query2;
107702
- }
107703
- return {
107704
- ...query2,
107705
- sql: appendSqlComment(query2.sql, comment)
107706
- };
107707
- }
107708
107680
  };
107709
107681
  function isEmpty(value) {
107710
107682
  if (Array.isArray(value)) {
@@ -107805,6 +107777,22 @@ function evalFieldOperation(op, value, scope, generators) {
107805
107777
  assertNever(op, `Unexpected field operation type: ${op["type"]}`);
107806
107778
  }
107807
107779
  }
107780
+ function applyComments(query2, sqlCommenter) {
107781
+ if (!sqlCommenter || sqlCommenter.plugins.length === 0) {
107782
+ return query2;
107783
+ }
107784
+ const comment = buildSqlComment(sqlCommenter.plugins, {
107785
+ query: sqlCommenter.queryInfo,
107786
+ sql: query2.sql
107787
+ });
107788
+ if (!comment) {
107789
+ return query2;
107790
+ }
107791
+ return {
107792
+ ...query2,
107793
+ sql: appendSqlComment(query2.sql, comment)
107794
+ };
107795
+ }
107808
107796
  async function getCrypto() {
107809
107797
  return globalThis.crypto ?? await import("node:crypto");
107810
107798
  }
@@ -110100,7 +110088,17 @@ var PrismaMariaDbAdapterFactory = class {
110100
110088
  this.#options = options;
110101
110089
  }
110102
110090
  async connect() {
110103
- const pool2 = mariadb.createPool(this.#config);
110091
+ let pool2;
110092
+ try {
110093
+ pool2 = mariadb.createPool(this.#config);
110094
+ } catch (error44) {
110095
+ if (error44 instanceof Error && error44.message.startsWith("error parsing connection string")) {
110096
+ throw new Error(
110097
+ "error parsing connection string, format must be 'mariadb://[<user>[:<password>]@]<host>[:<port>]/[<db>[?<opt1>=<value1>[&<opt2>=<value2>]]]'"
110098
+ );
110099
+ }
110100
+ throw error44;
110101
+ }
110104
110102
  if (this.#capabilities === void 0) {
110105
110103
  this.#capabilities = await getCapabilities(pool2);
110106
110104
  }
@@ -111974,10 +111972,15 @@ var App = class _App {
111974
111972
  #db;
111975
111973
  #transactionManager;
111976
111974
  #tracingHandler;
111975
+ #interpreter;
111977
111976
  constructor(db, transactionManager, tracingHandler) {
111978
111977
  this.#db = db;
111979
111978
  this.#transactionManager = transactionManager;
111980
111979
  this.#tracingHandler = tracingHandler;
111980
+ this.#interpreter = QueryInterpreter.forSql({
111981
+ tracingHelper: this.#tracingHandler,
111982
+ onQuery: logQuery
111983
+ });
111981
111984
  }
111982
111985
  /**
111983
111986
  * Connects to the database and initializes the application logic.
@@ -112011,12 +112014,12 @@ var App = class _App {
112011
112014
  * Executes a query plan and returns the result.
112012
112015
  *
112013
112016
  * @param queryPlan - The query plan to execute
112014
- * @param placeholderValues - Placeholder values for the query
112017
+ * @param scope - Placeholder values for the query
112015
112018
  * @param comments - Pre-computed SQL commenter tags from the client
112016
112019
  * @param resourceLimits - Resource limits for the query
112017
112020
  * @param transactionId - Transaction ID if running within a transaction
112018
112021
  */
112019
- async query(queryPlan, placeholderValues, comments, resourceLimits, transactionId) {
112022
+ async query(queryPlan, scope, comments, resourceLimits, transactionId) {
112020
112023
  const queryable = transactionId !== null ? await this.#transactionManager.getTransaction({ id: transactionId }, "query") : this.#db;
112021
112024
  const sqlCommenter = comments && Object.keys(comments).length > 0 ? {
112022
112025
  plugins: [() => comments],
@@ -112024,15 +112027,13 @@ var App = class _App {
112024
112027
  // query info was already used on the client side to compute the comments
112025
112028
  queryInfo: { type: "single", action: "queryRaw", query: {} }
112026
112029
  } : void 0;
112027
- const queryInterpreter = QueryInterpreter.forSql({
112028
- placeholderValues,
112029
- tracingHelper: this.#tracingHandler,
112030
- transactionManager: transactionId === null ? { enabled: true, manager: this.#transactionManager } : { enabled: false },
112031
- onQuery: logQuery,
112032
- sqlCommenter
112033
- });
112034
112030
  const result = await Promise.race([
112035
- queryInterpreter.run(queryPlan, queryable),
112031
+ this.#interpreter.run(queryPlan, {
112032
+ queryable,
112033
+ transactionManager: transactionId === null ? { enabled: true, manager: this.#transactionManager } : { enabled: false },
112034
+ scope,
112035
+ sqlCommenter
112036
+ }),
112036
112037
  import_promises3.default.setTimeout(resourceLimits.queryTimeout.total("milliseconds"), void 0, { ref: false }).then(() => {
112037
112038
  throw new ResourceLimitError("Query timeout exceeded");
112038
112039
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma/query-plan-executor",
3
- "version": "7.3.0-dev.13",
3
+ "version": "7.3.0-dev.15",
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",
@@ -20,11 +20,11 @@
20
20
  "temporal-polyfill": "0.3.0",
21
21
  "vitest": "3.2.4",
22
22
  "zod": "4.1.3",
23
- "@prisma/adapter-pg": "7.3.0-dev.13",
24
- "@prisma/adapter-mssql": "7.3.0-dev.13",
25
- "@prisma/adapter-mariadb": "7.3.0-dev.13",
26
- "@prisma/driver-adapter-utils": "7.3.0-dev.13",
27
- "@prisma/client-engine-runtime": "7.3.0-dev.13"
23
+ "@prisma/adapter-pg": "7.3.0-dev.15",
24
+ "@prisma/client-engine-runtime": "7.3.0-dev.15",
25
+ "@prisma/driver-adapter-utils": "7.3.0-dev.15",
26
+ "@prisma/adapter-mariadb": "7.3.0-dev.15",
27
+ "@prisma/adapter-mssql": "7.3.0-dev.15"
28
28
  },
29
29
  "files": [
30
30
  "dist"