prisma-sql 1.75.4 → 1.75.6

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.
@@ -2323,7 +2323,7 @@ var require_package = __commonJS({
2323
2323
  "package.json"(exports$1, module) {
2324
2324
  module.exports = {
2325
2325
  name: "prisma-sql",
2326
- version: "1.75.4",
2326
+ version: "1.75.6",
2327
2327
  description: "Convert Prisma queries to optimized SQL with type safety. 2-7x faster than Prisma Client.",
2328
2328
  main: "dist/index.cjs",
2329
2329
  module: "dist/index.js",
@@ -2389,13 +2389,13 @@ var require_package = __commonJS({
2389
2389
  license: "MIT",
2390
2390
  dependencies: {
2391
2391
  "@dee-wan/schema-parser": "1.4.0",
2392
- "@prisma/generator-helper": "^6.19.2",
2393
- "@prisma/internals": "^6.19.2"
2392
+ "@prisma/generator-helper": "^7.4.0",
2393
+ "@prisma/internals": "^7.4.0"
2394
2394
  },
2395
2395
  devDependencies: {
2396
2396
  "@faker-js/faker": "^10.2.0",
2397
- "@prisma/adapter-better-sqlite3": "^6.19.2",
2398
- "@prisma/adapter-pg": "^6.19.2",
2397
+ "@prisma/adapter-better-sqlite3": "^7.4.0",
2398
+ "@prisma/adapter-pg": "^7.4.0",
2399
2399
  "@semantic-release/changelog": "^6.0.3",
2400
2400
  "@semantic-release/git": "^10.0.1",
2401
2401
  "@types/better-sqlite3": "^7.6.13",
@@ -2409,8 +2409,8 @@ var require_package = __commonJS({
2409
2409
  tsx: "^4.21.0",
2410
2410
  typescript: "^5.9.3",
2411
2411
  vitest: "^4.0.18",
2412
- "@prisma/client": "6.19.2",
2413
- prisma: "6.19.2"
2412
+ "@prisma/client": "7.4.0",
2413
+ prisma: "7.4.0"
2414
2414
  },
2415
2415
  engines: {
2416
2416
  node: ">=16.0.0"
@@ -4662,6 +4662,12 @@ function maxDepthFromTree(nodes) {
4662
4662
  }
4663
4663
  return max;
4664
4664
  }
4665
+ function anyChildHasWhere(nodes) {
4666
+ for (const n of nodes) {
4667
+ if (n.hasChildWhere) return true;
4668
+ }
4669
+ return false;
4670
+ }
4665
4671
  function computeWhereInCost(nodes, parentCount) {
4666
4672
  const R = globalRoundtripRowEquivalent;
4667
4673
  let totalRows = 0;
@@ -4765,13 +4771,18 @@ function pickIncludeStrategy(params) {
4765
4771
  }
4766
4772
  }
4767
4773
  const costTree = buildCostTree(includeSpec, model, schemas);
4774
+ const treeDepth = maxDepthFromTree(costTree);
4775
+ if (treeDepth === 1 && anyChildHasWhere(costTree)) {
4776
+ if (debug)
4777
+ console.log(` [strategy] ${model.name}: depth-1 + childWhere \u2192 where-in`);
4778
+ return "where-in";
4779
+ }
4768
4780
  const P = isSingleParent ? 1 : takeValue != null ? takeValue : DEFAULT_PARENT_COUNT;
4769
4781
  const costW = computeWhereInCost(costTree, P);
4770
4782
  const costC = computeCorrelatedCost(costTree, P);
4771
4783
  if (debug) {
4772
- const depth = maxDepthFromTree(costTree);
4773
4784
  console.log(
4774
- ` [strategy] ${model.name}: P=${P} D=${depth} costW=${costW.toFixed(0)} costC=${costC.toFixed(0)}`
4785
+ ` [strategy] ${model.name}: P=${P} D=${treeDepth} costW=${costW.toFixed(0)} costC=${costC.toFixed(0)}`
4775
4786
  );
4776
4787
  }
4777
4788
  if (costC < costW) {
@@ -7896,6 +7907,7 @@ function buildIncludeSql(args, model, schemas, parentAlias, params, dialect, out
7896
7907
  }
7897
7908
 
7898
7909
  // src/builder/shared/order-by-relation.ts
7910
+ var MAX_RELATION_ORDER_BY_DEPTH = 10;
7899
7911
  function resolveTableRef(model, dialect) {
7900
7912
  const tableName = model.tableName || model.dbName || model.name;
7901
7913
  if (dialect === "sqlite") {
@@ -7907,6 +7919,90 @@ function resolveTableRef(model, dialect) {
7907
7919
  function findRelationField(model, fieldName) {
7908
7920
  return model.fields.find((f) => f.name === fieldName && f.isRelation);
7909
7921
  }
7922
+ function nextJoinAlias(ctx) {
7923
+ let alias;
7924
+ do {
7925
+ alias = `ob_${ctx.aliasCounter.value++}`;
7926
+ } while (ctx.usedAliases.has(alias));
7927
+ ctx.usedAliases.add(alias);
7928
+ return alias;
7929
+ }
7930
+ function resolveRelationOrderByChain(relationFieldName, value, currentModel, currentAlias, ctx, depth) {
7931
+ if (depth > MAX_RELATION_ORDER_BY_DEPTH) {
7932
+ throw new Error(
7933
+ `Relation orderBy nesting too deep (max ${MAX_RELATION_ORDER_BY_DEPTH} levels)`
7934
+ );
7935
+ }
7936
+ if ("_count" in value && value._count !== void 0) {
7937
+ throw new Error(
7938
+ `Relation orderBy with _count on '${relationFieldName}' is not yet supported by prisma-sql`
7939
+ );
7940
+ }
7941
+ const field = findRelationField(currentModel, relationFieldName);
7942
+ if (!field) {
7943
+ throw new Error(
7944
+ `Relation field '${relationFieldName}' not found on model ${currentModel.name}`
7945
+ );
7946
+ }
7947
+ const relatedModel = getModelByName(ctx.schemas, field.relatedModel);
7948
+ if (!relatedModel) {
7949
+ throw new Error(
7950
+ `Related model '${field.relatedModel}' not found for relation '${relationFieldName}'`
7951
+ );
7952
+ }
7953
+ const joinAlias = nextJoinAlias(ctx);
7954
+ const tableRef = resolveTableRef(relatedModel, ctx.dialect);
7955
+ const cond = joinCondition(
7956
+ field,
7957
+ currentModel,
7958
+ relatedModel,
7959
+ currentAlias,
7960
+ joinAlias
7961
+ );
7962
+ ctx.joins.push(`LEFT JOIN ${tableRef} ${joinAlias} ON ${cond}`);
7963
+ const relScalarSet = getScalarFieldSet(relatedModel);
7964
+ const relRelationSet = getRelationFieldSet(relatedModel);
7965
+ const nestedEntries = Object.entries(value).filter(([, v]) => v !== void 0);
7966
+ const orderFragments = [];
7967
+ for (const [nestedField, nestedValue] of nestedEntries) {
7968
+ if (relScalarSet.has(nestedField)) {
7969
+ const entries = normalizeAndValidateOrderBy(
7970
+ [{ [nestedField]: nestedValue }],
7971
+ relatedModel,
7972
+ parseOrderByValue
7973
+ );
7974
+ const sql = buildOrderByFragment(
7975
+ entries,
7976
+ joinAlias,
7977
+ ctx.dialect,
7978
+ relatedModel
7979
+ );
7980
+ if (sql) orderFragments.push(sql);
7981
+ continue;
7982
+ }
7983
+ if (relRelationSet.has(nestedField)) {
7984
+ if (!isPlainObject(nestedValue)) {
7985
+ throw new Error(
7986
+ `Relation orderBy for '${nestedField}' must be an object`
7987
+ );
7988
+ }
7989
+ const nested = resolveRelationOrderByChain(
7990
+ nestedField,
7991
+ nestedValue,
7992
+ relatedModel,
7993
+ joinAlias,
7994
+ ctx,
7995
+ depth + 1
7996
+ );
7997
+ orderFragments.push(...nested);
7998
+ continue;
7999
+ }
8000
+ throw new Error(
8001
+ `orderBy field '${nestedField}' does not exist on related model '${relatedModel.name}'`
8002
+ );
8003
+ }
8004
+ return orderFragments;
8005
+ }
7910
8006
  function buildOrderByWithRelations(orderBy, alias, dialect, model, schemas) {
7911
8007
  if (!isNotNullish(orderBy)) return { sql: "", joins: [] };
7912
8008
  const expanded = expandOrderByInput(orderBy);
@@ -7914,9 +8010,13 @@ function buildOrderByWithRelations(orderBy, alias, dialect, model, schemas) {
7914
8010
  const relationSet = getRelationFieldSet(model);
7915
8011
  const scalarSet = getScalarFieldSet(model);
7916
8012
  const orderFragments = [];
7917
- const joins = [];
7918
- const usedAliases = /* @__PURE__ */ new Set();
7919
- let relAliasCounter = 0;
8013
+ const ctx = {
8014
+ schemas,
8015
+ dialect,
8016
+ joins: [],
8017
+ usedAliases: /* @__PURE__ */ new Set(),
8018
+ aliasCounter: { value: 0 }
8019
+ };
7920
8020
  for (const [fieldName, value] of expanded) {
7921
8021
  if (scalarSet.has(fieldName)) {
7922
8022
  const entries = normalizeAndValidateOrderBy(
@@ -7932,65 +8032,15 @@ function buildOrderByWithRelations(orderBy, alias, dialect, model, schemas) {
7932
8032
  if (!isPlainObject(value)) {
7933
8033
  throw new Error(`Relation orderBy for '${fieldName}' must be an object`);
7934
8034
  }
7935
- const nestedEntries = Object.entries(value);
7936
- if (nestedEntries.length === 0) continue;
7937
- if ("_count" in value) {
7938
- throw new Error(
7939
- `Relation orderBy with _count on '${fieldName}' is not yet supported by prisma-sql`
7940
- );
7941
- }
7942
- const field = findRelationField(model, fieldName);
7943
- if (!field) {
7944
- throw new Error(
7945
- `Relation field '${fieldName}' not found on model ${model.name}`
7946
- );
7947
- }
7948
- const relatedModel = getModelByName(schemas, field.relatedModel);
7949
- if (!relatedModel) {
7950
- throw new Error(
7951
- `Related model '${field.relatedModel}' not found for relation '${fieldName}'`
7952
- );
7953
- }
7954
- const relScalarSet = getScalarFieldSet(relatedModel);
7955
- const relRelationSet = getRelationFieldSet(relatedModel);
7956
- for (const [nestedField] of nestedEntries) {
7957
- if (relRelationSet.has(nestedField)) {
7958
- throw new Error(
7959
- `Nested relation orderBy (${fieldName}.${nestedField}) is not yet supported by prisma-sql`
7960
- );
7961
- }
7962
- if (!relScalarSet.has(nestedField)) {
7963
- throw new Error(
7964
- `orderBy field '${nestedField}' does not exist on related model '${relatedModel.name}'`
7965
- );
7966
- }
7967
- }
7968
- let joinAlias;
7969
- do {
7970
- joinAlias = `ob_${relAliasCounter++}`;
7971
- } while (usedAliases.has(joinAlias));
7972
- usedAliases.add(joinAlias);
7973
- const tableRef = resolveTableRef(relatedModel, dialect);
7974
- const cond = joinCondition(
7975
- field,
8035
+ const fragments = resolveRelationOrderByChain(
8036
+ fieldName,
8037
+ value,
7976
8038
  model,
7977
- relatedModel,
7978
8039
  alias,
7979
- joinAlias
7980
- );
7981
- joins.push(`LEFT JOIN ${tableRef} ${joinAlias} ON ${cond}`);
7982
- const entries = normalizeAndValidateOrderBy(
7983
- [value],
7984
- relatedModel,
7985
- parseOrderByValue
7986
- );
7987
- const sql = buildOrderByFragment(
7988
- entries,
7989
- joinAlias,
7990
- dialect,
7991
- relatedModel
8040
+ ctx,
8041
+ 0
7992
8042
  );
7993
- if (sql) orderFragments.push(sql);
8043
+ orderFragments.push(...fragments);
7994
8044
  continue;
7995
8045
  }
7996
8046
  throw new Error(
@@ -7999,7 +8049,7 @@ function buildOrderByWithRelations(orderBy, alias, dialect, model, schemas) {
7999
8049
  }
8000
8050
  return {
8001
8051
  sql: orderFragments.join(SQL_SEPARATORS.ORDER_BY),
8002
- joins
8052
+ joins: ctx.joins
8003
8053
  };
8004
8054
  }
8005
8055