@prisma/client-engine-runtime 6.15.0-dev.3 → 6.15.0-dev.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/index.d.mts +27 -53
- package/dist/index.d.ts +27 -53
- package/dist/index.js +126 -148
- package/dist/index.mjs +126 -146
- package/dist/interpreter/generators.d.ts +1 -2
- package/dist/interpreter/render-query.d.ts +2 -2
- package/dist/query-plan.d.ts +23 -48
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -395,15 +395,15 @@ var DataMapperError = class extends Error {
|
|
|
395
395
|
};
|
|
396
396
|
function applyDataMap(data, structure, enums) {
|
|
397
397
|
switch (structure.type) {
|
|
398
|
-
case "
|
|
398
|
+
case "affectedRows":
|
|
399
399
|
if (typeof data !== "number") {
|
|
400
400
|
throw new DataMapperError(`Expected an affected rows count, got: ${typeof data} (${data})`);
|
|
401
401
|
}
|
|
402
402
|
return { count: data };
|
|
403
|
-
case "
|
|
403
|
+
case "object":
|
|
404
404
|
return mapArrayOrObject(data, structure.fields, enums, structure.skipNulls);
|
|
405
|
-
case "
|
|
406
|
-
return mapValue(data, "<result>", structure.
|
|
405
|
+
case "field":
|
|
406
|
+
return mapValue(data, "<result>", structure.fieldType, enums);
|
|
407
407
|
default:
|
|
408
408
|
assertNever(structure, `Invalid data mapping type: '${structure.type}'`);
|
|
409
409
|
}
|
|
@@ -441,10 +441,10 @@ function mapObject(data, fields, enums) {
|
|
|
441
441
|
const result = {};
|
|
442
442
|
for (const [name, node] of Object.entries(fields)) {
|
|
443
443
|
switch (node.type) {
|
|
444
|
-
case "
|
|
444
|
+
case "affectedRows": {
|
|
445
445
|
throw new DataMapperError(`Unexpected 'AffectedRows' node in data mapping for field '${name}'`);
|
|
446
446
|
}
|
|
447
|
-
case "
|
|
447
|
+
case "object": {
|
|
448
448
|
if (node.serializedName !== null && !Object.hasOwn(data, node.serializedName)) {
|
|
449
449
|
throw new DataMapperError(
|
|
450
450
|
`Missing data field (Object): '${name}'; node: ${JSON.stringify(node)}; data: ${JSON.stringify(data)}`
|
|
@@ -454,11 +454,11 @@ function mapObject(data, fields, enums) {
|
|
|
454
454
|
result[name] = mapArrayOrObject(target, node.fields, enums, node.skipNulls);
|
|
455
455
|
break;
|
|
456
456
|
}
|
|
457
|
-
case "
|
|
457
|
+
case "field":
|
|
458
458
|
{
|
|
459
459
|
const dbName = node.dbName;
|
|
460
460
|
if (Object.hasOwn(data, dbName)) {
|
|
461
|
-
result[name] =
|
|
461
|
+
result[name] = mapField(data[dbName], dbName, node.fieldType, enums);
|
|
462
462
|
} else {
|
|
463
463
|
throw new DataMapperError(
|
|
464
464
|
`Missing data field (Value): '${dbName}'; node: ${JSON.stringify(node)}; data: ${JSON.stringify(data)}`
|
|
@@ -472,20 +472,27 @@ function mapObject(data, fields, enums) {
|
|
|
472
472
|
}
|
|
473
473
|
return result;
|
|
474
474
|
}
|
|
475
|
-
function
|
|
475
|
+
function mapField(value, columnName, fieldType, enums) {
|
|
476
476
|
if (value === null) {
|
|
477
|
-
return
|
|
477
|
+
return fieldType.arity === "list" ? [] : null;
|
|
478
478
|
}
|
|
479
|
-
|
|
480
|
-
|
|
479
|
+
if (fieldType.arity === "list") {
|
|
480
|
+
const values = value;
|
|
481
|
+
return values.map((v, i) => mapValue(v, `${columnName}[${i}]`, fieldType, enums));
|
|
482
|
+
}
|
|
483
|
+
return mapValue(value, columnName, fieldType, enums);
|
|
484
|
+
}
|
|
485
|
+
function mapValue(value, columnName, scalarType, enums) {
|
|
486
|
+
switch (scalarType.type) {
|
|
487
|
+
case "unsupported":
|
|
481
488
|
return value;
|
|
482
|
-
case "
|
|
489
|
+
case "string": {
|
|
483
490
|
if (typeof value !== "string") {
|
|
484
491
|
throw new DataMapperError(`Expected a string in column '${columnName}', got ${typeof value}: ${value}`);
|
|
485
492
|
}
|
|
486
493
|
return value;
|
|
487
494
|
}
|
|
488
|
-
case "
|
|
495
|
+
case "int": {
|
|
489
496
|
switch (typeof value) {
|
|
490
497
|
case "number": {
|
|
491
498
|
return Math.trunc(value);
|
|
@@ -506,13 +513,13 @@ function mapValue(value, columnName, resultType, enums) {
|
|
|
506
513
|
throw new DataMapperError(`Expected an integer in column '${columnName}', got ${typeof value}: ${value}`);
|
|
507
514
|
}
|
|
508
515
|
}
|
|
509
|
-
case "
|
|
516
|
+
case "bigint": {
|
|
510
517
|
if (typeof value !== "number" && typeof value !== "string") {
|
|
511
518
|
throw new DataMapperError(`Expected a bigint in column '${columnName}', got ${typeof value}: ${value}`);
|
|
512
519
|
}
|
|
513
520
|
return { $type: "BigInt", value };
|
|
514
521
|
}
|
|
515
|
-
case "
|
|
522
|
+
case "float": {
|
|
516
523
|
if (typeof value === "number") return value;
|
|
517
524
|
if (typeof value === "string") {
|
|
518
525
|
const parsedValue = Number(value);
|
|
@@ -523,7 +530,7 @@ function mapValue(value, columnName, resultType, enums) {
|
|
|
523
530
|
}
|
|
524
531
|
throw new DataMapperError(`Expected a float in column '${columnName}', got ${typeof value}: ${value}`);
|
|
525
532
|
}
|
|
526
|
-
case "
|
|
533
|
+
case "boolean": {
|
|
527
534
|
if (typeof value === "boolean") return value;
|
|
528
535
|
if (typeof value === "number") return value === 1;
|
|
529
536
|
if (typeof value === "string") {
|
|
@@ -535,7 +542,7 @@ function mapValue(value, columnName, resultType, enums) {
|
|
|
535
542
|
throw new DataMapperError(`Expected a boolean in column '${columnName}', got ${typeof value}: ${value}`);
|
|
536
543
|
}
|
|
537
544
|
}
|
|
538
|
-
if (value
|
|
545
|
+
if (Array.isArray(value)) {
|
|
539
546
|
for (const byte of value) {
|
|
540
547
|
if (byte !== 0) return true;
|
|
541
548
|
}
|
|
@@ -543,37 +550,27 @@ function mapValue(value, columnName, resultType, enums) {
|
|
|
543
550
|
}
|
|
544
551
|
throw new DataMapperError(`Expected a boolean in column '${columnName}', got ${typeof value}: ${value}`);
|
|
545
552
|
}
|
|
546
|
-
case "
|
|
553
|
+
case "decimal":
|
|
547
554
|
if (typeof value !== "number" && typeof value !== "string" && !Decimal3.isDecimal(value)) {
|
|
548
555
|
throw new DataMapperError(`Expected a decimal in column '${columnName}', got ${typeof value}: ${value}`);
|
|
549
556
|
}
|
|
550
557
|
return { $type: "Decimal", value };
|
|
551
|
-
case "
|
|
558
|
+
case "datetime": {
|
|
552
559
|
if (typeof value === "string") {
|
|
553
|
-
return { $type: "DateTime", value:
|
|
560
|
+
return { $type: "DateTime", value: normalizeDateTime(value) };
|
|
554
561
|
}
|
|
555
562
|
if (typeof value === "number" || value instanceof Date) {
|
|
556
563
|
return { $type: "DateTime", value };
|
|
557
564
|
}
|
|
558
565
|
throw new DataMapperError(`Expected a date in column '${columnName}', got ${typeof value}: ${value}`);
|
|
559
566
|
}
|
|
560
|
-
case "
|
|
561
|
-
if (typeof value === "string") {
|
|
562
|
-
return { $type: "DateTime", value: `1970-01-01T${ensureTimezoneInIsoString(value)}` };
|
|
563
|
-
}
|
|
564
|
-
throw new DataMapperError(`Expected a time in column '${columnName}', got ${typeof value}: ${value}`);
|
|
565
|
-
}
|
|
566
|
-
case "Array": {
|
|
567
|
-
const values = value;
|
|
568
|
-
return values.map((v, i) => mapValue(v, `${columnName}[${i}]`, resultType.inner, enums));
|
|
569
|
-
}
|
|
570
|
-
case "Object": {
|
|
567
|
+
case "object": {
|
|
571
568
|
return { $type: "Json", value: safeJsonStringify(value) };
|
|
572
569
|
}
|
|
573
|
-
case "
|
|
570
|
+
case "json": {
|
|
574
571
|
return { $type: "Json", value: `${value}` };
|
|
575
572
|
}
|
|
576
|
-
case "
|
|
573
|
+
case "bytes": {
|
|
577
574
|
if (typeof value === "string" && value.startsWith("\\x")) {
|
|
578
575
|
return { $type: "Bytes", value: Buffer.from(value.slice(2), "hex").toString("base64") };
|
|
579
576
|
}
|
|
@@ -585,31 +582,38 @@ function mapValue(value, columnName, resultType, enums) {
|
|
|
585
582
|
}
|
|
586
583
|
throw new DataMapperError(`Expected a byte array in column '${columnName}', got ${typeof value}: ${value}`);
|
|
587
584
|
}
|
|
588
|
-
case "
|
|
589
|
-
const enumDef = enums[
|
|
585
|
+
case "enum": {
|
|
586
|
+
const enumDef = enums[scalarType.name];
|
|
590
587
|
if (enumDef === void 0) {
|
|
591
|
-
throw new DataMapperError(`Unknown enum '${
|
|
588
|
+
throw new DataMapperError(`Unknown enum '${scalarType.name}'`);
|
|
592
589
|
}
|
|
593
590
|
const enumValue = enumDef[`${value}`];
|
|
594
591
|
if (enumValue === void 0) {
|
|
595
|
-
throw new DataMapperError(`Value '${value}' not found in enum '${
|
|
592
|
+
throw new DataMapperError(`Value '${value}' not found in enum '${scalarType.name}'`);
|
|
596
593
|
}
|
|
597
594
|
return enumValue;
|
|
598
595
|
}
|
|
599
596
|
default:
|
|
600
|
-
assertNever(
|
|
597
|
+
assertNever(scalarType, `DataMapper: Unknown result type: ${scalarType["type"]}`);
|
|
601
598
|
}
|
|
602
599
|
}
|
|
603
|
-
var
|
|
604
|
-
function
|
|
605
|
-
const
|
|
606
|
-
if (
|
|
600
|
+
var TIME_TZ_PATTERN = /\d{2}:\d{2}:\d{2}(?:\.\d+)?(Z|[+-]\d{2}(:?\d{2})?)?$/;
|
|
601
|
+
function normalizeDateTime(dt) {
|
|
602
|
+
const matches = TIME_TZ_PATTERN.exec(dt);
|
|
603
|
+
if (matches === null) {
|
|
607
604
|
return `${dt}Z`;
|
|
608
|
-
} else if (results[0] !== "Z" && results[1] === void 0) {
|
|
609
|
-
return `${dt}:00`;
|
|
610
|
-
} else {
|
|
611
|
-
return dt;
|
|
612
605
|
}
|
|
606
|
+
let dtWithTz = dt;
|
|
607
|
+
const [timeTz, tz, tzMinuteOffset] = matches;
|
|
608
|
+
if (tz !== void 0 && tz !== "Z" && tzMinuteOffset === void 0) {
|
|
609
|
+
dtWithTz = `${dt}:00`;
|
|
610
|
+
} else if (tz === void 0) {
|
|
611
|
+
dtWithTz = `${dt}Z`;
|
|
612
|
+
}
|
|
613
|
+
if (timeTz.length === dt.length) {
|
|
614
|
+
return `1970-01-01T${dtWithTz}`;
|
|
615
|
+
}
|
|
616
|
+
return dtWithTz;
|
|
613
617
|
}
|
|
614
618
|
|
|
615
619
|
// src/tracing.ts
|
|
@@ -688,10 +692,10 @@ var GeneratorRegistry = class {
|
|
|
688
692
|
* method being called, meaning that the built-in time-based generators will always return
|
|
689
693
|
* the same value on repeated calls as long as the same snapshot is used.
|
|
690
694
|
*/
|
|
691
|
-
snapshot(
|
|
695
|
+
snapshot() {
|
|
692
696
|
return Object.create(this.#generators, {
|
|
693
697
|
now: {
|
|
694
|
-
value:
|
|
698
|
+
value: new NowGenerator()
|
|
695
699
|
}
|
|
696
700
|
});
|
|
697
701
|
}
|
|
@@ -708,12 +712,6 @@ var NowGenerator = class {
|
|
|
708
712
|
return this.#now.toISOString();
|
|
709
713
|
}
|
|
710
714
|
};
|
|
711
|
-
var MysqlNowGenerator = class {
|
|
712
|
-
#now = /* @__PURE__ */ new Date();
|
|
713
|
-
generate() {
|
|
714
|
-
return this.#now.toISOString().replace("T", " ").replace("Z", "");
|
|
715
|
-
}
|
|
716
|
-
};
|
|
717
715
|
var UuidGenerator = class {
|
|
718
716
|
generate(arg) {
|
|
719
717
|
if (arg === 4) {
|
|
@@ -867,74 +865,82 @@ function isPrismaValuePlaceholder(value) {
|
|
|
867
865
|
function isPrismaValueGenerator(value) {
|
|
868
866
|
return typeof value === "object" && value !== null && value["prisma__type"] === "generatorCall";
|
|
869
867
|
}
|
|
870
|
-
function isPrismaValueBytes(value) {
|
|
871
|
-
return typeof value === "object" && value !== null && value["prisma__type"] === "bytes";
|
|
872
|
-
}
|
|
873
|
-
function isPrismaValueBigInt(value) {
|
|
874
|
-
return typeof value === "object" && value !== null && value["prisma__type"] === "bigint";
|
|
875
|
-
}
|
|
876
868
|
|
|
877
869
|
// src/interpreter/render-query.ts
|
|
878
870
|
function renderQuery(dbQuery, scope, generators, maxChunkSize) {
|
|
879
|
-
const
|
|
880
|
-
|
|
881
|
-
switch (queryType) {
|
|
871
|
+
const args = dbQuery.args.map((arg) => evaluateArg(arg, scope, generators));
|
|
872
|
+
switch (dbQuery.type) {
|
|
882
873
|
case "rawSql":
|
|
883
|
-
return [renderRawSql(dbQuery.sql,
|
|
874
|
+
return [renderRawSql(dbQuery.sql, args, dbQuery.argTypes)];
|
|
884
875
|
case "templateSql": {
|
|
885
|
-
const chunks = dbQuery.chunkable ? chunkParams(dbQuery.fragments,
|
|
886
|
-
return chunks.map((
|
|
887
|
-
if (maxChunkSize !== void 0 &&
|
|
876
|
+
const chunks = dbQuery.chunkable ? chunkParams(dbQuery.fragments, args, maxChunkSize) : [args];
|
|
877
|
+
return chunks.map((params) => {
|
|
878
|
+
if (maxChunkSize !== void 0 && params.length > maxChunkSize) {
|
|
888
879
|
throw new UserFacingError("The query parameter limit supported by your database is exceeded.", "P2029");
|
|
889
880
|
}
|
|
890
|
-
return renderTemplateSql(dbQuery.fragments, dbQuery.placeholderFormat,
|
|
881
|
+
return renderTemplateSql(dbQuery.fragments, dbQuery.placeholderFormat, params, dbQuery.argTypes);
|
|
891
882
|
});
|
|
892
883
|
}
|
|
893
884
|
default:
|
|
894
|
-
assertNever(
|
|
885
|
+
assertNever(dbQuery["type"], `Invalid query type`);
|
|
895
886
|
}
|
|
896
887
|
}
|
|
897
|
-
function
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
let value = param;
|
|
902
|
-
while (doesRequireEvaluation(value)) {
|
|
903
|
-
if (isPrismaValuePlaceholder(value)) {
|
|
904
|
-
const found = scope[value.prisma__value.name];
|
|
888
|
+
function evaluateArg(arg, scope, generators) {
|
|
889
|
+
while (doesRequireEvaluation(arg)) {
|
|
890
|
+
if (isPrismaValuePlaceholder(arg)) {
|
|
891
|
+
const found = scope[arg.prisma__value.name];
|
|
905
892
|
if (found === void 0) {
|
|
906
|
-
throw new Error(`Missing value for query variable ${
|
|
893
|
+
throw new Error(`Missing value for query variable ${arg.prisma__value.name}`);
|
|
907
894
|
}
|
|
908
|
-
|
|
909
|
-
} else if (isPrismaValueGenerator(
|
|
910
|
-
const { name, args } =
|
|
895
|
+
arg = found;
|
|
896
|
+
} else if (isPrismaValueGenerator(arg)) {
|
|
897
|
+
const { name, args } = arg.prisma__value;
|
|
911
898
|
const generator = generators[name];
|
|
912
899
|
if (!generator) {
|
|
913
900
|
throw new Error(`Encountered an unknown generator '${name}'`);
|
|
914
901
|
}
|
|
915
|
-
|
|
902
|
+
arg = generator.generate(...args.map((arg2) => evaluateArg(arg2, scope, generators)));
|
|
916
903
|
} else {
|
|
917
|
-
assertNever(
|
|
904
|
+
assertNever(arg, `Unexpected unevaluated value type: ${arg}`);
|
|
918
905
|
}
|
|
919
906
|
}
|
|
920
|
-
if (Array.isArray(
|
|
921
|
-
|
|
922
|
-
} else if (isPrismaValueBytes(value)) {
|
|
923
|
-
value = Buffer.from(value.prisma__value, "base64");
|
|
924
|
-
} else if (isPrismaValueBigInt(value)) {
|
|
925
|
-
value = BigInt(value.prisma__value);
|
|
907
|
+
if (Array.isArray(arg)) {
|
|
908
|
+
arg = arg.map((el) => evaluateArg(el, scope, generators));
|
|
926
909
|
}
|
|
927
|
-
return
|
|
910
|
+
return arg;
|
|
928
911
|
}
|
|
929
|
-
function renderTemplateSql(fragments, placeholderFormat, params) {
|
|
912
|
+
function renderTemplateSql(fragments, placeholderFormat, params, argTypes) {
|
|
930
913
|
let sql = "";
|
|
931
914
|
const ctx = { placeholderNumber: 1 };
|
|
932
915
|
const flattenedParams = [];
|
|
933
|
-
|
|
934
|
-
|
|
916
|
+
const flattenedArgTypes = [];
|
|
917
|
+
for (const fragment of pairFragmentsWithParams(fragments, params, argTypes)) {
|
|
935
918
|
sql += renderFragment(fragment, placeholderFormat, ctx);
|
|
919
|
+
if (fragment.type === "stringChunk") {
|
|
920
|
+
continue;
|
|
921
|
+
}
|
|
922
|
+
const length = flattenedParams.length;
|
|
923
|
+
const added = flattenedParams.push(...flattenedFragmentParams(fragment)) - length;
|
|
924
|
+
if (fragment.argType.arity === "tuple") {
|
|
925
|
+
if (added % fragment.argType.elements.length !== 0) {
|
|
926
|
+
throw new Error(
|
|
927
|
+
`Malformed query template. Expected the number of parameters to match the tuple arity, but got ${added} parameters for a tuple of arity ${fragment.argType.elements.length}.`
|
|
928
|
+
);
|
|
929
|
+
}
|
|
930
|
+
for (let i = 0; i < added / fragment.argType.elements.length; i++) {
|
|
931
|
+
flattenedArgTypes.push(...fragment.argType.elements);
|
|
932
|
+
}
|
|
933
|
+
} else {
|
|
934
|
+
for (let i = 0; i < added; i++) {
|
|
935
|
+
flattenedArgTypes.push(fragment.argType);
|
|
936
|
+
}
|
|
937
|
+
}
|
|
936
938
|
}
|
|
937
|
-
return
|
|
939
|
+
return {
|
|
940
|
+
sql,
|
|
941
|
+
args: flattenedParams,
|
|
942
|
+
argTypes: flattenedArgTypes
|
|
943
|
+
};
|
|
938
944
|
}
|
|
939
945
|
function renderFragment(fragment, placeholderFormat, ctx) {
|
|
940
946
|
const fragmentType = fragment.type;
|
|
@@ -960,36 +966,17 @@ function renderFragment(fragment, placeholderFormat, ctx) {
|
|
|
960
966
|
function formatPlaceholder(placeholderFormat, placeholderNumber) {
|
|
961
967
|
return placeholderFormat.hasNumbering ? `${placeholderFormat.prefix}${placeholderNumber}` : placeholderFormat.prefix;
|
|
962
968
|
}
|
|
963
|
-
function renderRawSql(sql,
|
|
964
|
-
const argTypes = params.map((param) => toArgType(param));
|
|
969
|
+
function renderRawSql(sql, args, argTypes) {
|
|
965
970
|
return {
|
|
966
971
|
sql,
|
|
967
|
-
args
|
|
972
|
+
args,
|
|
968
973
|
argTypes
|
|
969
974
|
};
|
|
970
975
|
}
|
|
971
|
-
function toArgType(value) {
|
|
972
|
-
if (typeof value === "string") {
|
|
973
|
-
return "Text";
|
|
974
|
-
}
|
|
975
|
-
if (typeof value === "number") {
|
|
976
|
-
return "Numeric";
|
|
977
|
-
}
|
|
978
|
-
if (typeof value === "boolean") {
|
|
979
|
-
return "Boolean";
|
|
980
|
-
}
|
|
981
|
-
if (Array.isArray(value)) {
|
|
982
|
-
return "Array";
|
|
983
|
-
}
|
|
984
|
-
if (Buffer.isBuffer(value)) {
|
|
985
|
-
return "Bytes";
|
|
986
|
-
}
|
|
987
|
-
return "Unknown";
|
|
988
|
-
}
|
|
989
976
|
function doesRequireEvaluation(param) {
|
|
990
977
|
return isPrismaValuePlaceholder(param) || isPrismaValueGenerator(param);
|
|
991
978
|
}
|
|
992
|
-
function* pairFragmentsWithParams(fragments, params) {
|
|
979
|
+
function* pairFragmentsWithParams(fragments, params, argTypes) {
|
|
993
980
|
let index = 0;
|
|
994
981
|
for (const fragment of fragments) {
|
|
995
982
|
switch (fragment.type) {
|
|
@@ -997,7 +984,8 @@ function* pairFragmentsWithParams(fragments, params) {
|
|
|
997
984
|
if (index >= params.length) {
|
|
998
985
|
throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
|
|
999
986
|
}
|
|
1000
|
-
yield { ...fragment, value: params[index
|
|
987
|
+
yield { ...fragment, value: params[index], argType: argTypes?.[index] };
|
|
988
|
+
index++;
|
|
1001
989
|
break;
|
|
1002
990
|
}
|
|
1003
991
|
case "stringChunk": {
|
|
@@ -1008,15 +996,16 @@ function* pairFragmentsWithParams(fragments, params) {
|
|
|
1008
996
|
if (index >= params.length) {
|
|
1009
997
|
throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
|
|
1010
998
|
}
|
|
1011
|
-
const value = params[index
|
|
1012
|
-
yield { ...fragment, value: Array.isArray(value) ? value : [value] };
|
|
999
|
+
const value = params[index];
|
|
1000
|
+
yield { ...fragment, value: Array.isArray(value) ? value : [value], argType: argTypes?.[index] };
|
|
1001
|
+
index++;
|
|
1013
1002
|
break;
|
|
1014
1003
|
}
|
|
1015
1004
|
case "parameterTupleList": {
|
|
1016
1005
|
if (index >= params.length) {
|
|
1017
1006
|
throw new Error(`Malformed query template. Fragments attempt to read over ${params.length} parameters.`);
|
|
1018
1007
|
}
|
|
1019
|
-
const value = params[index
|
|
1008
|
+
const value = params[index];
|
|
1020
1009
|
if (!Array.isArray(value)) {
|
|
1021
1010
|
throw new Error(`Malformed query template. Tuple list expected.`);
|
|
1022
1011
|
}
|
|
@@ -1028,7 +1017,8 @@ function* pairFragmentsWithParams(fragments, params) {
|
|
|
1028
1017
|
throw new Error(`Malformed query template. Tuple expected.`);
|
|
1029
1018
|
}
|
|
1030
1019
|
}
|
|
1031
|
-
yield { ...fragment, value };
|
|
1020
|
+
yield { ...fragment, value, argType: argTypes?.[index] };
|
|
1021
|
+
index++;
|
|
1032
1022
|
break;
|
|
1033
1023
|
}
|
|
1034
1024
|
}
|
|
@@ -1054,7 +1044,7 @@ function* flattenedFragmentParams(fragment) {
|
|
|
1054
1044
|
function chunkParams(fragments, params, maxChunkSize) {
|
|
1055
1045
|
let totalParamCount = 0;
|
|
1056
1046
|
let maxParamsPerFragment = 0;
|
|
1057
|
-
for (const fragment of pairFragmentsWithParams(fragments, params)) {
|
|
1047
|
+
for (const fragment of pairFragmentsWithParams(fragments, params, void 0)) {
|
|
1058
1048
|
let paramSize = 0;
|
|
1059
1049
|
for (const _ of flattenedFragmentParams(fragment)) {
|
|
1060
1050
|
void _;
|
|
@@ -1064,7 +1054,7 @@ function chunkParams(fragments, params, maxChunkSize) {
|
|
|
1064
1054
|
totalParamCount += paramSize;
|
|
1065
1055
|
}
|
|
1066
1056
|
let chunkedParams = [[]];
|
|
1067
|
-
for (const fragment of pairFragmentsWithParams(fragments, params)) {
|
|
1057
|
+
for (const fragment of pairFragmentsWithParams(fragments, params, void 0)) {
|
|
1068
1058
|
switch (fragment.type) {
|
|
1069
1059
|
case "parameter": {
|
|
1070
1060
|
for (const params2 of chunkedParams) {
|
|
@@ -1130,16 +1120,8 @@ function chunkArray(array, chunkSize) {
|
|
|
1130
1120
|
// src/interpreter/serialize-sql.ts
|
|
1131
1121
|
import { ColumnTypeEnum } from "@prisma/driver-adapter-utils";
|
|
1132
1122
|
function serializeSql(resultSet) {
|
|
1133
|
-
const mappers = resultSet.columnTypes.map((type) => {
|
|
1134
|
-
switch (type) {
|
|
1135
|
-
case ColumnTypeEnum.Bytes:
|
|
1136
|
-
return (value) => Array.isArray(value) ? new Uint8Array(value) : value;
|
|
1137
|
-
default:
|
|
1138
|
-
return (value) => value;
|
|
1139
|
-
}
|
|
1140
|
-
});
|
|
1141
1123
|
return resultSet.rows.map(
|
|
1142
|
-
(row) => row.
|
|
1124
|
+
(row) => row.reduce((acc, value, index) => {
|
|
1143
1125
|
const splitByDot = resultSet.columnNames[index].split(".");
|
|
1144
1126
|
let nested = acc;
|
|
1145
1127
|
for (let i = 0; i < splitByDot.length; i++) {
|
|
@@ -1433,14 +1415,14 @@ var QueryInterpreter = class _QueryInterpreter {
|
|
|
1433
1415
|
queryPlan,
|
|
1434
1416
|
queryable,
|
|
1435
1417
|
this.#placeholderValues,
|
|
1436
|
-
this.#generators.snapshot(
|
|
1418
|
+
this.#generators.snapshot()
|
|
1437
1419
|
).catch((e) => rethrowAsUserFacing(e));
|
|
1438
1420
|
return value;
|
|
1439
1421
|
}
|
|
1440
1422
|
async interpretNode(node, queryable, scope, generators) {
|
|
1441
1423
|
switch (node.type) {
|
|
1442
1424
|
case "value": {
|
|
1443
|
-
return { value:
|
|
1425
|
+
return { value: evaluateArg(node.args, scope, generators) };
|
|
1444
1426
|
}
|
|
1445
1427
|
case "seq": {
|
|
1446
1428
|
let result;
|
|
@@ -1545,7 +1527,7 @@ var QueryInterpreter = class _QueryInterpreter {
|
|
|
1545
1527
|
}
|
|
1546
1528
|
case "mapField": {
|
|
1547
1529
|
const { value, lastInsertId } = await this.interpretNode(node.args.records, queryable, scope, generators);
|
|
1548
|
-
return { value:
|
|
1530
|
+
return { value: mapField2(value, node.args.field), lastInsertId };
|
|
1549
1531
|
}
|
|
1550
1532
|
case "join": {
|
|
1551
1533
|
const { value: parent, lastInsertId } = await this.interpretNode(node.args.parent, queryable, scope, generators);
|
|
@@ -1688,9 +1670,9 @@ function asRecord(value) {
|
|
|
1688
1670
|
}
|
|
1689
1671
|
throw new Error(`Expected object, got ${typeof value}`);
|
|
1690
1672
|
}
|
|
1691
|
-
function
|
|
1673
|
+
function mapField2(value, field) {
|
|
1692
1674
|
if (Array.isArray(value)) {
|
|
1693
|
-
return value.map((element) =>
|
|
1675
|
+
return value.map((element) => mapField2(element, field));
|
|
1694
1676
|
}
|
|
1695
1677
|
if (typeof value === "object" && value !== null) {
|
|
1696
1678
|
return value[field] ?? null;
|
|
@@ -1734,7 +1716,7 @@ function attachChildrenToParents(parentRecords, children) {
|
|
|
1734
1716
|
function evalFieldInitializer(initializer, lastInsertId, scope, generators) {
|
|
1735
1717
|
switch (initializer.type) {
|
|
1736
1718
|
case "value":
|
|
1737
|
-
return
|
|
1719
|
+
return evaluateArg(initializer.value, scope, generators);
|
|
1738
1720
|
case "lastInsertId":
|
|
1739
1721
|
return lastInsertId;
|
|
1740
1722
|
default:
|
|
@@ -1744,16 +1726,16 @@ function evalFieldInitializer(initializer, lastInsertId, scope, generators) {
|
|
|
1744
1726
|
function evalFieldOperation(op, value, scope, generators) {
|
|
1745
1727
|
switch (op.type) {
|
|
1746
1728
|
case "set":
|
|
1747
|
-
return
|
|
1729
|
+
return evaluateArg(op.value, scope, generators);
|
|
1748
1730
|
case "add":
|
|
1749
|
-
return asNumber2(value) + asNumber2(
|
|
1731
|
+
return asNumber2(value) + asNumber2(evaluateArg(op.value, scope, generators));
|
|
1750
1732
|
case "subtract":
|
|
1751
|
-
return asNumber2(value) - asNumber2(
|
|
1733
|
+
return asNumber2(value) - asNumber2(evaluateArg(op.value, scope, generators));
|
|
1752
1734
|
case "multiply":
|
|
1753
|
-
return asNumber2(value) * asNumber2(
|
|
1735
|
+
return asNumber2(value) * asNumber2(evaluateArg(op.value, scope, generators));
|
|
1754
1736
|
case "divide": {
|
|
1755
1737
|
const lhs = asNumber2(value);
|
|
1756
|
-
const rhs = asNumber2(
|
|
1738
|
+
const rhs = asNumber2(evaluateArg(op.value, scope, generators));
|
|
1757
1739
|
if (rhs === 0) {
|
|
1758
1740
|
return null;
|
|
1759
1741
|
}
|
|
@@ -2074,8 +2056,6 @@ export {
|
|
|
2074
2056
|
deserializeJsonResponse,
|
|
2075
2057
|
doKeysMatch,
|
|
2076
2058
|
isDeepStrictEqual,
|
|
2077
|
-
isPrismaValueBigInt,
|
|
2078
|
-
isPrismaValueBytes,
|
|
2079
2059
|
isPrismaValueGenerator,
|
|
2080
2060
|
isPrismaValuePlaceholder,
|
|
2081
2061
|
noopTracingHelper,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Provider } from '@prisma/driver-adapter-utils';
|
|
2
1
|
export declare class GeneratorRegistry {
|
|
3
2
|
#private;
|
|
4
3
|
constructor();
|
|
@@ -7,7 +6,7 @@ export declare class GeneratorRegistry {
|
|
|
7
6
|
* method being called, meaning that the built-in time-based generators will always return
|
|
8
7
|
* the same value on repeated calls as long as the same snapshot is used.
|
|
9
8
|
*/
|
|
10
|
-
snapshot(
|
|
9
|
+
snapshot(): Readonly<GeneratorRegistrySnapshot>;
|
|
11
10
|
/**
|
|
12
11
|
* Registers a new generator with the given name.
|
|
13
12
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SqlQuery } from '@prisma/driver-adapter-utils';
|
|
2
|
-
import
|
|
2
|
+
import { type QueryPlanDbQuery } from '../query-plan';
|
|
3
3
|
import { GeneratorRegistrySnapshot } from './generators';
|
|
4
4
|
import { ScopeBindings } from './scope';
|
|
5
5
|
export declare function renderQuery(dbQuery: QueryPlanDbQuery, scope: ScopeBindings, generators: GeneratorRegistrySnapshot, maxChunkSize?: number): SqlQuery[];
|
|
6
|
-
export declare function
|
|
6
|
+
export declare function evaluateArg(arg: unknown, scope: ScopeBindings, generators: GeneratorRegistrySnapshot): unknown;
|
package/dist/query-plan.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ArgType, Arity } from '@prisma/driver-adapter-utils';
|
|
1
2
|
export type PrismaValuePlaceholder = {
|
|
2
3
|
prisma__type: 'param';
|
|
3
4
|
prisma__value: {
|
|
@@ -14,59 +15,18 @@ export type PrismaValueGenerator = {
|
|
|
14
15
|
};
|
|
15
16
|
};
|
|
16
17
|
export declare function isPrismaValueGenerator(value: unknown): value is PrismaValueGenerator;
|
|
17
|
-
export type
|
|
18
|
-
prisma__type: 'bytes';
|
|
19
|
-
prisma__value: string;
|
|
20
|
-
};
|
|
21
|
-
export declare function isPrismaValueBytes(value: unknown): value is PrismaValueBytes;
|
|
22
|
-
export type PrismaValueBigInt = {
|
|
23
|
-
prisma__type: 'bigint';
|
|
24
|
-
prisma__value: string;
|
|
25
|
-
};
|
|
26
|
-
export declare function isPrismaValueBigInt(value: unknown): value is PrismaValueBigInt;
|
|
27
|
-
export type PrismaValue = string | boolean | number | PrismaValue[] | null | Record<string, unknown> | PrismaValuePlaceholder | PrismaValueGenerator | PrismaValueBytes | PrismaValueBigInt;
|
|
28
|
-
export type PrismaValueType = {
|
|
29
|
-
type: 'Any';
|
|
30
|
-
} | {
|
|
31
|
-
type: 'String';
|
|
32
|
-
} | {
|
|
33
|
-
type: 'Int';
|
|
34
|
-
} | {
|
|
35
|
-
type: 'BigInt';
|
|
36
|
-
} | {
|
|
37
|
-
type: 'Float';
|
|
38
|
-
} | {
|
|
39
|
-
type: 'Boolean';
|
|
40
|
-
} | {
|
|
41
|
-
type: 'Decimal';
|
|
42
|
-
} | {
|
|
43
|
-
type: 'Date';
|
|
44
|
-
} | {
|
|
45
|
-
type: 'Time';
|
|
46
|
-
} | {
|
|
47
|
-
type: 'Array';
|
|
48
|
-
inner: PrismaValueType;
|
|
49
|
-
} | {
|
|
50
|
-
type: 'Json';
|
|
51
|
-
} | {
|
|
52
|
-
type: 'Object';
|
|
53
|
-
} | {
|
|
54
|
-
type: 'Bytes';
|
|
55
|
-
} | {
|
|
56
|
-
type: 'Enum';
|
|
57
|
-
inner: string;
|
|
58
|
-
};
|
|
18
|
+
export type PrismaValue = string | boolean | number | PrismaValue[] | null | Record<string, unknown> | PrismaValuePlaceholder | PrismaValueGenerator;
|
|
59
19
|
export type ResultNode = {
|
|
60
|
-
type: '
|
|
20
|
+
type: 'affectedRows';
|
|
61
21
|
} | {
|
|
62
|
-
type: '
|
|
22
|
+
type: 'object';
|
|
63
23
|
fields: Record<string, ResultNode>;
|
|
64
24
|
serializedName: string | null;
|
|
65
25
|
skipNulls: boolean;
|
|
66
26
|
} | {
|
|
67
|
-
type: '
|
|
27
|
+
type: 'field';
|
|
68
28
|
dbName: string;
|
|
69
|
-
|
|
29
|
+
fieldType: FieldType;
|
|
70
30
|
};
|
|
71
31
|
export type QueryPlanBinding = {
|
|
72
32
|
name: string;
|
|
@@ -75,14 +35,20 @@ export type QueryPlanBinding = {
|
|
|
75
35
|
export type QueryPlanDbQuery = {
|
|
76
36
|
type: 'rawSql';
|
|
77
37
|
sql: string;
|
|
78
|
-
|
|
38
|
+
args: PrismaValue[];
|
|
39
|
+
argTypes: ArgType[];
|
|
79
40
|
} | {
|
|
80
41
|
type: 'templateSql';
|
|
81
42
|
fragments: Fragment[];
|
|
82
43
|
placeholderFormat: PlaceholderFormat;
|
|
83
|
-
|
|
44
|
+
args: PrismaValue[];
|
|
45
|
+
argTypes: DynamicArgType[];
|
|
84
46
|
chunkable: boolean;
|
|
85
47
|
};
|
|
48
|
+
export type DynamicArgType = ArgType | {
|
|
49
|
+
arity: 'tuple';
|
|
50
|
+
elements: ArgType[];
|
|
51
|
+
};
|
|
86
52
|
export type Fragment = {
|
|
87
53
|
type: 'stringChunk';
|
|
88
54
|
chunk: string;
|
|
@@ -300,3 +266,12 @@ export type ValidationError = {
|
|
|
300
266
|
child: string;
|
|
301
267
|
};
|
|
302
268
|
};
|
|
269
|
+
export type FieldType = {
|
|
270
|
+
arity: Arity;
|
|
271
|
+
} & FieldScalarType;
|
|
272
|
+
export type FieldScalarType = {
|
|
273
|
+
type: 'string' | 'int' | 'bigint' | 'float' | 'boolean' | 'json' | 'object' | 'datetime' | 'decimal' | 'bytes' | 'unsupported';
|
|
274
|
+
} | {
|
|
275
|
+
type: 'enum';
|
|
276
|
+
name: string;
|
|
277
|
+
};
|