prisma-sql 1.75.12 → 1.76.1
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 +318 -186
- package/dist/generator.cjs.map +1 -1
- package/dist/generator.js +318 -186
- package/dist/generator.js.map +1 -1
- package/dist/index.cjs +364 -227
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +364 -227
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/dist/generator.cjs
CHANGED
|
@@ -70,7 +70,7 @@ var require_package = __commonJS({
|
|
|
70
70
|
"package.json"(exports$1, module) {
|
|
71
71
|
module.exports = {
|
|
72
72
|
name: "prisma-sql",
|
|
73
|
-
version: "1.
|
|
73
|
+
version: "1.76.1",
|
|
74
74
|
description: "Convert Prisma queries to optimized SQL with type safety. 2-7x faster than Prisma Client.",
|
|
75
75
|
main: "dist/index.cjs",
|
|
76
76
|
module: "dist/index.js",
|
|
@@ -137,15 +137,15 @@ var require_package = __commonJS({
|
|
|
137
137
|
license: "MIT",
|
|
138
138
|
dependencies: {
|
|
139
139
|
"@dee-wan/schema-parser": "1.4.0",
|
|
140
|
-
"@prisma/generator-helper": "^7.4.
|
|
141
|
-
"@prisma/internals": "^7.4.
|
|
140
|
+
"@prisma/generator-helper": "^7.4.1",
|
|
141
|
+
"@prisma/internals": "^7.4.1",
|
|
142
142
|
dotenv: "^17.3.1",
|
|
143
143
|
postgres: "^3.4.8"
|
|
144
144
|
},
|
|
145
145
|
devDependencies: {
|
|
146
146
|
"@faker-js/faker": "^10.2.0",
|
|
147
|
-
"@prisma/adapter-better-sqlite3": "^7.4.
|
|
148
|
-
"@prisma/adapter-pg": "^7.4.
|
|
147
|
+
"@prisma/adapter-better-sqlite3": "^7.4.1",
|
|
148
|
+
"@prisma/adapter-pg": "^7.4.1",
|
|
149
149
|
"@semantic-release/changelog": "^6.0.3",
|
|
150
150
|
"@semantic-release/git": "^10.0.1",
|
|
151
151
|
"@types/better-sqlite3": "^7.6.13",
|
|
@@ -158,8 +158,8 @@ var require_package = __commonJS({
|
|
|
158
158
|
tsx: "^4.21.0",
|
|
159
159
|
typescript: "^5.9.3",
|
|
160
160
|
vitest: "^4.0.18",
|
|
161
|
-
"@prisma/client": "7.4.
|
|
162
|
-
prisma: "7.4.
|
|
161
|
+
"@prisma/client": "7.4.1",
|
|
162
|
+
prisma: "7.4.1"
|
|
163
163
|
},
|
|
164
164
|
engines: {
|
|
165
165
|
node: ">=16.0.0"
|
|
@@ -475,9 +475,6 @@ var SQL_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
475
475
|
]);
|
|
476
476
|
var SQL_RESERVED_WORDS = SQL_KEYWORDS;
|
|
477
477
|
var DEFAULT_WHERE_CLAUSE = "1=1";
|
|
478
|
-
var SPECIAL_FIELDS = Object.freeze({
|
|
479
|
-
ID: "id"
|
|
480
|
-
});
|
|
481
478
|
var SQL_TEMPLATES = Object.freeze({
|
|
482
479
|
PUBLIC_SCHEMA: "public",
|
|
483
480
|
WHERE: "WHERE",
|
|
@@ -606,29 +603,6 @@ function hasRequiredKeywords(sql) {
|
|
|
606
603
|
return hasSelect && hasFrom && upper.indexOf("SELECT") < upper.indexOf("FROM");
|
|
607
604
|
}
|
|
608
605
|
|
|
609
|
-
// src/builder/shared/errors.ts
|
|
610
|
-
var SqlBuilderError = class extends Error {
|
|
611
|
-
constructor(message, code, context) {
|
|
612
|
-
super(message);
|
|
613
|
-
this.name = "SqlBuilderError";
|
|
614
|
-
this.code = code;
|
|
615
|
-
this.context = context;
|
|
616
|
-
}
|
|
617
|
-
};
|
|
618
|
-
function createError(message, ctx, code = "VALIDATION_ERROR") {
|
|
619
|
-
const parts = [message];
|
|
620
|
-
if (isNonEmptyArray(ctx.path)) {
|
|
621
|
-
parts.push(`Path: ${ctx.path.join(".")}`);
|
|
622
|
-
}
|
|
623
|
-
if (isNotNullish(ctx.modelName)) {
|
|
624
|
-
parts.push(`Model: ${ctx.modelName}`);
|
|
625
|
-
}
|
|
626
|
-
if (isNonEmptyArray(ctx.availableFields)) {
|
|
627
|
-
parts.push(`Available fields: ${ctx.availableFields.join(", ")}`);
|
|
628
|
-
}
|
|
629
|
-
return new SqlBuilderError(parts.join("\n"), code, ctx);
|
|
630
|
-
}
|
|
631
|
-
|
|
632
606
|
// src/builder/shared/validators/sql-validators.ts
|
|
633
607
|
function isValidWhereClause(clause) {
|
|
634
608
|
return isNotNullish(clause) && clause.trim().length > 0 && clause !== DEFAULT_WHERE_CLAUSE;
|
|
@@ -771,8 +745,11 @@ function needsQuoting(identifier) {
|
|
|
771
745
|
}
|
|
772
746
|
|
|
773
747
|
// src/builder/shared/sql-utils.ts
|
|
748
|
+
var _a2;
|
|
749
|
+
var IS_PRODUCTION2 = typeof process !== "undefined" && ((_a2 = process.env) == null ? void 0 : _a2.NODE_ENV) === "production";
|
|
774
750
|
var COL_EXPR_CACHE = /* @__PURE__ */ new WeakMap();
|
|
775
751
|
var COL_WITH_ALIAS_CACHE = /* @__PURE__ */ new WeakMap();
|
|
752
|
+
var TABLE_REF_CACHE = /* @__PURE__ */ new Map();
|
|
776
753
|
function containsControlChars(s) {
|
|
777
754
|
for (let i = 0; i < s.length; i++) {
|
|
778
755
|
const code = s.charCodeAt(i);
|
|
@@ -1007,20 +984,33 @@ function buildTableReference(schemaName, tableName, dialect) {
|
|
|
1007
984
|
"buildTableReference: tableName is required and cannot be empty"
|
|
1008
985
|
);
|
|
1009
986
|
}
|
|
1010
|
-
if (containsControlChars(tableName)) {
|
|
1011
|
-
throw new Error(
|
|
1012
|
-
"buildTableReference: tableName contains invalid characters"
|
|
1013
|
-
);
|
|
1014
|
-
}
|
|
1015
987
|
const d = dialect != null ? dialect : "postgres";
|
|
1016
988
|
if (d === "sqlite") {
|
|
1017
|
-
|
|
989
|
+
const cacheKey2 = `\0${tableName}\0sqlite`;
|
|
990
|
+
let cached2 = TABLE_REF_CACHE.get(cacheKey2);
|
|
991
|
+
if (cached2) return cached2;
|
|
992
|
+
if (containsControlChars(tableName)) {
|
|
993
|
+
throw new Error(
|
|
994
|
+
"buildTableReference: tableName contains invalid characters"
|
|
995
|
+
);
|
|
996
|
+
}
|
|
997
|
+
cached2 = quote(tableName);
|
|
998
|
+
TABLE_REF_CACHE.set(cacheKey2, cached2);
|
|
999
|
+
return cached2;
|
|
1018
1000
|
}
|
|
1019
1001
|
if (isEmptyString(schemaName)) {
|
|
1020
1002
|
throw new Error(
|
|
1021
1003
|
"buildTableReference: schemaName is required and cannot be empty"
|
|
1022
1004
|
);
|
|
1023
1005
|
}
|
|
1006
|
+
const cacheKey = `${schemaName}\0${tableName}\0${d}`;
|
|
1007
|
+
let cached = TABLE_REF_CACHE.get(cacheKey);
|
|
1008
|
+
if (cached) return cached;
|
|
1009
|
+
if (containsControlChars(tableName)) {
|
|
1010
|
+
throw new Error(
|
|
1011
|
+
"buildTableReference: tableName contains invalid characters"
|
|
1012
|
+
);
|
|
1013
|
+
}
|
|
1024
1014
|
if (containsControlChars(schemaName)) {
|
|
1025
1015
|
throw new Error(
|
|
1026
1016
|
"buildTableReference: schemaName contains invalid characters"
|
|
@@ -1028,9 +1018,12 @@ function buildTableReference(schemaName, tableName, dialect) {
|
|
|
1028
1018
|
}
|
|
1029
1019
|
const safeSchema = schemaName.replace(/"/g, '""');
|
|
1030
1020
|
const safeTable = tableName.replace(/"/g, '""');
|
|
1031
|
-
|
|
1021
|
+
cached = `"${safeSchema}"."${safeTable}"`;
|
|
1022
|
+
TABLE_REF_CACHE.set(cacheKey, cached);
|
|
1023
|
+
return cached;
|
|
1032
1024
|
}
|
|
1033
1025
|
function assertSafeAlias(alias) {
|
|
1026
|
+
if (IS_PRODUCTION2) return;
|
|
1034
1027
|
if (typeof alias !== "string") {
|
|
1035
1028
|
throw new Error(`Invalid alias: expected string, got ${typeof alias}`);
|
|
1036
1029
|
}
|
|
@@ -1075,6 +1068,7 @@ function assertSafeAlias(alias) {
|
|
|
1075
1068
|
}
|
|
1076
1069
|
}
|
|
1077
1070
|
function assertSafeTableRef(tableRef) {
|
|
1071
|
+
if (IS_PRODUCTION2) return;
|
|
1078
1072
|
assertSafeQualifiedName(tableRef);
|
|
1079
1073
|
}
|
|
1080
1074
|
function normalizeKeyList(input) {
|
|
@@ -1105,7 +1099,7 @@ function normalizeField(field) {
|
|
|
1105
1099
|
return field;
|
|
1106
1100
|
}
|
|
1107
1101
|
function getFieldIndices(model) {
|
|
1108
|
-
var
|
|
1102
|
+
var _a4;
|
|
1109
1103
|
let cached = FIELD_INDICES_CACHE.get(model);
|
|
1110
1104
|
if (cached) return cached;
|
|
1111
1105
|
const scalarFields = /* @__PURE__ */ new Map();
|
|
@@ -1126,7 +1120,7 @@ function getFieldIndices(model) {
|
|
|
1126
1120
|
} else {
|
|
1127
1121
|
scalarFields.set(field.name, field);
|
|
1128
1122
|
scalarNames.push(field.name);
|
|
1129
|
-
const fieldType = String((
|
|
1123
|
+
const fieldType = String((_a4 = field.type) != null ? _a4 : "").toLowerCase();
|
|
1130
1124
|
if (fieldType === "json") {
|
|
1131
1125
|
jsonFields.add(field.name);
|
|
1132
1126
|
}
|
|
@@ -1140,12 +1134,16 @@ function getFieldIndices(model) {
|
|
|
1140
1134
|
quotedColumns.set(field.name, quote(columnName));
|
|
1141
1135
|
}
|
|
1142
1136
|
}
|
|
1137
|
+
const scalarFieldSet = new Set(scalarNames);
|
|
1138
|
+
const relationFieldSet = new Set(relationNames);
|
|
1143
1139
|
cached = Object.freeze({
|
|
1144
1140
|
scalarFields,
|
|
1145
1141
|
relationFields,
|
|
1146
1142
|
allFieldsByName,
|
|
1147
1143
|
scalarNames,
|
|
1148
1144
|
relationNames,
|
|
1145
|
+
scalarFieldSet,
|
|
1146
|
+
relationFieldSet,
|
|
1149
1147
|
jsonFields,
|
|
1150
1148
|
pkFields,
|
|
1151
1149
|
columnMap,
|
|
@@ -1155,10 +1153,10 @@ function getFieldIndices(model) {
|
|
|
1155
1153
|
return cached;
|
|
1156
1154
|
}
|
|
1157
1155
|
function getRelationFieldSet(model) {
|
|
1158
|
-
return
|
|
1156
|
+
return getFieldIndices(model).relationFieldSet;
|
|
1159
1157
|
}
|
|
1160
1158
|
function getScalarFieldSet(model) {
|
|
1161
|
-
return
|
|
1159
|
+
return getFieldIndices(model).scalarFieldSet;
|
|
1162
1160
|
}
|
|
1163
1161
|
function getColumnMap(model) {
|
|
1164
1162
|
return getFieldIndices(model).columnMap;
|
|
@@ -1170,6 +1168,34 @@ function getJsonFieldSet(model) {
|
|
|
1170
1168
|
return getFieldIndices(model).jsonFields;
|
|
1171
1169
|
}
|
|
1172
1170
|
|
|
1171
|
+
// src/builder/shared/relation-key-utils.ts
|
|
1172
|
+
var RELATION_KEYS_CACHE = /* @__PURE__ */ new WeakMap();
|
|
1173
|
+
function computeRelationKeys(field, context) {
|
|
1174
|
+
const fkFields = normalizeKeyList(field.foreignKey);
|
|
1175
|
+
if (fkFields.length === 0) {
|
|
1176
|
+
throw new Error(
|
|
1177
|
+
`Relation '${field.name}' is missing foreignKey for ${context}`
|
|
1178
|
+
);
|
|
1179
|
+
}
|
|
1180
|
+
const refs = normalizeKeyList(field.references);
|
|
1181
|
+
const refFields = refs.length > 0 ? refs : fkFields.length === 1 ? ["id"] : [];
|
|
1182
|
+
if (refFields.length !== fkFields.length) {
|
|
1183
|
+
throw new Error(
|
|
1184
|
+
`Relation '${field.name}' references count (${refFields.length}) doesn't match foreignKey count (${fkFields.length}) (context: ${context})`
|
|
1185
|
+
);
|
|
1186
|
+
}
|
|
1187
|
+
const childKeys = field.isForeignKeyLocal ? refFields : fkFields;
|
|
1188
|
+
const parentKeys = field.isForeignKeyLocal ? fkFields : refFields;
|
|
1189
|
+
return { childKeys, parentKeys };
|
|
1190
|
+
}
|
|
1191
|
+
function resolveRelationKeys(field, context = "include") {
|
|
1192
|
+
let cached = RELATION_KEYS_CACHE.get(field);
|
|
1193
|
+
if (cached) return cached;
|
|
1194
|
+
cached = computeRelationKeys(field, context);
|
|
1195
|
+
RELATION_KEYS_CACHE.set(field, cached);
|
|
1196
|
+
return cached;
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1173
1199
|
// src/builder/joins.ts
|
|
1174
1200
|
function isRelationField(fieldName, model) {
|
|
1175
1201
|
return getRelationFieldSet(model).has(fieldName);
|
|
@@ -1188,38 +1214,14 @@ function isValidRelationField(field) {
|
|
|
1188
1214
|
if (refs.length !== fk.length) return false;
|
|
1189
1215
|
return true;
|
|
1190
1216
|
}
|
|
1191
|
-
function getReferenceFieldNames(field, foreignKeyCount) {
|
|
1192
|
-
const refs = normalizeKeyList(field.references);
|
|
1193
|
-
if (refs.length === 0) {
|
|
1194
|
-
if (foreignKeyCount === 1) return [SPECIAL_FIELDS.ID];
|
|
1195
|
-
return [];
|
|
1196
|
-
}
|
|
1197
|
-
if (refs.length !== foreignKeyCount) return [];
|
|
1198
|
-
return refs;
|
|
1199
|
-
}
|
|
1200
1217
|
function joinCondition(field, parentModel, childModel, parentAlias, childAlias) {
|
|
1201
1218
|
assertSafeAlias(parentAlias);
|
|
1202
1219
|
assertSafeAlias(childAlias);
|
|
1203
|
-
const
|
|
1204
|
-
if (fkFields.length === 0) {
|
|
1205
|
-
throw createError(
|
|
1206
|
-
`Relation '${field.name}' is missing foreignKey. This indicates a schema parsing error. Relations must specify fields/references.`,
|
|
1207
|
-
{ field: field.name }
|
|
1208
|
-
);
|
|
1209
|
-
}
|
|
1210
|
-
const refFields = getReferenceFieldNames(field, fkFields.length);
|
|
1211
|
-
if (refFields.length !== fkFields.length) {
|
|
1212
|
-
throw createError(
|
|
1213
|
-
`Relation '${field.name}' is missing references (or references count does not match foreignKey count). This is required to support non-id and composite keys.`,
|
|
1214
|
-
{ field: field.name }
|
|
1215
|
-
);
|
|
1216
|
-
}
|
|
1220
|
+
const { childKeys, parentKeys } = resolveRelationKeys(field, "include");
|
|
1217
1221
|
const parts = [];
|
|
1218
|
-
for (let i = 0; i <
|
|
1219
|
-
const
|
|
1220
|
-
const
|
|
1221
|
-
const left = field.isForeignKeyLocal ? `${childAlias}.${quoteColumn(childModel, ref)}` : `${childAlias}.${quoteColumn(childModel, fk)}`;
|
|
1222
|
-
const right = field.isForeignKeyLocal ? `${parentAlias}.${quoteColumn(parentModel, fk)}` : `${parentAlias}.${quoteColumn(parentModel, ref)}`;
|
|
1222
|
+
for (let i = 0; i < parentKeys.length; i++) {
|
|
1223
|
+
const left = field.isForeignKeyLocal ? `${childAlias}.${quoteColumn(childModel, childKeys[i])}` : `${childAlias}.${quoteColumn(childModel, childKeys[i])}`;
|
|
1224
|
+
const right = field.isForeignKeyLocal ? `${parentAlias}.${quoteColumn(parentModel, parentKeys[i])}` : `${parentAlias}.${quoteColumn(parentModel, parentKeys[i])}`;
|
|
1223
1225
|
parts.push(`${left} = ${right}`);
|
|
1224
1226
|
}
|
|
1225
1227
|
return parts.length === 1 ? parts[0] : `(${parts.join(" AND ")})`;
|
|
@@ -1228,13 +1230,13 @@ function getModelByName(schemas, name) {
|
|
|
1228
1230
|
return schemas.find((m) => m.name === name);
|
|
1229
1231
|
}
|
|
1230
1232
|
function normalizeIntLike(name, v, opts = {}) {
|
|
1231
|
-
var
|
|
1233
|
+
var _a4, _b;
|
|
1232
1234
|
if (!isNotNullish(v)) return void 0;
|
|
1233
1235
|
if (schemaParser.isDynamicParameter(v)) return v;
|
|
1234
1236
|
if (typeof v !== "number" || !Number.isFinite(v) || !Number.isInteger(v)) {
|
|
1235
1237
|
throw new Error(`${name} must be an integer`);
|
|
1236
1238
|
}
|
|
1237
|
-
const min = (
|
|
1239
|
+
const min = (_a4 = opts.min) != null ? _a4 : 0;
|
|
1238
1240
|
const allowZero = (_b = opts.allowZero) != null ? _b : true;
|
|
1239
1241
|
if (!allowZero && v === 0) {
|
|
1240
1242
|
throw new Error(`${name} must be > 0`);
|
|
@@ -1380,6 +1382,14 @@ function reverseOrderByInput(orderBy) {
|
|
|
1380
1382
|
var normalizePairs = (pairs, parseValue) => {
|
|
1381
1383
|
const result = [];
|
|
1382
1384
|
for (const [field, rawValue] of pairs) {
|
|
1385
|
+
if (typeof rawValue === "string") {
|
|
1386
|
+
const lower = rawValue.toLowerCase();
|
|
1387
|
+
if (lower !== "asc" && lower !== "desc") {
|
|
1388
|
+
throw new Error(
|
|
1389
|
+
`Invalid orderBy direction '${rawValue}' for field '${field}'. Must be 'asc' or 'desc'`
|
|
1390
|
+
);
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1383
1393
|
if (!isScalarOrderByValue(rawValue)) continue;
|
|
1384
1394
|
const parsed = parseValue(rawValue, field);
|
|
1385
1395
|
result.push({
|
|
@@ -1461,6 +1471,29 @@ function ensureDeterministicOrderByInput(args) {
|
|
|
1461
1471
|
return addTiebreaker(orderBy, tiebreaker);
|
|
1462
1472
|
}
|
|
1463
1473
|
|
|
1474
|
+
// src/builder/shared/errors.ts
|
|
1475
|
+
var SqlBuilderError = class extends Error {
|
|
1476
|
+
constructor(message, code, context) {
|
|
1477
|
+
super(message);
|
|
1478
|
+
this.name = "SqlBuilderError";
|
|
1479
|
+
this.code = code;
|
|
1480
|
+
this.context = context;
|
|
1481
|
+
}
|
|
1482
|
+
};
|
|
1483
|
+
function createError(message, ctx, code = "VALIDATION_ERROR") {
|
|
1484
|
+
const parts = [message];
|
|
1485
|
+
if (isNonEmptyArray(ctx.path)) {
|
|
1486
|
+
parts.push(`Path: ${ctx.path.join(".")}`);
|
|
1487
|
+
}
|
|
1488
|
+
if (isNotNullish(ctx.modelName)) {
|
|
1489
|
+
parts.push(`Model: ${ctx.modelName}`);
|
|
1490
|
+
}
|
|
1491
|
+
if (isNonEmptyArray(ctx.availableFields)) {
|
|
1492
|
+
parts.push(`Available fields: ${ctx.availableFields.join(", ")}`);
|
|
1493
|
+
}
|
|
1494
|
+
return new SqlBuilderError(parts.join("\n"), code, ctx);
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1464
1497
|
// src/builder/shared/primary-key-utils.ts
|
|
1465
1498
|
var FIELD_BY_NAME_CACHE = /* @__PURE__ */ new WeakMap();
|
|
1466
1499
|
function normalizeField2(field) {
|
|
@@ -1745,7 +1778,7 @@ function assertCursorAndOrderFieldsScalar(model, cursor, orderEntries) {
|
|
|
1745
1778
|
}
|
|
1746
1779
|
}
|
|
1747
1780
|
function buildCursorCondition(cursor, orderBy, tableName, alias, params, dialect, model) {
|
|
1748
|
-
var
|
|
1781
|
+
var _a4;
|
|
1749
1782
|
assertSafeTableRef(tableName);
|
|
1750
1783
|
assertSafeAlias(alias);
|
|
1751
1784
|
const d = dialect != null ? dialect : getGlobalDialect();
|
|
@@ -1840,7 +1873,7 @@ function buildCursorCondition(cursor, orderBy, tableName, alias, params, dialect
|
|
|
1840
1873
|
const e = finalOrderEntries[level];
|
|
1841
1874
|
const c = col(alias, e.field, model);
|
|
1842
1875
|
const cursorField = cteName + "." + quoteColumn(model, e.field);
|
|
1843
|
-
const nulls = (
|
|
1876
|
+
const nulls = (_a4 = e.nulls) != null ? _a4 : defaultNullsFor(d, e.direction);
|
|
1844
1877
|
andParts.push(buildCursorInequalityExpr(c, e.direction, nulls, cursorField));
|
|
1845
1878
|
orClauses.push("(" + andParts.join(SQL_SEPARATORS.CONDITION_AND) + ")");
|
|
1846
1879
|
}
|
|
@@ -1960,34 +1993,6 @@ function createAliasGenerator(maxAliases = 1e4) {
|
|
|
1960
1993
|
};
|
|
1961
1994
|
}
|
|
1962
1995
|
|
|
1963
|
-
// src/builder/shared/relation-key-utils.ts
|
|
1964
|
-
var RELATION_KEYS_CACHE = /* @__PURE__ */ new WeakMap();
|
|
1965
|
-
function computeRelationKeys(field, context) {
|
|
1966
|
-
const fkFields = normalizeKeyList(field.foreignKey);
|
|
1967
|
-
if (fkFields.length === 0) {
|
|
1968
|
-
throw new Error(
|
|
1969
|
-
`Relation '${field.name}' is missing foreignKey for ${context}`
|
|
1970
|
-
);
|
|
1971
|
-
}
|
|
1972
|
-
const refs = normalizeKeyList(field.references);
|
|
1973
|
-
const refFields = refs.length > 0 ? refs : fkFields.length === 1 ? ["id"] : [];
|
|
1974
|
-
if (refFields.length !== fkFields.length) {
|
|
1975
|
-
throw new Error(
|
|
1976
|
-
`Relation '${field.name}' references count (${refFields.length}) doesn't match foreignKey count (${fkFields.length}) (context: ${context})`
|
|
1977
|
-
);
|
|
1978
|
-
}
|
|
1979
|
-
const childKeys = field.isForeignKeyLocal ? refFields : fkFields;
|
|
1980
|
-
const parentKeys = field.isForeignKeyLocal ? fkFields : refFields;
|
|
1981
|
-
return { childKeys, parentKeys };
|
|
1982
|
-
}
|
|
1983
|
-
function resolveRelationKeys(field, context = "include") {
|
|
1984
|
-
let cached = RELATION_KEYS_CACHE.get(field);
|
|
1985
|
-
if (cached) return cached;
|
|
1986
|
-
cached = computeRelationKeys(field, context);
|
|
1987
|
-
RELATION_KEYS_CACHE.set(field, cached);
|
|
1988
|
-
return cached;
|
|
1989
|
-
}
|
|
1990
|
-
|
|
1991
1996
|
// src/builder/shared/fk-join-utils.ts
|
|
1992
1997
|
var FK_COLUMN_PREFIX = "__fk";
|
|
1993
1998
|
function fkColumnName(index) {
|
|
@@ -2173,7 +2178,7 @@ function resolveCountRelationOrThrow(relName, model, schemaByName) {
|
|
|
2173
2178
|
`_count.${relName} references unknown relation on model ${model.name}`
|
|
2174
2179
|
);
|
|
2175
2180
|
}
|
|
2176
|
-
const field = model.
|
|
2181
|
+
const field = getFieldIndices(model).allFieldsByName.get(relName);
|
|
2177
2182
|
if (!field) {
|
|
2178
2183
|
throw new Error(
|
|
2179
2184
|
`_count.${relName} references unknown relation on model ${model.name}`
|
|
@@ -2250,12 +2255,11 @@ function buildCountJoinAndPair(args) {
|
|
|
2250
2255
|
pairSql: `${sqlStringLiteral(args.relName)}, COALESCE(${joinAlias}.${COUNT_COLUMN}, 0)`
|
|
2251
2256
|
};
|
|
2252
2257
|
}
|
|
2253
|
-
function buildRelationCountSql(countSelect, model, schemas, parentAlias, _params, dialect) {
|
|
2258
|
+
function buildRelationCountSql(countSelect, model, schemas, parentAlias, _params, dialect, modelMap) {
|
|
2254
2259
|
const joins = [];
|
|
2255
2260
|
const pairs = [];
|
|
2256
2261
|
const aliasGen = createAliasGenerator();
|
|
2257
|
-
const schemaByName =
|
|
2258
|
-
for (const m of schemas) schemaByName.set(m.name, m);
|
|
2262
|
+
const schemaByName = modelMap != null ? modelMap : new Map(schemas.map((m) => [m.name, m]));
|
|
2259
2263
|
for (const [relName, shouldCount] of Object.entries(countSelect)) {
|
|
2260
2264
|
if (!shouldCount) continue;
|
|
2261
2265
|
const resolved = resolveCountRelationOrThrow(relName, model, schemaByName);
|
|
@@ -2329,14 +2333,23 @@ function extractNestedIncludeSpec(relArgs, relModel) {
|
|
|
2329
2333
|
}
|
|
2330
2334
|
|
|
2331
2335
|
// src/builder/shared/include-tree-walker.ts
|
|
2332
|
-
|
|
2333
|
-
|
|
2336
|
+
var MODEL_MAP_CACHE = /* @__PURE__ */ new WeakMap();
|
|
2337
|
+
function getOrCreateModelMap(schemas) {
|
|
2338
|
+
let map = MODEL_MAP_CACHE.get(schemas);
|
|
2339
|
+
if (map) return map;
|
|
2340
|
+
map = /* @__PURE__ */ new Map();
|
|
2341
|
+
for (const m of schemas) map.set(m.name, m);
|
|
2342
|
+
MODEL_MAP_CACHE.set(schemas, map);
|
|
2343
|
+
return map;
|
|
2344
|
+
}
|
|
2345
|
+
function resolveIncludeRelations(includeSpec, model, schemas, modelMap) {
|
|
2346
|
+
const map = modelMap != null ? modelMap : getOrCreateModelMap(schemas);
|
|
2334
2347
|
const results = [];
|
|
2335
2348
|
for (const [relName, value] of Object.entries(includeSpec)) {
|
|
2336
2349
|
if (value === false) continue;
|
|
2337
|
-
const field = model.
|
|
2350
|
+
const field = getFieldIndices(model).allFieldsByName.get(relName);
|
|
2338
2351
|
if (!(field == null ? void 0 : field.isRelation) || !field.relatedModel) continue;
|
|
2339
|
-
const relModel =
|
|
2352
|
+
const relModel = map.get(field.relatedModel);
|
|
2340
2353
|
if (!relModel) continue;
|
|
2341
2354
|
const isList = typeof field.type === "string" && field.type.endsWith("[]");
|
|
2342
2355
|
const nestedSpec = isPlainObject(value) ? extractNestedIncludeSpec(value, relModel) : {};
|
|
@@ -2357,15 +2370,18 @@ var CORRELATED_S_UNBOUNDED = 3;
|
|
|
2357
2370
|
var CORRELATED_WHERE_PENALTY = 3;
|
|
2358
2371
|
var DEFAULT_FAN = 10;
|
|
2359
2372
|
var DEFAULT_PARENT_COUNT = 50;
|
|
2360
|
-
var SINGLE_PARENT_MAX_FLAT_JOIN_DEPTH =
|
|
2373
|
+
var SINGLE_PARENT_MAX_FLAT_JOIN_DEPTH = 2;
|
|
2361
2374
|
function getFanOut(modelName, relName) {
|
|
2362
2375
|
return DEFAULT_FAN;
|
|
2363
2376
|
}
|
|
2377
|
+
var DYNAMIC_TAKE_ESTIMATE = 10;
|
|
2364
2378
|
function readTake(relArgs) {
|
|
2365
2379
|
if (!isPlainObject(relArgs)) return Infinity;
|
|
2366
2380
|
const obj = relArgs;
|
|
2367
2381
|
if ("take" in obj && typeof obj.take === "number" && obj.take > 0)
|
|
2368
2382
|
return obj.take;
|
|
2383
|
+
if ("take" in obj && obj.take != null && schemaParser.isDynamicParameter(obj.take))
|
|
2384
|
+
return DYNAMIC_TAKE_ESTIMATE;
|
|
2369
2385
|
return Infinity;
|
|
2370
2386
|
}
|
|
2371
2387
|
function hasWhereClause(relArgs) {
|
|
@@ -2379,17 +2395,28 @@ function isListField(field) {
|
|
|
2379
2395
|
function hasPaginationArgs(value) {
|
|
2380
2396
|
if (!isPlainObject(value)) return false;
|
|
2381
2397
|
const obj = value;
|
|
2382
|
-
return "take" in obj && obj.take != null || "skip" in obj && typeof obj.skip === "number" && obj.skip > 0;
|
|
2398
|
+
return "take" in obj && obj.take != null || "skip" in obj && obj.skip != null && (typeof obj.skip === "number" && obj.skip > 0 || schemaParser.isDynamicParameter(obj.skip));
|
|
2383
2399
|
}
|
|
2384
|
-
function buildCostTree(includeSpec, model, schemas, depth = 0) {
|
|
2400
|
+
function buildCostTree(includeSpec, model, schemas, depth = 0, modelMap) {
|
|
2385
2401
|
if (depth > LIMITS.MAX_INCLUDE_DEPTH) return [];
|
|
2386
|
-
const relations = resolveIncludeRelations(
|
|
2402
|
+
const relations = resolveIncludeRelations(
|
|
2403
|
+
includeSpec,
|
|
2404
|
+
model,
|
|
2405
|
+
schemas,
|
|
2406
|
+
modelMap
|
|
2407
|
+
);
|
|
2387
2408
|
const nodes = [];
|
|
2388
2409
|
for (const rel of relations) {
|
|
2389
2410
|
const fan = rel.isList ? getFanOut(model.name, rel.relName) : 1;
|
|
2390
2411
|
const take = rel.isList ? readTake(rel.value) : 1;
|
|
2391
2412
|
const eff = Math.min(fan, take);
|
|
2392
|
-
const children = Object.keys(rel.nestedSpec).length > 0 ? buildCostTree(
|
|
2413
|
+
const children = Object.keys(rel.nestedSpec).length > 0 ? buildCostTree(
|
|
2414
|
+
rel.nestedSpec,
|
|
2415
|
+
rel.relModel,
|
|
2416
|
+
schemas,
|
|
2417
|
+
depth + 1,
|
|
2418
|
+
modelMap
|
|
2419
|
+
) : [];
|
|
2393
2420
|
nodes.push({
|
|
2394
2421
|
name: rel.relName,
|
|
2395
2422
|
fan,
|
|
@@ -2453,17 +2480,23 @@ function computeCorrelatedCost(nodes, parentCount) {
|
|
|
2453
2480
|
return R + parentCount * subqueryCost(nodes);
|
|
2454
2481
|
}
|
|
2455
2482
|
function hasOnlyToOneRelations(includeSpec, model) {
|
|
2483
|
+
const indices = getFieldIndices(model);
|
|
2456
2484
|
for (const [relName, value] of Object.entries(includeSpec)) {
|
|
2457
2485
|
if (value === false) continue;
|
|
2458
|
-
const field =
|
|
2486
|
+
const field = indices.allFieldsByName.get(relName);
|
|
2459
2487
|
if (!(field == null ? void 0 : field.isRelation)) continue;
|
|
2460
2488
|
if (isListField(field)) return false;
|
|
2461
2489
|
}
|
|
2462
2490
|
return true;
|
|
2463
2491
|
}
|
|
2464
|
-
function countIncludeDepth(includeSpec, model, schemas, depth = 0) {
|
|
2492
|
+
function countIncludeDepth(includeSpec, model, schemas, depth = 0, modelMap) {
|
|
2465
2493
|
if (depth > LIMITS.MAX_INCLUDE_DEPTH) return 0;
|
|
2466
|
-
const relations = resolveIncludeRelations(
|
|
2494
|
+
const relations = resolveIncludeRelations(
|
|
2495
|
+
includeSpec,
|
|
2496
|
+
model,
|
|
2497
|
+
schemas,
|
|
2498
|
+
modelMap
|
|
2499
|
+
);
|
|
2467
2500
|
let maxDepth = 0;
|
|
2468
2501
|
for (const rel of relations) {
|
|
2469
2502
|
let childDepth = 1;
|
|
@@ -2472,27 +2505,34 @@ function countIncludeDepth(includeSpec, model, schemas, depth = 0) {
|
|
|
2472
2505
|
rel.nestedSpec,
|
|
2473
2506
|
rel.relModel,
|
|
2474
2507
|
schemas,
|
|
2475
|
-
depth + 1
|
|
2508
|
+
depth + 1,
|
|
2509
|
+
modelMap
|
|
2476
2510
|
);
|
|
2477
2511
|
}
|
|
2478
2512
|
if (childDepth > maxDepth) maxDepth = childDepth;
|
|
2479
2513
|
}
|
|
2480
2514
|
return maxDepth;
|
|
2481
2515
|
}
|
|
2482
|
-
function hasChildPaginationAnywhere(includeSpec, model, schemas, depth = 0) {
|
|
2516
|
+
function hasChildPaginationAnywhere(includeSpec, model, schemas, depth = 0, modelMap) {
|
|
2483
2517
|
if (depth > LIMITS.MAX_INCLUDE_DEPTH) return false;
|
|
2484
2518
|
for (const [, value] of Object.entries(includeSpec)) {
|
|
2485
2519
|
if (value === false) continue;
|
|
2486
2520
|
if (hasPaginationArgs(value)) return true;
|
|
2487
2521
|
}
|
|
2488
|
-
const relations = resolveIncludeRelations(
|
|
2522
|
+
const relations = resolveIncludeRelations(
|
|
2523
|
+
includeSpec,
|
|
2524
|
+
model,
|
|
2525
|
+
schemas,
|
|
2526
|
+
modelMap
|
|
2527
|
+
);
|
|
2489
2528
|
for (const rel of relations) {
|
|
2490
2529
|
if (Object.keys(rel.nestedSpec).length > 0) {
|
|
2491
2530
|
if (hasChildPaginationAnywhere(
|
|
2492
2531
|
rel.nestedSpec,
|
|
2493
2532
|
rel.relModel,
|
|
2494
2533
|
schemas,
|
|
2495
|
-
depth + 1
|
|
2534
|
+
depth + 1,
|
|
2535
|
+
modelMap
|
|
2496
2536
|
)) {
|
|
2497
2537
|
return true;
|
|
2498
2538
|
}
|
|
@@ -2501,7 +2541,17 @@ function hasChildPaginationAnywhere(includeSpec, model, schemas, depth = 0) {
|
|
|
2501
2541
|
return false;
|
|
2502
2542
|
}
|
|
2503
2543
|
function pickIncludeStrategy(params) {
|
|
2504
|
-
const {
|
|
2544
|
+
const {
|
|
2545
|
+
includeSpec,
|
|
2546
|
+
model,
|
|
2547
|
+
schemas,
|
|
2548
|
+
method,
|
|
2549
|
+
takeValue,
|
|
2550
|
+
canFlatJoin,
|
|
2551
|
+
hasChildPagination,
|
|
2552
|
+
debug,
|
|
2553
|
+
modelMap
|
|
2554
|
+
} = params;
|
|
2505
2555
|
if (Object.keys(includeSpec).length === 0) return "where-in";
|
|
2506
2556
|
if (canFlatJoin && hasOnlyToOneRelations(includeSpec, model)) {
|
|
2507
2557
|
if (debug)
|
|
@@ -2510,7 +2560,7 @@ function pickIncludeStrategy(params) {
|
|
|
2510
2560
|
}
|
|
2511
2561
|
const isSingleParent = method === "findFirst" || method === "findUnique";
|
|
2512
2562
|
if (isSingleParent && canFlatJoin) {
|
|
2513
|
-
const depth = countIncludeDepth(includeSpec, model, schemas);
|
|
2563
|
+
const depth = countIncludeDepth(includeSpec, model, schemas, 0, modelMap);
|
|
2514
2564
|
if (depth <= SINGLE_PARENT_MAX_FLAT_JOIN_DEPTH) {
|
|
2515
2565
|
if (debug)
|
|
2516
2566
|
console.log(
|
|
@@ -2519,8 +2569,37 @@ function pickIncludeStrategy(params) {
|
|
|
2519
2569
|
return "flat-join";
|
|
2520
2570
|
}
|
|
2521
2571
|
}
|
|
2522
|
-
const costTree = buildCostTree(includeSpec, model, schemas);
|
|
2572
|
+
const costTree = buildCostTree(includeSpec, model, schemas, 0, modelMap);
|
|
2523
2573
|
const treeDepth = maxDepthFromTree(costTree);
|
|
2574
|
+
if (hasChildPagination && treeDepth >= 2) {
|
|
2575
|
+
if (debug)
|
|
2576
|
+
console.log(
|
|
2577
|
+
` [strategy] ${model.name}: childPagination + depth=${treeDepth} \u2265 2 \u2192 fallback`
|
|
2578
|
+
);
|
|
2579
|
+
return "fallback";
|
|
2580
|
+
}
|
|
2581
|
+
if (hasChildPagination && treeDepth === 1) {
|
|
2582
|
+
if (anyChildHasWhere(costTree)) {
|
|
2583
|
+
if (debug)
|
|
2584
|
+
console.log(
|
|
2585
|
+
` [strategy] ${model.name}: childPagination + depth=1 + childWhere \u2192 where-in`
|
|
2586
|
+
);
|
|
2587
|
+
return "where-in";
|
|
2588
|
+
}
|
|
2589
|
+
const hasSelectNarrowing = isPlainObject(params.args) && isPlainObject(params.args.select);
|
|
2590
|
+
if (hasSelectNarrowing) {
|
|
2591
|
+
if (debug)
|
|
2592
|
+
console.log(
|
|
2593
|
+
` [strategy] ${model.name}: childPagination + depth=1 + selectNarrowing \u2192 fallback`
|
|
2594
|
+
);
|
|
2595
|
+
return "fallback";
|
|
2596
|
+
}
|
|
2597
|
+
if (debug)
|
|
2598
|
+
console.log(
|
|
2599
|
+
` [strategy] ${model.name}: childPagination + depth=1 \u2192 where-in`
|
|
2600
|
+
);
|
|
2601
|
+
return "where-in";
|
|
2602
|
+
}
|
|
2524
2603
|
if (treeDepth === 1 && anyChildHasWhere(costTree)) {
|
|
2525
2604
|
if (debug)
|
|
2526
2605
|
console.log(` [strategy] ${model.name}: depth-1 + childWhere \u2192 where-in`);
|
|
@@ -2598,13 +2677,13 @@ function createAliasCounter() {
|
|
|
2598
2677
|
}
|
|
2599
2678
|
};
|
|
2600
2679
|
}
|
|
2601
|
-
function getRelationModel(parentModel, relationName, schemas) {
|
|
2680
|
+
function getRelationModel(parentModel, relationName, schemas, modelMap) {
|
|
2602
2681
|
const indices = getFieldIndices(parentModel);
|
|
2603
2682
|
const field = indices.allFieldsByName.get(relationName);
|
|
2604
2683
|
if (!(field == null ? void 0 : field.isRelation) || !field.relatedModel) {
|
|
2605
2684
|
throw new Error(`Invalid relation ${relationName} on ${parentModel.name}`);
|
|
2606
2685
|
}
|
|
2607
|
-
const relModel = schemas.find((m) => m.name === field.relatedModel);
|
|
2686
|
+
const relModel = modelMap ? modelMap.get(field.relatedModel) : schemas.find((m) => m.name === field.relatedModel);
|
|
2608
2687
|
if (!relModel) {
|
|
2609
2688
|
throw new Error(`Related model ${field.relatedModel} not found`);
|
|
2610
2689
|
}
|
|
@@ -2641,8 +2720,13 @@ function countActiveEntries(spec) {
|
|
|
2641
2720
|
}
|
|
2642
2721
|
return count;
|
|
2643
2722
|
}
|
|
2644
|
-
function canUseFlatJoinForAll(includeSpec, model, schemas, debug) {
|
|
2645
|
-
const relations = resolveIncludeRelations(
|
|
2723
|
+
function canUseFlatJoinForAll(includeSpec, model, schemas, debug, modelMap) {
|
|
2724
|
+
const relations = resolveIncludeRelations(
|
|
2725
|
+
includeSpec,
|
|
2726
|
+
model,
|
|
2727
|
+
schemas,
|
|
2728
|
+
modelMap
|
|
2729
|
+
);
|
|
2646
2730
|
if (relations.length < countActiveEntries(includeSpec)) {
|
|
2647
2731
|
return false;
|
|
2648
2732
|
}
|
|
@@ -2664,14 +2748,20 @@ function canUseFlatJoinForAll(includeSpec, model, schemas, debug) {
|
|
|
2664
2748
|
return false;
|
|
2665
2749
|
}
|
|
2666
2750
|
if (Object.keys(rel.nestedSpec).length > 0) {
|
|
2667
|
-
if (!canUseFlatJoinForAll(
|
|
2751
|
+
if (!canUseFlatJoinForAll(
|
|
2752
|
+
rel.nestedSpec,
|
|
2753
|
+
rel.relModel,
|
|
2754
|
+
schemas,
|
|
2755
|
+
debug,
|
|
2756
|
+
modelMap
|
|
2757
|
+
)) {
|
|
2668
2758
|
return false;
|
|
2669
2759
|
}
|
|
2670
2760
|
}
|
|
2671
2761
|
}
|
|
2672
2762
|
return true;
|
|
2673
2763
|
}
|
|
2674
|
-
function buildNestedJoins(parentModel, parentAlias, includeSpec, schemas, dialect, prefix, aliasCounter, depth = 0) {
|
|
2764
|
+
function buildNestedJoins(parentModel, parentAlias, includeSpec, schemas, dialect, prefix, aliasCounter, depth = 0, modelMap) {
|
|
2675
2765
|
if (depth > LIMITS.MAX_NESTED_JOIN_DEPTH) {
|
|
2676
2766
|
throw new Error(
|
|
2677
2767
|
`Nested joins exceeded maximum depth of ${LIMITS.MAX_NESTED_JOIN_DEPTH} at prefix '${prefix}'`
|
|
@@ -2685,7 +2775,7 @@ function buildNestedJoins(parentModel, parentAlias, includeSpec, schemas, dialec
|
|
|
2685
2775
|
const indices = getFieldIndices(parentModel);
|
|
2686
2776
|
const field = indices.allFieldsByName.get(relName);
|
|
2687
2777
|
if (!isValidRelationField(field)) continue;
|
|
2688
|
-
const relModel = getRelationModel(parentModel, relName, schemas);
|
|
2778
|
+
const relModel = getRelationModel(parentModel, relName, schemas, modelMap);
|
|
2689
2779
|
const relTable = buildTableReference(
|
|
2690
2780
|
SQL_TEMPLATES.PUBLIC_SCHEMA,
|
|
2691
2781
|
relModel.tableName,
|
|
@@ -2726,7 +2816,8 @@ function buildNestedJoins(parentModel, parentAlias, includeSpec, schemas, dialec
|
|
|
2726
2816
|
dialect,
|
|
2727
2817
|
nestedPrefix,
|
|
2728
2818
|
aliasCounter,
|
|
2729
|
-
depth + 1
|
|
2819
|
+
depth + 1,
|
|
2820
|
+
modelMap
|
|
2730
2821
|
);
|
|
2731
2822
|
joins.push(...deeper.joins);
|
|
2732
2823
|
selects.push(...deeper.selects);
|
|
@@ -2782,6 +2873,8 @@ function buildFlatJoinSql(spec) {
|
|
|
2782
2873
|
requiresReduction: false,
|
|
2783
2874
|
includeSpec: {}
|
|
2784
2875
|
};
|
|
2876
|
+
const modelMap = /* @__PURE__ */ new Map();
|
|
2877
|
+
for (const m of schemas) modelMap.set(m.name, m);
|
|
2785
2878
|
const includeSpec = extractRelationEntries(args, model).reduce(
|
|
2786
2879
|
(acc, { name, value }) => {
|
|
2787
2880
|
acc[name] = value;
|
|
@@ -2792,7 +2885,7 @@ function buildFlatJoinSql(spec) {
|
|
|
2792
2885
|
if (Object.keys(includeSpec).length === 0) {
|
|
2793
2886
|
return emptyResult;
|
|
2794
2887
|
}
|
|
2795
|
-
if (!canUseFlatJoinForAll(includeSpec, model, schemas)) {
|
|
2888
|
+
if (!canUseFlatJoinForAll(includeSpec, model, schemas, false, modelMap)) {
|
|
2796
2889
|
return emptyResult;
|
|
2797
2890
|
}
|
|
2798
2891
|
const { cleanWhere, params } = extractReferencedParams(
|
|
@@ -2828,7 +2921,8 @@ function buildFlatJoinSql(spec) {
|
|
|
2828
2921
|
dialect,
|
|
2829
2922
|
"",
|
|
2830
2923
|
aliasCounter,
|
|
2831
|
-
0
|
|
2924
|
+
0,
|
|
2925
|
+
modelMap
|
|
2832
2926
|
);
|
|
2833
2927
|
if (built.joins.length === 0) {
|
|
2834
2928
|
return emptyResult;
|
|
@@ -3832,8 +3926,8 @@ function buildOperator(expr, op, val, ctx, mode, fieldType) {
|
|
|
3832
3926
|
});
|
|
3833
3927
|
}
|
|
3834
3928
|
var MAX_PARAM_INDEX = Number.MAX_SAFE_INTEGER - 1e3;
|
|
3835
|
-
var
|
|
3836
|
-
var
|
|
3929
|
+
var _a3;
|
|
3930
|
+
var IS_PRODUCTION3 = typeof process !== "undefined" && ((_a3 = process.env) == null ? void 0 : _a3.NODE_ENV) === "production";
|
|
3837
3931
|
function assertSameLength(params, mappings) {
|
|
3838
3932
|
if (params.length !== mappings.length) {
|
|
3839
3933
|
throw new Error(
|
|
@@ -3893,7 +3987,7 @@ function validateMappings(mappings) {
|
|
|
3893
3987
|
}
|
|
3894
3988
|
}
|
|
3895
3989
|
function validateState(params, mappings, index) {
|
|
3896
|
-
if (
|
|
3990
|
+
if (IS_PRODUCTION3) {
|
|
3897
3991
|
assertSameLength(params, mappings);
|
|
3898
3992
|
assertValidNextIndex(index);
|
|
3899
3993
|
return;
|
|
@@ -3951,6 +4045,7 @@ function createStoreInternal(startIndex, dialect, initialParams = [], initialMap
|
|
|
3951
4045
|
if (frozen) {
|
|
3952
4046
|
params = params.slice();
|
|
3953
4047
|
mappings = mappings.slice();
|
|
4048
|
+
dynamicNameToIndex = new Map(dynamicNameToIndex);
|
|
3954
4049
|
frozen = false;
|
|
3955
4050
|
}
|
|
3956
4051
|
}
|
|
@@ -3967,6 +4062,7 @@ function createStoreInternal(startIndex, dialect, initialParams = [], initialMap
|
|
|
3967
4062
|
const dn = validateDynamicName(dynamicName);
|
|
3968
4063
|
const existing = dynamicNameToIndex.get(dn);
|
|
3969
4064
|
if (existing !== void 0) return formatPosition(existing);
|
|
4065
|
+
ensureMutable();
|
|
3970
4066
|
const position = index;
|
|
3971
4067
|
dynamicNameToIndex.set(dn, position);
|
|
3972
4068
|
return registerParam(void 0, { index: position, dynamicName: dn });
|
|
@@ -3997,7 +4093,7 @@ function createStoreInternal(startIndex, dialect, initialParams = [], initialMap
|
|
|
3997
4093
|
index,
|
|
3998
4094
|
params,
|
|
3999
4095
|
mappings,
|
|
4000
|
-
dynamicNameIndex:
|
|
4096
|
+
dynamicNameIndex: dynamicNameToIndex
|
|
4001
4097
|
};
|
|
4002
4098
|
cachedSnapshot = snap;
|
|
4003
4099
|
dirty = false;
|
|
@@ -4052,10 +4148,10 @@ function toPublicResult(clause, joins, params) {
|
|
|
4052
4148
|
|
|
4053
4149
|
// src/builder/where.ts
|
|
4054
4150
|
function buildWhereClause(where, options) {
|
|
4055
|
-
var
|
|
4151
|
+
var _a4, _b, _c, _d, _e;
|
|
4056
4152
|
assertSafeAlias(options.alias);
|
|
4057
4153
|
const dialect = options.dialect || getGlobalDialect();
|
|
4058
|
-
const params = (
|
|
4154
|
+
const params = (_a4 = options.params) != null ? _a4 : createParamStore(1, dialect);
|
|
4059
4155
|
const ctx = {
|
|
4060
4156
|
alias: options.alias,
|
|
4061
4157
|
model: options.model,
|
|
@@ -4138,12 +4234,13 @@ function reindexWhereParams(whereClause, specParams, collector) {
|
|
|
4138
4234
|
}
|
|
4139
4235
|
return clean;
|
|
4140
4236
|
}
|
|
4141
|
-
function getRelationModel2(parentModel, relationName, schemas) {
|
|
4142
|
-
var
|
|
4237
|
+
function getRelationModel2(parentModel, relationName, schemas, modelMap) {
|
|
4238
|
+
var _a4, _b;
|
|
4143
4239
|
const indices = getFieldIndices(parentModel);
|
|
4144
4240
|
const field = indices.allFieldsByName.get(relationName);
|
|
4145
4241
|
if (!(field == null ? void 0 : field.isRelation) || !field.relatedModel) return null;
|
|
4146
|
-
return (
|
|
4242
|
+
if (modelMap) return (_a4 = modelMap.get(field.relatedModel)) != null ? _a4 : null;
|
|
4243
|
+
return (_b = schemas.find((m) => m.name === field.relatedModel)) != null ? _b : null;
|
|
4147
4244
|
}
|
|
4148
4245
|
function extractOrderByInput(relArgs) {
|
|
4149
4246
|
if (!isPlainObject(relArgs)) return void 0;
|
|
@@ -4188,7 +4285,12 @@ function buildLateralForRelation(relationName, relArgs, field, relModel, parentM
|
|
|
4188
4285
|
const nestedIndices = getFieldIndices(relModel);
|
|
4189
4286
|
const nestedField = nestedIndices.allFieldsByName.get(nestedName);
|
|
4190
4287
|
if (!nestedField || !isValidRelationField(nestedField)) continue;
|
|
4191
|
-
const nestedModel = getRelationModel2(
|
|
4288
|
+
const nestedModel = getRelationModel2(
|
|
4289
|
+
relModel,
|
|
4290
|
+
nestedName,
|
|
4291
|
+
ctx.schemas,
|
|
4292
|
+
ctx.modelMap
|
|
4293
|
+
);
|
|
4192
4294
|
if (!nestedModel) continue;
|
|
4193
4295
|
const nested = buildLateralForRelation(
|
|
4194
4296
|
nestedName,
|
|
@@ -4291,12 +4393,12 @@ function buildLateralForRelation(relationName, relArgs, field, relModel, parentM
|
|
|
4291
4393
|
}
|
|
4292
4394
|
const joinSql = `LEFT JOIN LATERAL (${outerSql}) ${latAlias} ON true`;
|
|
4293
4395
|
const fieldTypes = selectedFields.map((fieldName) => {
|
|
4294
|
-
var
|
|
4396
|
+
var _a4;
|
|
4295
4397
|
const f = indices.scalarFields.get(fieldName);
|
|
4296
4398
|
if (!f) return null;
|
|
4297
4399
|
return {
|
|
4298
4400
|
fieldName: f.name,
|
|
4299
|
-
type: String((
|
|
4401
|
+
type: String((_a4 = f.type) != null ? _a4 : "").toLowerCase()
|
|
4300
4402
|
};
|
|
4301
4403
|
}).filter(Boolean);
|
|
4302
4404
|
const meta = {
|
|
@@ -4314,8 +4416,13 @@ function countActiveEntries2(spec) {
|
|
|
4314
4416
|
}
|
|
4315
4417
|
return count;
|
|
4316
4418
|
}
|
|
4317
|
-
function canUseLateralJoin(includeSpec, parentModel, schemas) {
|
|
4318
|
-
const relations = resolveIncludeRelations(
|
|
4419
|
+
function canUseLateralJoin(includeSpec, parentModel, schemas, modelMap) {
|
|
4420
|
+
const relations = resolveIncludeRelations(
|
|
4421
|
+
includeSpec,
|
|
4422
|
+
parentModel,
|
|
4423
|
+
schemas,
|
|
4424
|
+
modelMap
|
|
4425
|
+
);
|
|
4319
4426
|
if (relations.length < countActiveEntries2(includeSpec)) {
|
|
4320
4427
|
return false;
|
|
4321
4428
|
}
|
|
@@ -4324,14 +4431,14 @@ function canUseLateralJoin(includeSpec, parentModel, schemas) {
|
|
|
4324
4431
|
if (!keys || keys.childKeys.length === 0 || keys.parentKeys.length === 0)
|
|
4325
4432
|
return false;
|
|
4326
4433
|
if (Object.keys(rel.nestedSpec).length > 0) {
|
|
4327
|
-
if (!canUseLateralJoin(rel.nestedSpec, rel.relModel, schemas))
|
|
4434
|
+
if (!canUseLateralJoin(rel.nestedSpec, rel.relModel, schemas, modelMap))
|
|
4328
4435
|
return false;
|
|
4329
4436
|
}
|
|
4330
4437
|
}
|
|
4331
4438
|
return true;
|
|
4332
4439
|
}
|
|
4333
4440
|
function buildLateralJoinSql(spec) {
|
|
4334
|
-
var
|
|
4441
|
+
var _a4;
|
|
4335
4442
|
const {
|
|
4336
4443
|
from,
|
|
4337
4444
|
whereClause,
|
|
@@ -4351,6 +4458,8 @@ function buildLateralJoinSql(spec) {
|
|
|
4351
4458
|
isLateral: false,
|
|
4352
4459
|
lateralMeta: []
|
|
4353
4460
|
};
|
|
4461
|
+
const modelMap = /* @__PURE__ */ new Map();
|
|
4462
|
+
for (const m of schemas) modelMap.set(m.name, m);
|
|
4354
4463
|
const entries = extractRelationEntries(args, model);
|
|
4355
4464
|
const includeSpec = {};
|
|
4356
4465
|
for (const e of entries) {
|
|
@@ -4377,7 +4486,8 @@ function buildLateralJoinSql(spec) {
|
|
|
4377
4486
|
schemas,
|
|
4378
4487
|
dialect,
|
|
4379
4488
|
aliasCounter,
|
|
4380
|
-
collector
|
|
4489
|
+
collector,
|
|
4490
|
+
modelMap
|
|
4381
4491
|
};
|
|
4382
4492
|
const lateralJoins = [];
|
|
4383
4493
|
const lateralSelects = [];
|
|
@@ -4387,7 +4497,7 @@ function buildLateralJoinSql(spec) {
|
|
|
4387
4497
|
const indices = getFieldIndices(model);
|
|
4388
4498
|
const field = indices.allFieldsByName.get(relName);
|
|
4389
4499
|
if (!field || !isValidRelationField(field)) continue;
|
|
4390
|
-
const relModel = getRelationModel2(model, relName, schemas);
|
|
4500
|
+
const relModel = getRelationModel2(model, relName, schemas, modelMap);
|
|
4391
4501
|
if (!relModel) continue;
|
|
4392
4502
|
const result = buildLateralForRelation(
|
|
4393
4503
|
relName,
|
|
@@ -4405,7 +4515,7 @@ function buildLateralJoinSql(spec) {
|
|
|
4405
4515
|
lateralMeta.push(result.meta);
|
|
4406
4516
|
}
|
|
4407
4517
|
if (lateralJoins.length === 0) return emptyResult;
|
|
4408
|
-
const baseSelect = ((
|
|
4518
|
+
const baseSelect = ((_a4 = spec.select) != null ? _a4 : "").trim();
|
|
4409
4519
|
const allSelects = [baseSelect, ...lateralSelects].filter((s) => s && s.trim().length > 0).join(", ");
|
|
4410
4520
|
if (!allSelects) {
|
|
4411
4521
|
return emptyResult;
|
|
@@ -4525,9 +4635,9 @@ function renderOrderBySimple(entries, alias) {
|
|
|
4525
4635
|
return out.join(SQL_SEPARATORS.ORDER_BY);
|
|
4526
4636
|
}
|
|
4527
4637
|
function ensureIdTiebreakerEntries(entries, model) {
|
|
4528
|
-
var
|
|
4529
|
-
const idField = (_b = (
|
|
4530
|
-
|
|
4638
|
+
var _a4, _b;
|
|
4639
|
+
const idField = (_b = (_a4 = model == null ? void 0 : model.fields) == null ? void 0 : _a4.find) == null ? void 0 : _b.call(
|
|
4640
|
+
_a4,
|
|
4531
4641
|
(f) => f.name === DEFAULT_PRIMARY_KEY2 && !f.isRelation
|
|
4532
4642
|
);
|
|
4533
4643
|
if (!idField) return entries;
|
|
@@ -4569,14 +4679,14 @@ function buildJoinsSql(...joinGroups) {
|
|
|
4569
4679
|
return all.length > 0 ? " " + all.join(" ") : "";
|
|
4570
4680
|
}
|
|
4571
4681
|
function buildSqliteDistinctQuery(spec, selectWithIncludes, countJoins) {
|
|
4572
|
-
var
|
|
4682
|
+
var _a4, _b;
|
|
4573
4683
|
const { includes, from, whereClause, whereJoins, distinct, model } = spec;
|
|
4574
4684
|
if (!isNotNullish(distinct) || !isNonEmptyArray(distinct)) {
|
|
4575
4685
|
throw new Error("buildSqliteDistinctQuery requires distinct fields");
|
|
4576
4686
|
}
|
|
4577
4687
|
const scalarNames = parseSimpleScalarSelect(spec.select, from.alias);
|
|
4578
4688
|
const includeNames = includes.map((i) => i.name);
|
|
4579
|
-
const hasCount = Boolean((_b = (
|
|
4689
|
+
const hasCount = Boolean((_b = (_a4 = spec.args) == null ? void 0 : _a4.select) == null ? void 0 : _b[COUNT_SELECT_KEY]);
|
|
4580
4690
|
const outerSelectCols = buildOutputColumns(
|
|
4581
4691
|
scalarNames,
|
|
4582
4692
|
includeNames,
|
|
@@ -4676,12 +4786,12 @@ function resolveCountSelect(countSelectRaw, model) {
|
|
|
4676
4786
|
return null;
|
|
4677
4787
|
}
|
|
4678
4788
|
function buildIncludeColumns(spec) {
|
|
4679
|
-
var
|
|
4789
|
+
var _a4, _b, _c, _d, _e;
|
|
4680
4790
|
const { select, includes, dialect, model, schemas, from, params } = spec;
|
|
4681
4791
|
const baseSelect = (select != null ? select : "").trim();
|
|
4682
4792
|
let countCols = "";
|
|
4683
4793
|
let countJoins = [];
|
|
4684
|
-
const countSelectRaw = (_e = (_b = (
|
|
4794
|
+
const countSelectRaw = (_e = (_b = (_a4 = spec.args) == null ? void 0 : _a4.select) == null ? void 0 : _b[COUNT_SELECT_KEY]) != null ? _e : (_d = (_c = spec.args) == null ? void 0 : _c.include) == null ? void 0 : _d[COUNT_SELECT_KEY];
|
|
4685
4795
|
if (countSelectRaw) {
|
|
4686
4796
|
const resolvedCountSelect = resolveCountSelect(countSelectRaw, model);
|
|
4687
4797
|
if (resolvedCountSelect && Object.keys(resolvedCountSelect).length > 0) {
|
|
@@ -4863,16 +4973,33 @@ function constructFinalSql(spec) {
|
|
|
4863
4973
|
isNotNullish(pagination.take);
|
|
4864
4974
|
const takeValue = typeof pagination.take === "number" ? pagination.take : null;
|
|
4865
4975
|
if (dialect === "postgres" && hasIncludes) {
|
|
4866
|
-
const
|
|
4867
|
-
|
|
4868
|
-
|
|
4976
|
+
const modelMap = getOrCreateModelMap(schemas);
|
|
4977
|
+
const canFlatJoin = canUseFlatJoinForAll(
|
|
4978
|
+
includeSpec,
|
|
4979
|
+
model,
|
|
4980
|
+
schemas,
|
|
4981
|
+
false,
|
|
4982
|
+
modelMap
|
|
4983
|
+
);
|
|
4984
|
+
canUseLateralJoin(includeSpec, model, schemas, modelMap);
|
|
4985
|
+
const hasChildPag = hasChildPaginationAnywhere(
|
|
4986
|
+
includeSpec,
|
|
4987
|
+
model,
|
|
4988
|
+
schemas,
|
|
4989
|
+
0,
|
|
4990
|
+
modelMap
|
|
4991
|
+
);
|
|
4869
4992
|
const strategy = pickIncludeStrategy({
|
|
4870
4993
|
includeSpec,
|
|
4871
4994
|
model,
|
|
4872
4995
|
schemas,
|
|
4873
4996
|
method,
|
|
4997
|
+
args,
|
|
4874
4998
|
takeValue,
|
|
4875
|
-
canFlatJoin
|
|
4999
|
+
canFlatJoin,
|
|
5000
|
+
hasChildPagination: hasChildPag,
|
|
5001
|
+
modelMap
|
|
5002
|
+
});
|
|
4876
5003
|
if (strategy === "flat-join") {
|
|
4877
5004
|
const flatResult = buildFlatJoinSql(spec);
|
|
4878
5005
|
if (flatResult.sql) {
|
|
@@ -4995,8 +5122,8 @@ function buildDefaultScalarFields(model, alias) {
|
|
|
4995
5122
|
return out;
|
|
4996
5123
|
}
|
|
4997
5124
|
function getDefaultSelectCached(model, alias) {
|
|
4998
|
-
var
|
|
4999
|
-
return (
|
|
5125
|
+
var _a4;
|
|
5126
|
+
return (_a4 = DEFAULT_SELECT_CACHE.get(model)) == null ? void 0 : _a4.get(alias);
|
|
5000
5127
|
}
|
|
5001
5128
|
function cacheDefaultSelect(model, alias, sql) {
|
|
5002
5129
|
let cache = DEFAULT_SELECT_CACHE.get(model);
|
|
@@ -5278,7 +5405,8 @@ function buildSelectWithNestedIncludes(relArgs, relModel, relAlias, ctx) {
|
|
|
5278
5405
|
ctx.schemas,
|
|
5279
5406
|
relAlias,
|
|
5280
5407
|
ctx.params,
|
|
5281
|
-
ctx.dialect
|
|
5408
|
+
ctx.dialect,
|
|
5409
|
+
ctx.schemaByName
|
|
5282
5410
|
);
|
|
5283
5411
|
if (!countBuild.jsonPairs) return baseSelect2;
|
|
5284
5412
|
countJoins.push(...countBuild.joins);
|
|
@@ -5666,7 +5794,9 @@ function resolveTableRef(model, dialect) {
|
|
|
5666
5794
|
return buildTableReference(schema, tableName, dialect);
|
|
5667
5795
|
}
|
|
5668
5796
|
function findRelationField(model, fieldName) {
|
|
5669
|
-
|
|
5797
|
+
const field = getFieldIndices(model).allFieldsByName.get(fieldName);
|
|
5798
|
+
if (!field || !field.isRelation) return void 0;
|
|
5799
|
+
return field;
|
|
5670
5800
|
}
|
|
5671
5801
|
function nextJoinAlias(ctx) {
|
|
5672
5802
|
let alias;
|
|
@@ -5693,7 +5823,7 @@ function resolveRelationOrderByChain(relationFieldName, value, currentModel, cur
|
|
|
5693
5823
|
`Relation field '${relationFieldName}' not found on model ${currentModel.name}`
|
|
5694
5824
|
);
|
|
5695
5825
|
}
|
|
5696
|
-
const relatedModel =
|
|
5826
|
+
const relatedModel = ctx.modelMap.get(field.relatedModel);
|
|
5697
5827
|
if (!relatedModel) {
|
|
5698
5828
|
throw new Error(
|
|
5699
5829
|
`Related model '${field.relatedModel}' not found for relation '${relationFieldName}'`
|
|
@@ -5759,12 +5889,14 @@ function buildOrderByWithRelations(orderBy, alias, dialect, model, schemas) {
|
|
|
5759
5889
|
const relationSet = getRelationFieldSet(model);
|
|
5760
5890
|
const scalarSet = getScalarFieldSet(model);
|
|
5761
5891
|
const orderFragments = [];
|
|
5892
|
+
const modelMap = /* @__PURE__ */ new Map();
|
|
5893
|
+
for (const m of schemas) modelMap.set(m.name, m);
|
|
5762
5894
|
const ctx = {
|
|
5763
|
-
schemas,
|
|
5764
5895
|
dialect,
|
|
5765
5896
|
joins: [],
|
|
5766
5897
|
usedAliases: /* @__PURE__ */ new Set(),
|
|
5767
|
-
aliasCounter: { value: 0 }
|
|
5898
|
+
aliasCounter: { value: 0 },
|
|
5899
|
+
modelMap
|
|
5768
5900
|
};
|
|
5769
5901
|
for (const [fieldName, value] of expanded) {
|
|
5770
5902
|
if (scalarSet.has(fieldName)) {
|
|
@@ -5819,11 +5951,11 @@ function mapFirstOrderByByField(existing) {
|
|
|
5819
5951
|
return m;
|
|
5820
5952
|
}
|
|
5821
5953
|
function buildPostgresDistinctOrderBy(distinctFields, existing) {
|
|
5822
|
-
var
|
|
5954
|
+
var _a4;
|
|
5823
5955
|
const firstByField = mapFirstOrderByByField(existing);
|
|
5824
5956
|
const next = [];
|
|
5825
5957
|
for (const f of distinctFields) {
|
|
5826
|
-
next.push((
|
|
5958
|
+
next.push((_a4 = firstByField.get(f)) != null ? _a4 : { [f]: "asc" });
|
|
5827
5959
|
}
|
|
5828
5960
|
const distinctSet = new Set(distinctFields);
|
|
5829
5961
|
for (const obj of existing) {
|
|
@@ -6716,10 +6848,10 @@ function isPrismaMethod(v) {
|
|
|
6716
6848
|
return v === "findMany" || v === "findFirst" || v === "findUnique" || v === "aggregate" || v === "groupBy" || v === "count";
|
|
6717
6849
|
}
|
|
6718
6850
|
function resolveMethod(directive) {
|
|
6719
|
-
var
|
|
6851
|
+
var _a4, _b;
|
|
6720
6852
|
const m = directive == null ? void 0 : directive.method;
|
|
6721
6853
|
if (isPrismaMethod(m)) return m;
|
|
6722
|
-
const pm = (_b = (
|
|
6854
|
+
const pm = (_b = (_a4 = directive == null ? void 0 : directive.query) == null ? void 0 : _a4.processed) == null ? void 0 : _b.method;
|
|
6723
6855
|
if (isPrismaMethod(pm)) return pm;
|
|
6724
6856
|
return "findMany";
|
|
6725
6857
|
}
|
|
@@ -6882,7 +7014,7 @@ function extractIncludeSpec2(processed, modelDef) {
|
|
|
6882
7014
|
return includeSpec;
|
|
6883
7015
|
}
|
|
6884
7016
|
function buildAndNormalizeSql(args) {
|
|
6885
|
-
var
|
|
7017
|
+
var _a4;
|
|
6886
7018
|
const {
|
|
6887
7019
|
method,
|
|
6888
7020
|
processed,
|
|
@@ -6908,7 +7040,7 @@ function buildAndNormalizeSql(args) {
|
|
|
6908
7040
|
sqlResult.paramMappings,
|
|
6909
7041
|
dialect
|
|
6910
7042
|
);
|
|
6911
|
-
const includeSpec = (
|
|
7043
|
+
const includeSpec = (_a4 = sqlResult.includeSpec && isPlainObject(sqlResult.includeSpec) ? sqlResult.includeSpec : null) != null ? _a4 : extractIncludeSpec2(processed, modelDef);
|
|
6912
7044
|
return {
|
|
6913
7045
|
sql: normalized.sql,
|
|
6914
7046
|
paramMappings: normalized.paramMappings,
|
|
@@ -6933,8 +7065,8 @@ function finalizeDirective(args) {
|
|
|
6933
7065
|
skipWhereIn
|
|
6934
7066
|
} = args;
|
|
6935
7067
|
const params = normalizedMappings.map((m) => {
|
|
6936
|
-
var
|
|
6937
|
-
return (
|
|
7068
|
+
var _a4;
|
|
7069
|
+
return (_a4 = m.value) != null ? _a4 : void 0;
|
|
6938
7070
|
});
|
|
6939
7071
|
validateParamConsistencyByDialect(normalizedSql, params, dialect);
|
|
6940
7072
|
const { staticParams, dynamicKeys, paramOrder } = buildParamsFromMappings(normalizedMappings);
|
|
@@ -7367,9 +7499,9 @@ function processAllModelDirectives(directiveResults, config) {
|
|
|
7367
7499
|
}
|
|
7368
7500
|
function generateClient(options) {
|
|
7369
7501
|
return __async(this, null, function* () {
|
|
7370
|
-
var
|
|
7502
|
+
var _a4, _b;
|
|
7371
7503
|
const { datamodel, outputDir, config } = options;
|
|
7372
|
-
const runtimeImportPath = (
|
|
7504
|
+
const runtimeImportPath = (_a4 = options.runtimeImportPath) != null ? _a4 : "prisma-sql";
|
|
7373
7505
|
setGlobalDialect(config.dialect);
|
|
7374
7506
|
const models = schemaParser.convertDMMFToModels(datamodel);
|
|
7375
7507
|
const directiveResults = schemaParser.processAllDirectives(
|
|
@@ -8443,9 +8575,9 @@ function getDialectFromProvider(provider) {
|
|
|
8443
8575
|
);
|
|
8444
8576
|
}
|
|
8445
8577
|
function getOutputDir(options) {
|
|
8446
|
-
var
|
|
8578
|
+
var _a4, _b;
|
|
8447
8579
|
const schemaDir = path.dirname(options.schemaPath);
|
|
8448
|
-
if ((
|
|
8580
|
+
if ((_a4 = options.generator.output) == null ? void 0 : _a4.value) {
|
|
8449
8581
|
return path.resolve(schemaDir, options.generator.output.value);
|
|
8450
8582
|
}
|
|
8451
8583
|
const clientGenerator = options.otherGenerators.find(
|