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.
- 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.js
CHANGED
|
@@ -2312,7 +2312,7 @@ var require_package = __commonJS({
|
|
|
2312
2312
|
"package.json"(exports$1, module) {
|
|
2313
2313
|
module.exports = {
|
|
2314
2314
|
name: "prisma-sql",
|
|
2315
|
-
version: "1.75.
|
|
2315
|
+
version: "1.75.6",
|
|
2316
2316
|
description: "Convert Prisma queries to optimized SQL with type safety. 2-7x faster than Prisma Client.",
|
|
2317
2317
|
main: "dist/index.cjs",
|
|
2318
2318
|
module: "dist/index.js",
|
|
@@ -2378,13 +2378,13 @@ var require_package = __commonJS({
|
|
|
2378
2378
|
license: "MIT",
|
|
2379
2379
|
dependencies: {
|
|
2380
2380
|
"@dee-wan/schema-parser": "1.4.0",
|
|
2381
|
-
"@prisma/generator-helper": "^
|
|
2382
|
-
"@prisma/internals": "^
|
|
2381
|
+
"@prisma/generator-helper": "^7.4.0",
|
|
2382
|
+
"@prisma/internals": "^7.4.0"
|
|
2383
2383
|
},
|
|
2384
2384
|
devDependencies: {
|
|
2385
2385
|
"@faker-js/faker": "^10.2.0",
|
|
2386
|
-
"@prisma/adapter-better-sqlite3": "^
|
|
2387
|
-
"@prisma/adapter-pg": "^
|
|
2386
|
+
"@prisma/adapter-better-sqlite3": "^7.4.0",
|
|
2387
|
+
"@prisma/adapter-pg": "^7.4.0",
|
|
2388
2388
|
"@semantic-release/changelog": "^6.0.3",
|
|
2389
2389
|
"@semantic-release/git": "^10.0.1",
|
|
2390
2390
|
"@types/better-sqlite3": "^7.6.13",
|
|
@@ -2398,8 +2398,8 @@ var require_package = __commonJS({
|
|
|
2398
2398
|
tsx: "^4.21.0",
|
|
2399
2399
|
typescript: "^5.9.3",
|
|
2400
2400
|
vitest: "^4.0.18",
|
|
2401
|
-
"@prisma/client": "
|
|
2402
|
-
prisma: "
|
|
2401
|
+
"@prisma/client": "7.4.0",
|
|
2402
|
+
prisma: "7.4.0"
|
|
2403
2403
|
},
|
|
2404
2404
|
engines: {
|
|
2405
2405
|
node: ">=16.0.0"
|
|
@@ -4651,6 +4651,12 @@ function maxDepthFromTree(nodes) {
|
|
|
4651
4651
|
}
|
|
4652
4652
|
return max;
|
|
4653
4653
|
}
|
|
4654
|
+
function anyChildHasWhere(nodes) {
|
|
4655
|
+
for (const n of nodes) {
|
|
4656
|
+
if (n.hasChildWhere) return true;
|
|
4657
|
+
}
|
|
4658
|
+
return false;
|
|
4659
|
+
}
|
|
4654
4660
|
function computeWhereInCost(nodes, parentCount) {
|
|
4655
4661
|
const R = globalRoundtripRowEquivalent;
|
|
4656
4662
|
let totalRows = 0;
|
|
@@ -4754,13 +4760,18 @@ function pickIncludeStrategy(params) {
|
|
|
4754
4760
|
}
|
|
4755
4761
|
}
|
|
4756
4762
|
const costTree = buildCostTree(includeSpec, model, schemas);
|
|
4763
|
+
const treeDepth = maxDepthFromTree(costTree);
|
|
4764
|
+
if (treeDepth === 1 && anyChildHasWhere(costTree)) {
|
|
4765
|
+
if (debug)
|
|
4766
|
+
console.log(` [strategy] ${model.name}: depth-1 + childWhere \u2192 where-in`);
|
|
4767
|
+
return "where-in";
|
|
4768
|
+
}
|
|
4757
4769
|
const P = isSingleParent ? 1 : takeValue != null ? takeValue : DEFAULT_PARENT_COUNT;
|
|
4758
4770
|
const costW = computeWhereInCost(costTree, P);
|
|
4759
4771
|
const costC = computeCorrelatedCost(costTree, P);
|
|
4760
4772
|
if (debug) {
|
|
4761
|
-
const depth = maxDepthFromTree(costTree);
|
|
4762
4773
|
console.log(
|
|
4763
|
-
` [strategy] ${model.name}: P=${P} D=${
|
|
4774
|
+
` [strategy] ${model.name}: P=${P} D=${treeDepth} costW=${costW.toFixed(0)} costC=${costC.toFixed(0)}`
|
|
4764
4775
|
);
|
|
4765
4776
|
}
|
|
4766
4777
|
if (costC < costW) {
|
|
@@ -7885,6 +7896,7 @@ function buildIncludeSql(args, model, schemas, parentAlias, params, dialect, out
|
|
|
7885
7896
|
}
|
|
7886
7897
|
|
|
7887
7898
|
// src/builder/shared/order-by-relation.ts
|
|
7899
|
+
var MAX_RELATION_ORDER_BY_DEPTH = 10;
|
|
7888
7900
|
function resolveTableRef(model, dialect) {
|
|
7889
7901
|
const tableName = model.tableName || model.dbName || model.name;
|
|
7890
7902
|
if (dialect === "sqlite") {
|
|
@@ -7896,6 +7908,90 @@ function resolveTableRef(model, dialect) {
|
|
|
7896
7908
|
function findRelationField(model, fieldName) {
|
|
7897
7909
|
return model.fields.find((f) => f.name === fieldName && f.isRelation);
|
|
7898
7910
|
}
|
|
7911
|
+
function nextJoinAlias(ctx) {
|
|
7912
|
+
let alias;
|
|
7913
|
+
do {
|
|
7914
|
+
alias = `ob_${ctx.aliasCounter.value++}`;
|
|
7915
|
+
} while (ctx.usedAliases.has(alias));
|
|
7916
|
+
ctx.usedAliases.add(alias);
|
|
7917
|
+
return alias;
|
|
7918
|
+
}
|
|
7919
|
+
function resolveRelationOrderByChain(relationFieldName, value, currentModel, currentAlias, ctx, depth) {
|
|
7920
|
+
if (depth > MAX_RELATION_ORDER_BY_DEPTH) {
|
|
7921
|
+
throw new Error(
|
|
7922
|
+
`Relation orderBy nesting too deep (max ${MAX_RELATION_ORDER_BY_DEPTH} levels)`
|
|
7923
|
+
);
|
|
7924
|
+
}
|
|
7925
|
+
if ("_count" in value && value._count !== void 0) {
|
|
7926
|
+
throw new Error(
|
|
7927
|
+
`Relation orderBy with _count on '${relationFieldName}' is not yet supported by prisma-sql`
|
|
7928
|
+
);
|
|
7929
|
+
}
|
|
7930
|
+
const field = findRelationField(currentModel, relationFieldName);
|
|
7931
|
+
if (!field) {
|
|
7932
|
+
throw new Error(
|
|
7933
|
+
`Relation field '${relationFieldName}' not found on model ${currentModel.name}`
|
|
7934
|
+
);
|
|
7935
|
+
}
|
|
7936
|
+
const relatedModel = getModelByName(ctx.schemas, field.relatedModel);
|
|
7937
|
+
if (!relatedModel) {
|
|
7938
|
+
throw new Error(
|
|
7939
|
+
`Related model '${field.relatedModel}' not found for relation '${relationFieldName}'`
|
|
7940
|
+
);
|
|
7941
|
+
}
|
|
7942
|
+
const joinAlias = nextJoinAlias(ctx);
|
|
7943
|
+
const tableRef = resolveTableRef(relatedModel, ctx.dialect);
|
|
7944
|
+
const cond = joinCondition(
|
|
7945
|
+
field,
|
|
7946
|
+
currentModel,
|
|
7947
|
+
relatedModel,
|
|
7948
|
+
currentAlias,
|
|
7949
|
+
joinAlias
|
|
7950
|
+
);
|
|
7951
|
+
ctx.joins.push(`LEFT JOIN ${tableRef} ${joinAlias} ON ${cond}`);
|
|
7952
|
+
const relScalarSet = getScalarFieldSet(relatedModel);
|
|
7953
|
+
const relRelationSet = getRelationFieldSet(relatedModel);
|
|
7954
|
+
const nestedEntries = Object.entries(value).filter(([, v]) => v !== void 0);
|
|
7955
|
+
const orderFragments = [];
|
|
7956
|
+
for (const [nestedField, nestedValue] of nestedEntries) {
|
|
7957
|
+
if (relScalarSet.has(nestedField)) {
|
|
7958
|
+
const entries = normalizeAndValidateOrderBy(
|
|
7959
|
+
[{ [nestedField]: nestedValue }],
|
|
7960
|
+
relatedModel,
|
|
7961
|
+
parseOrderByValue
|
|
7962
|
+
);
|
|
7963
|
+
const sql = buildOrderByFragment(
|
|
7964
|
+
entries,
|
|
7965
|
+
joinAlias,
|
|
7966
|
+
ctx.dialect,
|
|
7967
|
+
relatedModel
|
|
7968
|
+
);
|
|
7969
|
+
if (sql) orderFragments.push(sql);
|
|
7970
|
+
continue;
|
|
7971
|
+
}
|
|
7972
|
+
if (relRelationSet.has(nestedField)) {
|
|
7973
|
+
if (!isPlainObject(nestedValue)) {
|
|
7974
|
+
throw new Error(
|
|
7975
|
+
`Relation orderBy for '${nestedField}' must be an object`
|
|
7976
|
+
);
|
|
7977
|
+
}
|
|
7978
|
+
const nested = resolveRelationOrderByChain(
|
|
7979
|
+
nestedField,
|
|
7980
|
+
nestedValue,
|
|
7981
|
+
relatedModel,
|
|
7982
|
+
joinAlias,
|
|
7983
|
+
ctx,
|
|
7984
|
+
depth + 1
|
|
7985
|
+
);
|
|
7986
|
+
orderFragments.push(...nested);
|
|
7987
|
+
continue;
|
|
7988
|
+
}
|
|
7989
|
+
throw new Error(
|
|
7990
|
+
`orderBy field '${nestedField}' does not exist on related model '${relatedModel.name}'`
|
|
7991
|
+
);
|
|
7992
|
+
}
|
|
7993
|
+
return orderFragments;
|
|
7994
|
+
}
|
|
7899
7995
|
function buildOrderByWithRelations(orderBy, alias, dialect, model, schemas) {
|
|
7900
7996
|
if (!isNotNullish(orderBy)) return { sql: "", joins: [] };
|
|
7901
7997
|
const expanded = expandOrderByInput(orderBy);
|
|
@@ -7903,9 +7999,13 @@ function buildOrderByWithRelations(orderBy, alias, dialect, model, schemas) {
|
|
|
7903
7999
|
const relationSet = getRelationFieldSet(model);
|
|
7904
8000
|
const scalarSet = getScalarFieldSet(model);
|
|
7905
8001
|
const orderFragments = [];
|
|
7906
|
-
const
|
|
7907
|
-
|
|
7908
|
-
|
|
8002
|
+
const ctx = {
|
|
8003
|
+
schemas,
|
|
8004
|
+
dialect,
|
|
8005
|
+
joins: [],
|
|
8006
|
+
usedAliases: /* @__PURE__ */ new Set(),
|
|
8007
|
+
aliasCounter: { value: 0 }
|
|
8008
|
+
};
|
|
7909
8009
|
for (const [fieldName, value] of expanded) {
|
|
7910
8010
|
if (scalarSet.has(fieldName)) {
|
|
7911
8011
|
const entries = normalizeAndValidateOrderBy(
|
|
@@ -7921,65 +8021,15 @@ function buildOrderByWithRelations(orderBy, alias, dialect, model, schemas) {
|
|
|
7921
8021
|
if (!isPlainObject(value)) {
|
|
7922
8022
|
throw new Error(`Relation orderBy for '${fieldName}' must be an object`);
|
|
7923
8023
|
}
|
|
7924
|
-
const
|
|
7925
|
-
|
|
7926
|
-
|
|
7927
|
-
throw new Error(
|
|
7928
|
-
`Relation orderBy with _count on '${fieldName}' is not yet supported by prisma-sql`
|
|
7929
|
-
);
|
|
7930
|
-
}
|
|
7931
|
-
const field = findRelationField(model, fieldName);
|
|
7932
|
-
if (!field) {
|
|
7933
|
-
throw new Error(
|
|
7934
|
-
`Relation field '${fieldName}' not found on model ${model.name}`
|
|
7935
|
-
);
|
|
7936
|
-
}
|
|
7937
|
-
const relatedModel = getModelByName(schemas, field.relatedModel);
|
|
7938
|
-
if (!relatedModel) {
|
|
7939
|
-
throw new Error(
|
|
7940
|
-
`Related model '${field.relatedModel}' not found for relation '${fieldName}'`
|
|
7941
|
-
);
|
|
7942
|
-
}
|
|
7943
|
-
const relScalarSet = getScalarFieldSet(relatedModel);
|
|
7944
|
-
const relRelationSet = getRelationFieldSet(relatedModel);
|
|
7945
|
-
for (const [nestedField] of nestedEntries) {
|
|
7946
|
-
if (relRelationSet.has(nestedField)) {
|
|
7947
|
-
throw new Error(
|
|
7948
|
-
`Nested relation orderBy (${fieldName}.${nestedField}) is not yet supported by prisma-sql`
|
|
7949
|
-
);
|
|
7950
|
-
}
|
|
7951
|
-
if (!relScalarSet.has(nestedField)) {
|
|
7952
|
-
throw new Error(
|
|
7953
|
-
`orderBy field '${nestedField}' does not exist on related model '${relatedModel.name}'`
|
|
7954
|
-
);
|
|
7955
|
-
}
|
|
7956
|
-
}
|
|
7957
|
-
let joinAlias;
|
|
7958
|
-
do {
|
|
7959
|
-
joinAlias = `ob_${relAliasCounter++}`;
|
|
7960
|
-
} while (usedAliases.has(joinAlias));
|
|
7961
|
-
usedAliases.add(joinAlias);
|
|
7962
|
-
const tableRef = resolveTableRef(relatedModel, dialect);
|
|
7963
|
-
const cond = joinCondition(
|
|
7964
|
-
field,
|
|
8024
|
+
const fragments = resolveRelationOrderByChain(
|
|
8025
|
+
fieldName,
|
|
8026
|
+
value,
|
|
7965
8027
|
model,
|
|
7966
|
-
relatedModel,
|
|
7967
8028
|
alias,
|
|
7968
|
-
|
|
7969
|
-
|
|
7970
|
-
joins.push(`LEFT JOIN ${tableRef} ${joinAlias} ON ${cond}`);
|
|
7971
|
-
const entries = normalizeAndValidateOrderBy(
|
|
7972
|
-
[value],
|
|
7973
|
-
relatedModel,
|
|
7974
|
-
parseOrderByValue
|
|
7975
|
-
);
|
|
7976
|
-
const sql = buildOrderByFragment(
|
|
7977
|
-
entries,
|
|
7978
|
-
joinAlias,
|
|
7979
|
-
dialect,
|
|
7980
|
-
relatedModel
|
|
8029
|
+
ctx,
|
|
8030
|
+
0
|
|
7981
8031
|
);
|
|
7982
|
-
|
|
8032
|
+
orderFragments.push(...fragments);
|
|
7983
8033
|
continue;
|
|
7984
8034
|
}
|
|
7985
8035
|
throw new Error(
|
|
@@ -7988,7 +8038,7 @@ function buildOrderByWithRelations(orderBy, alias, dialect, model, schemas) {
|
|
|
7988
8038
|
}
|
|
7989
8039
|
return {
|
|
7990
8040
|
sql: orderFragments.join(SQL_SEPARATORS.ORDER_BY),
|
|
7991
|
-
joins
|
|
8041
|
+
joins: ctx.joins
|
|
7992
8042
|
};
|
|
7993
8043
|
}
|
|
7994
8044
|
|