prisma-sql 1.75.4 → 1.75.5
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/generator.cjs +119 -69
- package/dist/generator.cjs.map +1 -1
- package/dist/generator.js +119 -69
- package/dist/generator.js.map +1 -1
- package/dist/index.cjs +112 -62
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +112 -62
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/dist/generator.cjs
CHANGED
|
@@ -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.
|
|
2326
|
+
version: "1.75.5",
|
|
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": "^
|
|
2393
|
-
"@prisma/internals": "^
|
|
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": "^
|
|
2398
|
-
"@prisma/adapter-pg": "^
|
|
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": "
|
|
2413
|
-
prisma: "
|
|
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=${
|
|
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) {
|
|
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);
|
|
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
|
|
7918
|
-
|
|
7919
|
-
|
|
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
|
|
7936
|
-
|
|
7937
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|